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

feat(package-manager): runtime bin-link + --no-runtime (#437 slice D3 + E)#506

Merged
zkochan merged 2 commits into
mainfrom
feat/437-slice-d3-e-f
May 13, 2026
Merged

feat(package-manager): runtime bin-link + --no-runtime (#437 slice D3 + E)#506
zkochan merged 2 commits into
mainfrom
feat/437-slice-d3-e-f

Conversation

@zkochan

@zkochan zkochan commented May 13, 2026

Copy link
Copy Markdown
Member

Summary

Closes the install-pipeline side of #437. After this PR, a frozen-lockfile install can fetch a runtime archive, write its CAS-imported files into the virtual store slot, and create cmd-shims for the declared executables under each importer's node_modules/.bin/.

Slice D3 — runtime bin-link integration

Runtime archives (node@runtime:, deno@runtime:, bun@runtime:) don't ship a package.json, so the existing bin-link step had nothing to consume off the slot. fetch_binary_resolution_to_cas now synthesizes one in the same shape upstream's appendManifest does:

{ "name": "<pkg.name>", "version": "<pkg.version>", "bin": <BinarySpec> }

The bytes go through StoreDir::write_cas_file (same content-addressing as every other CAS-imported file), the resulting cas-path is inserted into the snapshot's cas_paths under "package.json", and the existing link_bins_of_packages flow picks it up.

link_bins::build_has_bin_set now includes Binary / Variations resolutions unconditionally — pnpm v11 doesn't emit hasBin: true on runtime metadata, but the synthesized manifest always carries bins, so the lookup must not be gated on the metadata flag.

Slice E — --no-runtime flag

  • New Config::skip_runtimes: bool (default false, reserved for pnpm-workspace.yaml / .npmrc plumbing in a follow-up).
  • New InstallArgs::no_runtime CLI flag (--no-runtime).
  • CLI computes config.skip_runtimes || --no-runtime and threads it through InstallInstallFrozenLockfile. When true, every snapshot whose metadata resolution is Binary or Variations is added to the install-time skip set (re-using add_optional_excluded since the bucket count and .modules.yaml.skipped semantics line up with --no-optional).

Slice F — what's in / what's deferred

Unit-tested:

  • synthesize_runtime_manifest_emits_name_version_and_bin_single — pins BinarySpec::Single → JSON string.
  • synthesize_runtime_manifest_emits_name_version_and_bin_map — pins BinarySpec::Map → JSON object.
  • synthesize_runtime_manifest_preserves_scoped_name@scope/name round-trips through the name field.
  • build_has_bin_set_includes_runtime_resolutions_even_when_has_bin_is_absent — verified by removing the runtime arm (test fails as expected).
  • archive_filter_for_only_returns_filter_for_unscoped_node (from slice D2) covers the per-package filter dispatcher.
  • node_extras_filter_matches_upstream_regex_alternations (from slice D2) covers the regex port.

Deferred to a follow-up: end-to-end install fixtures (recorded-archive frozen-lockfile install, variant-mismatch error, --no-runtime integration, integrity-mismatch path, path-traversal). They need either a small recorded Node archive in the repo or a mockable pnpm-resolution-mirror; keeping this PR reviewable.

Test plan

  • All 9 install_package_by_snapshot::tests::* pass.
  • All 15 link_bins::tests::* pass (added build_has_bin_set_includes_runtime_resolutions...).
  • All existing pacquet-package-manager tests pass (skip_runtimes threaded through every Install { ... } and Config { ... } literal across the workspace).
  • just ready, taplo format --check, just dylint, cargo doc -D warnings green.

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

Summary by CodeRabbit

  • New Features

    • Added a CLI flag to skip installing runtime dependencies (Node, Deno, Bun)
    • Added a config option to exclude runtime dependencies from installs
    • Installer now synthesizes runtime package manifests when needed so runtime artifacts can be handled without full installs
  • Bug Fixes

    • Bin-linking now recognizes synthesized runtime packages when determining available binaries
  • Tests

    • Added and updated unit tests covering runtime synthesis and skip-runtime behavior

Review Change Stack

… + E)

Closes the install-pipeline side of #437:

**Slice D3 — runtime bin-link integration.** Runtime archives
(`node@runtime:`, etc.) don't ship a `package.json`, so the
existing bin-link step had nothing to consume off the slot.
`fetch_binary_resolution_to_cas` now synthesizes one in the same
shape upstream's `appendManifest` does:

  { "name": "<pkg.name>", "version": "<pkg.version>", "bin": <BinarySpec> }

The bytes go through `StoreDir::write_cas_file` (same content-
addressing as every other CAS-imported file), the resulting cas-path
is inserted into the snapshot's `cas_paths` under `package.json`,
and the existing `link_bins_of_packages` flow picks it up.

`link_bins::build_has_bin_set` now includes `Binary` / `Variations`
resolutions unconditionally — pnpm v11 doesn't emit `hasBin: true`
on runtime metadata, but the synthesized manifest always carries
bins, so the lookup must not be gated on the metadata flag.

**Slice E — `--no-runtime` flag.** New `Config::skip_runtimes`
(default false) and `InstallArgs::no_runtime` CLI flag. The CLI
computes `config.skip_runtimes || --no-runtime` and threads it
through `Install` → `InstallFrozenLockfile`. When set, every
snapshot whose metadata resolution is `Binary` or `Variations` is
added to the install-time skip set (re-using
`add_optional_excluded` since the bucket count and
`.modules.yaml.skipped` semantics line up with `--no-optional`).

**Unit tests.**

- `synthesize_runtime_manifest_emits_name_version_and_bin_single` —
  pins `BinarySpec::Single` → JSON string.
- `synthesize_runtime_manifest_emits_name_version_and_bin_map` —
  pins `BinarySpec::Map` → JSON object with all bin entries.
- `synthesize_runtime_manifest_preserves_scoped_name` — `@scope/name`
  round-trips through the `name` field.
- `build_has_bin_set_includes_runtime_resolutions_even_when_has_bin_is_absent`
  — pins the runtime arm. Verified by removing the arm — test
  fails as expected.

End-to-end install fixtures (slice F's remaining items —
recorded-archive frozen-lockfile install, variant-mismatch
error, `--no-runtime` integration, integrity-mismatch path) need
a small recorded Node archive in the repo (or a mockable
`pnpm-resolution-mirror`). Tracking them as a separate
follow-up so this PR stays reviewable.
Copilot AI review requested due to automatic review settings May 13, 2026 22:31
@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b55fdcf5-9fe6-4a55-b527-6411d9a56943

📥 Commits

Reviewing files that changed from the base of the PR and between 841493b and 990dc77.

📒 Files selected for processing (1)
  • crates/package-manager/src/install_frozen_lockfile.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/package-manager/src/install_frozen_lockfile.rs
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Code Coverage
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Lint and Test (windows-latest)
  • GitHub Check: Lint and Test (ubuntu-latest)
  • GitHub Check: Lint and Test (macos-latest)
  • GitHub Check: Run benchmark on ubuntu-latest

📝 Walkthrough

Walkthrough

Adds a --no-runtime CLI flag and skip_runtimes config option, threads the flag through Install, excludes Binary/Variations runtime snapshots in frozen-lockfile installs, synthesizes runtime package.json manifests into the CAS, and updates bin-linking to recognize synthesized runtime bins.

Changes

Runtime dependency skipping via CLI flag and config

Layer / File(s) Summary
CLI flag and config schema
crates/cli/src/cli_args/install.rs, crates/config/src/lib.rs
InstallArgs gains --no-runtime flag; Config gains skip_runtimes: bool field documenting runtime dependency exclusion.
Install struct threading
crates/package-manager/src/install.rs, crates/package-manager/src/install_frozen_lockfile.rs, crates/package-manager/src/add.rs
Install and InstallFrozenLockfile gain skip_runtimes field; Add::run and Install::run thread the field through the frozen-lockfile dispatch.
CLI logic: compute and apply skip decision
crates/cli/src/cli_args/install.rs
InstallArgs::run destructures no_runtime, computes `skip_runtimes = config.skip_runtimes
Install frozen lockfile runtime filtering
crates/package-manager/src/install_frozen_lockfile.rs
When skip_runtimes is enabled, packages with LockfileResolution::Binary or LockfileResolution::Variations are added to skipped-snapshots via add_optional_excluded.
Runtime manifest synthesis and CAS import
crates/package-manager/src/install_package_by_snapshot.rs
fetch_binary_resolution_to_cas refactored to accept package_key, synthesizes runtime package.json with name/version/bin metadata, writes to CAS, and adds SynthesizeRuntimeManifest error variant.
Bin-linking for runtime resolutions
crates/package-manager/src/link_bins.rs
build_has_bin_set extended to include LockfileResolution::Binary and LockfileResolution::Variations entries alongside explicit has_bin == Some(true) metadata.
Manifest synthesis unit tests
crates/package-manager/src/install_package_by_snapshot/tests.rs
New test cases verify synthesize_runtime_manifest_bytes JSON output for BinarySpec::Single, BinarySpec::Map, and scoped package name preservation.
Bin-linking tests for runtime resolutions
crates/package-manager/src/link_bins/tests.rs
Added helper constructors and test case verifying build_has_bin_set includes Binary and Variations entries unconditionally while filtering registry/directory by has_bin presence.
Test fixture updates
crates/package-manager/src/install/tests.rs, crates/package-manager/src/install_package_from_registry/tests.rs
All Install { ... } struct literals and Config initializations updated to include skip_runtimes: false.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • pnpm/pacquet#496: Overlaps in changes to fetch_binary_resolution_to_cas and Binary/Variations handling.
  • pnpm/pacquet#333: Related changes to build_has_bin_set and bin-linking logic.
  • pnpm/pacquet#485: Similar use of skipped-snapshots plumbing in frozen-lockfile installs.

Suggested reviewers

  • anonrig

Poem

🐰 I hop the tree of code tonight,
Skip runtimes with a little light,
A flag, a synth, a CAS-file song,
Binaries quiet, installs move along. 🥕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: implementing runtime bin-link integration and the --no-runtime CLI flag, with specific reference to the issue slices (#437 D3 + E).
Description check ✅ Passed The description comprehensively covers the PR objectives, changes, and testing approach. It includes a clear summary, linked issue, test plan, and implementation details across all affected modules.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/437-slice-d3-e-f

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions

github-actions Bot commented May 13, 2026

Copy link
Copy Markdown

Micro-Benchmark Results

Linux

group                          main                                   pr
-----                          ----                                   --
tarball/download_dependency    1.01     16.1±0.39ms   270.2 KB/sec    1.00     15.9±0.10ms   272.4 KB/sec

@codecov

codecov Bot commented May 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 45.00000% with 44 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.54%. Comparing base (e10d0e5) to head (990dc77).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
...package-manager/src/install_package_by_snapshot.rs 43.90% 23 Missing ⚠️
...tes/package-manager/src/install_frozen_lockfile.rs 12.50% 21 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #506      +/-   ##
==========================================
- Coverage   88.64%   88.54%   -0.11%     
==========================================
  Files         122      124       +2     
  Lines       13273    13500     +227     
==========================================
+ Hits        11766    11953     +187     
- Misses       1507     1547      +40     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/package-manager/src/install_frozen_lockfile.rs`:
- Around line 365-371: The code widening the semantics of the --no-runtime flag
currently drops transitive runtime snapshots (the block that mutates
dependenciesByProjectId when --no-runtime/skipRuntimes is set); change that
logic to match pnpm semantics by only filtering runtime entries at the
same/project-level (i.e., implement skipRuntimes to exclude runtime packages
from direct runtime resolution but do NOT prune or drop transitive runtime
snapshots from the lockfile traversal), locate the conditional that applies the
filter in install_frozen_lockfile.rs (the --no-runtime / skipRuntimes branch)
and revert the transitive-removal behavior so transitive runtime deps remain
available while still excluding runtime entries where pnpm would.

In `@crates/package-manager/src/link_bins.rs`:
- Around line 238-241: The matches! guard is moving meta.resolution (which is
not Copy) out of a borrowed meta; change the guard to match on a reference
instead — e.g., use matches!(&meta.resolution, LockfileResolution::Binary(_) |
LockfileResolution::Variations(_)) so you borrow the enum rather than move it;
update the patterns if necessary to match referenced variants
(LockfileResolution::Binary, LockfileResolution::Variations) and keep the rest
of the surrounding logic in link_bins.rs unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f630d49-d120-4838-b6c7-47ce04e60b2c

📥 Commits

Reviewing files that changed from the base of the PR and between e10d0e5 and 841493b.

📒 Files selected for processing (11)
  • crates/cli/src/cli_args/install.rs
  • crates/config/src/lib.rs
  • crates/package-manager/src/add.rs
  • crates/package-manager/src/install.rs
  • crates/package-manager/src/install/tests.rs
  • crates/package-manager/src/install_frozen_lockfile.rs
  • crates/package-manager/src/install_package_by_snapshot.rs
  • crates/package-manager/src/install_package_by_snapshot/tests.rs
  • crates/package-manager/src/install_package_from_registry/tests.rs
  • crates/package-manager/src/link_bins.rs
  • crates/package-manager/src/link_bins/tests.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: copilot-pull-request-reviewer
  • GitHub Check: Code Coverage
  • GitHub Check: Lint and Test (ubuntu-latest)
  • GitHub Check: Lint and Test (windows-latest)
  • GitHub Check: Lint and Test (macos-latest)
  • GitHub Check: Run benchmark on ubuntu-latest
  • GitHub Check: Run benchmark on ubuntu-latest
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Preserve existing method chains and pipe-trait chains; do not break them into intermediate let bindings unless there is a concrete justification such as a compilation failure, borrow checker rejection, meaningful performance improvement, or other technical necessity. Refactoring for style alone is not sufficient justification.
Choose owned vs. borrowed parameters to minimize copies; prefer borrowed types (&Path over &PathBuf, &str over &String) when it does not force extra copies.
Prefer Arc::clone(&x) and Rc::clone(&x) over x.clone() for reference-counted types to make the cost visible at the call site.
Do not use star imports inside module bodies. Write use super::{Foo, bar} instead of use super::*; for any glob whose target is a module you control. External-crate preludes (e.g., use rayon::prelude::*;) and root-of-module re-exports (e.g., pub use submodule::*; in lib.rs) are exceptions.
Follow Rust API Guidelines for naming, as documented in https://rust-lang.github.io/api-guidelines/naming.html.
Declare a newtype wrapper for any branded string type being ported from TypeScript pnpm. Do not collapse the brand into a plain String or &str; give the type its own struct so misuse is a type error.
When porting branded string types where upstream TypeScript always validates before construction, validate in the Rust port too. Construct the wrapper only via TryFrom<String> and/or FromStr; do not provide an infallible public constructor that takes an arbitrary string.
For branded string types where upstream TypeScript never validates (used purely for type-safety to prevent confusion between string slots), expose an infallible From<String> and From<&str> constructor in the Rust wrapper.
When upstream TypeScript occasionally constructs a branded type without validation (via bare as assertion), add a from_str_unchecked (or similarly named) constructor on the Rust side. Keep the validating constructor as well; `from_str_u...

Files:

  • crates/package-manager/src/install_package_from_registry/tests.rs
  • crates/package-manager/src/link_bins.rs
  • crates/config/src/lib.rs
  • crates/package-manager/src/install.rs
  • crates/cli/src/cli_args/install.rs
  • crates/package-manager/src/install_frozen_lockfile.rs
  • crates/package-manager/src/link_bins/tests.rs
  • crates/package-manager/src/add.rs
  • crates/package-manager/src/install_package_by_snapshot/tests.rs
  • crates/package-manager/src/install_package_by_snapshot.rs
  • crates/package-manager/src/install/tests.rs
🧠 Learnings (4)
📚 Learning: 2026-05-01T10:01:33.766Z
Learnt from: zkochan
Repo: pnpm/pacquet PR: 349
File: crates/reporter/src/tests.rs:121-121
Timestamp: 2026-05-01T10:01:33.766Z
Learning: In Rust test code, follow the repo’s CODE_STYLE_GUIDE test-logging rule: add logging (e.g., `eprintln!`/`eprintln!(...)`) so that useful diagnostic values are printed when a test fails, unless the assertion is `assert_eq!` (where the differing values are already included). Concretely, if you use assertions like `assert!`, `assert_ne!`, etc., ensure the test logs the relevant actual/expected values (or context) before/around the assertion so failures can be diagnosed without rerunning.

Applied to files:

  • crates/package-manager/src/install_package_from_registry/tests.rs
  • crates/package-manager/src/link_bins/tests.rs
  • crates/package-manager/src/install_package_by_snapshot/tests.rs
  • crates/package-manager/src/install/tests.rs
📚 Learning: 2026-05-07T23:19:08.272Z
Learnt from: KSXGitHub
Repo: pnpm/pacquet PR: 401
File: tasks/integrated-benchmark/src/work_env.rs:343-344
Timestamp: 2026-05-07T23:19:08.272Z
Learning: When reviewing Rust code in pnpm/pacquet for deprecated API usage, do not automatically treat `serde_saphyr::to_string` as deprecated. In `serde-saphyr` v0.0.25, `serde_saphyr::to_string` has no `#[deprecated]` attribute (the `#[deprecated]` later in `serde-saphyr-0.0.25/src/lib.rs` applies to a different function). Only flag `serde_saphyr::to_string` as deprecated if the resolved dependency version’s source shows `#[deprecated]` on that specific function.

Applied to files:

  • crates/package-manager/src/install_package_from_registry/tests.rs
  • crates/package-manager/src/link_bins.rs
  • crates/config/src/lib.rs
  • crates/package-manager/src/install.rs
  • crates/cli/src/cli_args/install.rs
  • crates/package-manager/src/install_frozen_lockfile.rs
  • crates/package-manager/src/link_bins/tests.rs
  • crates/package-manager/src/add.rs
  • crates/package-manager/src/install_package_by_snapshot/tests.rs
  • crates/package-manager/src/install_package_by_snapshot.rs
  • crates/package-manager/src/install/tests.rs
📚 Learning: 2026-05-13T19:22:48.951Z
Learnt from: zkochan
Repo: pnpm/pacquet PR: 478
File: crates/package-manager/src/hoisted_dep_graph.rs:51-55
Timestamp: 2026-05-13T19:22:48.951Z
Learning: When reviewing this Rust codebase, avoid introducing/using a newtype like `PkgIdWithPatchHash` in only one module (e.g., `hoisted_dep_graph.rs`) if other related pacquet modules still represent the upstream pnpm “pkg id with patch hash” as a plain `String` (e.g., `virtual_store_layout`). For type consistency, either keep `pkg_id_with_patch_hash` as `String` here, or require a workspace-wide sweep that defines/extracts the `PkgIdWithPatchHash` newtype once and updates all call sites together (otherwise defer the refactor to a coordinated follow-up PR).

Applied to files:

  • crates/package-manager/src/install_package_from_registry/tests.rs
  • crates/package-manager/src/link_bins.rs
  • crates/package-manager/src/install.rs
  • crates/package-manager/src/install_frozen_lockfile.rs
  • crates/package-manager/src/link_bins/tests.rs
  • crates/package-manager/src/add.rs
  • crates/package-manager/src/install_package_by_snapshot/tests.rs
  • crates/package-manager/src/install_package_by_snapshot.rs
  • crates/package-manager/src/install/tests.rs
📚 Learning: 2026-05-13T20:09:22.171Z
Learnt from: zkochan
Repo: pnpm/pacquet PR: 486
File: crates/package-manager/src/hoisted_dep_graph.rs:472-476
Timestamp: 2026-05-13T20:09:22.171Z
Learning: In pnpm/pacquet, when generating serialized `hoisted_locations` strings (used for `.modules.yaml`), normalize path separators to forward slashes (e.g., replace `\\` with `/`). This preserves cross-platform portability: the output must not use OS-native separators because upstream pnpm’s `path.relative` can return platform-specific separators, which would break consistency with pnpm/pacquet’s other serialized formats on Windows.

Applied to files:

  • crates/package-manager/src/install_package_from_registry/tests.rs
  • crates/package-manager/src/link_bins.rs
  • crates/package-manager/src/install.rs
  • crates/package-manager/src/install_frozen_lockfile.rs
  • crates/package-manager/src/link_bins/tests.rs
  • crates/package-manager/src/add.rs
  • crates/package-manager/src/install_package_by_snapshot/tests.rs
  • crates/package-manager/src/install_package_by_snapshot.rs
  • crates/package-manager/src/install/tests.rs
🔇 Additional comments (10)
crates/config/src/lib.rs (1)

262-273: LGTM!

crates/package-manager/src/install_package_from_registry/tests.rs (1)

34-34: LGTM!

crates/package-manager/src/add.rs (1)

91-91: LGTM!

crates/package-manager/src/install/tests.rs (1)

56-56: LGTM!

Also applies to: 110-110, 147-147, 213-213, 272-272, 348-348, 409-409, 490-490, 628-628, 722-722, 838-838, 929-929, 1028-1028, 1071-1071, 1156-1156, 1243-1243, 1294-1294, 1375-1375, 1446-1446, 1523-1523, 1701-1701, 1811-1811, 1904-1904, 2003-2003, 2087-2087, 2174-2174

crates/package-manager/src/install.rs (1)

39-46: LGTM!

Also applies to: 150-150, 299-299

crates/cli/src/cli_args/install.rs (1)

59-67: LGTM!

Also applies to: 73-78, 89-94, 102-102

crates/package-manager/src/install_frozen_lockfile.rs (1)

381-384: ⚡ Quick win

No changes needed. The code correctly borrows meta.resolution through automatic dereferencing. The matches! macro handles borrowed enum references properly, and there is no move semantics hazard here.

			> Likely an incorrect or invalid review comment.
crates/package-manager/src/install_package_by_snapshot/tests.rs (1)

3-3: LGTM!

Also applies to: 7-8, 212-297

crates/package-manager/src/link_bins/tests.rs (1)

1-3: LGTM!

Also applies to: 6-10, 13-13, 495-605

crates/package-manager/src/install_package_by_snapshot.rs (1)

12-12: LGTM!

Also applies to: 141-156, 296-296, 351-351, 582-698

Comment thread crates/package-manager/src/install_frozen_lockfile.rs Outdated
Comment thread crates/package-manager/src/link_bins.rs
@github-actions

Copy link
Copy Markdown

Integrated-Benchmark Report (Linux)

Scenario: Frozen Lockfile

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 2.495 ± 0.065 2.402 2.581 1.00
pacquet@main 2.501 ± 0.068 2.387 2.596 1.00 ± 0.04
pnpm 5.701 ± 0.052 5.624 5.805 2.29 ± 0.06
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 2.49467866896,
      "stddev": 0.0649281519056914,
      "median": 2.49329887686,
      "user": 2.6256371799999996,
      "system": 3.4819801999999997,
      "min": 2.4022019338600002,
      "max": 2.5805629578600002,
      "times": [
        2.5683184318600003,
        2.43174423186,
        2.44334348886,
        2.57232159986,
        2.48346515886,
        2.5219934048600003,
        2.43970288686,
        2.5031325948600003,
        2.5805629578600002,
        2.4022019338600002
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 2.5007598299600002,
      "stddev": 0.06758736295007756,
      "median": 2.50961755886,
      "user": 2.5907365799999997,
      "system": 3.4873862000000004,
      "min": 2.3872154508600003,
      "max": 2.59630314786,
      "times": [
        2.48628351486,
        2.53283659686,
        2.49513313886,
        2.58738110186,
        2.52410197886,
        2.4324960458600002,
        2.53023733886,
        2.59630314786,
        2.3872154508600003,
        2.43560998486
      ]
    },
    {
      "command": "pnpm",
      "mean": 5.70059476416,
      "stddev": 0.05206951709450585,
      "median": 5.7029620008599995,
      "user": 8.326199780000001,
      "system": 4.243370399999999,
      "min": 5.623806184859999,
      "max": 5.80465791086,
      "times": [
        5.68146234486,
        5.69075375786,
        5.72059100986,
        5.6681126828599995,
        5.715170243859999,
        5.64025504086,
        5.72324146386,
        5.7378970018599995,
        5.623806184859999,
        5.80465791086
      ]
    }
  ]
}

