Skip to content

refactor(pacquet/config): replace default callback with self#11736

Merged
KSXGitHub merged 3 commits into
mainfrom
claude/refactor-config-builder-cO880
May 19, 2026
Merged

refactor(pacquet/config): replace default callback with self#11736
KSXGitHub merged 3 commits into
mainfrom
claude/refactor-config-builder-cO880

Conversation

@KSXGitHub

@KSXGitHub KSXGitHub commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Config::current's default callback was invoked unconditionally on the function's first line, so the laziness it advertised was never exercised. The single production caller passed Default::default, and 17 of 18 test callers passed Config::new. Only one test passed a custom closure — to seed a non-default starting Config.

Reshape Config::current into a builder that takes mut self. Callers build the starting Config themselves; the method layers .npmrc and pnpm-workspace.yaml on top. The method name stays current.

  • Production: Config::default().current::<Host>(&dir)
  • Outlier test: Config { symlink: false, ..Config::new() }.current::<H>(...)

Out of scope: the inner layering logic — only the entry shape changes.

Resolves #11731.


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

Summary by CodeRabbit

  • Refactor
    • Simplified the configuration method API for improved consistency
    • Updated configuration initialization pattern across the codebase
    • Enhanced internal configuration handling logic

Review Change Stack

… a mut-self builder

The closure was invoked unconditionally on the first line, so the laziness
it advertised was never exercised. Production passed `Default::default`,
17 of 18 test callers passed `Config::new`, and a single test passed a
custom closure only to seed a non-default starting value.

Replace it with a builder-style `current_dir(mut self, start_dir)` method.
Callers build the starting `Config` themselves and the method layers
`.npmrc` and `pnpm-workspace.yaml` on top. The lone outlier test becomes
`Config { symlink: false, ..Config::new() }.current_dir::<H>(...)`.

Resolves #11731.
@coderabbitai

coderabbitai Bot commented May 19, 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: 7965ab81-4d35-4498-a502-d2e21979643f

📥 Commits

Reviewing files that changed from the base of the PR and between c83b002 and 754e12e.

📒 Files selected for processing (3)
  • pacquet/crates/cli/src/cli_args.rs
  • pacquet/crates/config/src/api.rs
  • pacquet/crates/config/src/lib.rs
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (1)
pacquet/**/*.rs

📄 CodeRabbit inference engine (pacquet/AGENTS.md)

pacquet/**/*.rs: Log emissions must mirror pnpm's pnpm:<channel> events through globalLogger / logger.debug(...) / streamParser.write(...) calls with matching payload and ordering for @pnpm/cli.default-reporter compatibility
Prefer real fixtures (tempfile::TempDir, mocked registry, integration tests) over dependency-injection seams for testing, reserving DI only for branches real fixtures cannot cover (filesystem error kinds, deterministic time, process-global state, external-service paths)
Declare a newtype wrapper (struct) for branded string types instead of collapsing the brand into plain String or &str
If upstream pnpm always validates before construction of a branded string type, validate too by constructing only via TryFrom and/or FromStr
If upstream pnpm never validates a branded string type, brand only for type-safety by exposing an infallible From and From<&str> constructor
If upstream pnpm occasionally constructs a branded string type without validation, expose from_str_unchecked constructor alongside the validating constructor
Match upstream pnpm serde behavior for branded string types by using #[serde(try_from = "String")] for deserialization and #[serde(into = "String")] for serialization
Use #[derive(derive_more::From)] and #[derive(derive_more::Into)] for mechanical branded string type conversions instead of handwriting impl blocks
Model upstream string literal unions or string literal types as Rust enums instead of newtype wrappers
Treat string template literal types (e.g., ${string}@${string}) as branded string types with the same validation discipline as other branded strings
Choose owned vs. borrowed parameters to minimize copies; widen to the most encompassing type (&Path over &PathBuf, &str over &String) when it doesn't force extra copies
Prefer Arc::clone(&x) / Rc::clone(&x) over x.clone() for reference-counted types to make the cost visible at the call site
Follow test-logging guidance in the style guide: log before...

Files:

  • pacquet/crates/cli/src/cli_args.rs
  • pacquet/crates/config/src/api.rs
  • pacquet/crates/config/src/lib.rs
🔇 Additional comments (3)
pacquet/crates/config/src/lib.rs (1)

896-897: LGTM!

Also applies to: 914-915, 932-932, 938-938, 945-946, 1019-1020, 1024-1024, 1032-1032, 1041-1041, 1046-1046, 1232-1233, 1247-1248, 1268-1269, 1282-1283, 1316-1317, 1332-1333, 1346-1346, 1375-1377, 1397-1398, 1422-1422, 1442-1442, 1475-1475, 1526-1527, 1547-1547, 1572-1572, 1598-1598, 1640-1641, 1683-1684

