Skip to content

refactor(config): remove rawLocalConfig and force* hoist flags#11199

Merged
zkochan merged 8 commits into
mainfrom
refactor-config3
Apr 5, 2026
Merged

refactor(config): remove rawLocalConfig and force* hoist flags#11199
zkochan merged 8 commits into
mainfrom
refactor-config3

Conversation

@zkochan

@zkochan zkochan commented Apr 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove rawLocalConfig from ConfigContext, config reader, inheritPickedConfig, UniversalOptions, and all consumers
  • Remove forceHoistPattern, forcePublicHoistPattern, forceShamefullyHoistvalidateModules now always checks for hoist pattern mismatches. Config values are always authoritative (v11 breaking change)
  • Auto-set saveWorkspaceProtocol = true when using --workspace with linkWorkspacePackages off, instead of throwing an error (the error was only useful when rawLocalConfig could distinguish explicit --no-save-workspace-protocol from the default)
  • Set frozenLockfile: false explicitly in patchCommit install call, since it needs to update the lockfile after changing patchedDependencies
  • Remove dead rawLocalConfig overrides in deploy and patchCommit

Test plan

  • Compiles cleanly
  • Lint passes
  • Unit tests pass (CI)
  • E2e tests pass (CI)

zkochan added 3 commits April 5, 2026 00:04
rawLocalConfig detected whether hoist settings were explicitly
set. In v11, config values are always authoritative.

- Remove rawLocalConfig from ConfigContext, config reader,
  inheritPickedConfig, UniversalOptions
- Remove forceHoistPattern, forcePublicHoistPattern,
  forceShamefullyHoist — validateModules always checks now
- Simplify save-workspace-protocol check
- Remove dead rawLocalConfig overrides in deploy/patchCommit
@zkochan zkochan marked this pull request as ready for review April 4, 2026 22:10
Copilot AI review requested due to automatic review settings April 4, 2026 22:10

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

This PR refactors config handling by removing rawLocalConfig from the config context/options plumbing and deleting “force* hoist” flags, making configured hoist patterns always authoritative during module validation. It also simplifies workspace save-workspace-protocol conflict handling to always throw.

Changes:

  • Remove rawLocalConfig from ConfigContext/UniversalOptions and update config inheritance + tests/util defaults accordingly.
  • Remove forceHoistPattern / forcePublicHoistPattern / forceShamefullyHoist and make validateModules always check hoist/public-hoist pattern mismatches.
  • Simplify installDeps workspace conflict logic to always throw when link-workspace-packages=false and save-workspace-protocol=false.

Reviewed changes

