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] Add warning when using globalIgnoredOptionalDependencies in < pnpm 9.0.0 #5001

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@microsoft/rush",
"comment": "Add warning when the `globalIgnoredOptionalDependencies` property is specified in `common/config/rush/pnpm-config.json` and the repo is configured to use pnpm <9.0.0.",
"type": "none"
}
],
"packageName": "@microsoft/rush"
}
20 changes: 18 additions & 2 deletions libraries/rush-lib/src/logic/installManager/InstallHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
JsonFile,
LockFile
} from '@rushstack/node-core-library';
import { Colorize } from '@rushstack/terminal';
import { Colorize, type ITerminal } from '@rushstack/terminal';

import { LastInstallFlag } from '../../api/LastInstallFlag';
import type { PackageManagerName } from '../../api/packageManager/PackageManager';
Expand All @@ -21,6 +21,7 @@ import type { PnpmOptionsConfiguration } from '../pnpm/PnpmOptionsConfiguration'
import { merge } from '../../utilities/objectUtilities';
import type { Subspace } from '../../api/Subspace';
import { RushConstants } from '../RushConstants';
import * as semver from 'semver';

interface ICommonPackageJson extends IPackageJson {
pnpm?: {
Expand All @@ -38,7 +39,8 @@ export class InstallHelpers {
public static generateCommonPackageJson(
rushConfiguration: RushConfiguration,
subspace: Subspace,
dependencies: Map<string, string> = new Map<string, string>()
dependencies: Map<string, string> = new Map<string, string>(),
terminal: ITerminal
): void {
const commonPackageJson: ICommonPackageJson = {
dependencies: {},
Expand Down Expand Up @@ -71,6 +73,20 @@ export class InstallHelpers {
}

if (pnpmOptions.globalIgnoredOptionalDependencies) {
if (
rushConfiguration.rushConfigurationJson.pnpmVersion !== undefined &&
semver.lt(rushConfiguration.rushConfigurationJson.pnpmVersion, '9.0.0')
) {
terminal.writeWarningLine(
Colorize.yellow(
`Your version of pnpm (${rushConfiguration.rushConfigurationJson.pnpmVersion}) ` +
`doesn't support the "globalIgnoredOptionalDependencies" field in ` +
`${rushConfiguration.commonRushConfigFolder}/${RushConstants.pnpmConfigFilename}. ` +
'Remove this field or upgrade to pnpm 9.'
)
);
}

commonPackageJson.pnpm.ignoredOptionalDependencies = pnpmOptions.globalIgnoredOptionalDependencies;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ export class RushInstallManager extends BaseInstallManager {
InstallHelpers.generateCommonPackageJson(
this.rushConfiguration,
this.rushConfiguration.defaultSubspace,
commonDependencies
commonDependencies,
this._terminal
);

stopwatch.stop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ export class WorkspaceInstallManager extends BaseInstallManager {
}

// Write the common package.json
InstallHelpers.generateCommonPackageJson(this.rushConfiguration, subspace, undefined);
InstallHelpers.generateCommonPackageJson(this.rushConfiguration, subspace, undefined, this._terminal);

// Save the generated workspace file. Don't update the file timestamp unless the content has changed,
// since "rush install" will consider this timestamp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration
* dependencies. The settings are copied into the pnpm.ignoredOptionalDependencies field of the common/temp/package.json
* file that is generated by Rush during installation.
*
* (SUPPORTED ONLY IN PNPM 9.0.0 AND NEWER)
*
* PNPM documentation: https://pnpm.io/package_json#pnpmignoredoptionaldependencies
*/
public readonly globalIgnoredOptionalDependencies: string[] | undefined;
Expand Down
21 changes: 20 additions & 1 deletion libraries/rush-lib/src/logic/test/InstallHelpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,35 @@
import { InstallHelpers } from '../installManager/InstallHelpers';
import { RushConfiguration } from '../../api/RushConfiguration';
import { type IPackageJson, JsonFile } from '@rushstack/node-core-library';
import { StringBufferTerminalProvider, Terminal } from '@rushstack/terminal';

describe('InstallHelpers', () => {
describe('generateCommonPackageJson', () => {
const originalJsonFileSave = JsonFile.save;
const mockJsonFileSave: jest.Mock = jest.fn();
let terminal: Terminal;
let terminalProvider: StringBufferTerminalProvider;

beforeAll(() => {
JsonFile.save = mockJsonFileSave;
});

beforeEach(() => {
terminalProvider = new StringBufferTerminalProvider();
terminal = new Terminal(terminalProvider);
});

afterEach(() => {
expect({
output: terminalProvider.getOutput({ normalizeSpecialCharacters: true }),
verbose: terminalProvider.getVerbose({ normalizeSpecialCharacters: true }),
error: terminalProvider.getDebugOutput({ normalizeSpecialCharacters: true }),
warning: terminalProvider.getWarningOutput({ normalizeSpecialCharacters: true }),
debug: terminalProvider.getDebugOutput({ normalizeSpecialCharacters: true })
}).toMatchSnapshot('Terminal Output');
mockJsonFileSave.mockClear();
});

afterAll(() => {
JsonFile.save = originalJsonFileSave;
});
Expand All @@ -26,7 +44,8 @@ describe('InstallHelpers', () => {
InstallHelpers.generateCommonPackageJson(
rushConfiguration,
rushConfiguration.defaultSubspace,
undefined
undefined,
terminal
);
const packageJson: IPackageJson = mockJsonFileSave.mock.calls[0][0];
expect(packageJson).toEqual(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`InstallHelpers generateCommonPackageJson generates correct package json with pnpm configurations: Terminal Output 1`] = `
Object {
"debug": "",
"error": "",
"output": "",
"verbose": "",
"warning": "",
}
`;
2 changes: 1 addition & 1 deletion libraries/rush-lib/src/schemas/pnpm-config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
},

"globalIgnoredOptionalDependencies": {
"description": "This field allows you to skip the installation of specific optional dependencies. The listed packages will be treated as if they are not present in the dependency tree during installation, meaning they will not be installed even if required by other packages.",
"description": "This field allows you to skip the installation of specific optional dependencies. The listed packages will be treated as if they are not present in the dependency tree during installation, meaning they will not be installed even if required by other packages.\n\n(SUPPORTED ONLY IN PNPM 9.0.0 AND NEWER)\n\nPNPM documentation: https://pnpm.io/package_json#pnpmalloweddeprecatedversions",
"type": "array",
"items": {
"description": "Specify the package name of the optional dependency to be ignored.",
Expand Down
Loading