pacquet/crates/config/src/api.rs (1)

7-7: LGTM!

Also applies to: 83-83

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

102-103: LGTM!


📝 Walkthrough

Walkthrough

This PR refactors Config::current from a two-parameter API accepting a factory callback into a single-parameter builder method that receives mut self, allowing callers to construct the initial configuration before layering .npmrc and workspace settings onto it. All call sites and documentation are updated to the new pattern.

Changes

Config::current builder pattern migration

Layer / File(s) Summary
Core API refactor and implementation
pacquet/crates/config/src/lib.rs
Config::current signature changes from pub fn current<Sys, Default>(start_dir: &Path, default: Default) to pub fn current<Sys>(mut self, start_dir: &Path). Implementation refactors to apply .npmrc registry/proxy/TLS settings and workspace YAML configuration directly onto self, re-anchoring modules_dir and virtual_store_dir to workspace root before applying settings, then rebuilding auth headers and global-virtual-store derivation onto self before returning Ok(self).
Documentation and usage examples
pacquet/crates/config/src/api.rs
Module-level doc and ignored example code are updated to show Config::default().current::<Host>(&dir) instead of Config::current::<Host, _>(&dir, Default::default), aligning with the new builder pattern.
Production and test call site updates
pacquet/crates/cli/src/cli_args.rs, pacquet/crates/config/src/lib.rs (tests)
Production caller in cli_args.rs and 18 test call sites are updated to use Config::new().current::<Sys>(...) or Config { ... }.current::<Sys>(...) chaining instead of Config::current::<Sys, _>(..., Config::new).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • pnpm/pnpm#11730: Companion refactor to the same Config::current capability-trait API that updates related call sites and documentation patterns in cli_args.rs and config/src/api.rs.

Suggested reviewers

  • zkochan

Poem

🐰 A builder rose, no callbacks needed here,
Config takes self and layers far more clear,
From factory ghosts to chaining so sweet,
The config refactor makes the API complete! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main refactoring: replacing a default callback parameter with a mut self builder-style signature in Config::current.
Linked Issues check ✅ Passed The PR fully implements the refactoring specified in #11731: Config::current now takes mut self instead of a default closure, all call sites are updated, and the builder-style API is complete.
Out of Scope Changes check ✅ Passed All changes are in-scope: three files updated to align with the refactored Config::current signature, with no extraneous modifications beyond what the builder-style conversion requires.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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 claude/refactor-config-builder-cO880

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.

❤️ Share

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

@github-actions

github-actions Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Micro-Benchmark Results

Linux

group                          main                                   pr
-----                          ----                                   --
tarball/download_dependency    1.02      7.8±0.34ms   554.3 KB/sec    1.00      7.7±0.39ms   566.9 KB/sec

@codecov-commenter

codecov-commenter commented May 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.85%. Comparing base (c83b002) to head (754e12e).

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #11736   +/-   ##
=======================================
  Coverage   89.85%   89.85%           
=======================================
  Files         145      145           
  Lines       16424    16426    +2     
=======================================
+ Hits        14757    14759    +2     
  Misses       1667     1667           

☔ 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.

claude added 2 commits May 19, 2026 01:50
The previous commit renamed the loader to current_dir; revert the name back
to Config::current. Only the entry shape (builder-style mut self instead of
a default callback) is intentional — the rename was not.
@github-actions

Copy link
Copy Markdown
Contributor

Integrated-Benchmark Report (Linux)

Scenario: Frozen Lockfile

Command Mean [s] Min [s] Max [s] Relative
pacquet@HEAD 2.439 ± 0.076 2.342 2.566 1.02 ± 0.04
pacquet@main 2.402 ± 0.043 2.332 2.472 1.00
pnpm 4.853 ± 0.037 4.808 4.906 2.02 ± 0.04
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 2.4392141665,
      "stddev": 0.0763076835019069,
      "median": 2.4175111162,
      "user": 2.6485406999999994,
      "system": 3.7357871000000005,
      "min": 2.3421295267,
      "max": 2.5658202906999996,
      "times": [
        2.5233206716999996,
        2.3421295267,
        2.4876508506999997,
        2.4102093907,
        2.5658202906999996,
        2.5075095967,
        2.3859676157,
        2.4248128416999997,
        2.3676577326999997,
        2.3770631477
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 2.4024879022,
      "stddev": 0.04312745452273411,
      "median": 2.4146350252,
      "user": 2.6116134,
      "system": 3.7462828000000004,
      "min": 2.3319620017,
      "max": 2.4724483456999997,
      "times": [
        2.3895882836999998,
        2.4216151246999997,
        2.4234152066999997,
        2.3319620017,
        2.4724483456999997,
        2.4164149836999997,
        2.3453527306999997,
        2.3715855857,
        2.4396416927,
        2.4128550666999997
      ]
    },
    {
      "command": "pnpm",
      "mean": 4.8533832765,
      "stddev": 0.03661553512910324,
      "median": 4.8444775366999995,
      "user": 8.1632713,
      "system": 4.2837559,
      "min": 4.8077602836999995,
      "max": 4.9064369057,
      "times": [
        4.8083310337,
        4.9015440707,
        4.9064369057,
        4.8619727317,
        4.8371334097,
        4.8518216637,
        4.8934660687,
        4.829760880699999,
        4.8356057167,
        4.8077602836999995
      ]
    }
  ]
}

