Skip to content
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

[rush-lib] Add autoInstallPeers in pnpm-config #4379

Merged
merged 4 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@microsoft/rush",
"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"
}
],
"packageName": "@microsoft/rush"
}
2 changes: 2 additions & 0 deletions common/reviews/api/rush-lib.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ export interface IPhasedCommand extends IRushCommand {

// @internal
export interface _IPnpmOptionsJson extends IPackageManagerOptionsJsonBase {
autoInstallPeers?: boolean;
globalAllowedDeprecatedVersions?: Record<string, string>;
globalNeverBuiltDependencies?: string[];
globalOverrides?: Record<string, string>;
Expand Down Expand Up @@ -965,6 +966,7 @@ export class PhasedCommandHooks {

// @public
export class PnpmOptionsConfiguration extends PackageManagerOptionsConfigurationBase {
readonly autoInstallPeers: boolean | undefined;
readonly globalAllowedDeprecatedVersions: Record<string, string> | undefined;
readonly globalNeverBuiltDependencies: string[] | undefined;
readonly globalOverrides: Record<string, string> | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@
*/
/*[LINE "DEMO"]*/ "resolutionMode": "time-based",

/**
* 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 value is false.
*/
/*[LINE "DEMO"]*/ "autoInstallPeers": false,
g-chao marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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,
Expand Down
28 changes: 28 additions & 0 deletions libraries/rush-lib/src/logic/base/BaseInstallManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,34 @@ ${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 both pnpm-config.json and .npmrc, rush will default it to "false"
*/
const isAutoInstallPeersInNpmrc: boolean = isVariableSetInNpmrcFile(
this.rushConfiguration.commonRushConfigFolder,
'auto-install-peers'
);

let 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.`
);
}
} 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}`);
}

/*
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
Expand Down
13 changes: 13 additions & 0 deletions libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ export interface IPnpmOptionsJson extends IPackageManagerOptionsJsonBase {
* {@inheritDoc PnpmOptionsConfiguration.resolutionMode}
*/
resolutionMode?: PnpmResolutionMode;
/**
* {@inheritDoc PnpmOptionsConfiguration.autoInstallPeers}
*/
autoInstallPeers?: boolean;
}

/**
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down
5 changes: 5 additions & 0 deletions libraries/rush-lib/src/schemas/pnpm-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 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"
g-chao marked this conversation as resolved.
Show resolved Hide resolved
}
}
}