Copilot reviewed 39 out of 39 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
releasing/commands/test/publish/utils/index.ts Drop rawLocalConfig from test default options.
releasing/commands/test/deploy/utils/index.ts Drop rawLocalConfig from test default options.
releasing/commands/src/deploy/deploy.ts Remove rawLocalConfig overrides; rely on explicit frozen-lockfile options in deploy flows.
patching/commands/test/utils/index.ts Drop rawLocalConfig from test default options.
patching/commands/src/patchCommit.ts Remove rawLocalConfig override when calling install.handler().
installing/deps-installer/test/install/hoist.ts Update hoist mismatch tests to reflect removal of forceHoistPattern.
installing/deps-installer/src/install/validateModules.ts Remove force flags from API and make hoist/public-hoist checks unconditional.
installing/deps-installer/src/install/index.ts Stop passing force hoist flags into validateModules.
installing/deps-installer/src/install/extendInstallOptions.ts Remove force* fields from strict install options typings.
installing/context/src/index.ts Remove force hoist/public-hoist flags from context option types.
installing/commands/test/utils/index.ts Drop rawLocalConfig from test default options.
installing/commands/test/update/issue-7415.ts Drop rawLocalConfig from test default options.
installing/commands/test/update/interactive.ts Drop rawLocalConfig from test default options.
installing/commands/test/prune.ts Drop rawLocalConfig from test default options.
installing/commands/test/peerDependencies.ts Drop rawLocalConfig from test default options and remove raw override.
installing/commands/test/fetch.ts Drop rawLocalConfig from test default options.
installing/commands/test/add.ts Drop rawLocalConfig from test default options and remove raw override path.
installing/commands/src/remove.ts Remove rawLocalConfig from handler option pick list.
installing/commands/src/recursive.ts Remove rawLocalConfig + force hoist flags from recursive options and plumbing.
installing/commands/src/installDeps.ts Remove rawLocalConfig usage; always throw on workspace save-workspace-protocol conflict; remove force-hoist derivation.
installing/commands/src/install.ts Remove rawLocalConfig from install command option type.
exec/commands/test/utils/index.ts Drop rawLocalConfig from exec/dlx test default options.
engine/runtime/commands/src/env/node.ts Remove rawLocalConfig from env/node command options typing.
engine/pm/commands/test/self-updater/selfUpdate.test.ts Drop rawLocalConfig from self-updater test options.
deps/inspection/commands/test/outdated/utils/index.ts Drop rawLocalConfig from test default options.
deps/inspection/commands/test/listing/utils/index.ts Drop rawLocalConfig from test default options.
deps/compliance/commands/test/sbom/utils/index.ts Drop rawLocalConfig from test default options.
deps/compliance/commands/test/licenses/utils/index.ts Drop rawLocalConfig from test default options.
deps/compliance/commands/test/audit/utils/options.ts Drop rawLocalConfig from test default options.
config/reader/test/index.ts Remove skipped tests that asserted rawLocalConfig behavior.
config/reader/src/loadNpmrcFiles.ts Update workspace npmrc field comment (no longer “for rawLocalConfig”).
config/reader/src/inheritPickedConfig.ts Remove rawLocalConfig inheritance from picked-config helper.
config/reader/src/index.ts Stop constructing rawLocalConfig; remove it from returned context.
config/reader/src/Config.ts Remove rawLocalConfig from UniversalOptions and ConfigContext.
config/reader/src/auth.test.ts Update auth inheritance tests to no longer assert rawLocalConfig merging.
config/commands/test/utils/index.ts Drop rawLocalConfig from config-command test context.
building/commands/test/build/utils/index.ts Drop rawLocalConfig from build test default options.
building/commands/src/build/recursive.ts Remove rawLocalConfig from build recursive option typing.
building/commands/src/build/rebuild.ts Remove rawLocalConfig from rebuild option typing.
Comments suppressed due to low confidence (2)

installing/deps-installer/src/install/validateModules.ts:75

  • validateModules() now always checks publicHoistPattern mismatch, but when opts.forceNewModules is true and the workspace root is not an importer (rootProject == null), this path throws instead of purging the lockfileDir/node_modules (unlike the later compatibility checks that add a synthetic importer when rootProject is null). Consider purging the lockfileDir modules dir here as well when rootProject is null (or pushing a synthetic importer into importersToPurge) so filtered/workspace-root-less installs behave consistently.
    installing/deps-installer/src/install/validateModules.ts:93
  • The hoistPattern mismatch check is now unconditional but only runs when rootProject != null. In workspaces where the lockfileDir/root is not an importer (rootProject == null), hoist-pattern differences in .modules.yaml will no longer be detected/purged. Consider running this comparison against the root modules directory regardless of rootProject presence (and purge lockfileDir/node_modules when forceNewModules is true).

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

Comment on lines 115 to 118
return install.handler({
...opts,
patchedDependencies,
rawLocalConfig: {
...opts.rawLocalConfig,
'frozen-lockfile': false,
},
}) as Promise<undefined>

Copilot AI Apr 4, 2026

Copy link

Choose a reason for hiding this comment

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

patch-commit invokes install.handler() after updating patchedDependencies, which may require updating the lockfile. With the rawLocalConfig override removed, this call will now respect a workspace/user frozen-lockfile setting and can fail unexpectedly. Consider explicitly setting frozenLockfile: false (and/or preferFrozenLockfile: false) for this install invocation to preserve the previous behavior and avoid blocking patch-commit when frozen-lockfile is enabled in config.

Copilot uses AI. Check for mistakes.
zkochan added 4 commits April 5, 2026 00:16
patch-commit needs to update the lockfile after changing
patchedDependencies, so frozen lockfile must be disabled.
Instead of throwing when linkWorkspacePackages is off and
saveWorkspaceProtocol is falsy, auto-enable the workspace
protocol. The previous error was only useful when the user
explicitly passed --no-save-workspace-protocol, which required
rawLocalConfig to detect.
Now that hoist pattern mismatches are always validated,
the test triggers node_modules purge which needs TTY
confirmation disabled.
Now that hoist pattern mismatches are always validated,
e2e tests must use consistent hoist settings across
commands operating on the same node_modules.

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

