feat(pacquet/config): port preferWorkspacePackages setting#12032
Conversation
Port the `preferWorkspacePackages` setting from pnpm. When enabled, a workspace package wins over a newer registry pick during resolution. Default `false`, matching pnpm. - Config plumbing: `Config.prefer_workspace_packages`, `WorkspaceSettings.prefer_workspace_packages`, `PNPM_CONFIG_PREFER_WORKSPACE_PACKAGES` env overlay, and the `clear_workspace_only_fields` / `apply_to` wiring. - Install pipeline: thread `config.prefer_workspace_packages` into the `ResolveOptions` built in `install_with_fresh_lockfile`. The npm resolver already consumes this flag in `try_workspace_shadow`. - Optimistic-repeat-install drift: `WorkspaceStateSettings.prefer_workspace_packages` is now compared by `settings_match` and written by `current_settings`. A switch to the setting between installs invalidates the cached-modules fast path. Closes one of the items on #12009.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
📜 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). (3)
🧰 Additional context used📓 Path-based instructions (1)pacquet/**/*.rs📄 CodeRabbit inference engine (pacquet/AGENTS.md)
Files:
🧠 Learnings (3)📚 Learning: 2026-05-20T19:40:55.051ZApplied to files:
📚 Learning: 2026-05-22T00:08:44.646ZApplied to files:
📚 Learning: 2026-05-20T23:07:58.444ZApplied to files:
🔇 Additional comments (9)
📝 WalkthroughWalkthroughThis PR adds support for the ChangespreferWorkspacePackages Configuration and Integration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Review Summary by QodoPort preferWorkspacePackages setting from pnpm
WalkthroughsDescription• Port preferWorkspacePackages setting from pnpm configuration • Thread setting through install pipeline into ResolveOptions • Add drift detection for optimistic-repeat-install invalidation • Extend tests to verify setting round-trips and behavior Diagramflowchart LR
A["pnpm-workspace.yaml"] -->|"parse"| B["WorkspaceSettings.prefer_workspace_packages"]
B -->|"apply_to"| C["Config.prefer_workspace_packages"]
C -->|"thread"| D["ResolveOptions"]
D -->|"consume"| E["npm resolver try_workspace_shadow"]
C -->|"compare"| F["settings_match drift check"]
C -->|"write"| G["WorkspaceStateSettings"]
File Changes1. pacquet/crates/config/src/env_overlay.rs
|
|
Actionable comments posted: 0 |
Micro-Benchmark ResultsLinux |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #12032 +/- ##
==========================================
- Coverage 88.30% 88.29% -0.01%
==========================================
Files 228 228
Lines 28961 28966 +5
==========================================
+ Hits 25573 25575 +2
- Misses 3388 3391 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Integrated-Benchmark Report (Linux)Scenario: Isolated linker: fresh restore, cold cache + cold store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 2.0932339412200003,
"stddev": 0.06610418260709262,
"median": 2.0981334820199997,
"user": 2.76979166,
"system": 3.2595043999999995,
"min": 2.00034820152,
"max": 2.18120268352,
"times": [
2.09391898752,
2.06271720152,
2.14323255052,
2.0236524295200002,
2.01584973452,
2.18120268352,
2.13106739352,
2.1780022535200003,
2.00034820152,
2.10234797652
]
},
{
"command": "pacquet@main",
"mean": 2.10010877372,
"stddev": 0.0653159145630942,
"median": 2.10637037652,
"user": 2.74328696,
"system": 3.2991504,
"min": 1.9592219265200002,
"max": 2.18826924352,
"times": [
2.10132294852,
2.02902358452,
2.11028265852,
2.13717855152,
2.10245809452,
2.08739478852,
1.9592219265200002,
2.12880984252,
2.18826924352,
2.15712609852
]
}
]
}Scenario: Isolated linker: fresh restore, hot cache + hot store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 0.6992721530600001,
"stddev": 0.0923278566868327,
"median": 0.6720849375600001,
"user": 0.3770428999999999,
"system": 1.3503535,
"min": 0.6571035270600001,
"max": 0.9590369100600001,
"times": [
0.9590369100600001,
0.6717865460600001,
0.6571035270600001,
0.7025289600600001,
0.6726144350600001,
0.65954951106,
0.6811033510600001,
0.65848841806,
0.6723833290600001,
0.6581265430600001
]
},
{
"command": "pacquet@main",
"mean": 0.66817127056,
"stddev": 0.015222856461511699,
"median": 0.6646840870600002,
"user": 0.3688219,
"system": 1.3541347,
"min": 0.6516668550600001,
"max": 0.69637586506,
"times": [
0.6914244250600001,
0.67379726906,
0.6516668550600001,
0.65935273906,
0.6597337820600001,
0.6517194630600001,
0.6638441060600001,
0.6655240680600001,
0.66827413306,
0.69637586506
]
}
]
}Scenario: Isolated linker: fresh install, cold cache + cold store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 2.3737591018399997,
"stddev": 0.03444858242296407,
"median": 2.37101929814,
"user": 3.9096494,
"system": 3.0217899999999993,
"min": 2.31266591814,
"max": 2.4293964831399997,
"times": [
2.37772099114,
2.3463962611399998,
2.41183337914,
2.35331962214,
2.4046675031399998,
2.4293964831399997,
2.3759400241399997,
2.31266591814,
2.35955226414,
2.36609857214
]
},
{
"command": "pacquet@main",
"mean": 2.3672956751400003,
"stddev": 0.0221311492027324,
"median": 2.36727800214,
"user": 3.8815138999999994,
"system": 3.0362381999999997,
"min": 2.33693328714,
"max": 2.40372140314,
"times": [
2.37061923414,
2.38124853314,
2.33716072014,
2.39540330414,
2.40372140314,
2.3705469461399997,
2.33693328714,
2.35862807414,
2.3640090581399997,
2.35468619114
]
}
]
}Scenario: Isolated linker: fresh install, hot cache + hot store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 1.5713471432600001,
"stddev": 0.04393511004477553,
"median": 1.5775113918600001,
"user": 1.76755016,
"system": 1.80921624,
"min": 1.4917516963600002,
"max": 1.62246608636,
"times": [
1.5761560033600002,
1.6118967133600002,
1.6173554853600003,
1.6012322403600001,
1.62246608636,
1.52421217036,
1.4917516963600002,
1.57886678036,
1.5394974413600002,
1.5500368153600002
]
},
{
"command": "pacquet@main",
"mean": 1.5964863171600001,
"stddev": 0.054817701641631314,
"median": 1.5955620923600002,
"user": 1.78031986,
"system": 1.8122501400000002,
"min": 1.51927488536,
"max": 1.6779342353600002,
"times": [
1.6120668763600001,
1.6035485553600002,
1.55818357636,
1.6744488773600001,
1.5756225883600001,
1.58757562936,
1.51927488536,
1.6779342353600002,
1.5260412773600003,
1.6301666703600002
]
}
]
} |
|
| Branch | pr/12032 |
| Testbed | pacquet |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result milliseconds (ms) (Result Δ%) | Upper Boundary milliseconds (ms) (Limit %) |
|---|---|---|---|
| isolated-linker.fresh-install.cold-cache.cold-store | 📈 view plot 🚷 view threshold | 2,373.76 ms(+1.94%)Baseline: 2,328.67 ms | 2,794.40 ms (84.95%) |
| isolated-linker.fresh-install.hot-cache.hot-store | 📈 view plot 🚷 view threshold | 1,571.35 ms(+7.98%)Baseline: 1,455.27 ms | 1,746.33 ms (89.98%) |
| isolated-linker.fresh-restore.cold-cache.cold-store | 📈 view plot 🚷 view threshold | 2,093.23 ms(+1.68%)Baseline: 2,058.58 ms | 2,470.30 ms (84.74%) |
| isolated-linker.fresh-restore.hot-cache.hot-store | 📈 view plot 🚷 view threshold | 699.27 ms(+2.93%)Baseline: 679.34 ms | 815.21 ms (85.78%) |
Summary
Port the
preferWorkspacePackagessetting from pnpm. When enabled, a workspace package wins over a newer registry pick during resolution. Defaultfalse, matching pnpm.Config.prefer_workspace_packages,WorkspaceSettings.prefer_workspace_packages,PNPM_CONFIG_PREFER_WORKSPACE_PACKAGESenv overlay, and theclear_workspace_only_fields/apply_towiring.config.prefer_workspace_packagesinto theResolveOptionsbuilt byinstall_with_fresh_lockfile. The npm resolver'stry_workspace_shadowalready consumes this flag, mirroring pnpm's registry-pick + workspace shadow.WorkspaceStateSettings.prefer_workspace_packagesis now compared bysettings_matchand written bycurrent_settings. A switch to the setting between installs invalidates the cached-modules fast path.Closes one of the items on #12009.
Test plan
Ported / extended from upstream pnpm:
parses_common_settings_from_yamlto assertpreferWorkspacePackages: trueround-trips frompnpm-workspace.yaml.returns_skipped_when_prefer_workspace_packages_driftin the optimistic-repeat-install drift suite — mirrors pnpm's per-keycheckDepsStatussettings walk and matches thededupe_peersdrift test added in feat(pacquet/deps-resolver): port dedupePeers setting #12022.current_settingstest assertsprefer_workspace_packages: Some(false)is now written toWorkspaceStateSettings.returns_up_to_date_when_state_carries_unported_pnpm_settingsno longer overridesprefer_workspace_packages— it is now a ported setting and the drift gate must honor it.Resolver behavior was already covered by
prefer_workspace_packages_keeps_workspace_over_newer_registry(ports the upstream npm-resolver test); this PR makes the flag actually reachable from end-user configuration.Local checks:
cargo check --workspace --all-targets,cargo clippy --locked --workspace --all-targets -- --deny warnings,cargo fmt --check,taplo format --check,typos pacquet/all clean.pacquet-config(230 tests),pacquet-package-manager(341 tests), and the relevantpacquet-resolving-npm-resolvertest pass locally.Written by an agent (Claude Code, claude-opus-4-7).
Summary by CodeRabbit
prefer_workspace_packagesconfiguration option, allowing users to control whether workspace packages are preferred over registry packages during dependency resolution. This setting can be configured via environment variables, workspace configuration files, or global settings.