Zoltan Kochan ceec335e85 fix(package-manager): link optionalDependencies siblings into slot (#526)
`create_symlink_layout` only iterated `snapshot.dependencies`, so a
package whose CPU/OS-specific siblings live entirely under
`optionalDependencies` (e.g. `@typescript/native-preview`,
`@reflink/reflink`, every `*-darwin-arm64` / `*-linux-x64` family)
ended up with a slot `node_modules/<scope>/` containing only the
parent package — no platform binary sibling. Consumers that do
`require.resolve('@typescript/native-preview-darwin-arm64')` from
inside `getExePath.js` walked parent directories and found nothing,
so `tsgo --version` (and every other tool that delegates to a
platform variant) crashed with `Unable to resolve … missing the
package on disk`.

Port upstream's `dependencies ∪ optionalDependencies` merge — the
graph builder at
https://github.com/pnpm/pnpm/blob/da65e6262/deps/graph-builder/src/lockfileToDepGraph.ts#L150-L156
unifies both maps into one `allDeps` for each node's children, and
`linkAllModules` then symlinks every child with two short-circuits:
`alias === depNode.name` (a snapshot referencing itself) and
`!pkg.installable && pkg.optional` (a non-materialized optional).
See https://github.com/pnpm/pnpm/blob/da65e6262/installing/deps-installer/src/install/link.ts#L521-L549.

`create_symlink_layout` now takes both maps and a `SkippedSnapshots`
reference, merges them, and applies both short-circuits. The skip
set is threaded through `InstallPackageBySnapshot` (cold batch) and
the warm-batch `CreateVirtualDirBySnapshot` call site in
`CreateVirtualStore::run`, so a target dropped by the installability
pass, by `--no-optional`, or by a swallowed optional fetch failure
gets no dangling symlink.

Five new unit tests in `create_symlink_layout/tests.rs` cover the
matching-optional happy path, the skipped-optional dangling-link
guard, the self-name guard for entries listed in either bucket, the
both-buckets-absent no-op, and the alias-resolve path (aliased deps
still link the alias filename while resolving the slot via the
target's name). End-to-end verification: `pacquet install
--frozen-lockfile` followed by `tsgo --version` in the pnpm v11
repo now succeeds; the matching `native-preview-darwin-arm64`
sibling shows up in the slot's `node_modules/@typescript/`.

---
Written by an agent (Claude Code, claude-opus-4-7).
2026-05-14 16:44:16 +02:00
Description
No description provided
MIT 280 MiB
Languages
Rust 56.4%
TypeScript 43%
JavaScript 0.5%