Scenario: Frozen Lockfile (Hot Cache)

Command Mean [ms] Min [ms] Max [ms] Relative
pacquet@HEAD 744.8 ± 39.3 703.4 843.6 1.00
pacquet@main 816.8 ± 46.7 763.9 917.0 1.10 ± 0.09
pnpm 2412.5 ± 132.7 2279.9 2732.3 3.24 ± 0.25
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 0.7447543064600002,
      "stddev": 0.039341296637116344,
      "median": 0.73763581806,
      "user": 0.36405374,
      "system": 1.62188208,
      "min": 0.70344815656,
      "max": 0.84364976956,
      "times": [
        0.84364976956,
        0.7498882235600001,
        0.74416146256,
        0.7583074105600001,
        0.7279127455600001,
        0.7561017585600001,
        0.7122694995600001,
        0.7311101735600001,
        0.7206938645600001,
        0.70344815656
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 0.8167777660600001,
      "stddev": 0.04665706853021891,
      "median": 0.8226501445600001,
      "user": 0.3805867399999999,
      "system": 1.6255397799999998,
      "min": 0.7639175545600001,
      "max": 0.91704111456,
      "times": [
        0.8464094135600001,
        0.7663326705600001,
        0.8293436015600001,
        0.76967916656,
        0.7639175545600001,
        0.8223301715600001,
        0.82297011756,
        0.7940241545600001,
        0.91704111456,
        0.8357296955600001
      ]
    },
    {
      "command": "pnpm",
      "mean": 2.4125018659600004,
      "stddev": 0.13273958532138191,
      "median": 2.35979283106,
      "user": 2.7929191399999995,
      "system": 2.15872758,
      "min": 2.27992613956,
      "max": 2.7323436185600003,
      "times": [
        2.48969277556,
        2.33620955556,
        2.7323436185600003,
        2.37419312856,
        2.3378061635600003,
        2.27992613956,
        2.3647098245600002,
        2.3445208235600004,
        2.3548758375600003,
        2.51074079256
      ]
    }
  ]
}

Address CodeRabbit review on #506: my initial implementation
iterated `packages` (every metadata entry) and added all
`Binary` / `Variations` snapshots to the skip set, which widened
the behavior beyond pnpm's `skipRuntimes`. Per the cardinal rule
(CLAUDE.md: "Port behavior faithfully. ... Do not invent
behavior that pnpm does not have."), match upstream exactly.

Upstream's filter at
[`installing/deps-installer/src/install/index.ts`](https://github.com/pnpm/pnpm/blob/94240bc046/installing/deps-installer/src/install/index.ts#L1374-L1387)
iterates `dependenciesByProjectId` (per-importer direct deps) and
adds `depPath` to `ctx.skipped` when `depPath.includes('@runtime:')`.
Transitive runtime entries — unusual but possible — stay in the
install.

Pacquet now mirrors that exactly: walk each importer's
`dependencies` / `dev_dependencies` / `optional_dependencies`,
build the candidate snapshot key from `(alias, version)`, check
for the `@runtime:` substring, and only add the metadata-confirmed
`Binary` / `Variations` keys to `skipped`. Aliased runtime deps
(unusual) fall through the same way upstream does — pnpm's lookup
is by depPath, not by alias.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants