From 75d17ce2fd44cd93d01ef5dedef4c32781e9b270 Mon Sep 17 00:00:00 2001 From: Chao Date: Tue, 3 Oct 2023 13:47:42 -0700 Subject: [PATCH 1/4] [rush-lib] Add autoInstallPeers in pnpm-config --- common/reviews/api/rush-lib.api.md | 2 ++ .../src/logic/base/BaseInstallManager.ts | 21 +++++++++++++++++++ .../logic/pnpm/PnpmOptionsConfiguration.ts | 13 ++++++++++++ .../src/schemas/pnpm-config.schema.json | 5 +++++ 4 files changed, 41 insertions(+) diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index e7e22736cb..bc7e774a23 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -651,6 +651,7 @@ export interface IPhasedCommand extends IRushCommand { // @internal export interface _IPnpmOptionsJson extends IPackageManagerOptionsJsonBase { + autoInstallPeers?: boolean; globalAllowedDeprecatedVersions?: Record; globalNeverBuiltDependencies?: string[]; globalOverrides?: Record; @@ -965,6 +966,7 @@ export class PhasedCommandHooks { // @public export class PnpmOptionsConfiguration extends PackageManagerOptionsConfigurationBase { + readonly autoInstallPeers: boolean | undefined; readonly globalAllowedDeprecatedVersions: Record | undefined; readonly globalNeverBuiltDependencies: string[] | undefined; readonly globalOverrides: Record | undefined; diff --git a/libraries/rush-lib/src/logic/base/BaseInstallManager.ts b/libraries/rush-lib/src/logic/base/BaseInstallManager.ts index b800330650..17619c7e7c 100644 --- a/libraries/rush-lib/src/logic/base/BaseInstallManager.ts +++ b/libraries/rush-lib/src/logic/base/BaseInstallManager.ts @@ -643,6 +643,27 @@ ${gitLfsHookHandling} args.push('--strict-peer-dependencies'); } + /* + 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 + If user set auto-install-peers in .npmrc only, do nothing, let pnpm handle it + If user does not set auto-install-peers in pnpm-config.json and .npmrc, do nothing, let pnpm handle it + */ + const isAutoInstallPeersInNpmrc: boolean = isVariableSetInNpmrcFile( + this.rushConfiguration.commonRushConfigFolder, + 'auto-install-peers' + ); + const autoInstallPeers: boolean | undefined = this.rushConfiguration.pnpmOptions.autoInstallPeers; + if (autoInstallPeers !== undefined) { + if (isAutoInstallPeersInNpmrc) { + this._terminal.writeWarningLine( + `Warning: PNPM's auto-install-peers is specified in both .npmrc and pnpm-config.json. ` + + `The value in pnpm-config.json will take precedence.` + ); + } + args.push(`--config.auto-install-peers=${autoInstallPeers}`); + } + /* If user set resolution-mode in pnpm-config.json only, use the value in pnpm-config.json If user set resolution-mode in pnpm-config.json and .npmrc, use the value in pnpm-config.json diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts b/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts index d24dda8490..8b7d5739dd 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts @@ -107,6 +107,10 @@ export interface IPnpmOptionsJson extends IPackageManagerOptionsJsonBase { * {@inheritDoc PnpmOptionsConfiguration.resolutionMode} */ resolutionMode?: PnpmResolutionMode; + /** + * {@inheritDoc PnpmOptionsConfiguration.autoInstallPeers} + */ + autoInstallPeers?: boolean; } /** @@ -209,6 +213,14 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration */ public readonly useWorkspaces: boolean; + /** + * When true, any missing non-optional peer dependencies are automatically installed. + * + * @remarks + * The default value is same as PNPM default value. (In PNPM 8.x, this value is true) + */ + public readonly autoInstallPeers: boolean | undefined; + /** * The "globalOverrides" setting provides a simple mechanism for overriding version selections * for all dependencies of all projects in the monorepo workspace. The settings are copied @@ -332,6 +344,7 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration this.unsupportedPackageJsonSettings = json.unsupportedPackageJsonSettings; this._globalPatchedDependencies = json.globalPatchedDependencies; this.resolutionMode = json.resolutionMode; + this.autoInstallPeers = json.autoInstallPeers; } /** @internal */ diff --git a/libraries/rush-lib/src/schemas/pnpm-config.schema.json b/libraries/rush-lib/src/schemas/pnpm-config.schema.json index 6eb3e97db4..60cac19c49 100644 --- a/libraries/rush-lib/src/schemas/pnpm-config.schema.json +++ b/libraries/rush-lib/src/schemas/pnpm-config.schema.json @@ -165,6 +165,11 @@ "description": "This option overrides the resolution-mode in PNPM. Use it if you want to change the default resolution behavior when installing dependencies. Defaults to \"highest\".\n\nPNPM documentation: https://pnpm.io/npmrc#resolution-mode.", "type": "string", "enum": ["highest", "time-based", "lowest-direct"] + }, + + "autoInstallPeers": { + "description": "This option overrides the auto-install-peers in PNPM. Use it if you want to change the default resolution behavior when installing dependencies. Defaults to \"highest\".\n\nPNPM documentation: https://pnpm.io/npmrc#auto-install-peers.", + "type": "boolean" } } } From 59dc1e35251fbc0bee7a74403ebb18888d78d020 Mon Sep 17 00:00:00 2001 From: Chao Date: Tue, 3 Oct 2023 13:49:15 -0700 Subject: [PATCH 2/4] generate changelog --- .../rush/chao-auto-install-peers_2023-10-03-20-48.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json diff --git a/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json b/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json new file mode 100644 index 0000000000..7f491e4ead --- /dev/null +++ b/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "[rush-lib] Add autoInstallPeers in pnpm-config", + "type": "none" + } + ], + "packageName": "@microsoft/rush" +} \ No newline at end of file From 701f9a0c3bb6bb627ea9d7969ed45b63957241e7 Mon Sep 17 00:00:00 2001 From: Chao Date: Tue, 3 Oct 2023 17:17:58 -0700 Subject: [PATCH 3/4] fix: fixes based on PR feedback --- .../chao-auto-install-peers_2023-10-03-20-48.json | 2 +- .../rush-init/common/config/rush/pnpm-config.json | 9 +++++++++ .../rush-lib/src/logic/base/BaseInstallManager.ts | 11 +++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json b/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json index 7f491e4ead..59d2ba6ad1 100644 --- a/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json +++ b/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json @@ -2,7 +2,7 @@ "changes": [ { "packageName": "@microsoft/rush", - "comment": "[rush-lib] Add autoInstallPeers in pnpm-config", + "comment": "Add a new setting `autoInstallPeers` in pnpm-config.json", "type": "none" } ], diff --git a/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json b/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json index 0d27d52e64..b97d80c253 100644 --- a/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json +++ b/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json @@ -43,6 +43,15 @@ */ /*[LINE "DEMO"]*/ "resolutionMode": "time-based", + /** + * When true, any missing non-optional peer dependencies are automatically installed. + * + * PNPM documentation: https://pnpm.io/npmrc#auto-install-peers + * + * The default is `false`. + */ + /*[LINE "DEMO"]*/ "autoInstallPeers": false, + /** * If true, then Rush will add the `--strict-peer-dependencies` command-line parameter when * invoking PNPM. This causes `rush update` to fail if there are unsatisfied peer dependencies, diff --git a/libraries/rush-lib/src/logic/base/BaseInstallManager.ts b/libraries/rush-lib/src/logic/base/BaseInstallManager.ts index 17619c7e7c..5df4655228 100644 --- a/libraries/rush-lib/src/logic/base/BaseInstallManager.ts +++ b/libraries/rush-lib/src/logic/base/BaseInstallManager.ts @@ -647,13 +647,14 @@ ${gitLfsHookHandling} 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 If user set auto-install-peers in .npmrc only, do nothing, let pnpm handle it - If user does not set auto-install-peers in pnpm-config.json and .npmrc, do nothing, let pnpm handle it + If user does not set auto-install-peers in both pnpm-config.json and .npmrc, rush will default it to "false" */ const isAutoInstallPeersInNpmrc: boolean = isVariableSetInNpmrcFile( this.rushConfiguration.commonRushConfigFolder, 'auto-install-peers' ); - const autoInstallPeers: boolean | undefined = this.rushConfiguration.pnpmOptions.autoInstallPeers; + + let autoInstallPeers: boolean | undefined = this.rushConfiguration.pnpmOptions.autoInstallPeers; if (autoInstallPeers !== undefined) { if (isAutoInstallPeersInNpmrc) { this._terminal.writeWarningLine( @@ -661,6 +662,12 @@ ${gitLfsHookHandling} `The value in pnpm-config.json will take precedence.` ); } + } else if (!isAutoInstallPeersInNpmrc) { + // if auto-install-peers isn't specified in either .npmrc or pnpm-config.json, + // then rush will default it to "false" + autoInstallPeers = false; + } + if (autoInstallPeers !== undefined) { args.push(`--config.auto-install-peers=${autoInstallPeers}`); } From 65d948a9e99d9647ef5613aa38ccd92499f97a21 Mon Sep 17 00:00:00 2001 From: Chao Date: Wed, 4 Oct 2023 11:13:47 -0700 Subject: [PATCH 4/4] fix: fixes based on PR feedback --- ...ao-auto-install-peers_2023-10-03-20-48.json | 2 +- .../common/config/rush/pnpm-config.json | 18 ++++++++++++++---- .../src/schemas/pnpm-config.schema.json | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json b/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json index 59d2ba6ad1..777312048e 100644 --- a/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json +++ b/common/changes/@microsoft/rush/chao-auto-install-peers_2023-10-03-20-48.json @@ -2,7 +2,7 @@ "changes": [ { "packageName": "@microsoft/rush", - "comment": "Add a new setting `autoInstallPeers` in pnpm-config.json", + "comment": "(IMPORTANT) Add a new setting `autoInstallPeers` in pnpm-config.json; be aware that Rush changes PNPM's default if you are using PNPM 8 or newer", "type": "none" } ], diff --git a/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json b/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json index b97d80c253..0254b0310f 100644 --- a/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json +++ b/libraries/rush-lib/assets/rush-init/common/config/rush/pnpm-config.json @@ -44,11 +44,21 @@ /*[LINE "DEMO"]*/ "resolutionMode": "time-based", /** - * When true, any missing non-optional peer dependencies are automatically installed. - * + * This setting determines whether PNPM will automatically install (non-optional) + * missing peer dependencies instead of reporting an error. Doing so conveniently + * avoids the need to specify peer versions in package.json, but in a large monorepo + * this often creates worse problems. The reason is that peer dependency behavior + * is inherently complicated, and it is easier to troubleshoot consequences of an explicit + * version than an invisible heuristic. The original NPM RFC discussion pointed out + * some other problems with this feature: https://github.com/npm/rfcs/pull/43 + + * IMPORTANT: Without Rush, the setting defaults to true for PNPM 8 and newer; however, + * as of Rush version 5.109.0 the default is always false unless `autoInstallPeers` + * is specified in pnpm-config.json or .npmrc, regardless of your PNPM version. + * PNPM documentation: https://pnpm.io/npmrc#auto-install-peers - * - * The default is `false`. + + * The default value is false. */ /*[LINE "DEMO"]*/ "autoInstallPeers": false, diff --git a/libraries/rush-lib/src/schemas/pnpm-config.schema.json b/libraries/rush-lib/src/schemas/pnpm-config.schema.json index 60cac19c49..6d87e34a5b 100644 --- a/libraries/rush-lib/src/schemas/pnpm-config.schema.json +++ b/libraries/rush-lib/src/schemas/pnpm-config.schema.json @@ -168,7 +168,7 @@ }, "autoInstallPeers": { - "description": "This option overrides the auto-install-peers in PNPM. Use it if you want to change the default resolution behavior when installing dependencies. Defaults to \"highest\".\n\nPNPM documentation: https://pnpm.io/npmrc#auto-install-peers.", + "description": "This setting determines whether PNPM will automatically install (non-optional) missing peer dependencies instead of reporting an error. With Rush, the default value is always false.\n\nPNPM documentation: https://pnpm.io/npmrc#auto-install-peers", "type": "boolean" } }