You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #434 (umbrella, closed). Pacquet currently writes the raw wanted lockfile as <virtual_store_dir>/lock.yaml (install.rs:389-393). Upstream pnpm writes a filtered version — the lockfile with optional + skipped subtrees pruned and include flags applied — so a subsequent install can diff against what was actually materialized rather than against the resolver's full ambition.
Without the prune, the current lockfile claims optional snapshots that were dropped by --no-optional (slice 5) or by installability (slice 1) or by fetch failures (slice 4) are present. The next install's diff would treat those as "already done" and skip work that should actually run.
Scope
Port filterLockfileByImportersAndEngine as a Lockfile::filter_for_current on pacquet-lockfile, with one pacquet-specific simplification: instead of re-running engine + supportedArchitectures + skipped checks at filter time, reuse the SkippedSnapshots set already produced during install — its union of installability + fetch_failed + optional_excluded is the exact set upstream's filter would also drop, just precomputed during the install pipeline. Same observable filter result, no duplicated walk.
Importer-side filter (include): filterImporter.ts:4-16 — drop dependencies / devDependencies / optionalDependencies whose include bool is false.
Importer.optionalDependencies post-filter: filterLockfileByImportersAndEngine.ts:75-83 — even when include.optionalDependencies is true, drop entries whose resolved snapshot didn't survive the packages-level filter.
Pacquet's implementation
New helper on pacquet-package-manager (not pacquet-lockfile — IncludedDependencies lives in pacquet-modules-yaml and SkippedSnapshots lives in pacquet-package-manager, so the filter belongs where it can see both): filter_for_current(lockfile: &Lockfile, included: IncludedDependencies, skipped: &SkippedSnapshots) -> Lockfile.
Importer filter: drop dep maps per include; further filter optional_dependencies so entries pointing at dropped snapshots are removed too.
Reachability walk: from filtered importer roots, BFS through snapshot dependencies + optional_dependencies, skipping any key in skipped. The result is the set of snapshot keys to keep.
Snapshot + packages filter: drop entries whose key isn't reachable.
Wire site: install.rs:389-393 already calls save_current_to_virtual_store_dir. Replace the raw write with lockfile.filter_for_current(included, &frozen_skipped).save_current_to_virtual_store_dir(...).
optionalDependencies.ts:213optional subdependency is not removed from current lockfile when new dependency is added — multi-install case.
optionalDependencies.ts:74 — reverify-current-matches-wanted-with-skipped (already partially covered by slice 3, but the current-lockfile contents differ now).
Plus unit tests on filter_for_current itself: importer-level filtering, reachability walk, skipped-snapshot drop, optional_dependencies post-filter against the packages-level prune.
Follow-up to #434 (umbrella, closed). Pacquet currently writes the raw wanted lockfile as
<virtual_store_dir>/lock.yaml(install.rs:389-393). Upstream pnpm writes a filtered version — the lockfile with optional + skipped subtrees pruned andincludeflags applied — so a subsequent install can diff against what was actually materialized rather than against the resolver's full ambition.Without the prune, the current lockfile claims optional snapshots that were dropped by
--no-optional(slice 5) or by installability (slice 1) or by fetch failures (slice 4) are present. The next install's diff would treat those as "already done" and skip work that should actually run.Scope
Port
filterLockfileByImportersAndEngineas aLockfile::filter_for_currentonpacquet-lockfile, with one pacquet-specific simplification: instead of re-running engine + supportedArchitectures + skipped checks at filter time, reuse theSkippedSnapshotsset already produced during install — its union ofinstallability+fetch_failed+optional_excludedis the exact set upstream's filter would also drop, just precomputed during the install pipeline. Same observable filter result, no duplicated walk.Upstream's flow pinned at pnpm/pnpm@94240bc046:
deps-restorer/src/index.ts:311—const { lockfile: filteredLockfile, ... } = filterLockfileByImportersAndEngine(wantedLockfile, initialImporterIds, filterOpts).deps-restorer/src/index.ts:687-695—writeCurrentLockfile(currentLockfileDir, filteredLockfile).include):filterImporter.ts:4-16— dropdependencies/devDependencies/optionalDependencieswhose include bool is false.filterLockfileByImportersAndEngine.ts:75-83— even wheninclude.optionalDependenciesis true, drop entries whose resolved snapshot didn't survive the packages-level filter.Pacquet's implementation
pacquet-package-manager(notpacquet-lockfile—IncludedDependencieslives inpacquet-modules-yamlandSkippedSnapshotslives inpacquet-package-manager, so the filter belongs where it can see both):filter_for_current(lockfile: &Lockfile, included: IncludedDependencies, skipped: &SkippedSnapshots) -> Lockfile.include; further filteroptional_dependenciesso entries pointing at dropped snapshots are removed too.dependencies + optional_dependencies, skipping any key inskipped. The result is the set of snapshot keys to keep.install.rs:389-393already callssave_current_to_virtual_store_dir. Replace the raw write withlockfile.filter_for_current(included, &frozen_skipped).save_current_to_virtual_store_dir(...).Tests to port
optionalDependencies.ts:618remove optional dependencies that are not used— main coverage.optionalDependencies.ts:213optional subdependency is not removed from current lockfile when new dependency is added— multi-install case.optionalDependencies.ts:74— reverify-current-matches-wanted-with-skipped (already partially covered by slice 3, but the current-lockfile contents differ now).Plus unit tests on
filter_for_currentitself: importer-level filtering, reachability walk, skipped-snapshot drop,optional_dependenciespost-filter against the packages-level prune.Out of scope
optionalDependencies.ts:633) — pacquet doesn't fully wire the hoisted node-linker through the lockfile-write path yet; folding it into slice 6 mixes concerns. Tracked separately under Support nodeLinker: 'hoisted' — umbrella #438 (hoisted-linker umbrella).flipping current_lockfile_exists— actually already happens through the on-disk file presence check; not a separate bool.pnpm install --filterslicing —selectedImporterIdsupstream concept; pacquet doesn't have--filteryet.Upstream pin
pnpm/pnpm@94240bc046. Pacquet umbrella slice 1 in #439, slice 2 in #456, slice 3 in #467, slice 4 in #474, slice 5 in #485; this is umbrella slice 6.
Written by an agent (Claude Code, claude-opus-4-7).