Copilot reviewed 41 out of 41 changed files in this pull request and generated 1 comment.


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

Comment on lines 186 to 188
if (!opts.linkWorkspacePackages && !opts.saveWorkspaceProtocol) {
if (opts.rawLocalConfig['save-workspace-protocol'] === false) {
throw new PnpmError('BAD_OPTIONS', 'This workspace has link-workspace-packages turned off, \
so dependencies are linked from the workspace only when the workspace protocol is used. \
Either set link-workspace-packages to true or don\'t use the --no-save-workspace-protocol option \
when running add/update with the --workspace option')
} else {
opts.saveWorkspaceProtocol = true
}
opts.saveWorkspaceProtocol = true
}

Copilot AI Apr 4, 2026

Copy link

Choose a reason for hiding this comment

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

The new logic forces saveWorkspaceProtocol to true when workspace is used with linkWorkspacePackages=false, even if saveWorkspaceProtocol was explicitly set to false by the caller/CLI. This contradicts the PR description which says we “always throw on conflict”; either update the PR description (and any related docs/changeset) to reflect the new behavior, or reintroduce an explicit-conflict error using cliOptions/explicitlySetKeys to detect --no-save-workspace-protocol.

Copilot uses AI. Check for mistakes.
pnpm remove does not accept --shamefully-hoist flag, so set
it in pnpm-workspace.yaml instead to keep it consistent
across add and remove commands.
@zkochan zkochan merged commit b5d93c6 into main Apr 5, 2026
12 checks passed
@zkochan zkochan deleted the refactor-config3 branch April 5, 2026 09:36
zkochan added a commit that referenced this pull request May 6, 2026
Closes #11488.

`pnpm fetch` writes forced-empty `hoistPattern: []` and `publicHoistPattern: []` into `.modules.yaml` (because its `virtualStoreOnly` install path skips hoisting). In v10 the follow-up `pnpm install` ignored these unless the user had explicitly set a hoist-pattern in their config. v11's [#11199](#11199) removed that explicit-config gate, so `validateModules` now always sees the empty patterns as a hoist-pattern change and purges `node_modules` — slow on every CI run, and per the bug report sometimes leaves the modules dir in an `ERR_MODULE_NOT_FOUND` state on subsequent runs.

The fix marks `.modules.yaml` with a new `virtualStoreOnly: true` field after a fetch. `validateModules` recognizes this flag as "incomplete install state" and skips the `PUBLIC_HOIST_PATTERN_DIFF` / `HOIST_PATTERN_DIFF` comparisons. The next install then completes the missing post-import linking in place rather than purging. The flag is dropped from `.modules.yaml` once a normal install runs.

A genuine hoist-pattern change (without a fetch in between) still triggers the purge as before — verified manually with `publicHoistPattern` in `pnpm-workspace.yaml`.
zkochan added a commit that referenced this pull request May 6, 2026
Closes #11488.

`pnpm fetch` writes forced-empty `hoistPattern: []` and `publicHoistPattern: []` into `.modules.yaml` (because its `virtualStoreOnly` install path skips hoisting). In v10 the follow-up `pnpm install` ignored these unless the user had explicitly set a hoist-pattern in their config. v11's [#11199](#11199) removed that explicit-config gate, so `validateModules` now always sees the empty patterns as a hoist-pattern change and purges `node_modules` — slow on every CI run, and per the bug report sometimes leaves the modules dir in an `ERR_MODULE_NOT_FOUND` state on subsequent runs.

The fix marks `.modules.yaml` with a new `virtualStoreOnly: true` field after a fetch. `validateModules` recognizes this flag as "incomplete install state" and skips the `PUBLIC_HOIST_PATTERN_DIFF` / `HOIST_PATTERN_DIFF` comparisons. The next install then completes the missing post-import linking in place rather than purging. The flag is dropped from `.modules.yaml` once a normal install runs.

A genuine hoist-pattern change (without a fetch in between) still triggers the purge as before — verified manually with `publicHoistPattern` in `pnpm-workspace.yaml`.
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.

2 participants