Repository navigation
[rush] Make "rush add" and "rush upgrade-interactive" aware of PNPM catalogs - #6141
Draft
Bharat Middha (bmiddha) wants to merge 1 commit into
Draft
Bharat Middha (bmiddha) wants to merge 1 commit into
Bharat Middha (bmiddha) wants to merge 1 commit into
Conversation
Bharat Middha (bmiddha)
force-pushed
the
bmiddha-catalog-aware-rush-add
branch
from
October 14, 2026 20:55
4b51e7a to
dfd37db
Compare
Bharat Middha (bmiddha)
added this pull request to stack #6134
October 14, 2026 21:29
"rush add" writes PNPM catalog references (catalog: / catalog:<name>) when a catalog of the project's subspace has a matching entry, accepts explicit catalog references, and with --make-consistent updates the catalog entry instead of replacing references with versions. A project's existing catalog reference is never silently replaced with a version. "rush upgrade-interactive" lists dependencies referenced through a catalog and upgrades them by bumping the catalog entry. When the updated pnpm-config.json is shared with other subspaces, the needed "rush update --subspace" commands are printed. npm-check-fork now honors a provided cwdPackageJson. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bharat Middha (bmiddha)
force-pushed
the
bmiddha-catalog-aware-rush-add
branch
from
October 15, 2026 01:50
dfd37db to
cf57821
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
rush addandrush upgrade-interactiveignored PNPM catalogs, which caused three problems:rush add -p fooalways wrote a literal version, even when a catalog had an entry forfoo.rush add -p foo@catalog:was rejected as an invalid SemVer specifier.rush addandrush upgrade-interactiveoverwrote a project's own"foo": "catalog:"with a literal version.rush upgrade-interactivealso never offered dependencies referenced through a catalog, because npm-check skips non-SemVer specifiers.Both commands now work with catalogs, much like pnpm's
catalogMode: preferand pnpm 12'supdate -i:rush addwrites catalog references when a catalog matches.--make-consistentandrush upgrade-interactiveupdate the catalog entry inpnpm-config.jsoninstead of turning references into literal versions.Details
"Catalogs" below means the effective
globalCatalogsof the target project's subspace: its ownpnpm-config.json, falling back tocommon/config/rush/pnpm-config.json(getEffectivePnpmCatalogs()from #6138).rush addrush add -p foo, and a catalog hasfoocatalog:if thedefaultcatalog is chosen, otherwisecatalog:<name>. When several catalogs havefoo, Rush prefers a catalog the target projects already referencefoothrough, then catalogs other projects reference it through (catalogNamesByPackageName), thendefault. If it is still ambiguous, Rush writes the literal version as before and prints a note suggestingfoo@catalog:<name>.rush add -p foo@<range>, and the range equals a catalog entry~1.2.3from the registry, is also matched against the catalog entries.rush add -p foo@<range>, and the range differs from the catalog entryensureConsistentVersionsgate still applies as usual.rush add -p foo@<range> --make-consistent, andfoois catalogedpnpm-config.jsonto<range>and writes the catalog reference. Every catalog consumer stays consistent, and consumers with literal versions (pluscommon-versions.json) are updated as before.rush add -p foo@catalog:/foo@catalog:<name>AddActionfor PNPM repos only, with a clear error for npm/yarn. Rush validates that the catalog exists and has an entry forfoo, with a clear error otherwise.catalog:defaultis normalized tocatalog:. An existing literal version is replaced."foo": "catalog:..."catalog:defaultstays as written. With--make-consistent, Rush updates the entry of the referenced catalog. Otherwise Rush fails with an error explaining how to proceed (--make-consistent, orfoo@catalog:) before anything is written.rush upgrade-interactiveInteractiveUpgradergives npm-check a copy of the project'spackage.jsonin which each catalog reference is replaced by its catalog version, so cataloged dependencies are listed. This needed a small@rushstack/npm-check-forkchange: honor a providedcwdPackageJsonand stop mutating the default options object.catalog:inpackage.json. The range style (~/^) is inferred from the catalog version.--make-consistent, catalog consumers in other projects get the catalog update, and literal consumers get the new version. This runs per subspace of the selected projects, using the pending catalog changes.--make-consistent, theensureConsistentVersionsgate checks the versions every project will use after the catalog change. This matters because changing a catalog entry also changes what other consumers get.Shared
pnpm-config.jsonPendingPnpmCatalogUpdatesclass.package.jsonfiles, throughPnpmOptionsConfiguration.updateGlobalCatalogsAsync(). That also updates the in-memory catalogs, so the followingrush updatesees them.catalog:tools typescript: ~5.3.0 -> ~5.4.5).rush update --subspace <name>per affected subspace. Otherwise pnpm 12's frozen-install catalog check and the repo-state hashes would drift. With--skip-update, the target's own subspace is listed too.--variantpnpm-config.jsondoes not vary by variant:Subspace.getPnpmConfigFilePath()has no variant parameter, and only common-versions, the shrinkwrap, and the pnpmfile do. So--variantkeeps selectingcommon-versions.jsonas before, while catalogs always come from the subspace's (or the common)pnpm-config.json.Relation to #6140
In #6140,
--make-consistentskipped other projects' catalog references with a warning. Now that catalog entries can be updated safely, those references are handled by updating the catalog entry, and the warning is gone.Compatibility and performance
rush add(--packageand the command description).getMismatchesruns once per affected subspace only with--make-consistent.How it was tested
New unit tests
PackageJsonUpdater.test.ts(31 tests) uses therepoWithCatalogsandrepoWithSubspacesCommonCatalogsfixtures, with mocked registry, install, and file writes. It covers:rush addcase in the table above, including the catalog-choice preferences and the ambiguous note-m, and the error without-mpnpm-config.json(no hint) and--skip-updateupgrade-interactivefor regular and dev deps, mixed catalog and literal projects,-m, and its ECV gateAddAction.test.ts: parsessemver@catalog:andtypescript@catalog:tools(passed through withrangeStyle: passthrough), and rejectsassert@catalog:in an npm repo.NpmCheckState.test.ts: covers a providedcwdPackageJson.Commands run on the final commit
The pinned Rush can't install pnpm 12.13.0, so a locally built dev Rush from #6136 and above was used. For
install,common/scriptswas refreshed temporarily and is not part of this PR.node <dev-rush>/apps/rush/lib-commonjs/start-dev.js installnode <dev-rush>/apps/rush/lib-commonjs/start-dev.js build --to @microsoft/rush-libcd libraries/rush-lib && node_modules/.bin/heft testTarExecutable › kills tar when its signal aborts while it runs)cd libraries/rush-lib && node_modules/.bin/heft test --test-path-pattern "PackageJsonUpdater|AddAction|CommandLineHelp|RushCommandLine|VersionMismatch|InteractiveUpgrader|DependencyAnalyzer"cd libraries/npm-check-fork && node_modules/.bin/heft testrush prettier(pre-commit hook)The
CommandLineHelpandRushCommandLinesnapshots were updated for the newrush addhelp text.Impacted documentation
--make-consistentbehavior)Change files:
@microsoft/rush(minor),@rushstack/npm-check-fork(patch).