From d0f4e049df9f434a1b400056d644076baad5e69b Mon Sep 17 00:00:00 2001 From: wbern Date: Wed, 13 Jan 2021 21:45:53 +0100 Subject: [PATCH 1/4] Support --from flag for filtered installs inside workspaces --- .../rush-lib/src/cli/actions/InstallAction.ts | 22 ++++++++++++++++++- apps/rush-lib/src/cli/actions/UpdateAction.ts | 3 ++- .../CommandLineHelp.test.ts.snap | 15 ++++++++++++- apps/rush-lib/src/logic/PackageJsonUpdater.ts | 3 ++- .../src/logic/base/BaseInstallManager.ts | 8 ++++++- .../installManager/WorkspaceInstallManager.ts | 13 +++++++---- 6 files changed, 55 insertions(+), 9 deletions(-) diff --git a/apps/rush-lib/src/cli/actions/InstallAction.ts b/apps/rush-lib/src/cli/actions/InstallAction.ts index 81fa35f50b..ee56b861da 100644 --- a/apps/rush-lib/src/cli/actions/InstallAction.ts +++ b/apps/rush-lib/src/cli/actions/InstallAction.ts @@ -9,7 +9,9 @@ import { RushCommandLineParser } from '../RushCommandLineParser'; export class InstallAction extends BaseInstallAction { protected _toFlag!: CommandLineStringListParameter; + protected _fromFlag!: CommandLineStringListParameter; protected _toVersionPolicy!: CommandLineStringListParameter; + protected _fromVersionPolicy!: CommandLineStringListParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -44,6 +46,15 @@ export class InstallAction extends BaseInstallAction { 'to specify the project in the current working directory. This argument is only valid in workspace ' + 'environments.' }); + this._fromFlag = this.defineStringListParameter({ + parameterLongName: '--from', + parameterShortName: '-f', + argumentName: 'PROJECT2', + description: + 'Run install in the specified project and all projects that directly or indirectly depend on the ' + + 'specified project. "." can be used as shorthand to specify the project in the current working directory.' + + ' This argument is only valid in workspace environments.' + }); this._toVersionPolicy = this.defineStringListParameter({ parameterLongName: '--to-version-policy', argumentName: 'VERSION_POLICY_NAME', @@ -51,6 +62,14 @@ export class InstallAction extends BaseInstallAction { 'Run install in all projects with the specified version policy and all of their dependencies. ' + 'This argument is only valid in workspace environments.' }); + this._fromVersionPolicy = this.defineStringListParameter({ + parameterLongName: '--from-version-policy', + argumentName: 'VERSION_POLICY_NAME', + description: + 'Run command in all projects with the specified version policy ' + + 'and all projects that directly or indirectly depend on projects with the specified version policy.' + + ' This argument is only valid in workspace environments.' + }); } protected buildInstallOptions(): IInstallManagerOptions { @@ -67,7 +86,8 @@ export class InstallAction extends BaseInstallAction { // Because the 'defaultValue' option on the _maxInstallAttempts parameter is set, // it is safe to assume that the value is not null maxInstallAttempts: this._maxInstallAttempts.value!, - toProjects: this.mergeProjectsWithVersionPolicy(this._toFlag, this._toVersionPolicy) + toProjects: this.mergeProjectsWithVersionPolicy(this._toFlag, this._toVersionPolicy), + fromProjects: this.mergeProjectsWithVersionPolicy(this._fromFlag, this._fromVersionPolicy) }; } } diff --git a/apps/rush-lib/src/cli/actions/UpdateAction.ts b/apps/rush-lib/src/cli/actions/UpdateAction.ts index f51b0f20f6..df7c6d8ac6 100644 --- a/apps/rush-lib/src/cli/actions/UpdateAction.ts +++ b/apps/rush-lib/src/cli/actions/UpdateAction.ts @@ -70,7 +70,8 @@ export class UpdateAction extends BaseInstallAction { // Because the 'defaultValue' option on the _maxInstallAttempts parameter is set, // it is safe to assume that the value is not null maxInstallAttempts: this._maxInstallAttempts.value!, - toProjects: [] + toProjects: [], + fromProjects: [] }; } } diff --git a/apps/rush-lib/src/cli/test/__snapshots__/CommandLineHelp.test.ts.snap b/apps/rush-lib/src/cli/test/__snapshots__/CommandLineHelp.test.ts.snap index dfda786b8b..c8be119c45 100644 --- a/apps/rush-lib/src/cli/test/__snapshots__/CommandLineHelp.test.ts.snap +++ b/apps/rush-lib/src/cli/test/__snapshots__/CommandLineHelp.test.ts.snap @@ -400,8 +400,9 @@ exports[`CommandLineHelp prints the help for each action: install 1`] = ` "usage: rush install [-h] [-p] [--bypass-policy] [--no-link] [--network-concurrency COUNT] [--debug-package-manager] [--max-install-attempts NUMBER] [--ignore-hooks] - [--variant VARIANT] [-t PROJECT1] + [--variant VARIANT] [-t PROJECT1] [-f PROJECT2] [--to-version-policy VERSION_POLICY_NAME] + [--from-version-policy VERSION_POLICY_NAME] The \\"rush install\\" command installs package dependencies for all your @@ -450,10 +451,22 @@ Optional arguments: dependencies. \\".\\" can be used as shorthand to specify the project in the current working directory. This argument is only valid in workspace environments. + -f PROJECT2, --from PROJECT2 + Run install in the specified project and all projects + that directly or indirectly depend on the specified + project. \\".\\" can be used as shorthand to specify the + project in the current working directory. This + argument is only valid in workspace environments. --to-version-policy VERSION_POLICY_NAME Run install in all projects with the specified version policy and all of their dependencies. This argument is only valid in workspace environments. + --from-version-policy VERSION_POLICY_NAME + Run command in all projects with the specified + version policy and all projects that directly or + indirectly depend on projects with the specified + version policy. This argument is only valid in + workspace environments. " `; diff --git a/apps/rush-lib/src/logic/PackageJsonUpdater.ts b/apps/rush-lib/src/logic/PackageJsonUpdater.ts index ad699c9740..9ae55a24c3 100644 --- a/apps/rush-lib/src/logic/PackageJsonUpdater.ts +++ b/apps/rush-lib/src/logic/PackageJsonUpdater.ts @@ -143,7 +143,8 @@ export class PackageJsonUpdater { collectLogFile: false, variant: variant, maxInstallAttempts: RushConstants.defaultMaxInstallAttempts, - toProjects: [] + toProjects: [], + fromProjects: [] }; const installManager: BaseInstallManager = InstallManagerFactory.getInstallManager( this._rushConfiguration, diff --git a/apps/rush-lib/src/logic/base/BaseInstallManager.ts b/apps/rush-lib/src/logic/base/BaseInstallManager.ts index 1ea7eda22f..dedd07438d 100644 --- a/apps/rush-lib/src/logic/base/BaseInstallManager.ts +++ b/apps/rush-lib/src/logic/base/BaseInstallManager.ts @@ -102,6 +102,11 @@ export interface IInstallManagerOptions { * The list of projects that should be installed, along with project dependencies. */ toProjects: ReadonlyArray; + + /** + * The list of projects that should be installed, along with dependencies of the project. + */ + fromProjects: ReadonlyArray; } /** @@ -148,7 +153,8 @@ export abstract class BaseInstallManager { } public async doInstall(): Promise { - const isFilteredInstall: boolean = this.options.toProjects.length > 0; + const isFilteredInstall: boolean = + this.options.toProjects.length > 0 || this.options.fromProjects.length > 0; const useWorkspaces: boolean = this.rushConfiguration.pnpmOptions && this.rushConfiguration.pnpmOptions.useWorkspaces; diff --git a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts index 57acbcb6d6..d1afe003ad 100644 --- a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts +++ b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts @@ -522,7 +522,7 @@ export class WorkspaceInstallManager extends BaseInstallManager { if (!workspaceImporter) { // Filtered installs will not contain all projects in the shrinkwrap, but if one is // missing during a full install, something has gone wrong - if (this.options.toProjects.length === 0) { + if (this.options.toProjects.length === 0 && this.options.fromProjects.length === 0) { throw new InternalError( `Cannot find shrinkwrap entry using importer key for workspace project: ${importerKey}` ); @@ -587,9 +587,14 @@ export class WorkspaceInstallManager extends BaseInstallManager { args.push('--recursive'); args.push('--link-workspace-packages', 'false'); - // "..." selects the specified package and all direct and indirect dependencies - for (const toProject of this.options.toProjects) { - args.push('--filter', `${toProject.packageName}...`); + const filteredProjects: string[] = this.options.toProjects + // "..." selects the specified package and all direct and indirect dependencies + .map((p) => p.packageName + '...') + // ..."" selects the specified package and all direct and indirect dependents of that package + .concat(this.options.fromProjects.map((p) => '...' + p.packageName)); + + for (const filteredProject of filteredProjects) { + args.push('--filter', filteredProject); } } } From 54123f767f1f131fc16e8a6a0b133433accf5247 Mon Sep 17 00:00:00 2001 From: wbern Date: Wed, 13 Jan 2021 21:48:16 +0100 Subject: [PATCH 2/4] rush change --- .../@microsoft/rush/from-flag_2021-01-13-20-47.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@microsoft/rush/from-flag_2021-01-13-20-47.json diff --git a/common/changes/@microsoft/rush/from-flag_2021-01-13-20-47.json b/common/changes/@microsoft/rush/from-flag_2021-01-13-20-47.json new file mode 100644 index 0000000000..ae70578d31 --- /dev/null +++ b/common/changes/@microsoft/rush/from-flag_2021-01-13-20-47.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "Add support for --from flag for filtered installs when using workspaces", + "type": "none" + } + ], + "packageName": "@microsoft/rush", + "email": "wbern@users.noreply.github.com" +} \ No newline at end of file From bf5554388aa3c3d380df1fdaa3faa9d9b100e812 Mon Sep 17 00:00:00 2001 From: wbern Date: Thu, 14 Jan 2021 08:20:41 +0100 Subject: [PATCH 3/4] simplify logic --- .../installManager/WorkspaceInstallManager.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts index d1afe003ad..4beb1aea6a 100644 --- a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts +++ b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts @@ -587,14 +587,14 @@ export class WorkspaceInstallManager extends BaseInstallManager { args.push('--recursive'); args.push('--link-workspace-packages', 'false'); - const filteredProjects: string[] = this.options.toProjects - // "..." selects the specified package and all direct and indirect dependencies - .map((p) => p.packageName + '...') - // ..."" selects the specified package and all direct and indirect dependents of that package - .concat(this.options.fromProjects.map((p) => '...' + p.packageName)); - - for (const filteredProject of filteredProjects) { - args.push('--filter', filteredProject); + // "..." selects the specified package and all direct and indirect dependencies + for (const toProject of this.options.toProjects) { + args.push('--filter', `${toProject.packageName}...`); + } + + // ..."" selects the specified package and all direct and indirect dependents of that package + for (const toProject of this.options.fromProjects) { + args.push('--filter', `...${toProject.packageName}`); } } } From 33f6d9cf1fefb149d34300169a5e4b7323e6e7d8 Mon Sep 17 00:00:00 2001 From: wbern Date: Thu, 14 Jan 2021 08:22:05 +0100 Subject: [PATCH 4/4] nitpick --- .../src/logic/installManager/WorkspaceInstallManager.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts index 4beb1aea6a..48e3cff0f9 100644 --- a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts +++ b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts @@ -593,8 +593,8 @@ export class WorkspaceInstallManager extends BaseInstallManager { } // ..."" selects the specified package and all direct and indirect dependents of that package - for (const toProject of this.options.fromProjects) { - args.push('--filter', `...${toProject.packageName}`); + for (const fromProject of this.options.fromProjects) { + args.push('--filter', `...${fromProject.packageName}`); } } }