-
Notifications
You must be signed in to change notification settings - Fork 674
Add 'rush-pnpm up' support for catalogs #5585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ea6ee3d
8323e43
f715b55
ad97f17
a6e3c54
46f7359
19f5af2
89041c9
9507313
cb3c760
073c2b6
88b3000
c59d56f
d89bc91
27445b9
20f3cf8
30a60dd
fe4d784
fa9b039
8d44296
3842170
93d85a5
1ffabcd
30064fe
3ee9066
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "changes": [ | ||
| { | ||
| "packageName": "@microsoft/rush", | ||
| "comment": "Add catalog support to `rush-pnpm update`.", | ||
| "type": "none" | ||
| } | ||
| ], | ||
| "packageName": "@microsoft/rush" | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,133 @@ | ||||||
| // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. | ||||||
| // See LICENSE in the project root for license information. | ||||||
|
|
||||||
| import * as path from 'node:path'; | ||||||
| import { FileSystem, JsonFile } from '@rushstack/node-core-library'; | ||||||
| import { TestUtilities } from '@rushstack/heft-config-file'; | ||||||
| import { RushConfiguration } from '../../api/RushConfiguration'; | ||||||
|
|
||||||
| const MONOREPO_ROOT: string = path.dirname( | ||||||
| RushConfiguration.tryFindRushJsonLocation({ startingFolder: __dirname })! | ||||||
| ); | ||||||
| const CATALOG_SYNC_REPO_PATH: string = `${__dirname}/catalogSyncTestRepo`; | ||||||
|
|
||||||
| describe('RushPnpmCommandLineParser', () => { | ||||||
| describe('catalog syncing', () => { | ||||||
| const testRepoPath: string = `${MONOREPO_ROOT}/temp/catalog-sync-test-repo`; | ||||||
| const pnpmConfigPath: string = `${testRepoPath}/common/config/rush/pnpm-config.json`; | ||||||
| const pnpmWorkspacePath: string = `${testRepoPath}/common/temp/pnpm-workspace.yaml`; | ||||||
|
|
||||||
| beforeEach(async () => { | ||||||
| await FileSystem.copyFilesAsync({ sourcePath: CATALOG_SYNC_REPO_PATH, destinationPath: testRepoPath }); | ||||||
|
|
||||||
| // common/temp is gitignored so it is not part of the static repo; copy the initial workspace file here | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a |
||||||
| await FileSystem.copyFilesAsync({ | ||||||
| sourcePath: `${CATALOG_SYNC_REPO_PATH}/pnpm-workspace.yaml`, | ||||||
| destinationPath: pnpmWorkspacePath | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| afterEach(async () => { | ||||||
| await FileSystem.deleteFolderAsync(testRepoPath); | ||||||
| }); | ||||||
|
|
||||||
| it('syncs updated catalogs from pnpm-workspace.yaml to pnpm-config.json', async () => { | ||||||
| const updatedWorkspaceYaml = `packages: | ||||||
| - '../../apps/*' | ||||||
| catalogs: | ||||||
| default: | ||||||
| react: ^18.2.0 | ||||||
| react-dom: ^18.2.0 | ||||||
| typescript: ~5.3.0 | ||||||
| frontend: | ||||||
| vue: ^3.4.0 | ||||||
| `; | ||||||
| await FileSystem.writeFileAsync(pnpmWorkspacePath, updatedWorkspaceYaml); | ||||||
|
|
||||||
| const rushConfiguration: RushConfiguration = RushConfiguration.loadFromConfigurationFile( | ||||||
| `${testRepoPath}/rush.json` | ||||||
| ); | ||||||
|
|
||||||
| const subspace = rushConfiguration.getSubspace('default'); | ||||||
| const pnpmOptions = subspace.getPnpmOptions(); | ||||||
|
|
||||||
| expect(TestUtilities.stripAnnotations(pnpmOptions?.globalCatalogs)).toEqual({ | ||||||
| default: { | ||||||
| react: '^18.0.0', | ||||||
| 'react-dom': '^18.0.0' | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
| const { PnpmWorkspaceFile } = require('../../logic/pnpm/PnpmWorkspaceFile'); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you just import this at the top? |
||||||
| const newCatalogs = await PnpmWorkspaceFile.loadCatalogsFromFileAsync(pnpmWorkspacePath); | ||||||
|
|
||||||
| await pnpmOptions?.updateGlobalCatalogsAsync(newCatalogs); | ||||||
|
|
||||||
| const updatedRushConfiguration: RushConfiguration = RushConfiguration.loadFromConfigurationFile( | ||||||
| `${testRepoPath}/rush.json` | ||||||
| ); | ||||||
| const updatedSubspace = updatedRushConfiguration.getSubspace('default'); | ||||||
| const updatedPnpmOptions = updatedSubspace.getPnpmOptions(); | ||||||
|
|
||||||
| expect(TestUtilities.stripAnnotations(updatedPnpmOptions?.globalCatalogs)).toEqual({ | ||||||
| default: { | ||||||
| react: '^18.2.0', | ||||||
| 'react-dom': '^18.2.0', | ||||||
| typescript: '~5.3.0' | ||||||
| }, | ||||||
| frontend: { | ||||||
| vue: '^3.4.0' | ||||||
| } | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| it('does not update pnpm-config.json when catalogs are unchanged', async () => { | ||||||
| const { PnpmWorkspaceFile } = require('../../logic/pnpm/PnpmWorkspaceFile'); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| const newCatalogs = await PnpmWorkspaceFile.loadCatalogsFromFileAsync(pnpmWorkspacePath); | ||||||
|
|
||||||
| const rushConfiguration: RushConfiguration = RushConfiguration.loadFromConfigurationFile( | ||||||
| `${testRepoPath}/rush.json` | ||||||
| ); | ||||||
| const subspace = rushConfiguration.getSubspace('default'); | ||||||
| const pnpmOptions = subspace.getPnpmOptions(); | ||||||
|
|
||||||
| await pnpmOptions?.updateGlobalCatalogsAsync(newCatalogs); | ||||||
|
|
||||||
| const savedConfig = JsonFile.load(pnpmConfigPath); | ||||||
| expect(savedConfig.globalCatalogs).toEqual({ | ||||||
| default: { | ||||||
| react: '^18.0.0', | ||||||
| 'react-dom': '^18.0.0' | ||||||
| } | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| it('removes catalogs when pnpm-workspace.yaml has no catalogs', async () => { | ||||||
| const workspaceWithoutCatalogs = `packages: | ||||||
| - '../../apps/*' | ||||||
| `; | ||||||
| await FileSystem.writeFileAsync(pnpmWorkspacePath, workspaceWithoutCatalogs); | ||||||
|
|
||||||
| const { PnpmWorkspaceFile } = require('../../logic/pnpm/PnpmWorkspaceFile'); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| const newCatalogs = await PnpmWorkspaceFile.loadCatalogsFromFileAsync(pnpmWorkspacePath); | ||||||
|
|
||||||
| expect(newCatalogs).toBeUndefined(); | ||||||
|
|
||||||
| const rushConfiguration: RushConfiguration = RushConfiguration.loadFromConfigurationFile( | ||||||
| `${testRepoPath}/rush.json` | ||||||
| ); | ||||||
| const subspace = rushConfiguration.getSubspace('default'); | ||||||
| const pnpmOptions = subspace.getPnpmOptions(); | ||||||
|
|
||||||
| await pnpmOptions?.updateGlobalCatalogsAsync(newCatalogs); | ||||||
|
|
||||||
| const updatedRushConfiguration: RushConfiguration = RushConfiguration.loadFromConfigurationFile( | ||||||
| `${testRepoPath}/rush.json` | ||||||
| ); | ||||||
| const updatedSubspace = updatedRushConfiguration.getSubspace('default'); | ||||||
| const updatedPnpmOptions = updatedSubspace.getPnpmOptions(); | ||||||
|
|
||||||
| expect(updatedPnpmOptions?.globalCatalogs).toBeUndefined(); | ||||||
| }); | ||||||
| }); | ||||||
| }); | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "globalCatalogs": { | ||
| "default": { | ||
| "react": "^18.0.0", | ||
| "react-dom": "^18.0.0" | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| packages: | ||
| - '../../apps/*' | ||
| catalogs: | ||
| default: | ||
| react: ^18.0.0 | ||
| react-dom: ^18.0.0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush.schema.json", | ||
| "rushVersion": "5.166.0", | ||
| "pnpmVersion": "10.28.1", | ||
| "nodeSupportedVersionRange": ">=18.0.0", | ||
| "projects": [] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -535,18 +535,32 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration | |
| public updateGlobalPatchedDependencies(patchedDependencies: Record<string, string> | undefined): void { | ||
| this._globalPatchedDependencies = patchedDependencies; | ||
| this._json.globalPatchedDependencies = patchedDependencies; | ||
| if (this.jsonFilename) { | ||
| JsonFile.save(this._json, this.jsonFilename, { updateExistingFile: true }); | ||
| } | ||
| JsonFile.save(this._json, this.jsonFilename as string, { updateExistingFile: true }); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will throw if |
||
| } | ||
|
|
||
| /** | ||
| * Updates globalOnlyBuiltDependencies field of the PNPM options in the common/config/rush/pnpm-config.json file. | ||
| */ | ||
| public updateGlobalOnlyBuiltDependencies(onlyBuiltDependencies: string[] | undefined): void { | ||
| public async updateGlobalOnlyBuiltDependenciesAsync( | ||
| onlyBuiltDependencies: string[] | undefined | ||
| ): Promise<void> { | ||
| this._json.globalOnlyBuiltDependencies = onlyBuiltDependencies; | ||
| if (this.jsonFilename) { | ||
| JsonFile.save(this._json, this.jsonFilename, { updateExistingFile: true }); | ||
| } | ||
| await JsonFile.saveAsync(this._json, this.jsonFilename as string, { | ||
| updateExistingFile: true, | ||
| ignoreUndefinedValues: true | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Updates globalCatalogs field of the PNPM options in the common/config/rush/pnpm-config.json file. | ||
| */ | ||
| public async updateGlobalCatalogsAsync( | ||
| catalogs: Record<string, Record<string, string>> | undefined | ||
| ): Promise<void> { | ||
| this._json.globalCatalogs = catalogs; | ||
| await JsonFile.saveAsync(this._json, this.jsonFilename as string, { | ||
| updateExistingFile: true, | ||
| ignoreUndefinedValues: true | ||
| }); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't do anything outside of the project folder. Do this in
<projectRoot>/temp/catalog-sync-test-repo