From 61c1b93bfa4b766e698dd59e0111e7d3731209a8 Mon Sep 17 00:00:00 2001 From: "Mr. Example" Date: Sat, 6 Jul 2019 10:32:29 +0300 Subject: [PATCH 01/11] Copy resolutions section from source package.json for yarn --- apps/rush-lib/src/api/PackageJsonEditor.ts | 11 +++++++++++ apps/rush-lib/src/logic/InstallManager.ts | 9 +++++++++ .../yarn-resolutions_2019-07-06-07-35.json | 11 +++++++++++ .../rush/yarn-resolutions_2019-07-06-07-35.json | 11 +++++++++++ common/reviews/api/node-core-library.api.md | 1 + common/reviews/api/rush-lib.api.md | 2 ++ libraries/node-core-library/src/IPackageJson.ts | 6 ++++++ 7 files changed, 51 insertions(+) create mode 100644 common/changes/@microsoft/node-core-library/yarn-resolutions_2019-07-06-07-35.json create mode 100644 common/changes/@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json diff --git a/apps/rush-lib/src/api/PackageJsonEditor.ts b/apps/rush-lib/src/api/PackageJsonEditor.ts index 53a1ab85ad7..4cfa4f0bf43 100644 --- a/apps/rush-lib/src/api/PackageJsonEditor.ts +++ b/apps/rush-lib/src/api/PackageJsonEditor.ts @@ -72,6 +72,10 @@ export class PackageJsonEditor { // SemVer range in one of the other fields for consumers. Thus "dependencies", "optionalDependencies", // and "peerDependencies" are mutually exclusive, but "devDependencies" is not. private readonly _devDependencies: Map; + + // NOTE: The "resolutions" is yarn specific featrue that controls package + // resolution override within yarn. + private readonly _resolutions: object; private _modified: boolean; private constructor(filepath: string, data: IPackageJson) { @@ -81,6 +85,7 @@ export class PackageJsonEditor { this._dependencies = new Map(); this._devDependencies = new Map(); + this._resolutions = {}; const dependencies: { [key: string]: string } = data.dependencies || {}; const optionalDependencies: { [key: string]: string } = data.optionalDependencies || {}; @@ -125,6 +130,8 @@ export class PackageJsonEditor { new PackageJsonDependency(packageName, devDependencies[packageName], DependencyType.Dev, _onChange)); }); + this._resolutions = data.resolutions || {}; + Sort.sortMapKeys(this._dependencies); Sort.sortMapKeys(this._devDependencies); @@ -167,6 +174,10 @@ export class PackageJsonEditor { return [...this._devDependencies.values()]; } + public get resolutions(): object { + return { ...this._resolutions }; + } + public tryGetDependency(packageName: string): PackageJsonDependency | undefined { return this._dependencies.get(packageName); } diff --git a/apps/rush-lib/src/logic/InstallManager.ts b/apps/rush-lib/src/logic/InstallManager.ts index 383e1a005b5..f575c74ea50 100644 --- a/apps/rush-lib/src/logic/InstallManager.ts +++ b/apps/rush-lib/src/logic/InstallManager.ts @@ -12,6 +12,7 @@ import * as os from 'os'; import * as path from 'path'; import * as semver from 'semver'; import * as tar from 'tar'; +import { isEmpty } from 'lodash'; import * as globEscape from 'glob-escape'; import { JsonFile, @@ -677,6 +678,14 @@ export class InstallManager { } } + if (!isEmpty(packageJson.resolutions)) { + tempPackageJson.resolutions = tempPackageJson.resolutions || {}; + commonPackageJson.resolutions = commonPackageJson.resolutions || {}; + + tempPackageJson.resolutions = packageJson.resolutions; + commonPackageJson.resolutions = { ...commonPackageJson.resolutions, ...packageJson.resolutions }; + } + // NPM expects the root of the tarball to have a directory called 'package' const npmPackageFolder: string = 'package'; diff --git a/common/changes/@microsoft/node-core-library/yarn-resolutions_2019-07-06-07-35.json b/common/changes/@microsoft/node-core-library/yarn-resolutions_2019-07-06-07-35.json new file mode 100644 index 00000000000..a5aa522e27e --- /dev/null +++ b/common/changes/@microsoft/node-core-library/yarn-resolutions_2019-07-06-07-35.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/node-core-library", + "comment": "Add support of resolutuions section for yarn", + "type": "minor" + } + ], + "packageName": "@microsoft/node-core-library", + "email": "MasterLambaster@gmail.com" +} \ No newline at end of file diff --git a/common/changes/@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json b/common/changes/@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json new file mode 100644 index 00000000000..4d73cde2d83 --- /dev/null +++ b/common/changes/@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Add support of resolutuions section for yarn", + "packageName": "@microsoft/rush", + "type": "none" + } + ], + "packageName": "@microsoft/rush", + "email": "MasterLambaster@gmail.com" +} \ No newline at end of file diff --git a/common/reviews/api/node-core-library.api.md b/common/reviews/api/node-core-library.api.md index ddf118c1584..35367957753 100644 --- a/common/reviews/api/node-core-library.api.md +++ b/common/reviews/api/node-core-library.api.md @@ -285,6 +285,7 @@ export interface INodePackageJson { peerDependencies?: IPackageJsonDependencyTable; private?: boolean; repository?: string; + resolutions?: Object; scripts?: IPackageJsonScriptTable; // @beta tsdocMetadata?: string; diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index 2f982d3720b..ef3e2541e83 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -204,6 +204,8 @@ export class PackageJsonEditor { // (undocumented) readonly name: string; // (undocumented) + readonly resolutions: object; + // (undocumented) saveIfModified(): boolean; // (undocumented) tryGetDependency(packageName: string): PackageJsonDependency | undefined; diff --git a/libraries/node-core-library/src/IPackageJson.ts b/libraries/node-core-library/src/IPackageJson.ts index 34021606b06..22801b6ce73 100644 --- a/libraries/node-core-library/src/IPackageJson.ts +++ b/libraries/node-core-library/src/IPackageJson.ts @@ -137,6 +137,12 @@ export interface IPackageJsonScriptTable { * A table of script hooks that a package manager or build tool may invoke. */ scripts?: IPackageJsonScriptTable; + + /** + * A table of package version resolutions. This feature is only available in + * yarn. + */ + resolutions?: Object; } /** From 7b3684c1bd5ee063c53ff34a85e12d934226b83e Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 17 Jul 2019 16:32:54 +0300 Subject: [PATCH 02/11] Apply copy suggestions from code review Co-Authored-By: Ian Clanton-Thuon --- apps/rush-lib/src/api/PackageJsonEditor.ts | 5 ++++- .../node-core-library/yarn-resolutions_2019-07-06-07-35.json | 4 ++-- .../@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/rush-lib/src/api/PackageJsonEditor.ts b/apps/rush-lib/src/api/PackageJsonEditor.ts index 4cfa4f0bf43..364975dc90b 100644 --- a/apps/rush-lib/src/api/PackageJsonEditor.ts +++ b/apps/rush-lib/src/api/PackageJsonEditor.ts @@ -73,7 +73,7 @@ export class PackageJsonEditor { // and "peerDependencies" are mutually exclusive, but "devDependencies" is not. private readonly _devDependencies: Map; - // NOTE: The "resolutions" is yarn specific featrue that controls package + // NOTE: The "resolutions" field is a yarn specific feature that controls package // resolution override within yarn. private readonly _resolutions: object; private _modified: boolean; @@ -174,6 +174,9 @@ export class PackageJsonEditor { return [...this._devDependencies.values()]; } + /** + * This field is a Yarn-specific feature that allows overriding of package resolution. + */ public get resolutions(): object { return { ...this._resolutions }; } diff --git a/common/changes/@microsoft/node-core-library/yarn-resolutions_2019-07-06-07-35.json b/common/changes/@microsoft/node-core-library/yarn-resolutions_2019-07-06-07-35.json index a5aa522e27e..826aaeb75db 100644 --- a/common/changes/@microsoft/node-core-library/yarn-resolutions_2019-07-06-07-35.json +++ b/common/changes/@microsoft/node-core-library/yarn-resolutions_2019-07-06-07-35.json @@ -2,10 +2,10 @@ "changes": [ { "packageName": "@microsoft/node-core-library", - "comment": "Add support of resolutuions section for yarn", + "comment": "Include the Yarn \"resolutions\" field in \"IPackageJson\".", "type": "minor" } ], "packageName": "@microsoft/node-core-library", "email": "MasterLambaster@gmail.com" -} \ No newline at end of file +} diff --git a/common/changes/@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json b/common/changes/@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json index 4d73cde2d83..709b8d3aacc 100644 --- a/common/changes/@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json +++ b/common/changes/@microsoft/rush/yarn-resolutions_2019-07-06-07-35.json @@ -1,11 +1,11 @@ { "changes": [ { - "comment": "Add support of resolutuions section for yarn", + "comment": "Add support for the Yarn \"resolutions\" package.json feature.", "packageName": "@microsoft/rush", "type": "none" } ], "packageName": "@microsoft/rush", "email": "MasterLambaster@gmail.com" -} \ No newline at end of file +} From 213ce52eb00383b6b24240c1f0bcdbb2f521f42c Mon Sep 17 00:00:00 2001 From: "Mr. Example" Date: Wed, 17 Jul 2019 16:55:37 +0300 Subject: [PATCH 03/11] Use resolutions only for yarn package manager --- apps/rush-lib/src/logic/InstallManager.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/rush-lib/src/logic/InstallManager.ts b/apps/rush-lib/src/logic/InstallManager.ts index f575c74ea50..16c2f317c40 100644 --- a/apps/rush-lib/src/logic/InstallManager.ts +++ b/apps/rush-lib/src/logic/InstallManager.ts @@ -679,11 +679,12 @@ export class InstallManager { } if (!isEmpty(packageJson.resolutions)) { - tempPackageJson.resolutions = tempPackageJson.resolutions || {}; - commonPackageJson.resolutions = commonPackageJson.resolutions || {}; + // We do not expect resolutions key to be provided for package managers other than yarn + if (this._rushConfiguration.packageManager !== 'yarn') { + throw new Error("Unexpected 'resolutions' section found in package.json. Only yarn supports this feature."); + } tempPackageJson.resolutions = packageJson.resolutions; - commonPackageJson.resolutions = { ...commonPackageJson.resolutions, ...packageJson.resolutions }; } // NPM expects the root of the tarball to have a directory called 'package' From b1579fbe08c7a25e2af5042867b900f42bd6d667 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 17 Jul 2019 16:57:51 +0300 Subject: [PATCH 04/11] Use more specific type based on code review suggestion Co-Authored-By: Ian Clanton-Thuon --- libraries/node-core-library/src/IPackageJson.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/node-core-library/src/IPackageJson.ts b/libraries/node-core-library/src/IPackageJson.ts index 22801b6ce73..43f8cdff640 100644 --- a/libraries/node-core-library/src/IPackageJson.ts +++ b/libraries/node-core-library/src/IPackageJson.ts @@ -142,7 +142,7 @@ export interface IPackageJsonScriptTable { * A table of package version resolutions. This feature is only available in * yarn. */ - resolutions?: Object; + resolutions?: { [name: string]: string }; } /** From 87329b8308914d8d4c648477ef023c57eaeb48f3 Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Thu, 25 Jul 2019 17:55:13 -0700 Subject: [PATCH 05/11] Fix a typing. --- apps/rush-lib/src/api/PackageJsonEditor.ts | 4 ++-- common/reviews/api/node-core-library.api.md | 4 +++- common/reviews/api/rush-lib.api.md | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/rush-lib/src/api/PackageJsonEditor.ts b/apps/rush-lib/src/api/PackageJsonEditor.ts index 364975dc90b..b8311ec9738 100644 --- a/apps/rush-lib/src/api/PackageJsonEditor.ts +++ b/apps/rush-lib/src/api/PackageJsonEditor.ts @@ -75,7 +75,7 @@ export class PackageJsonEditor { // NOTE: The "resolutions" field is a yarn specific feature that controls package // resolution override within yarn. - private readonly _resolutions: object; + private readonly _resolutions: { [name: string]: string }; private _modified: boolean; private constructor(filepath: string, data: IPackageJson) { @@ -177,7 +177,7 @@ export class PackageJsonEditor { /** * This field is a Yarn-specific feature that allows overriding of package resolution. */ - public get resolutions(): object { + public get resolutions(): { [name: string]: string } { return { ...this._resolutions }; } diff --git a/common/reviews/api/node-core-library.api.md b/common/reviews/api/node-core-library.api.md index 35367957753..fdd44f22efd 100644 --- a/common/reviews/api/node-core-library.api.md +++ b/common/reviews/api/node-core-library.api.md @@ -285,7 +285,9 @@ export interface INodePackageJson { peerDependencies?: IPackageJsonDependencyTable; private?: boolean; repository?: string; - resolutions?: Object; + resolutions?: { + [name: string]: string; + }; scripts?: IPackageJsonScriptTable; // @beta tsdocMetadata?: string; diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index ef3e2541e83..d285bcafec0 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -203,8 +203,9 @@ export class PackageJsonEditor { static load(filePath: string): PackageJsonEditor; // (undocumented) readonly name: string; - // (undocumented) - readonly resolutions: object; + readonly resolutions: { + [name: string]: string; + }; // (undocumented) saveIfModified(): boolean; // (undocumented) From 7e4347a182143c89e391042b2f5bffc0f7c2c74d Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Thu, 13 May 2021 21:13:39 -0700 Subject: [PATCH 06/11] rush build --- common/reviews/api/rush-lib.api.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index a8a31314447..673e821f01c 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -260,6 +260,9 @@ export class PackageJsonEditor { static load(filePath: string): PackageJsonEditor; // (undocumented) get name(): string; + get resolutions(): { + [name: string]: string; + }; // (undocumented) saveIfModified(): boolean; saveToObject(): IPackageJson; From 25ecbce15275b89ae29e746e5da0d8d4999ac681 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Thu, 13 May 2021 22:05:14 -0700 Subject: [PATCH 07/11] PR feedback: model PackageJsonEditor.resolutions like the other PackageJsonDependency tables --- apps/rush-lib/src/api/PackageJsonEditor.ts | 107 ++++++++++++------ .../installManager/RushInstallManager.ts | 7 +- common/reviews/api/rush-lib.api.md | 8 +- 3 files changed, 79 insertions(+), 43 deletions(-) diff --git a/apps/rush-lib/src/api/PackageJsonEditor.ts b/apps/rush-lib/src/api/PackageJsonEditor.ts index d328e6ee2da..49aa5037574 100644 --- a/apps/rush-lib/src/api/PackageJsonEditor.ts +++ b/apps/rush-lib/src/api/PackageJsonEditor.ts @@ -2,7 +2,7 @@ // See LICENSE in the project root for license information. import * as semver from 'semver'; -import { Import, IPackageJson, JsonFile, Sort } from '@rushstack/node-core-library'; +import { Import, InternalError, IPackageJson, JsonFile, Sort } from '@rushstack/node-core-library'; const lodash: typeof import('lodash') = Import.lazy('lodash', require); @@ -13,7 +13,8 @@ export const enum DependencyType { Regular = 'dependencies', Dev = 'devDependencies', Optional = 'optionalDependencies', - Peer = 'peerDependencies' + Peer = 'peerDependencies', + YarnResolutions = 'resolutions' } /** @@ -67,7 +68,7 @@ export class PackageJsonEditor { // NOTE: The "resolutions" field is a yarn specific feature that controls package // resolution override within yarn. - private readonly _resolutions: { [name: string]: string }; + private readonly _resolutions: Map; private _modified: boolean; private _sourceData: IPackageJson; @@ -78,7 +79,7 @@ export class PackageJsonEditor { this._dependencies = new Map(); this._devDependencies = new Map(); - this._resolutions = {}; + this._resolutions = new Map(); const dependencies: { [key: string]: string } = data.dependencies || {}; const optionalDependencies: { [key: string]: string } = data.optionalDependencies || {}; @@ -145,8 +146,19 @@ export class PackageJsonEditor { ); }); - this._resolutions = data.resolutions || {}; + Object.keys(data.resolutions || {}).forEach((packageName: string) => { + this._resolutions.set( + packageName, + new PackageJsonDependency( + packageName, + devDependencies[packageName], + DependencyType.YarnResolutions, + _onChange + ) + ); + }); + // (Do not sort this._resolutions because order may be significant; the RFC is unclear about that.) Sort.sortMapKeys(this._dependencies); Sort.sortMapKeys(this._devDependencies); } catch (e) { @@ -190,9 +202,12 @@ export class PackageJsonEditor { /** * This field is a Yarn-specific feature that allows overriding of package resolution. + * + * @see {@link https://github.com/yarnpkg/rfcs/blob/master/implemented/0000-selective-versions-resolutions.md + * | 0000-selective-versions-resolutions.md RFC} */ - public get resolutions(): { [name: string]: string } { - return { ...this._resolutions }; + public get resolutionsList(): ReadonlyArray { + return [...this._resolutions.values()]; } public tryGetDependency(packageName: string): PackageJsonDependency | undefined { @@ -216,16 +231,23 @@ export class PackageJsonEditor { ); // Rush collapses everything that isn't a devDependency into the dependencies - // field, so we need to set the value dependening on dependency type - if ( - dependencyType === DependencyType.Regular || - dependencyType === DependencyType.Optional || - dependencyType === DependencyType.Peer - ) { - this._dependencies.set(packageName, dependency); - } else { - this._devDependencies.set(packageName, dependency); + // field, so we need to set the value depending on dependency type + switch (dependencyType) { + case DependencyType.Regular: + case DependencyType.Optional: + case DependencyType.Peer: + this._dependencies.set(packageName, dependency); + break; + case DependencyType.Dev: + this._devDependencies.set(packageName, dependency); + break; + case DependencyType.YarnResolutions: + this._resolutions.set(packageName, dependency); + break; + default: + throw new InternalError('Unsupported DependencyType'); } + this._modified = true; } @@ -268,31 +290,36 @@ export class PackageJsonEditor { delete normalizedData.optionalDependencies; delete normalizedData.peerDependencies; delete normalizedData.devDependencies; + delete normalizedData.resolutions; const keys: string[] = [...this._dependencies.keys()].sort(); for (const packageName of keys) { const dependency: PackageJsonDependency = this._dependencies.get(packageName)!; - if (dependency.dependencyType === DependencyType.Regular) { - if (!normalizedData.dependencies) { - normalizedData.dependencies = {}; - } - normalizedData.dependencies[dependency.name] = dependency.version; - } - - if (dependency.dependencyType === DependencyType.Optional) { - if (!normalizedData.optionalDependencies) { - normalizedData.optionalDependencies = {}; - } - normalizedData.optionalDependencies[dependency.name] = dependency.version; - } - - if (dependency.dependencyType === DependencyType.Peer) { - if (!normalizedData.peerDependencies) { - normalizedData.peerDependencies = {}; - } - normalizedData.peerDependencies[dependency.name] = dependency.version; + switch (dependency.dependencyType) { + case DependencyType.Regular: + if (!normalizedData.dependencies) { + normalizedData.dependencies = {}; + } + normalizedData.dependencies[dependency.name] = dependency.version; + break; + case DependencyType.Optional: + if (!normalizedData.optionalDependencies) { + normalizedData.optionalDependencies = {}; + } + normalizedData.optionalDependencies[dependency.name] = dependency.version; + break; + case DependencyType.Peer: + if (!normalizedData.peerDependencies) { + normalizedData.peerDependencies = {}; + } + normalizedData.peerDependencies[dependency.name] = dependency.version; + break; + case DependencyType.Dev: // uses this._devDependencies instead + case DependencyType.YarnResolutions: // uses this._resolutions instead + default: + throw new InternalError('Unsupported DependencyType'); } } @@ -307,6 +334,16 @@ export class PackageJsonEditor { normalizedData.devDependencies[dependency.name] = dependency.version; } + // (Do not sort this._resolutions because order may be significant; the RFC is unclear about that.) + for (const packageName of this._resolutions.keys()) { + const dependency: PackageJsonDependency = this._resolutions.get(packageName)!; + + if (!normalizedData.resolutions) { + normalizedData.resolutions = {}; + } + normalizedData.resolutions[dependency.name] = dependency.version; + } + return normalizedData; } } diff --git a/apps/rush-lib/src/logic/installManager/RushInstallManager.ts b/apps/rush-lib/src/logic/installManager/RushInstallManager.ts index 567804d3392..a9717f5d104 100644 --- a/apps/rush-lib/src/logic/installManager/RushInstallManager.ts +++ b/apps/rush-lib/src/logic/installManager/RushInstallManager.ts @@ -8,7 +8,6 @@ import * as os from 'os'; import * as path from 'path'; import * as semver from 'semver'; import * as ssri from 'ssri'; -import { isEmpty } from 'lodash'; import { JsonFile, Text, @@ -257,15 +256,15 @@ export class RushInstallManager extends BaseInstallManager { } } - if (!isEmpty(packageJson.resolutions)) { + if (packageJson.resolutionsList.length > 0) { // We do not expect resolutions key to be provided for package managers other than yarn if (this.rushConfiguration.packageManager !== 'yarn') { throw new Error( - "Unexpected 'resolutions' section found in package.json. Only yarn supports this feature." + "Unexpected 'resolutions' section found in package.json. Only Yarn supports this feature." ); } - tempPackageJson.resolutions = packageJson.resolutions; + tempPackageJson.resolutions = packageJson.saveToObject().resolutions; } // Example: "C:\MyRepo\common\temp\projects\my-project-2" diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index 673e821f01c..fad59779419 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -87,7 +87,9 @@ export const enum DependencyType { // (undocumented) Peer = "peerDependencies", // (undocumented) - Regular = "dependencies" + Regular = "dependencies", + // (undocumented) + YarnResolutions = "resolutions" } // @public @@ -260,9 +262,7 @@ export class PackageJsonEditor { static load(filePath: string): PackageJsonEditor; // (undocumented) get name(): string; - get resolutions(): { - [name: string]: string; - }; + get resolutionsList(): ReadonlyArray; // (undocumented) saveIfModified(): boolean; saveToObject(): IPackageJson; From f3f32d917ed73d77b98202ebc915c6ef3d9c3b58 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Thu, 13 May 2021 22:05:59 -0700 Subject: [PATCH 08/11] rush change --- .../yarn-resolutions_2021-05-14-05-05.json | 11 +++++++++++ .../yarn-resolutions_2021-05-14-05-05.json | 11 +++++++++++ .../yarn-resolutions_2021-05-14-05-05.json | 11 +++++++++++ .../rundown/yarn-resolutions_2021-05-14-05-05.json | 11 +++++++++++ 4 files changed, 44 insertions(+) create mode 100644 common/changes/@microsoft/rush-stack-compiler-3.8/yarn-resolutions_2021-05-14-05-05.json create mode 100644 common/changes/@microsoft/rush-stack-compiler-3.9/yarn-resolutions_2021-05-14-05-05.json create mode 100644 common/changes/@rushstack/node-core-library/yarn-resolutions_2021-05-14-05-05.json create mode 100644 common/changes/@rushstack/rundown/yarn-resolutions_2021-05-14-05-05.json diff --git a/common/changes/@microsoft/rush-stack-compiler-3.8/yarn-resolutions_2021-05-14-05-05.json b/common/changes/@microsoft/rush-stack-compiler-3.8/yarn-resolutions_2021-05-14-05-05.json new file mode 100644 index 00000000000..e85748c5e9f --- /dev/null +++ b/common/changes/@microsoft/rush-stack-compiler-3.8/yarn-resolutions_2021-05-14-05-05.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush-stack-compiler-3.8", + "comment": "", + "type": "none" + } + ], + "packageName": "@microsoft/rush-stack-compiler-3.8", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@microsoft/rush-stack-compiler-3.9/yarn-resolutions_2021-05-14-05-05.json b/common/changes/@microsoft/rush-stack-compiler-3.9/yarn-resolutions_2021-05-14-05-05.json new file mode 100644 index 00000000000..35751848f72 --- /dev/null +++ b/common/changes/@microsoft/rush-stack-compiler-3.9/yarn-resolutions_2021-05-14-05-05.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush-stack-compiler-3.9", + "comment": "", + "type": "none" + } + ], + "packageName": "@microsoft/rush-stack-compiler-3.9", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@rushstack/node-core-library/yarn-resolutions_2021-05-14-05-05.json b/common/changes/@rushstack/node-core-library/yarn-resolutions_2021-05-14-05-05.json new file mode 100644 index 00000000000..a18f56bf958 --- /dev/null +++ b/common/changes/@rushstack/node-core-library/yarn-resolutions_2021-05-14-05-05.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@rushstack/node-core-library", + "comment": "", + "type": "none" + } + ], + "packageName": "@rushstack/node-core-library", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@rushstack/rundown/yarn-resolutions_2021-05-14-05-05.json b/common/changes/@rushstack/rundown/yarn-resolutions_2021-05-14-05-05.json new file mode 100644 index 00000000000..66ae345f9e7 --- /dev/null +++ b/common/changes/@rushstack/rundown/yarn-resolutions_2021-05-14-05-05.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@rushstack/rundown", + "comment": "", + "type": "none" + } + ], + "packageName": "@rushstack/rundown", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file From 1483b3db4b9bb932b41f4730382e7ba2acbd09ec Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Thu, 13 May 2021 22:10:02 -0700 Subject: [PATCH 09/11] Improve type for IPackageJson.resolutions --- apps/rush-lib/src/api/PackageJsonEditor.ts | 5 +++-- common/reviews/api/node-core-library.api.md | 4 +--- libraries/node-core-library/src/IPackageJson.ts | 9 ++++++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/rush-lib/src/api/PackageJsonEditor.ts b/apps/rush-lib/src/api/PackageJsonEditor.ts index 49aa5037574..00b8df32ff6 100644 --- a/apps/rush-lib/src/api/PackageJsonEditor.ts +++ b/apps/rush-lib/src/api/PackageJsonEditor.ts @@ -203,8 +203,9 @@ export class PackageJsonEditor { /** * This field is a Yarn-specific feature that allows overriding of package resolution. * - * @see {@link https://github.com/yarnpkg/rfcs/blob/master/implemented/0000-selective-versions-resolutions.md - * | 0000-selective-versions-resolutions.md RFC} + * @remarks + * See the {@link https://github.com/yarnpkg/rfcs/blob/master/implemented/0000-selective-versions-resolutions.md + * | 0000-selective-versions-resolutions.md RFC} for details. */ public get resolutionsList(): ReadonlyArray { return [...this._resolutions.values()]; diff --git a/common/reviews/api/node-core-library.api.md b/common/reviews/api/node-core-library.api.md index 1fd498a32a5..19ee114b8cb 100644 --- a/common/reviews/api/node-core-library.api.md +++ b/common/reviews/api/node-core-library.api.md @@ -465,9 +465,7 @@ export interface INodePackageJson { peerDependencies?: IPackageJsonDependencyTable; private?: boolean; repository?: string; - resolutions?: { - [name: string]: string; - }; + resolutions?: Record; scripts?: IPackageJsonScriptTable; // @beta tsdocMetadata?: string; diff --git a/libraries/node-core-library/src/IPackageJson.ts b/libraries/node-core-library/src/IPackageJson.ts index e461dd7f8b2..d215ff6e9bf 100644 --- a/libraries/node-core-library/src/IPackageJson.ts +++ b/libraries/node-core-library/src/IPackageJson.ts @@ -139,10 +139,13 @@ export interface INodePackageJson { scripts?: IPackageJsonScriptTable; /** - * A table of package version resolutions. This feature is only available in - * yarn. + * A table of package version resolutions. This feature is only implemented by the Yarn package manager. + * + * @remarks + * See the {@link https://github.com/yarnpkg/rfcs/blob/master/implemented/0000-selective-versions-resolutions.md + * | 0000-selective-versions-resolutions.md RFC} for details. */ - resolutions?: { [name: string]: string }; + resolutions?: Record; } /** From 5b4176a9bdfd39b15e2c4f0151d84c27f9a14c44 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Fri, 14 May 2021 15:18:59 -0700 Subject: [PATCH 10/11] PR feedback --- apps/rush-lib/src/api/PackageJsonEditor.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/rush-lib/src/api/PackageJsonEditor.ts b/apps/rush-lib/src/api/PackageJsonEditor.ts index 00b8df32ff6..629792c3c96 100644 --- a/apps/rush-lib/src/api/PackageJsonEditor.ts +++ b/apps/rush-lib/src/api/PackageJsonEditor.ts @@ -86,6 +86,7 @@ export class PackageJsonEditor { const peerDependencies: { [key: string]: string } = data.peerDependencies || {}; const devDependencies: { [key: string]: string } = data.devDependencies || {}; + const resolutions: { [key: string]: string } = data.resolutions || {}; const _onChange: () => void = this._onChange.bind(this); @@ -146,12 +147,12 @@ export class PackageJsonEditor { ); }); - Object.keys(data.resolutions || {}).forEach((packageName: string) => { + Object.keys(resolutions || {}).forEach((packageName: string) => { this._resolutions.set( packageName, new PackageJsonDependency( packageName, - devDependencies[packageName], + resolutions[packageName], DependencyType.YarnResolutions, _onChange ) From 2db822e9ce7dad3fef60f18f4fdaf6ec4a35d556 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Fri, 14 May 2021 16:22:09 -0700 Subject: [PATCH 11/11] Do not report an error when the Yarn-specific "resolutions" package.json field is used without Yarn. This check only worked with useWorkspaces=false, and there may be valid use cases for packages that target multiple package managers --- .../src/logic/installManager/RushInstallManager.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/apps/rush-lib/src/logic/installManager/RushInstallManager.ts b/apps/rush-lib/src/logic/installManager/RushInstallManager.ts index a9717f5d104..92a8d361a9a 100644 --- a/apps/rush-lib/src/logic/installManager/RushInstallManager.ts +++ b/apps/rush-lib/src/logic/installManager/RushInstallManager.ts @@ -256,15 +256,11 @@ export class RushInstallManager extends BaseInstallManager { } } - if (packageJson.resolutionsList.length > 0) { - // We do not expect resolutions key to be provided for package managers other than yarn - if (this.rushConfiguration.packageManager !== 'yarn') { - throw new Error( - "Unexpected 'resolutions' section found in package.json. Only Yarn supports this feature." - ); + if (this.rushConfiguration.packageManager === 'yarn') { + // This feature is only implemented by the Yarn package manager + if (packageJson.resolutionsList.length > 0) { + tempPackageJson.resolutions = packageJson.saveToObject().resolutions; } - - tempPackageJson.resolutions = packageJson.saveToObject().resolutions; } // Example: "C:\MyRepo\common\temp\projects\my-project-2"