From 5274040be7b5c26173f6d227d563cf924518685c Mon Sep 17 00:00:00 2001 From: Bart van den Ende Date: Sat, 6 Jun 2026 11:34:07 +0200 Subject: [PATCH] fix: [rush] Parse pnpm-config.json with JsonSyntax.JsonWithComments --- ...ix-pnpm-config-jsonc_2026-06-06-09-15.json | 11 +++++++ .../src/logic/ProjectChangeAnalyzer.ts | 11 ++++--- .../logic/test/ProjectChangeAnalyzer.test.ts | 29 +++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 common/changes/@microsoft/rush/fix-pnpm-config-jsonc_2026-06-06-09-15.json diff --git a/common/changes/@microsoft/rush/fix-pnpm-config-jsonc_2026-06-06-09-15.json b/common/changes/@microsoft/rush/fix-pnpm-config-jsonc_2026-06-06-09-15.json new file mode 100644 index 0000000000..f673998d32 --- /dev/null +++ b/common/changes/@microsoft/rush/fix-pnpm-config-jsonc_2026-06-06-09-15.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Fix a regression where Rush change-detection treated any `pnpm-config.json` containing comments as unparseable, causing every project to be flagged as impacted.", + "type": "patch", + "packageName": "@microsoft/rush" + } + ], + "packageName": "@microsoft/rush", + "email": "bartvandenende-wm@users.noreply.github.com" +} diff --git a/libraries/rush-lib/src/logic/ProjectChangeAnalyzer.ts b/libraries/rush-lib/src/logic/ProjectChangeAnalyzer.ts index 236f41285e..3dc0fc6ed2 100644 --- a/libraries/rush-lib/src/logic/ProjectChangeAnalyzer.ts +++ b/libraries/rush-lib/src/logic/ProjectChangeAnalyzer.ts @@ -6,7 +6,7 @@ import * as path from 'node:path'; import ignore, { type Ignore } from 'ignore'; import type { IReadonlyLookupByPath, LookupByPath, IPrefixMatch } from '@rushstack/lookup-by-path'; -import { Path, FileSystem, Async, AlreadyReportedError, Sort } from '@rushstack/node-core-library'; +import { Path, FileSystem, Async, AlreadyReportedError, Sort, JsonFile } from '@rushstack/node-core-library'; import { getRepoChanges, getRepoRoot, @@ -545,16 +545,16 @@ export class ProjectChangeAnalyzer { blobSpec: `${mergeCommit}:${pnpmConfigRelativePath}`, repositoryRoot: repoRoot }); - const oldPnpmConfig: IPnpmOptionsJson = JSON.parse(oldPnpmConfigText); + const oldPnpmConfig: IPnpmOptionsJson = JsonFile.parseString(oldPnpmConfigText); oldCatalogs = oldPnpmConfig.globalCatalogs ?? {}; } catch { // Old file didn't exist or was unparseable — treat all packages in all current catalogs as changed if (rushConfiguration.subspacesFeatureEnabled) { - terminal.writeLine( + terminal.writeWarningLine( `"${subspace.subspaceName}" subspace pnpm-config.json was created or unparseable. Assuming all projects are affected.` ); } else { - terminal.writeLine( + terminal.writeWarningLine( `pnpm-config.json was created or unparseable. Assuming all projects are affected.` ); } @@ -608,8 +608,7 @@ export class ProjectChangeAnalyzer { // Check each project in the subspace to see if it depends on a changed catalog package const subspaceProjects: RushConfigurationProject[] = subspace.getProjects(); subspaceProjects.forEach((project) => { - const { dependencies, devDependencies, optionalDependencies, peerDependencies } = - project.packageJson; + const { dependencies, devDependencies, optionalDependencies, peerDependencies } = project.packageJson; const allDependencies: Set<[string, string]> = new Set( [dependencies, devDependencies, optionalDependencies, peerDependencies].flatMap((deps) => Object.entries(deps ?? {}) diff --git a/libraries/rush-lib/src/logic/test/ProjectChangeAnalyzer.test.ts b/libraries/rush-lib/src/logic/test/ProjectChangeAnalyzer.test.ts index cb183942e5..bbc8274c26 100644 --- a/libraries/rush-lib/src/logic/test/ProjectChangeAnalyzer.test.ts +++ b/libraries/rush-lib/src/logic/test/ProjectChangeAnalyzer.test.ts @@ -842,6 +842,35 @@ describe(ProjectChangeAnalyzer.name, () => { // 'c' has no catalog deps expect(changedProjects.has(rushConfiguration.getProjectByName('c')!)).toBe(false); }); + + it('parses pnpm-config.json blobs containing comments (regression #5813)', async () => { + const rushConfiguration: RushConfiguration = getCatalogRushConfiguration(); + mockPnpmConfigChanged(); + mockGetBlobContentAsync.mockImplementation(() => { + return Promise.resolve( + `// banner comment from rush init template\n` + + `/* block comment */\n` + + JSON.stringify({ + globalCatalogs: { + default: { react: '^18.0.0', semver: '^7.5.4' }, + tools: { typescript: '~5.3.0', eslint: '^8.50.0' } + } + }) + ); + }); + + const projectChangeAnalyzer: ProjectChangeAnalyzer = new ProjectChangeAnalyzer(rushConfiguration); + const terminal: Terminal = new Terminal(new StringBufferTerminalProvider(true)); + + const changedProjects = await projectChangeAnalyzer.getChangedProjectsAsync({ + enableFiltering: false, + includeExternalDependencies: false, + targetBranchName: 'main', + terminal + }); + + expect(changedProjects.size).toBe(0); + }); }); describe('subspace catalog change detection', () => {