diff --git a/common/changes/@microsoft/rush/sennyeya-resolution-only-for-install_2024-08-16-16-38.json b/common/changes/@microsoft/rush/sennyeya-resolution-only-for-install_2024-08-16-16-38.json new file mode 100644 index 00000000000..ed63aa17b99 --- /dev/null +++ b/common/changes/@microsoft/rush/sennyeya-resolution-only-for-install_2024-08-16-16-38.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "Add support for `--resolution-only` to `rush install` to enforce strict peer dependency resolution.", + "type": "none" + } + ], + "packageName": "@microsoft/rush" +} \ No newline at end of file diff --git a/libraries/rush-lib/src/api/test/__snapshots__/RushCommandLine.test.ts.snap b/libraries/rush-lib/src/api/test/__snapshots__/RushCommandLine.test.ts.snap index 1176f03cc55..64f648883b6 100644 --- a/libraries/rush-lib/src/api/test/__snapshots__/RushCommandLine.test.ts.snap +++ b/libraries/rush-lib/src/api/test/__snapshots__/RushCommandLine.test.ts.snap @@ -462,6 +462,14 @@ Object { "required": false, "shortName": undefined, }, + Object { + "description": "Only perform dependency resolution, useful for ensuring peer dependendencies are up to date. Note that this flag is only supported when using the pnpm package manager.", + "environmentVariable": undefined, + "kind": "Flag", + "longName": "--resolution-only", + "required": false, + "shortName": undefined, + }, ], }, Object { diff --git a/libraries/rush-lib/src/cli/actions/InstallAction.ts b/libraries/rush-lib/src/cli/actions/InstallAction.ts index 97598c95a16..63925b70fc6 100644 --- a/libraries/rush-lib/src/cli/actions/InstallAction.ts +++ b/libraries/rush-lib/src/cli/actions/InstallAction.ts @@ -11,6 +11,7 @@ import type { RushConfigurationProject } from '../../api/RushConfigurationProjec export class InstallAction extends BaseInstallAction { private readonly _checkOnlyParameter: CommandLineFlagParameter; + private readonly _resolutionOnlyParameter: CommandLineFlagParameter | undefined; public constructor(parser: RushCommandLineParser) { super({ @@ -45,6 +46,13 @@ export class InstallAction extends BaseInstallAction { parameterLongName: '--check-only', description: `Only check the validity of the shrinkwrap file without performing an install.` }); + + if (this.rushConfiguration?.packageManager === 'pnpm') { + this._resolutionOnlyParameter = this.defineFlagParameter({ + parameterLongName: '--resolution-only', + description: `Only perform dependency resolution, useful for ensuring peer dependendencies are up to date. Note that this flag is only supported when using the pnpm package manager.` + }); + } } protected async buildInstallOptionsAsync(): Promise> { @@ -71,6 +79,7 @@ export class InstallAction extends BaseInstallAction { pnpmFilterArgumentValues: (await this._selectionParameters?.getPnpmFilterArgumentValuesAsync(this._terminal)) ?? [], checkOnly: this._checkOnlyParameter.value, + resolutionOnly: this._resolutionOnlyParameter?.value, beforeInstallAsync: () => this.rushSession.hooks.beforeInstall.promise(this), terminal: this._terminal }; diff --git a/libraries/rush-lib/src/cli/test/__snapshots__/CommandLineHelp.test.ts.snap b/libraries/rush-lib/src/cli/test/__snapshots__/CommandLineHelp.test.ts.snap index 6d7ef926f75..bab50aaa6b9 100644 --- a/libraries/rush-lib/src/cli/test/__snapshots__/CommandLineHelp.test.ts.snap +++ b/libraries/rush-lib/src/cli/test/__snapshots__/CommandLineHelp.test.ts.snap @@ -627,6 +627,7 @@ exports[`CommandLineHelp prints the help for each action: install 1`] = ` [--to-version-policy VERSION_POLICY_NAME] [--from-version-policy VERSION_POLICY_NAME] [--subspace SUBSPACE_NAME] [--check-only] + [--resolution-only] The \\"rush install\\" command installs package dependencies for all your @@ -755,6 +756,10 @@ Optional arguments: be enabled in subspaces.json. --check-only Only check the validity of the shrinkwrap file without performing an install. + --resolution-only Only perform dependency resolution, useful for + ensuring peer dependendencies are up to date. Note + that this flag is only supported when using the pnpm + package manager. " `; diff --git a/libraries/rush-lib/src/logic/base/BaseInstallManager.ts b/libraries/rush-lib/src/logic/base/BaseInstallManager.ts index 2ec3b4aec7a..f781e34b766 100644 --- a/libraries/rush-lib/src/logic/base/BaseInstallManager.ts +++ b/libraries/rush-lib/src/logic/base/BaseInstallManager.ts @@ -745,12 +745,18 @@ ${gitLfsHookHandling} pnpmFilterArgumentValues, onlyShrinkwrap, networkConcurrency, - allowShrinkwrapUpdates + allowShrinkwrapUpdates, + resolutionOnly } = options; if (offline && this.rushConfiguration.packageManager !== 'pnpm') { throw new Error('The "--offline" parameter is only supported when using the PNPM package manager.'); } + if (resolutionOnly && this.rushConfiguration.packageManager !== 'pnpm') { + throw new Error( + 'The "--resolution-only" parameter is only supported when using the PNPM package manager.' + ); + } if (this.rushConfiguration.packageManager === 'npm') { if (semver.lt(this.rushConfiguration.packageManagerToolVersion, '5.0.0')) { // NOTE: @@ -842,6 +848,10 @@ ${gitLfsHookHandling} args.push('--strict-peer-dependencies'); } + if (resolutionOnly) { + args.push('--resolution-only'); + } + /* If user set auto-install-peers in pnpm-config.json only, use the value in pnpm-config.json If user set auto-install-peers in pnpm-config.json and .npmrc, use the value in pnpm-config.json diff --git a/libraries/rush-lib/src/logic/base/BaseInstallManagerTypes.ts b/libraries/rush-lib/src/logic/base/BaseInstallManagerTypes.ts index e9241c6fbb4..051c96105d6 100644 --- a/libraries/rush-lib/src/logic/base/BaseInstallManagerTypes.ts +++ b/libraries/rush-lib/src/logic/base/BaseInstallManagerTypes.ts @@ -22,6 +22,11 @@ export interface IInstallManagerOptions { */ checkOnly: boolean; + /** + * Whether to only run resolutions. Only supported for PNPM. + */ + resolutionOnly?: boolean; + /** * Whether a "--bypass-policy" flag can be specified. */