Scenario: Frozen Lockfile (Hot Cache)

Command Mean [ms] Min [ms] Max [ms] Relative
pacquet@HEAD 679.2 ± 62.4 650.0 855.6 1.00
pacquet@main 694.1 ± 36.2 663.2 758.0 1.02 ± 0.11
pnpm 2653.7 ± 58.5 2565.2 2790.3 3.91 ± 0.37
BENCHMARK_REPORT.json
{
  "results": [
    {
      "command": "pacquet@HEAD",
      "mean": 0.67919360546,
      "stddev": 0.0624314253049751,
      "median": 0.6602758077599999,
      "user": 0.3687704,
      "system": 1.5528836600000002,
      "min": 0.64998060576,
      "max": 0.85562461676,
      "times": [
        0.85562461676,
        0.66167595576,
        0.66365376876,
        0.65842749976,
        0.65232133576,
        0.66148420076,
        0.65906741476,
        0.64998060576,
        0.65331788876,
        0.67638276776
      ]
    },
    {
      "command": "pacquet@main",
      "mean": 0.69406727646,
      "stddev": 0.03622546331243175,
      "median": 0.67958125776,
      "user": 0.3941126,
      "system": 1.55855056,
      "min": 0.66316180476,
      "max": 0.75797928376,
      "times": [
        0.75205933876,
        0.66859558576,
        0.67912486576,
        0.72221584376,
        0.6662228717600001,
        0.68240996976,
        0.66886555076,
        0.75797928376,
        0.68003764976,
        0.66316180476
      ]
    },
    {
      "command": "pnpm",
      "mean": 2.65374178926,
      "stddev": 0.0585076242150254,
      "median": 2.65083848076,
      "user": 3.2331701,
      "system": 2.2706366599999996,
      "min": 2.56519553376,
      "max": 2.79030943176,
      "times": [
        2.6775434587599998,
        2.64918364876,
        2.63233325076,
        2.79030943176,
        2.6795412707599997,
        2.60996712976,
        2.65333769176,
        2.65249331276,
        2.56519553376,
        2.6275131637599998
      ]
    }
  ]
}

@KSXGitHub KSXGitHub marked this pull request as ready for review May 19, 2026 02:31
@KSXGitHub KSXGitHub requested a review from zkochan as a code owner May 19, 2026 02:31
Copilot AI review requested due to automatic review settings May 19, 2026 02:31
@KSXGitHub KSXGitHub enabled auto-merge (squash) May 19, 2026 02:32

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.

Pull request overview

Refactors Config::current from a function taking a default: FnOnce() -> Config closure into a builder method taking mut self. The previous closure was invoked unconditionally on the first line, so its laziness was never used, and 18 of 19 callers passed Config::new/Default::default. The new shape lets callers construct the starting Config directly and chain .current::<Sys>(&dir).

Changes:

  • Reshape Config::current signature: drop the Default generic and closure parameter, take mut self, rename internal configself.
  • Update the single production call site in cli_args.rs to Config::default().current::<Host>(&dir).
  • Update all test call sites; the one outlier now uses Config { symlink: false, ..Config::new() }.current::<HostWithHome>(...).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
pacquet/crates/config/src/lib.rs Convert Config::current to a mut self builder; update all in-module test callers.
pacquet/crates/config/src/api.rs Update doc examples to the new Config::default().current::<Host>(&dir) form.
pacquet/crates/cli/src/cli_args.rs Update the production call site to the builder form.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@KSXGitHub KSXGitHub merged commit f77244f into main May 19, 2026
33 of 34 checks passed
@KSXGitHub KSXGitHub deleted the claude/refactor-config-builder-cO880 branch May 19, 2026 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(pacquet/config): replace Config::current's default callback with a mut self builder method

5 participants