Skip to content

pacquet: materialise file:<workspace> snapshots in create_virtual_store #12038

Description

@zkochan

Problem

When an installer keeps dedupeInjectedDeps: false and the workspace has an injected dep — e.g. dependenciesMeta: { b: { injected: true } } on packages/a consuming packages/b via workspace:* — pacquet:

  1. Resolves b to file:packages/b (correct).
  2. Writes the snapshot in pnpm-lock.yaml under file:packages/b (correct, after feat(pacquet): port dedupeInjectedDeps #12023's ImporterDepVersion::File arm).
  3. Symlinks packages/a/node_modules/b<virtual_store>/b@file+packages+b/node_modules/b.
  4. Never copies packages/b's contents into <virtual_store>/b@file+packages+b/.

So the symlink in step 3 points at a directory that doesn't exist on disk.

How it surfaces

  • Linux / macOS: pacquet install exits 0. The dangling symlink silently breaks anything that tries to read through it; pnpm itself can no longer load that importer's deps from pacquet-written output.
  • Windows: the bin-link pass that walks each importer's node_modules reading package.json for bin manifests trips ERROR_INVALID_NAME (os error 123) reading through the broken link with a mixed-separator path (packages/a\\node_modules\\b\\package.json). Install fails.

#12023 ships an e2e regression test for the lockfile-writer's File arm (pacquet/crates/cli/tests/dedupe_injected_deps.rs::injected_workspace_dep_with_dedupe_off_writes_file_arm) marked #[cfg_attr(target_os = \"windows\", ignore = \"…\")] because of this gap. The test should be re-enabled on Windows once this is fixed.

Expected behavior

Pacquet's create_virtual_store pass should treat a file:<workspace> snapshot the same way pnpm does: copy (or hardlink, depending on packageImportMethod) the source workspace project's contents into <virtual_store>/<name>@file+<path>/node_modules/<name>/ so the per-importer symlink resolves to a real directory.

Upstream's runLifecycleHooksConcurrently + storeController.importPackage flow for injected dirs is the closest pnpm equivalent; pacquet's install_package_by_snapshot.rs already has a TODO comment at the dependenciesMeta[*].injected = true branch on the matter.

Scope

  • Recognise file:<rel-path-to-lockfile-dir> snapshot keys during create_virtual_store.
  • Resolve the source workspace project dir from the path payload.
  • Materialise the contents into the virtual store using the install's configured packageImportMethod (clone / hardlink / copy).
  • Make sure excludeLinksFromLockfile interactions still work — the materialised path must agree with the symlink target the linker computes.
  • Re-enable the #[cfg_attr(target_os = \"windows\", ignore)] on the e2e test above.

Related


Written by an agent (Claude Code, claude-opus-4-7).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions