mirror of
https://github.com/pnpm/pnpm.git
synced 2026-06-28 01:45:30 -04:00
* fix(deps-resolver): make peer-dependent deduplication deterministic When a peer-suffixed package variant is a subset of two or more mutually incompatible larger variants, `deduplicateDepPaths` chose which one to collapse it into based on the order dep paths were inserted into the per-pkgId set, which reflects importer/resolution order and varies between platforms. The same workspace could then resolve to different lockfiles on different machines, making `pnpm dedupe --check` alternate between pass and fail. The depth-count sorter `nodeDepsCount(a) - nodeDepsCount(b)` is not a total order, so equal-count variants keep their (order-dependent) relative position. Tie-break on the dep path string to give a deterministic winner regardless of insertion order. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(deps-resolver): assert resolved depPath is defined before order check The order-invariance assertion compared two undefined values, which would pass silently if the depPath never resolved. Assert both are defined first. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(pacquet): port dedupePeerDependents collapse Port pnpm's `dedupePeerDependents` pass (resolvePeers tail block + `deduplicateAll` / `deduplicateDepPaths` / `nodeDepsCount` / `isCompatibleAndHasMoreDeps`) into pacquet, carrying the pnpm/pnpm#12179 determinism fix: the collapse target is chosen by a total order over `(dep count, dep path)` so it no longer depends on importer/resolution order. Runs in `resolve_peers_workspace` after `dedupe_injected_deps`, gated on `config.dedupe_peer_dependents` (default true) threaded through `WorkspaceResolveOptions`. Duplicate variant groups are reconstructed by grouping the finished graph on `resolved_package_id` instead of threading pnpm's `depPathsByPkgId` through the walk. Since pacquet has no unified post-resolve lockfile pruner, the pass reuses `dedupe_injected_deps::prune_unreachable` to drop collapsed orphans so they don't surface in the lockfile. Both unit tests from pnpm's dedupeDepPaths.test.ts are ported (the version-mismatch collapse and the importer-order determinism case), plus end-to-end remap+prune and incompatible-variant coverage. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Zoltan Kochan <z@kochan.io>