Skip to content

feat(pypi): narrow/broad release breadth + multi-variant remove/rollback fixes#90

Merged
Mikola Lysenko (mikolalysenko) merged 1 commit into
mainfrom
feat/pypi-multi-release-breadth
May 28, 2026
Merged

feat(pypi): narrow/broad release breadth + multi-variant remove/rollback fixes#90
Mikola Lysenko (mikolalysenko) merged 1 commit into
mainfrom
feat/pypi-multi-release-breadth

Conversation

@mikolalysenko
Copy link
Copy Markdown
Collaborator

Summary

PyPI is the only ecosystem that carries a Socket-specific artifact_id PURL qualifier, so one package@version can resolve to several patch variants (one per wheel/sdist release). Only the installed distribution can ever apply, yet scan/get downloaded every variant and remove/rollback mishandled the qualified manifest keys. This PR adds a download-time breadth control and fixes the multi-variant lifecycle bugs it exposed.

Feature — download-time release breadth (narrow by default)

  • --all-releases flag (env SOCKET_ALL_RELEASES, default off) on scan and get.
    • Narrow (default): keep only the patch for the locally-installed distribution → smallest .socket/.
    • Broad (--all-releases): keep every release variant → manifest portable across environments (cross-platform CI caches).
  • select_installed_variant (core patch/apply.rs): picks the variant whose first patched file is Ready/AlreadyPatched against the on-disk package. Shared by the narrow filter and the rollback dedupe so selection stays consistent with apply.
  • filter_to_installed_releases (commands/get.rs): runs in the shared download path. Non-PyPI ecosystems and single-variant packages pass through untouched. Falls back to broad (with a warning surfaced in the JSON warnings array) when the package isn't installed or no variant matches the on-disk bytes.

Correctness fixes surfaced by multi-release manifests

  • Base-PURL matching (purl_matches_identifier, core utils/purl.rs): remove/rollback of a base PURL now affect every release variant; a qualified PURL or UUID still targets exactly one. Previously a base PURL matched nothing (manifest keys are qualified for PyPI).
  • Rollback variant dedupe: rollback groups discovered packages by base PURL and rolls back only the installed-dist variant — ending the spurious HashMismatch failures a broad manifest would otherwise cause (all variants resolve to the same on-disk file).
  • remove lists each variant when a base PURL expands, so the blast radius is visible before confirmation.
  • detect_prunable compares on stripped base PURLs, so scan --all-releases --sync no longer prunes the variants it just downloaded.

Tests

  • New in_process_pypi_multi_release.rs: real pip install six==1.16.0 + a three-variant wiremock exercising narrow-keeps-one, broad-keeps-all, remove-base-clears-all-and-rolls-back, and rollback-all-succeeds.
  • Unit tests for purl_matches_identifier, find_patches_to_rollback, remove_patch_from_manifest, detect_prunable (PyPI keep/prune), and --all-releases parse defaults for scan + get.

Full workspace suite: 1573 passed, 0 failed; clippy clean under the pinned 1.93.1 toolchain.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

…ack fixes

PyPI is the only ecosystem that carries a Socket-specific `artifact_id`
PURL qualifier, so a single `package@version` can resolve to several
patch variants (one per wheel/sdist release). Only the installed
distribution can ever apply, but scan/get downloaded every variant and
remove/rollback mishandled the qualified keys.

Feature — download-time release breadth (narrow default):
- Add `--all-releases` (env `SOCKET_ALL_RELEASES`, default off) to `scan`
  and `get`. Narrow keeps only the variant matching the installed
  distribution; broad keeps every variant (portable across environments).
- `select_installed_variant` (core `patch/apply.rs`) picks the variant
  whose first patched file is Ready/AlreadyPatched against the on-disk
  package — shared by the narrow filter and rollback dedupe.
- `filter_to_installed_releases` (commands/get.rs) runs in the shared
  download path; non-PyPI ecosystems and single-variant packages pass
  through untouched. Falls back to broad (with a warning surfaced in the
  JSON `warnings` array) when the package is not installed or no variant
  matches the on-disk bytes.

Correctness fixes surfaced by multi-release manifests:
- Base-PURL matching (`purl_matches_identifier`, core utils/purl.rs):
  `remove`/`rollback` of a base PURL now affect every release variant;
  a qualified PURL or UUID still targets exactly one. Previously a base
  PURL matched nothing because manifest keys are qualified.
- Rollback variant dedupe: rollback groups discovered packages by base
  PURL and rolls back only the installed-dist variant, ending the
  spurious HashMismatch failures that broad manifests would have caused
  (the non-installed variants resolve to the same on-disk file).
- `remove` lists each variant when a base PURL expands, so the blast
  radius is visible before confirmation.
- `detect_prunable` compares on stripped base PURLs, so
  `scan --all-releases --sync` no longer prunes the very variants it just
  downloaded.

Tests:
- New in_process_pypi_multi_release.rs: real `pip install six` + a
  three-variant wiremock exercising narrow-keeps-one, broad-keeps-all,
  remove-base-clears-all-and-rolls-back, and rollback-all-succeeds.
- Unit tests for purl_matches_identifier, find_patches_to_rollback,
  remove_patch_from_manifest, detect_prunable (PyPI keep/prune), and
  `--all-releases` parse defaults for scan + get.

Full workspace suite: 1573 passed, 0 failed; clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) merged commit c182e72 into main May 28, 2026
30 checks passed
@mikolalysenko Mikola Lysenko (mikolalysenko) deleted the feat/pypi-multi-release-breadth branch May 28, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants