Skip to content
This repository was archived by the owner on May 14, 2026. It is now read-only.
This repository was archived by the owner on May 14, 2026. It is now read-only.

Persist .modules.yaml.skipped + headless seed-and-recompute (#434 slice 3) #463

@zkochan

Description

@zkochan

Follow-up to #434 (umbrella, closed). Pacquet's slice 1 (#439) computes a SkippedSnapshots set on every frozen-lockfile install but never serializes it. The next install always recomputes from scratch — correct for the common case (constraints in the lockfile drive the recompute), incorrect for the edge case upstream cares about: a snapshot that was previously skipped should stay skipped on the next run even when the lockfile's per-snapshot metadata is later relaxed.

Scope

Mirror pnpm/pnpm@94240bc046 at three sites:

Write

Modules.skipped: Vec<String> is already declared at crates/modules-yaml/src/lib.rs:197 and sorted-on-write at :407, but build_modules_manifest leaves it Default::default(). Wire SkippedSnapshots (produced inside InstallFrozenLockfile::run) up to Install::run so build_modules_manifest can serialize the PackageKeys as the sorted depPath string list pnpm writes — see upstream literal at index.ts:1625.

Read + seed

On a subsequent install, read .modules.yaml.skipped (via read_modules_manifest) and seed the in-memory SkippedSnapshots before invoking compute_skipped_snapshots. The seed entries short-circuit the per-snapshot re-check, mirroring upstream's early return at lockfileToDepGraph.ts:194: if a key is already in the skip set, the per-snapshot installability check is bypassed and no pnpm:skipped-optional-dependency event is re-emitted.

The seed-preservation must also apply on the fast path (any_installability_constraint returns false), so a previously-skipped snapshot survives even when the lockfile's per-snapshot constraints have since been removed.

Per-snapshot re-check

For non-seeded snapshots, compute_skipped_snapshots already re-runs package_is_installable from scratch — that covers the "host arch changed since last install" case upstream guards at :206-215. No change needed beyond accepting the seed input.

Tests

Port from installing/deps-installer/test/install/optionalDependencies.ts:

  • :74 skip optional dependency that does not support the current OS — remove node_modules, reinstall with frozenLockfile: true, verify skipped packages remain skipped. This is the first survives-frozen-reinstall coverage and the canonical write-then-seed-then-read flow.
  • :470 skip optional dependency that does not support the current OS, when doing install on a subset of workspace projects — same shape, multi-importer.

Out of scope

  • Current-lockfile write (<virtual_store_dir>/lock.yaml) — that's umbrella slice 6, builds on this slice.
  • --no-optional plumbing — umbrella slice 5.
  • --force headless re-check (which bypasses the seed) — pacquet doesn't expose --force yet.

Upstream pin

pnpm/pnpm@94240bc046. Pacquet slice 1 in #439, slice 2 in #456; this is umbrella slice 3.


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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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