From d5badbbcd095cff66558c2edd05277d92984aa66 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 15:17:15 -0800 Subject: [PATCH 01/23] Add Selection helpers --- apps/rush-lib/src/logic/Selection.ts | 108 ++++++++++ .../rush-lib/src/logic/test/Selection.test.ts | 204 ++++++++++++++++++ 2 files changed, 312 insertions(+) create mode 100644 apps/rush-lib/src/logic/Selection.ts create mode 100644 apps/rush-lib/src/logic/test/Selection.test.ts diff --git a/apps/rush-lib/src/logic/Selection.ts b/apps/rush-lib/src/logic/Selection.ts new file mode 100644 index 00000000000..8b6e8774f9b --- /dev/null +++ b/apps/rush-lib/src/logic/Selection.ts @@ -0,0 +1,108 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +/** + * Minimal subset of RushConfigurationProject needed for graph manipulation. + * Used to facilitate type safety in unit tests. + * @internal + */ +export interface IPartialProject> { + localDependencyProjectSet: ReadonlySet; + localDependentProjectSet: ReadonlySet; +} + +/** + * Computes the intersection of two or more sets. + */ +export function intersection(first: Iterable, ...rest: ReadonlySet[]): Set { + return new Set(generateIntersection(first, ...rest)); +} + +/** + * Computes the union of two or more sets. + */ +export function union(...sets: Iterable[]): Set { + return new Set(generateConcatenation(...sets)); +} + +/** + * Computes a set that contains the input projects and all the direct and indirect dependencies thereof. + */ +export function expandAllDependencies>(input: Iterable): Set { + return expandAll(input, expandDependenciesStep); +} + +/** + * Computes a set that contains the input projects and all projects that directly or indirectly depend on them. + */ +export function expandAllDependents>(input: Iterable): Set { + return expandAll(input, expandDependentsStep); +} + +/** + * Iterates the direct dependencies of the listed projects. May contain duplicates. + */ +export function* directDependenciesOf>(input: Iterable): Iterable { + for (const item of input) { + yield* item.localDependencyProjectSet; + } +} + +/** + * Iterates the projects that directly depend on the listed projects. May contain duplicates. + */ +export function* directDependentsOf>(input: Iterable): Iterable { + for (const item of input) { + yield* item.localDependentProjectSet; + } +} + +/** + * Function used for incremental mutation of a set, e.g. when expanding dependencies or dependents + */ +interface IExpansionStepFunction { + (project: T, targetSet: Set): void; +} + +function* generateIntersection(first: Iterable, ...rest: ReadonlySet[]): Iterable { + for (const item of first) { + if (rest.every((set: ReadonlySet) => set.has(item))) { + yield item; + } + } +} + +function* generateConcatenation(...sets: Iterable[]): Iterable { + for (const set of sets) { + yield* set; + } +} + +/** + * Adds all dependencies of the specified project to the target set. + */ +function expandDependenciesStep>(project: T, targetSet: Set): void { + for (const dep of project.localDependencyProjectSet) { + targetSet.add(dep); + } +} +/** + * Adds all project that depend on the specified project to the target set. + */ +function expandDependentsStep>(project: T, targetSet: Set): void { + for (const dep of project.localDependentProjectSet) { + targetSet.add(dep); + } +} + +/** + * Computes a set derived from the input by cloning it, then iterating over every member of the new set and + * calling a step function that may add more elements to the set. + */ +function expandAll(input: Iterable, expandStep: IExpansionStepFunction): Set { + const result: Set = new Set(input); + for (const item of result) { + expandStep(item, result); + } + return result; +} diff --git a/apps/rush-lib/src/logic/test/Selection.test.ts b/apps/rush-lib/src/logic/test/Selection.test.ts new file mode 100644 index 00000000000..be2f7bc4f1d --- /dev/null +++ b/apps/rush-lib/src/logic/test/Selection.test.ts @@ -0,0 +1,204 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +import { + IPartialProject, + union, + intersection, + expandAllDependencies, + expandAllDependents +} from '../Selection'; + +interface ISimpleGraphable extends IPartialProject { + localDependentProjectSet: Set; + toString(): string; +} + +const projectA: ISimpleGraphable = { + localDependencyProjectSet: new Set(), + localDependentProjectSet: new Set(), + toString() { + return 'A'; + } +}; +const projectB: ISimpleGraphable = { + localDependencyProjectSet: new Set(), + localDependentProjectSet: new Set(), + toString() { + return 'B'; + } +}; +const projectC: ISimpleGraphable = { + localDependencyProjectSet: new Set(), + localDependentProjectSet: new Set(), + toString() { + return 'C'; + } +}; +const projectD: ISimpleGraphable = { + localDependencyProjectSet: new Set([projectA, projectB]), + localDependentProjectSet: new Set(), + toString() { + return 'D'; + } +}; +const projectE: ISimpleGraphable = { + localDependencyProjectSet: new Set([projectC, projectD]), + localDependentProjectSet: new Set(), + toString() { + return 'E'; + } +}; +const projectF: ISimpleGraphable = { + localDependencyProjectSet: new Set([projectE]), + localDependentProjectSet: new Set(), + toString() { + return 'F'; + } +}; +const projectG: ISimpleGraphable = { + localDependencyProjectSet: new Set(), + localDependentProjectSet: new Set(), + toString() { + return 'G'; + } +}; +const projectH: ISimpleGraphable = { + localDependencyProjectSet: new Set([projectF, projectG]), + localDependentProjectSet: new Set(), + toString() { + return 'H'; + } +}; + +const nodes: Set = new Set([ + projectA, + projectB, + projectC, + projectD, + projectE, + projectF, + projectG, + projectH +]); + +// Populate the bidirectional graph +for (const node of nodes) { + for (const dep of node.localDependencyProjectSet) { + dep.localDependentProjectSet.add(node); + } +} + +expect.extend({ + toMatchSet(received: ReadonlySet, expected: ReadonlySet): jest.CustomMatcherResult { + for (const element of expected) { + if (!received.has(element)) { + return { + pass: false, + message: () => `Expected [${[...received].join(', ')}] to contain ${element}` + }; + } + } + for (const element of received) { + if (!expected.has(element)) { + return { + pass: false, + message: () => `Expected [${[...received].join(', ')}] to not contain ${element}` + }; + } + } + + return { + pass: true, + message: () => `Expected [${[...received].join(', ')}] to not match [${[...expected].join(', ')}]` + }; + } +}); + +declare global { + // Disabling eslint here because it is needed for module augmentation + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace jest { + // eslint-disable-next-line @typescript-eslint/naming-convention + export interface Matchers { + toMatchSet(expected: T): R; + } + } +} + +describe('union', () => { + it('combines sets', () => { + const result: ReadonlySet = union( + [projectA, projectB], + [projectC], + [projectA], + [projectB] + ); + + expect(result).toMatchSet(new Set([projectA, projectB, projectC])); + }); +}); + +describe('intersection', () => { + it('intersects sets', () => { + const result: ReadonlySet = intersection( + [projectC, projectD], + new Set([projectD, projectE, projectG, projectA]), + new Set([projectD]) + ); + + expect(result).toMatchSet(new Set([projectD])); + }); + + it('will produce the empty set in nothing matches', () => { + const result: ReadonlySet = intersection( + [projectC, projectD], + new Set([projectE, projectG, projectA]), + new Set([projectD]) + ); + + expect(result).toMatchSet(new Set()); + }); + + it('handles identical inputs', () => { + const result: ReadonlySet = intersection(nodes, nodes, nodes); + + expect(result).toMatchSet(nodes); + }); +}); + +describe('expandAllDependencies', () => { + it('expands at least one level of dependencies', () => { + const result: ReadonlySet = expandAllDependencies([projectD]); + + expect(result).toMatchSet(new Set([projectA, projectB, projectD])); + }); + it('expands all levels of dependencies', () => { + const result: ReadonlySet = expandAllDependencies([projectF]); + + expect(result).toMatchSet(new Set([projectA, projectB, projectC, projectD, projectE, projectF])); + }); + it('handles multiple inputs', () => { + const result: ReadonlySet = expandAllDependencies([projectC, projectD]); + + expect(result).toMatchSet(new Set([projectA, projectB, projectC, projectD])); + }); +}); + +describe('expandAllDependents', () => { + it('expands at least one level of dependents', () => { + const result: ReadonlySet = expandAllDependents([projectF]); + + expect(result).toMatchSet(new Set([projectF, projectH])); + }); + it('expands all levels of dependents', () => { + const result: ReadonlySet = expandAllDependents([projectC]); + + expect(result).toMatchSet(new Set([projectC, projectE, projectF, projectH])); + }); + it('handles multiple inputs', () => { + const result: ReadonlySet = expandAllDependents([projectC, projectB]); + + expect(result).toMatchSet(new Set([projectB, projectC, projectD, projectE, projectF, projectH])); + }); +}); From 40a03719777596a2f2c0fd19ec7ea26cc4012d3e Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 15:17:48 -0800 Subject: [PATCH 02/23] Include local optionalDependencies in downstream --- apps/rush-lib/src/api/RushConfiguration.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/rush-lib/src/api/RushConfiguration.ts b/apps/rush-lib/src/api/RushConfiguration.ts index a611dd528ca..7a4673867a0 100644 --- a/apps/rush-lib/src/api/RushConfiguration.ts +++ b/apps/rush-lib/src/api/RushConfiguration.ts @@ -783,6 +783,7 @@ export class RushConfiguration { // Compute the downstream dependencies within the list of Rush projects. this._populateDownstreamDependencies(project.packageJson.dependencies, project.packageName); this._populateDownstreamDependencies(project.packageJson.devDependencies, project.packageName); + this._populateDownstreamDependencies(project.packageJson.optionalDependencies, project.packageName); this._versionPolicyConfiguration.validate(this.projectsByName); } } From d3bf6a58282380b4e70958975013de5f8b46e651 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 15:27:53 -0800 Subject: [PATCH 03/23] Use sets, rework selection mechanics --- apps/rush-lib/src/api/RushConfiguration.ts | 2 +- .../src/api/RushConfigurationProject.ts | 75 +++++++-- .../src/cli/actions/BaseRushAction.ts | 24 +-- .../rush-lib/src/cli/actions/InstallAction.ts | 15 +- apps/rush-lib/src/cli/actions/UpdateAction.ts | 4 +- .../src/cli/scriptActions/BulkScriptAction.ts | 71 ++++++--- apps/rush-lib/src/logic/PackageJsonUpdater.ts | 4 +- apps/rush-lib/src/logic/PublishUtilities.ts | 4 +- apps/rush-lib/src/logic/TaskSelector.ts | 147 ++++-------------- .../src/logic/base/BaseInstallManager.ts | 11 +- .../src/logic/buildCache/ProjectBuildCache.ts | 2 +- .../installManager/WorkspaceInstallManager.ts | 8 +- .../src/logic/taskRunner/TaskCollection.ts | 2 +- 13 files changed, 180 insertions(+), 189 deletions(-) diff --git a/apps/rush-lib/src/api/RushConfiguration.ts b/apps/rush-lib/src/api/RushConfiguration.ts index 7a4673867a0..b927f813b2f 100644 --- a/apps/rush-lib/src/api/RushConfiguration.ts +++ b/apps/rush-lib/src/api/RushConfiguration.ts @@ -1669,7 +1669,7 @@ export class RushConfiguration { const depProject: RushConfigurationProject | undefined = this.projectsByName.get(dependencyName); if (depProject) { - depProject.downstreamDependencyProjects.push(packageName); + depProject.downstreamDependencyProjectSet.add(packageName); } }); } diff --git a/apps/rush-lib/src/api/RushConfigurationProject.ts b/apps/rush-lib/src/api/RushConfigurationProject.ts index 315a1c9b9f5..f7bf6b0df36 100644 --- a/apps/rush-lib/src/api/RushConfigurationProject.ts +++ b/apps/rush-lib/src/api/RushConfigurationProject.ts @@ -54,8 +54,9 @@ export class RushConfigurationProject { private _shouldPublish: boolean; private _skipRushCheck: boolean; private _publishFolder: string; - private _downstreamDependencyProjects: string[]; - private _localDependencyProjects: ReadonlyArray | undefined; + private _downstreamDependencyProjects: Set; + private _localDependencyProjects: ReadonlySet | undefined; + private _localDependentProjects: ReadonlySet | undefined; private readonly _rushConfiguration: RushConfiguration; /** @internal */ @@ -144,7 +145,7 @@ export class RushConfigurationProject { } this._shouldPublish = !!projectJson.shouldPublish; this._skipRushCheck = !!projectJson.skipRushCheck; - this._downstreamDependencyProjects = []; + this._downstreamDependencyProjects = new Set(); this._versionPolicyName = projectJson.versionPolicyName; this._publishFolder = this._projectFolder; @@ -227,25 +228,55 @@ export class RushConfigurationProject { /** * A list of projects within the Rush configuration which directly depend on this package. + * @deprecated Use downstreamDependencyProjectSet instead */ public get downstreamDependencyProjects(): string[] { + return [...this._downstreamDependencyProjects]; + } + + /** + * A set of projects within the Rush configuration which directly depend on this package. + */ + public get downstreamDependencyProjectSet(): Set { return this._downstreamDependencyProjects; } /** * A map of projects within the Rush configuration which are directly depended on by this project + * @deprecated Use localDependencyProjectSet instead */ public get localDependencyProjects(): ReadonlyArray { + return [...this.localDependencyProjectSet]; + } + + /** + * The set of projects within the Rush configuration which are directly depended on by this project + */ + public get localDependencyProjectSet(): ReadonlySet { if (!this._localDependencyProjects) { - this._localDependencyProjects = [ - ...this._getLocalDependencyProjects(this.packageJson.dependencies), - ...this._getLocalDependencyProjects(this.packageJson.devDependencies), - ...this._getLocalDependencyProjects(this.packageJson.optionalDependencies) - ]; + const self: RushConfigurationProject = this; + this._localDependencyProjects = new Set( + (function* () { + yield* self._getLocalDependencyProjects(self.packageJson.dependencies); + yield* self._getLocalDependencyProjects(self.packageJson.devDependencies); + yield* self._getLocalDependencyProjects(self.packageJson.optionalDependencies); + })() + ); } return this._localDependencyProjects; } + /** + * The set of projects withint he rush configuration which directly depend on this project. + * Excludes those that declare this project as a cyclicDependencyProject + */ + public get localDependentProjectSet(): ReadonlySet { + if (!this._localDependentProjects) { + this._localDependentProjects = new Set(this._getLocalDependentProjects()); + } + return this._localDependentProjects; + } + /** * The parsed NPM "package.json" file from projectFolder. * @deprecated Use packageJsonEditor instead @@ -358,10 +389,13 @@ export class RushConfigurationProject { return isMain; } - private _getLocalDependencyProjects( + /** + * Compute the local rush projects that this project immediately depends on, + * according to the specific dependency group from package.json + */ + private *_getLocalDependencyProjects( dependencies: IPackageJsonDependencyTable = {} - ): RushConfigurationProject[] { - const localDependencyProjects: RushConfigurationProject[] = []; + ): Iterable { for (const dependency of Object.keys(dependencies)) { // Skip if we can't find the local project or it's a cyclic dependency const localProject: RushConfigurationProject | undefined = this._rushConfiguration.getProjectByName( @@ -377,15 +411,28 @@ export class RushConfigurationProject { case DependencySpecifierType.Version: case DependencySpecifierType.Range: if (semver.satisfies(localProject.packageJson.version, dependencySpecifier.versionSpecifier)) { - localDependencyProjects.push(localProject); + yield localProject; } break; case DependencySpecifierType.Workspace: - localDependencyProjects.push(localProject); + yield localProject; break; } } } - return localDependencyProjects; + } + + /** + * Compute the local rush projects that immediately depend on this project + */ + private *_getLocalDependentProjects(): Iterable { + for (const projectName of this.downstreamDependencyProjectSet) { + const localProject: RushConfigurationProject | undefined = this._rushConfiguration.getProjectByName( + projectName + ); + if (localProject && localProject.localDependencyProjectSet.has(this)) { + yield localProject; + } + } } } diff --git a/apps/rush-lib/src/cli/actions/BaseRushAction.ts b/apps/rush-lib/src/cli/actions/BaseRushAction.ts index c740312abb1..a9ab3fe6eb4 100644 --- a/apps/rush-lib/src/cli/actions/BaseRushAction.ts +++ b/apps/rush-lib/src/cli/actions/BaseRushAction.ts @@ -131,13 +131,11 @@ export abstract class BaseRushAction extends BaseConfiglessRushAction { return super.onExecute(); } - protected mergeProjectsWithVersionPolicy( - projectsParameters: CommandLineStringListParameter, - versionPoliciesParameters: CommandLineStringListParameter - ): RushConfigurationProject[] { + protected *evaluateProjects( + projectsParameters: CommandLineStringListParameter + ): Iterable { const packageJsonLookup: PackageJsonLookup = new PackageJsonLookup(); - const projects: RushConfigurationProject[] = []; for (const projectParameter of projectsParameters.values) { if (projectParameter === '.') { const packageJson: IPackageJson | undefined = packageJsonLookup.tryLoadPackageJsonFor(process.cwd()); @@ -146,7 +144,7 @@ export abstract class BaseRushAction extends BaseConfiglessRushAction { packageJson.name ); if (project) { - projects.push(project); + yield project; } else { console.log( colors.red( @@ -174,21 +172,23 @@ export abstract class BaseRushAction extends BaseConfiglessRushAction { throw new AlreadyReportedError(); } - projects.push(project); + yield project; } } + } + protected *evaluateVersionPolicyProjects( + versionPoliciesParameters: CommandLineStringListParameter + ): Iterable { if (versionPoliciesParameters.values && versionPoliciesParameters.values.length > 0) { - this.rushConfiguration.projects.forEach((project) => { + for (const project of this.rushConfiguration.projects) { const matches: boolean = versionPoliciesParameters.values.some((policyName) => { return project.versionPolicyName === policyName; }); if (matches) { - projects.push(project); + yield project; } - }); + } } - - return projects; } } diff --git a/apps/rush-lib/src/cli/actions/InstallAction.ts b/apps/rush-lib/src/cli/actions/InstallAction.ts index 78681ea1e20..5e3a2845df2 100644 --- a/apps/rush-lib/src/cli/actions/InstallAction.ts +++ b/apps/rush-lib/src/cli/actions/InstallAction.ts @@ -6,6 +6,8 @@ import { CommandLineStringListParameter } from '@rushstack/ts-command-line'; import { BaseInstallAction } from './BaseInstallAction'; import { IInstallManagerOptions } from '../../logic/base/BaseInstallManager'; import { RushCommandLineParser } from '../RushCommandLineParser'; +import { RushConfigurationProject } from '../../api/RushConfigurationProject'; +import * as Selection from '../../logic/Selection'; export class InstallAction extends BaseInstallAction { protected _toFlag!: CommandLineStringListParameter; @@ -73,6 +75,15 @@ export class InstallAction extends BaseInstallAction { } protected buildInstallOptions(): IInstallManagerOptions { + const toProjects: Set = Selection.union( + this.evaluateProjects(this._toFlag), + this.evaluateVersionPolicyProjects(this._toVersionPolicy) + ); + const fromProjects: Set = Selection.union( + this.evaluateProjects(this._fromFlag), + this.evaluateVersionPolicyProjects(this._fromVersionPolicy) + ); + return { debug: this.parser.isDebug, allowShrinkwrapUpdates: false, @@ -86,8 +97,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), - fromProjects: this.mergeProjectsWithVersionPolicy(this._fromFlag, this._fromVersionPolicy) + toProjects, + fromProjects }; } } diff --git a/apps/rush-lib/src/cli/actions/UpdateAction.ts b/apps/rush-lib/src/cli/actions/UpdateAction.ts index df7c6d8ac6d..fb712c6d97e 100644 --- a/apps/rush-lib/src/cli/actions/UpdateAction.ts +++ b/apps/rush-lib/src/cli/actions/UpdateAction.ts @@ -70,8 +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: [], - fromProjects: [] + toProjects: new Set(), + fromProjects: new Set() }; } } diff --git a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts index c2424a51ccf..75b4c8621aa 100644 --- a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts +++ b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts @@ -24,8 +24,9 @@ import { Utilities } from '../../utilities/Utilities'; import { RushConstants } from '../../logic/RushConstants'; import { EnvironmentVariableNames } from '../../api/EnvironmentConfiguration'; import { LastLinkFlag, LastLinkFlagFactory } from '../../api/LastLinkFlag'; -import { IRushConfigurationProjectJson } from '../../api/RushConfigurationProject'; +import { IRushConfigurationProjectJson, RushConfigurationProject } from '../../api/RushConfigurationProject'; import { BuildCacheConfiguration } from '../../api/BuildCacheConfiguration'; +import * as Selection from '../../logic/Selection'; /** * Constructor parameters for BulkScriptAction. @@ -59,8 +60,8 @@ export class BulkScriptAction extends BaseScriptAction { private _commandToRun: string; private _changedProjectsOnly!: CommandLineFlagParameter; - private _fromFlag!: CommandLineStringListParameter; - private _toFlag!: CommandLineStringListParameter; + private _fromProject!: CommandLineStringListParameter; + private _toProject!: CommandLineStringListParameter; private _fromVersionPolicy!: CommandLineStringListParameter; private _toVersionPolicy!: CommandLineStringListParameter; private _verboseParameter!: CommandLineFlagParameter; @@ -115,11 +116,26 @@ export class BulkScriptAction extends BaseScriptAction { | BuildCacheConfiguration | undefined = await BuildCacheConfiguration.loadFromDefaultPathAsync(terminal, this.rushConfiguration); + const fromProjects: Set = Selection.union( + this.evaluateProjects(this._fromProject), + this.evaluateVersionPolicyProjects(this._fromVersionPolicy) + ); + + const toProjects: Set = Selection.union( + // --to + this.evaluateProjects(this._toProject), + // --to-version-policy + this.evaluateVersionPolicyProjects(this._toVersionPolicy), + // --from / --from-version-policy + Selection.expandAllDependents(fromProjects) + ); + + const selection: Set = Selection.expandAllDependencies(toProjects); + const taskSelector: TaskSelector = new TaskSelector({ rushConfiguration: this.rushConfiguration, buildCacheConfiguration, - toProjects: this.mergeProjectsWithVersionPolicy(this._toFlag, this._toVersionPolicy), - fromProjects: this.mergeProjectsWithVersionPolicy(this._fromFlag, this._fromVersionPolicy), + selection, commandToRun: this._commandToRun, customParameterValues, isQuietMode: isQuietMode, @@ -182,37 +198,46 @@ export class BulkScriptAction extends BaseScriptAction { ' operating system and number of CPU cores.' }); } - this._toFlag = this.defineStringListParameter({ + + this._toProject = this.defineStringListParameter({ parameterLongName: '--to', parameterShortName: '-t', argumentName: 'PROJECT', description: - 'Run command in the specified project and all of its dependencies. "." can be used as shorthand ' + - 'to specify the project in the current working directory.', + 'Run command on the selection instead of all projects. ' + + 'Adds the specified project and all its dependencies to the current selection. ' + + '"." can be used as shorthand to specify the project in the current working directory. ' + + 'Additional use of "--from" or "--to" will further expand the selection.', completions: this._getProjectNames.bind(this) }); - this._fromVersionPolicy = this.defineStringListParameter({ - parameterLongName: '--from-version-policy', - argumentName: 'VERSION_POLICY_NAME', + + this._fromProject = this.defineStringListParameter({ + parameterLongName: '--from', + parameterShortName: '-f', + argumentName: 'PROJECT', 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' + 'Run command on the selection instead of all projects. ' + + 'Add the specified project and all of its direct or indirect dependencies to the current selection. ' + + '"." can be used as shorthand to specify the project in the current working directory. ' + + 'Additional use of "--from" or "--to" will further expand the selection.', + completions: this._getProjectNames.bind(this) }); + this._toVersionPolicy = this.defineStringListParameter({ parameterLongName: '--to-version-policy', argumentName: 'VERSION_POLICY_NAME', description: - 'Run command in all projects with the specified version policy and all of their dependencies' + 'Run command on the selection instead of all projects. ' + + 'Adds all projects with the specified version policy, and all dependencies thereof, to the current selection.' }); - this._fromFlag = this.defineStringListParameter({ - parameterLongName: '--from', - parameterShortName: '-f', - argumentName: 'PROJECT', + this._fromVersionPolicy = this.defineStringListParameter({ + parameterLongName: '--from-version-policy', + argumentName: 'VERSION_POLICY_NAME', description: - 'Run command 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.', - completions: this._getProjectNames.bind(this) + 'Run command on the selection instead of all projects. ' + + 'Adds all projects with the specified version policy, and all projects that depend on them, to the current selection.' }); + this._verboseParameter = this.defineFlagParameter({ parameterLongName: '--verbose', parameterShortName: '-v', @@ -296,8 +321,8 @@ export class BulkScriptAction extends BaseScriptAction { private _collectTelemetry(stopwatch: Stopwatch, success: boolean): void { const extraData: { [key: string]: string } = { - command_to: (this._toFlag.values.length > 0).toString(), - command_from: (this._fromFlag.values.length > 0).toString() + command_to: (this._toProject.values.length > 0).toString(), + command_from: (this._fromProject.values.length > 0).toString() }; for (const customParameter of this.customParameters) { diff --git a/apps/rush-lib/src/logic/PackageJsonUpdater.ts b/apps/rush-lib/src/logic/PackageJsonUpdater.ts index 9ae55a24c3d..7491f0e924e 100644 --- a/apps/rush-lib/src/logic/PackageJsonUpdater.ts +++ b/apps/rush-lib/src/logic/PackageJsonUpdater.ts @@ -143,8 +143,8 @@ export class PackageJsonUpdater { collectLogFile: false, variant: variant, maxInstallAttempts: RushConstants.defaultMaxInstallAttempts, - toProjects: [], - fromProjects: [] + toProjects: new Set(), + fromProjects: new Set() }; const installManager: BaseInstallManager = InstallManagerFactory.getInstallManager( this._rushConfiguration, diff --git a/apps/rush-lib/src/logic/PublishUtilities.ts b/apps/rush-lib/src/logic/PublishUtilities.ts index d9e5a31731f..70e4114aab0 100644 --- a/apps/rush-lib/src/logic/PublishUtilities.ts +++ b/apps/rush-lib/src/logic/PublishUtilities.ts @@ -85,7 +85,7 @@ export class PublishUtilities { const change: IChangeInfo = allChanges[packageName]; const project: RushConfigurationProject = allPackages.get(packageName)!; const pkg: IPackageJson = project.packageJson; - const deps: string[] = project.downstreamDependencyProjects; + const deps: Set = project.downstreamDependencyProjectSet; // Write the new version expected for the change. const skipVersionBump: boolean = PublishUtilities._shouldSkipVersionBump( @@ -596,7 +596,7 @@ export class PublishUtilities { projectsToExclude?: Set ): void { const packageName: string = change.packageName; - const downstreamNames: string[] = allPackages.get(packageName)!.downstreamDependencyProjects; + const downstreamNames: Set = allPackages.get(packageName)!.downstreamDependencyProjectSet; // Iterate through all downstream dependencies for the package. if (downstreamNames) { diff --git a/apps/rush-lib/src/logic/TaskSelector.ts b/apps/rush-lib/src/logic/TaskSelector.ts index 424c8384c41..e045a11b33d 100644 --- a/apps/rush-lib/src/logic/TaskSelector.ts +++ b/apps/rush-lib/src/logic/TaskSelector.ts @@ -11,8 +11,7 @@ import { TaskCollection } from './taskRunner/TaskCollection'; export interface ITaskSelectorConstructor { rushConfiguration: RushConfiguration; buildCacheConfiguration: BuildCacheConfiguration | undefined; - toProjects: ReadonlyArray; - fromProjects: ReadonlyArray; + selection: Set; commandToRun: string; customParameterValues: string[]; isQuietMode: boolean; @@ -29,7 +28,6 @@ export interface ITaskSelectorConstructor { * - registering the necessary ProjectBuilders with the TaskRunner, which actually orchestrates execution */ export class TaskSelector { - private _taskCollection: TaskCollection; private _options: ITaskSelectorConstructor; private _packageChangeAnalyzer: PackageChangeAnalyzer; @@ -37,7 +35,6 @@ export class TaskSelector { this._options = options; this._packageChangeAnalyzer = new PackageChangeAnalyzer(options.rushConfiguration); - this._taskCollection = new TaskCollection(); } public static getScriptToRun( @@ -60,143 +57,51 @@ export class TaskSelector { } public registerTasks(): TaskCollection { - if (this._options.toProjects.length > 0) { - this._registerToProjects(this._options.toProjects); - } - if (this._options.fromProjects.length > 0) { - this._registerFromProjects(this._options.fromProjects); - } - if (this._options.toProjects.length === 0 && this._options.fromProjects.length === 0) { - this._registerAll(); - } + const selectedProjects: Set = this._computeSelectedProjects(); - return this._taskCollection; + return this._createTaskCollection(selectedProjects); } - private _registerToProjects(toProjects: ReadonlyArray): void { - const dependencies: Map = new Map(); - - for (const toProject of toProjects) { - this._collectAllDependencies(toProject, dependencies); - } + private _computeSelectedProjects(): Set { + const { selection } = this._options; - // Register any dependencies it may have - for (const dependencyProject of dependencies.values()) { - this._registerTask(dependencyProject); + if (selection.size) { + return selection; } - if (!this._options.ignoreDependencyOrder) { - // Add ordering relationships for each dependency - for (const dependencyProject of dependencies.values()) { - this._taskCollection.addDependencies( - ProjectBuilder.getTaskName(dependencyProject), - dependencyProject.localDependencyProjects.map((x) => ProjectBuilder.getTaskName(x)) - ); - } - } + // Default to all projects + return new Set(this._options.rushConfiguration.projects); } - private _registerFromProjects(fromProjects: ReadonlyArray): void { - const dependentList: Map> = this._getDependentGraph(); - const dependents: Map = new Map(); - - for (const fromProject of fromProjects) { - this._collectAllDependents(dependentList, fromProject, dependents); - } + private _createTaskCollection(projects: ReadonlySet): TaskCollection { + const taskCollection: TaskCollection = new TaskCollection(); - // Register all downstream dependents - for (const dependentProject of dependents.values()) { - this._registerTask(dependentProject); + // Register all tasks + for (const rushProject of projects) { + this._registerTask(rushProject, taskCollection); } - if (!this._options.ignoreDependencyOrder) { - // Only add ordering relationships for projects which have been registered - // e.g. package C may depend on A & B, but if we are only building A's downstream, we will ignore B - for (const dependentProject of dependents.values()) { - this._taskCollection.addDependencies( - ProjectBuilder.getTaskName(dependentProject), - dependentProject.localDependencyProjects - .filter((dep) => dependents.has(dep.packageName)) - .map((x) => ProjectBuilder.getTaskName(x)) - ); + function* getDependencyTaskNames(project: RushConfigurationProject): Iterable { + for (const dep of project.localDependencyProjectSet) { + // Only add relationships for projects in the set + if (projects.has(dep)) { + yield ProjectBuilder.getTaskName(dep); + } } } - } - - private _registerAll(): void { - // Register all tasks - for (const rushProject of this._options.rushConfiguration.projects) { - this._registerTask(rushProject); - } if (!this._options.ignoreDependencyOrder) { // Add ordering relationships for each dependency - for (const project of this._options.rushConfiguration.projects) { - this._taskCollection.addDependencies( - ProjectBuilder.getTaskName(project), - project.localDependencyProjects.map((x) => ProjectBuilder.getTaskName(x)) - ); - } - } - } - - /** - * Collects all upstream dependencies for a certain project - */ - private _collectAllDependencies( - project: RushConfigurationProject, - result: Map - ): void { - if (!result.has(project.packageName)) { - result.set(project.packageName, project); - - for (const dependencyProject of project.localDependencyProjects) { - this._collectAllDependencies(dependencyProject, result); - } - } - } - - /** - * Collects all downstream dependents of a certain project - */ - private _collectAllDependents( - dependentList: Map>, - project: RushConfigurationProject, - result: Map - ): void { - if (!result.has(project.packageName)) { - result.set(project.packageName, project); - - for (const dependent of dependentList.get(project.packageName) || []) { - this._collectAllDependents(dependentList, dependent, result); - } - } - } - - /** - * Inverts the localLinks to arrive at the dependent graph. This helps when using the --from flag - */ - private _getDependentGraph(): Map> { - const dependentList: Map> = new Map< - string, - Set - >(); - - for (const project of this._options.rushConfiguration.projects) { - for (const { packageName } of project.localDependencyProjects) { - if (!dependentList.has(packageName)) { - dependentList.set(packageName, new Set()); - } - - dependentList.get(packageName)!.add(project); + for (const project of projects) { + taskCollection.addDependencies(ProjectBuilder.getTaskName(project), getDependencyTaskNames(project)); } } - return dependentList; + return taskCollection; } - private _registerTask(project: RushConfigurationProject | undefined): void { - if (!project || this._taskCollection.hasTask(ProjectBuilder.getTaskName(project))) { + private _registerTask(project: RushConfigurationProject | undefined, taskCollection: TaskCollection): void { + if (!project || taskCollection.hasTask(ProjectBuilder.getTaskName(project))) { return; } @@ -211,7 +116,7 @@ export class TaskSelector { ); } - this._taskCollection.addTask( + taskCollection.addTask( new ProjectBuilder({ rushProject: project, rushConfiguration: this._options.rushConfiguration, diff --git a/apps/rush-lib/src/logic/base/BaseInstallManager.ts b/apps/rush-lib/src/logic/base/BaseInstallManager.ts index dedd07438d9..315f0aeb9e4 100644 --- a/apps/rush-lib/src/logic/base/BaseInstallManager.ts +++ b/apps/rush-lib/src/logic/base/BaseInstallManager.ts @@ -99,14 +99,14 @@ export interface IInstallManagerOptions { maxInstallAttempts: number; /** - * The list of projects that should be installed, along with project dependencies. + * The set of projects that should be installed, along with project dependencies. */ - toProjects: ReadonlyArray; + toProjects: ReadonlySet; /** - * The list of projects that should be installed, along with dependencies of the project. + * The set of projects that should be installed, along with dependencies of the project. */ - fromProjects: ReadonlyArray; + fromProjects: ReadonlySet; } /** @@ -153,8 +153,7 @@ export abstract class BaseInstallManager { } public async doInstall(): Promise { - const isFilteredInstall: boolean = - this.options.toProjects.length > 0 || this.options.fromProjects.length > 0; + const isFilteredInstall: boolean = this.options.toProjects.size > 0 || this.options.fromProjects.size > 0; const useWorkspaces: boolean = this.rushConfiguration.pnpmOptions && this.rushConfiguration.pnpmOptions.useWorkspaces; diff --git a/apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts b/apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts index b5036a39144..a721aa9b56a 100644 --- a/apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts +++ b/apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts @@ -301,7 +301,7 @@ export class ProjectBuildCache { return undefined; } else { projectStates.push(projectState); - for (const dependency of projectToProcess.localDependencyProjects) { + for (const dependency of projectToProcess.localDependencyProjectSet) { if (!projectsThatHaveBeenProcessed.has(dependency)) { newProjectsToProcess.add(dependency); } diff --git a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts index 48e3cff0f9b..7ceb63177a2 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 && this.options.fromProjects.length === 0) { + if (this.options.toProjects.size === 0 && this.options.fromProjects.size === 0) { throw new InternalError( `Cannot find shrinkwrap entry using importer key for workspace project: ${importerKey}` ); @@ -531,7 +531,11 @@ export class WorkspaceInstallManager extends BaseInstallManager { } const localDependencyProjectNames: Set = new Set( - project.localDependencyProjects.map((x) => x.packageName) + (function* (deps: Iterable): Iterable { + for (const dep of deps) { + yield dep.packageName; + } + })(project.localDependencyProjectSet) ); // Loop through non-local dependencies. Skip peer dependencies because they're only a constraint diff --git a/apps/rush-lib/src/logic/taskRunner/TaskCollection.ts b/apps/rush-lib/src/logic/taskRunner/TaskCollection.ts index c21d1484bc1..659ce50543b 100644 --- a/apps/rush-lib/src/logic/taskRunner/TaskCollection.ts +++ b/apps/rush-lib/src/logic/taskRunner/TaskCollection.ts @@ -44,7 +44,7 @@ export class TaskCollection { * @param taskName - the string name of the task for which we are defining dependencies. A task with this * name must already have been registered. */ - public addDependencies(taskName: string, taskDependencies: string[]): void { + public addDependencies(taskName: string, taskDependencies: Iterable): void { const task: Task | undefined = this._tasks.get(taskName); if (!task) { From 22db410511720f60e267b5ac342bef6e2f278772 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 15:28:11 -0800 Subject: [PATCH 04/23] Report critical path length in verbose logs --- .../src/logic/taskRunner/TaskRunner.ts | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/rush-lib/src/logic/taskRunner/TaskRunner.ts b/apps/rush-lib/src/logic/taskRunner/TaskRunner.ts index 73f4ad287d4..1ac8e83be53 100644 --- a/apps/rush-lib/src/logic/taskRunner/TaskRunner.ts +++ b/apps/rush-lib/src/logic/taskRunner/TaskRunner.ts @@ -156,10 +156,28 @@ export class TaskRunner { if (!this._quietMode) { const plural: string = this._tasks.length === 1 ? '' : 's'; this._terminal.writeStdoutLine(`Selected ${this._tasks.length} project${plural}:`); + const maxNameLength: number = this._tasks.reduce((max, task) => Math.max(max, task.name.length), 0); this._terminal.writeStdoutLine( this._tasks - .map((x) => ` ${x.name}`) - .sort() + .sort((x, y) => { + const diff: number = (y.criticalPathLength || 0) - (x.criticalPathLength || 0); + if (diff !== 0) { + return diff; + } + if (x.name < y.name) { + return -1; + } + if (x.name > y.name) { + return 1; + } + return 0; + }) + .map((x) => { + if (x.criticalPathLength !== undefined) { + return ` ${x.name.padEnd(maxNameLength, ' ')} (Depth: ${x.criticalPathLength})`; + } + return ` ${x.name}`; + }) .join('\n') ); this._terminal.writeStdoutLine(''); From fd78cddf2605c7e5321d2c939d9515beee0f1d96 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 15:28:22 -0800 Subject: [PATCH 05/23] Add --to-except --- .../src/cli/scriptActions/BulkScriptAction.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts index 75b4c8621aa..08071d8c56a 100644 --- a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts +++ b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts @@ -62,6 +62,7 @@ export class BulkScriptAction extends BaseScriptAction { private _changedProjectsOnly!: CommandLineFlagParameter; private _fromProject!: CommandLineStringListParameter; private _toProject!: CommandLineStringListParameter; + private _toExceptProject!: CommandLineStringListParameter; private _fromVersionPolicy!: CommandLineStringListParameter; private _toVersionPolicy!: CommandLineStringListParameter; private _verboseParameter!: CommandLineFlagParameter; @@ -126,6 +127,8 @@ export class BulkScriptAction extends BaseScriptAction { this.evaluateProjects(this._toProject), // --to-version-policy this.evaluateVersionPolicyProjects(this._toVersionPolicy), + // --to-except + Selection.directDependenciesOf(this.evaluateProjects(this._toExceptProject)), // --from / --from-version-policy Selection.expandAllDependents(fromProjects) ); @@ -210,6 +213,17 @@ export class BulkScriptAction extends BaseScriptAction { 'Additional use of "--from" or "--to" will further expand the selection.', completions: this._getProjectNames.bind(this) }); + this._toExceptProject = this.defineStringListParameter({ + parameterLongName: '--to-except', + parameterShortName: '-T', + argumentName: 'PROJECT2', + description: + 'Run command on the selection instead of all projects. ' + + 'Adds all dependencies of the specified project to the current selection. ' + + '"." can be used as shorthand to specify the project in the current working directory. ' + + 'Additional use of "--from" or "--to" will further expand the selection.', + completions: this._getProjectNames.bind(this) + }); this._fromProject = this.defineStringListParameter({ parameterLongName: '--from', From 51ce22f46fc6163b278c9a8fb19ec238279f31d3 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 15:28:36 -0800 Subject: [PATCH 06/23] rush change --- .../@microsoft/rush/rework-deps_2021-01-08-01-48.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json diff --git a/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json new file mode 100644 index 00000000000..22859018bc7 --- /dev/null +++ b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "Add `--to-except` command line option to BulkScriptAction to build all dependencies of the target project, but not the project itself. This option is intended for use with the future `--watch` option", + "type": "minor" + } + ], + "packageName": "@microsoft/rush", + "email": "dmichon-msft@users.noreply.github.com" +} \ No newline at end of file From ff09f4e59af0dad00f5dff8505e6c7f2ab1c6f02 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 15:30:42 -0800 Subject: [PATCH 07/23] Update API --- common/reviews/api/rush-lib.api.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index 094e3a6c577..ae93776ff89 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -413,10 +413,15 @@ export class RushConfigurationProject { // @internal constructor(projectJson: IRushConfigurationProjectJson, rushConfiguration: RushConfiguration, tempProjectName: string); get cyclicDependencyProjects(): Set; + // @deprecated get downstreamDependencyProjects(): string[]; + get downstreamDependencyProjectSet(): Set; // @beta get isMainProject(): boolean; + // @deprecated get localDependencyProjects(): ReadonlyArray; + get localDependencyProjectSet(): ReadonlySet; + get localDependentProjectSet(): ReadonlySet; // @deprecated get packageJson(): IPackageJson; // @beta From ee5b119684587c036ec00918dac85709e6cedae6 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 17:42:16 -0800 Subject: [PATCH 08/23] Add `--affected-by`, `--affected-by-except` --- .../src/cli/scriptActions/BulkScriptAction.ts | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts index 08071d8c56a..ef66ae911de 100644 --- a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts +++ b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts @@ -63,6 +63,8 @@ export class BulkScriptAction extends BaseScriptAction { private _fromProject!: CommandLineStringListParameter; private _toProject!: CommandLineStringListParameter; private _toExceptProject!: CommandLineStringListParameter; + private _affectedByProject!: CommandLineStringListParameter; + private _affectedByExceptProject!: CommandLineStringListParameter; private _fromVersionPolicy!: CommandLineStringListParameter; private _toVersionPolicy!: CommandLineStringListParameter; private _verboseParameter!: CommandLineFlagParameter; @@ -117,11 +119,15 @@ export class BulkScriptAction extends BaseScriptAction { | BuildCacheConfiguration | undefined = await BuildCacheConfiguration.loadFromDefaultPathAsync(terminal, this.rushConfiguration); + // Include all projects that depend on these projects, and all dependencies thereof const fromProjects: Set = Selection.union( + // --from this.evaluateProjects(this._fromProject), + // --from-version-policy this.evaluateVersionPolicyProjects(this._fromVersionPolicy) ); + // Include dependencies of these projects const toProjects: Set = Selection.union( // --to this.evaluateProjects(this._toProject), @@ -133,7 +139,19 @@ export class BulkScriptAction extends BaseScriptAction { Selection.expandAllDependents(fromProjects) ); - const selection: Set = Selection.expandAllDependencies(toProjects); + // These projects will not have their dependencies included + const affectedByProjects: Set = Selection.union( + // --affected-by + this.evaluateProjects(this._affectedByProject), + // --affected-by-except + Selection.directDependentsOf(this.evaluateProjects(this._affectedByExceptProject)) + ); + + const selection: Set = Selection.union( + Selection.expandAllDependencies(toProjects), + // Only dependents of these projects, not dependencies + Selection.expandAllDependents(affectedByProjects) + ); const taskSelector: TaskSelector = new TaskSelector({ rushConfiguration: this.rushConfiguration, @@ -210,18 +228,18 @@ export class BulkScriptAction extends BaseScriptAction { 'Run command on the selection instead of all projects. ' + 'Adds the specified project and all its dependencies to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of "--from" or "--to" will further expand the selection.', + 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', completions: this._getProjectNames.bind(this) }); this._toExceptProject = this.defineStringListParameter({ parameterLongName: '--to-except', parameterShortName: '-T', - argumentName: 'PROJECT2', + argumentName: 'PROJECT', description: 'Run command on the selection instead of all projects. ' + 'Adds all dependencies of the specified project to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of "--from" or "--to" will further expand the selection.', + 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', completions: this._getProjectNames.bind(this) }); @@ -231,9 +249,33 @@ export class BulkScriptAction extends BaseScriptAction { argumentName: 'PROJECT', description: 'Run command on the selection instead of all projects. ' + - 'Add the specified project and all of its direct or indirect dependencies to the current selection. ' + + 'Add the specified project and all projects that depend on it, and all the dependencies of those projects, to the current selection. ' + + '"." can be used as shorthand to specify the project in the current working directory. ' + + 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', + completions: this._getProjectNames.bind(this) + }); + + this._affectedByProject = this.defineStringListParameter({ + parameterLongName: '--affected-by', + parameterShortName: '-a', + argumentName: 'PROJECT', + description: + 'Run command on the selection instead of all projects. ' + + 'Add the specified project and all projects that would be affected by a change to it to the current selection. ' + + '"." can be used as shorthand to specify the project in the current working directory. ' + + 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', + completions: this._getProjectNames.bind(this) + }); + + this._affectedByExceptProject = this.defineStringListParameter({ + parameterLongName: '--affected-by-except', + parameterShortName: '-A', + argumentName: 'PROJECT', + description: + 'Run command on the selection instead of all projects. ' + + 'Add all projects that would be affected by a change to the specified project (except the project itself) to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of "--from" or "--to" will further expand the selection.', + 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', completions: this._getProjectNames.bind(this) }); From 2bd1d41b275c885a194577273d36fcb95b8761f2 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 16:21:14 -0800 Subject: [PATCH 09/23] Update snapshots --- .../CommandLineHelp.test.ts.snap | 208 +++++++++++++----- 1 file changed, 152 insertions(+), 56 deletions(-) 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 b1340c4320d..92585141595 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 @@ -110,10 +110,11 @@ Optional arguments: `; exports[`CommandLineHelp prints the help for each action: build 1`] = ` -"usage: rush build [-h] [-p COUNT] [-t PROJECT] - [--from-version-policy VERSION_POLICY_NAME] - [--to-version-policy VERSION_POLICY_NAME] [-f PROJECT] [-v] - [-o] [--ignore-hooks] [-s] [-m] +"usage: rush build [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] [-f PROJECT] + [-a PROJECT] [-A PROJECT] + [--to-version-policy VERSION_POLICY_NAME] + [--from-version-policy VERSION_POLICY_NAME] [-v] [-o] + [--ignore-hooks] [-s] [-m] This command is similar to \\"rush rebuild\\", except that \\"rush build\\" performs @@ -140,22 +141,53 @@ Optional arguments: cores. This parameter may alternatively be specified via the RUSH_PARALLELISM environment variable. -t PROJECT, --to PROJECT - Run command in the specified project and all of its - dependencies. \\".\\" can be used as shorthand to specify - the project in the current working directory. - --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 - --to-version-policy VERSION_POLICY_NAME - Run command in all projects with the specified - version policy and all of their dependencies + Run command on the selection instead of all projects. + Adds the specified project and all its dependencies + to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + -T PROJECT, --to-except PROJECT + Run command on the selection instead of all projects. + Adds all dependencies of the specified project to the + current selection. \\".\\" can be used as shorthand to + specify the project in the current working directory. + Additional use of \\"--affected-by\\", \\"--from\\", or + \\"--to\\" will further expand the selection. -f PROJECT, --from PROJECT - Run command 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. + Run command on the selection instead of all projects. + Add the specified project and all projects that + depend on it, and all the dependencies of those + projects, to the current selection. \\".\\" can be used + as shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + -a PROJECT, --affected-by PROJECT + Run command on the selection instead of all projects. + Add the specified project and all projects that would + be affected by a change to it to the current + selection. \\".\\" can be used as shorthand to specify + the project in the current working directory. + Additional use of \\"--affected-by\\", \\"--from\\", or + \\"--to\\" will further expand the selection. + -A PROJECT, --affected-by-except PROJECT + Run command on the selection instead of all projects. + Add all projects that would be affected by a change + to the specified project (except the project itself) + to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + --to-version-policy VERSION_POLICY_NAME + Run command on the selection instead of all projects. + Adds all projects with the specified version policy, + and all dependencies thereof, to the current + selection. + --from-version-policy VERSION_POLICY_NAME + Run command on the selection instead of all projects. + Adds all projects with the specified version policy, + and all projects that depend on them, to the current + selection. -v, --verbose Display the logs during the build, rather than just displaying the build status summary -o, --changed-projects-only @@ -285,10 +317,11 @@ Optional arguments: `; exports[`CommandLineHelp prints the help for each action: import-strings 1`] = ` -"usage: rush import-strings [-h] [-p COUNT] [-t PROJECT] - [--from-version-policy VERSION_POLICY_NAME] +"usage: rush import-strings [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] + [-f PROJECT] [-a PROJECT] [-A PROJECT] [--to-version-policy VERSION_POLICY_NAME] - [-f PROJECT] [-v] [--ignore-hooks] + [--from-version-policy VERSION_POLICY_NAME] [-v] + [--ignore-hooks] [--locale {en-us,fr-fr,es-es,zh-cn}] @@ -307,22 +340,53 @@ Optional arguments: cores. This parameter may alternatively be specified via the RUSH_PARALLELISM environment variable. -t PROJECT, --to PROJECT - Run command in the specified project and all of its - dependencies. \\".\\" can be used as shorthand to specify - the project in the current working directory. - --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 - --to-version-policy VERSION_POLICY_NAME - Run command in all projects with the specified - version policy and all of their dependencies + Run command on the selection instead of all projects. + Adds the specified project and all its dependencies + to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + -T PROJECT, --to-except PROJECT + Run command on the selection instead of all projects. + Adds all dependencies of the specified project to the + current selection. \\".\\" can be used as shorthand to + specify the project in the current working directory. + Additional use of \\"--affected-by\\", \\"--from\\", or + \\"--to\\" will further expand the selection. -f PROJECT, --from PROJECT - Run command 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. + Run command on the selection instead of all projects. + Add the specified project and all projects that + depend on it, and all the dependencies of those + projects, to the current selection. \\".\\" can be used + as shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + -a PROJECT, --affected-by PROJECT + Run command on the selection instead of all projects. + Add the specified project and all projects that would + be affected by a change to it to the current + selection. \\".\\" can be used as shorthand to specify + the project in the current working directory. + Additional use of \\"--affected-by\\", \\"--from\\", or + \\"--to\\" will further expand the selection. + -A PROJECT, --affected-by-except PROJECT + Run command on the selection instead of all projects. + Add all projects that would be affected by a change + to the specified project (except the project itself) + to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + --to-version-policy VERSION_POLICY_NAME + Run command on the selection instead of all projects. + Adds all projects with the specified version policy, + and all dependencies thereof, to the current + selection. + --from-version-policy VERSION_POLICY_NAME + Run command on the selection instead of all projects. + Adds all projects with the specified version policy, + and all projects that depend on them, to the current + selection. -v, --verbose Display the logs during the build, rather than just displaying the build status summary --ignore-hooks Skips execution of the \\"eventHooks\\" scripts defined @@ -615,10 +679,11 @@ Optional arguments: `; exports[`CommandLineHelp prints the help for each action: rebuild 1`] = ` -"usage: rush rebuild [-h] [-p COUNT] [-t PROJECT] - [--from-version-policy VERSION_POLICY_NAME] - [--to-version-policy VERSION_POLICY_NAME] [-f PROJECT] - [-v] [--ignore-hooks] [-s] [-m] +"usage: rush rebuild [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] [-f PROJECT] + [-a PROJECT] [-A PROJECT] + [--to-version-policy VERSION_POLICY_NAME] + [--from-version-policy VERSION_POLICY_NAME] [-v] + [--ignore-hooks] [-s] [-m] This command assumes that the package.json file for each project contains a @@ -642,22 +707,53 @@ Optional arguments: cores. This parameter may alternatively be specified via the RUSH_PARALLELISM environment variable. -t PROJECT, --to PROJECT - Run command in the specified project and all of its - dependencies. \\".\\" can be used as shorthand to specify - the project in the current working directory. - --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 - --to-version-policy VERSION_POLICY_NAME - Run command in all projects with the specified - version policy and all of their dependencies + Run command on the selection instead of all projects. + Adds the specified project and all its dependencies + to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + -T PROJECT, --to-except PROJECT + Run command on the selection instead of all projects. + Adds all dependencies of the specified project to the + current selection. \\".\\" can be used as shorthand to + specify the project in the current working directory. + Additional use of \\"--affected-by\\", \\"--from\\", or + \\"--to\\" will further expand the selection. -f PROJECT, --from PROJECT - Run command 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. + Run command on the selection instead of all projects. + Add the specified project and all projects that + depend on it, and all the dependencies of those + projects, to the current selection. \\".\\" can be used + as shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + -a PROJECT, --affected-by PROJECT + Run command on the selection instead of all projects. + Add the specified project and all projects that would + be affected by a change to it to the current + selection. \\".\\" can be used as shorthand to specify + the project in the current working directory. + Additional use of \\"--affected-by\\", \\"--from\\", or + \\"--to\\" will further expand the selection. + -A PROJECT, --affected-by-except PROJECT + Run command on the selection instead of all projects. + Add all projects that would be affected by a change + to the specified project (except the project itself) + to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of \\"--affected-by\\", + \\"--from\\", or \\"--to\\" will further expand the selection. + --to-version-policy VERSION_POLICY_NAME + Run command on the selection instead of all projects. + Adds all projects with the specified version policy, + and all dependencies thereof, to the current + selection. + --from-version-policy VERSION_POLICY_NAME + Run command on the selection instead of all projects. + Adds all projects with the specified version policy, + and all projects that depend on them, to the current + selection. -v, --verbose Display the logs during the build, rather than just displaying the build status summary --ignore-hooks Skips execution of the \\"eventHooks\\" scripts defined From 2612c094c2eaf3e8bc0ce74818948a693514d710 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 17:51:28 -0800 Subject: [PATCH 10/23] Update changefile --- .../changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json index 22859018bc7..16d0b0af64c 100644 --- a/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json +++ b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json @@ -2,8 +2,8 @@ "changes": [ { "packageName": "@microsoft/rush", - "comment": "Add `--to-except` command line option to BulkScriptAction to build all dependencies of the target project, but not the project itself. This option is intended for use with the future `--watch` option", - "type": "minor" + "comment": "Add `--to-except` command line option to BulkScriptAction to build all dependencies of the target project, but not the project itself. This option is intended for use with the future `--watch` option.\nAdd `--affected-by` and `--affected-by-except` options to build only projects that are directly affected by changes to the specified project.", + "type": "none" } ], "packageName": "@microsoft/rush", From b0065db52d07e7a36c1d5cf298d0e9c986e4ca0e Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 18:02:56 -0800 Subject: [PATCH 11/23] Add --only, revise docs --- .../src/cli/scriptActions/BulkScriptAction.ts | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts index ef66ae911de..183016101b7 100644 --- a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts +++ b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts @@ -61,6 +61,7 @@ export class BulkScriptAction extends BaseScriptAction { private _changedProjectsOnly!: CommandLineFlagParameter; private _fromProject!: CommandLineStringListParameter; + private _onlyProject!: CommandLineStringListParameter; private _toProject!: CommandLineStringListParameter; private _toExceptProject!: CommandLineStringListParameter; private _affectedByProject!: CommandLineStringListParameter; @@ -119,6 +120,9 @@ export class BulkScriptAction extends BaseScriptAction { | BuildCacheConfiguration | undefined = await BuildCacheConfiguration.loadFromDefaultPathAsync(terminal, this.rushConfiguration); + // Include exactly these projects (--only) + const onlyProjects: Iterable = this.evaluateProjects(this._onlyProject); + // Include all projects that depend on these projects, and all dependencies thereof const fromProjects: Set = Selection.union( // --from @@ -148,6 +152,7 @@ export class BulkScriptAction extends BaseScriptAction { ); const selection: Set = Selection.union( + onlyProjects, Selection.expandAllDependencies(toProjects), // Only dependents of these projects, not dependencies Selection.expandAllDependents(affectedByProjects) @@ -228,7 +233,7 @@ export class BulkScriptAction extends BaseScriptAction { 'Run command on the selection instead of all projects. ' + 'Adds the specified project and all its dependencies to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', + 'Additional use of any selection commands will further expand the selection.', completions: this._getProjectNames.bind(this) }); this._toExceptProject = this.defineStringListParameter({ @@ -239,7 +244,7 @@ export class BulkScriptAction extends BaseScriptAction { 'Run command on the selection instead of all projects. ' + 'Adds all dependencies of the specified project to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', + 'Additional use of any selection commands will further expand the selection.', completions: this._getProjectNames.bind(this) }); @@ -251,7 +256,18 @@ export class BulkScriptAction extends BaseScriptAction { 'Run command on the selection instead of all projects. ' + 'Add the specified project and all projects that depend on it, and all the dependencies of those projects, to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', + 'Additional use of any selection commands will further expand the selection.', + completions: this._getProjectNames.bind(this) + }); + this._onlyProject = this.defineStringListParameter({ + parameterLongName: '--only', + parameterShortName: '-o', + argumentName: 'PROJECT', + description: + 'Run command on the selection instead of all projects. ' + + 'Add the specified project (and only the specified project) to the current selection. ' + + '"." can be used as shorthand to specify the project in the current working directory. ' + + 'Additional use of any selection commands will further expand the selection.', completions: this._getProjectNames.bind(this) }); @@ -263,7 +279,7 @@ export class BulkScriptAction extends BaseScriptAction { 'Run command on the selection instead of all projects. ' + 'Add the specified project and all projects that would be affected by a change to it to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', + 'Additional use of any selection commands will further expand the selection.', completions: this._getProjectNames.bind(this) }); @@ -275,7 +291,7 @@ export class BulkScriptAction extends BaseScriptAction { 'Run command on the selection instead of all projects. ' + 'Add all projects that would be affected by a change to the specified project (except the project itself) to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of "--affected-by", "--from", or "--to" will further expand the selection.', + 'Additional use of any selection commands will further expand the selection.', completions: this._getProjectNames.bind(this) }); @@ -284,14 +300,16 @@ export class BulkScriptAction extends BaseScriptAction { argumentName: 'VERSION_POLICY_NAME', description: 'Run command on the selection instead of all projects. ' + - 'Adds all projects with the specified version policy, and all dependencies thereof, to the current selection.' + 'Adds all projects with the specified version policy, and all dependencies thereof, to the current selection. ' + + 'Additional use of any selection commands will further expand the selection.' }); this._fromVersionPolicy = this.defineStringListParameter({ parameterLongName: '--from-version-policy', argumentName: 'VERSION_POLICY_NAME', description: 'Run command on the selection instead of all projects. ' + - 'Adds all projects with the specified version policy, and all projects that depend on them, to the current selection.' + 'Adds all projects with the specified version policy, and all projects that depend on them, to the current selection. ' + + 'Additional use of any selection commands will further expand the selection.' }); this._verboseParameter = this.defineFlagParameter({ @@ -302,7 +320,7 @@ export class BulkScriptAction extends BaseScriptAction { if (this._isIncrementalBuildAllowed) { this._changedProjectsOnly = this.defineFlagParameter({ parameterLongName: '--changed-projects-only', - parameterShortName: '-o', + parameterShortName: '-c', description: 'If specified, the incremental build will only rebuild projects that have changed, ' + 'but not any projects that directly or indirectly depend on the changed package.' From 297098d3da4f005cae2240c1d4d88ee0f319b0e8 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 18:03:40 -0800 Subject: [PATCH 12/23] Update snapshots --- .../CommandLineHelp.test.ts.snap | 109 +++++++++++------- 1 file changed, 68 insertions(+), 41 deletions(-) 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 92585141595..bf6343bbb2d 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 @@ -111,9 +111,9 @@ Optional arguments: exports[`CommandLineHelp prints the help for each action: build 1`] = ` "usage: rush build [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] [-f PROJECT] - [-a PROJECT] [-A PROJECT] + [-o PROJECT] [-a PROJECT] [-A PROJECT] [--to-version-policy VERSION_POLICY_NAME] - [--from-version-policy VERSION_POLICY_NAME] [-v] [-o] + [--from-version-policy VERSION_POLICY_NAME] [-v] [-c] [--ignore-hooks] [-s] [-m] @@ -145,52 +145,61 @@ Optional arguments: Adds the specified project and all its dependencies to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. -T PROJECT, --to-except PROJECT Run command on the selection instead of all projects. Adds all dependencies of the specified project to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. - Additional use of \\"--affected-by\\", \\"--from\\", or - \\"--to\\" will further expand the selection. + Additional use of any selection commands will further + expand the selection. -f PROJECT, --from PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that depend on it, and all the dependencies of those projects, to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. + -o PROJECT, --only PROJECT + Run command on the selection instead of all projects. + Add the specified project (and only the specified + project) to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of any selection + commands will further expand the selection. -a PROJECT, --affected-by PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that would be affected by a change to it to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. - Additional use of \\"--affected-by\\", \\"--from\\", or - \\"--to\\" will further expand the selection. + Additional use of any selection commands will further + expand the selection. -A PROJECT, --affected-by-except PROJECT Run command on the selection instead of all projects. Add all projects that would be affected by a change to the specified project (except the project itself) to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. --to-version-policy VERSION_POLICY_NAME Run command on the selection instead of all projects. Adds all projects with the specified version policy, and all dependencies thereof, to the current - selection. + selection. Additional use of any selection commands + will further expand the selection. --from-version-policy VERSION_POLICY_NAME Run command on the selection instead of all projects. Adds all projects with the specified version policy, and all projects that depend on them, to the current - selection. + selection. Additional use of any selection commands + will further expand the selection. -v, --verbose Display the logs during the build, rather than just displaying the build status summary - -o, --changed-projects-only + -c, --changed-projects-only If specified, the incremental build will only rebuild projects that have changed, but not any projects that directly or indirectly depend on the changed package. @@ -318,7 +327,7 @@ Optional arguments: exports[`CommandLineHelp prints the help for each action: import-strings 1`] = ` "usage: rush import-strings [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] - [-f PROJECT] [-a PROJECT] [-A PROJECT] + [-f PROJECT] [-o PROJECT] [-a PROJECT] [-A PROJECT] [--to-version-policy VERSION_POLICY_NAME] [--from-version-policy VERSION_POLICY_NAME] [-v] [--ignore-hooks] @@ -344,49 +353,58 @@ Optional arguments: Adds the specified project and all its dependencies to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. -T PROJECT, --to-except PROJECT Run command on the selection instead of all projects. Adds all dependencies of the specified project to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. - Additional use of \\"--affected-by\\", \\"--from\\", or - \\"--to\\" will further expand the selection. + Additional use of any selection commands will further + expand the selection. -f PROJECT, --from PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that depend on it, and all the dependencies of those projects, to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. + -o PROJECT, --only PROJECT + Run command on the selection instead of all projects. + Add the specified project (and only the specified + project) to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of any selection + commands will further expand the selection. -a PROJECT, --affected-by PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that would be affected by a change to it to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. - Additional use of \\"--affected-by\\", \\"--from\\", or - \\"--to\\" will further expand the selection. + Additional use of any selection commands will further + expand the selection. -A PROJECT, --affected-by-except PROJECT Run command on the selection instead of all projects. Add all projects that would be affected by a change to the specified project (except the project itself) to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. --to-version-policy VERSION_POLICY_NAME Run command on the selection instead of all projects. Adds all projects with the specified version policy, and all dependencies thereof, to the current - selection. + selection. Additional use of any selection commands + will further expand the selection. --from-version-policy VERSION_POLICY_NAME Run command on the selection instead of all projects. Adds all projects with the specified version policy, and all projects that depend on them, to the current - selection. + selection. Additional use of any selection commands + will further expand the selection. -v, --verbose Display the logs during the build, rather than just displaying the build status summary --ignore-hooks Skips execution of the \\"eventHooks\\" scripts defined @@ -680,7 +698,7 @@ Optional arguments: exports[`CommandLineHelp prints the help for each action: rebuild 1`] = ` "usage: rush rebuild [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] [-f PROJECT] - [-a PROJECT] [-A PROJECT] + [-o PROJECT] [-a PROJECT] [-A PROJECT] [--to-version-policy VERSION_POLICY_NAME] [--from-version-policy VERSION_POLICY_NAME] [-v] [--ignore-hooks] [-s] [-m] @@ -711,49 +729,58 @@ Optional arguments: Adds the specified project and all its dependencies to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. -T PROJECT, --to-except PROJECT Run command on the selection instead of all projects. Adds all dependencies of the specified project to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. - Additional use of \\"--affected-by\\", \\"--from\\", or - \\"--to\\" will further expand the selection. + Additional use of any selection commands will further + expand the selection. -f PROJECT, --from PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that depend on it, and all the dependencies of those projects, to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. + -o PROJECT, --only PROJECT + Run command on the selection instead of all projects. + Add the specified project (and only the specified + project) to the current selection. \\".\\" can be used as + shorthand to specify the project in the current + working directory. Additional use of any selection + commands will further expand the selection. -a PROJECT, --affected-by PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that would be affected by a change to it to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. - Additional use of \\"--affected-by\\", \\"--from\\", or - \\"--to\\" will further expand the selection. + Additional use of any selection commands will further + expand the selection. -A PROJECT, --affected-by-except PROJECT Run command on the selection instead of all projects. Add all projects that would be affected by a change to the specified project (except the project itself) to the current selection. \\".\\" can be used as shorthand to specify the project in the current - working directory. Additional use of \\"--affected-by\\", - \\"--from\\", or \\"--to\\" will further expand the selection. + working directory. Additional use of any selection + commands will further expand the selection. --to-version-policy VERSION_POLICY_NAME Run command on the selection instead of all projects. Adds all projects with the specified version policy, and all dependencies thereof, to the current - selection. + selection. Additional use of any selection commands + will further expand the selection. --from-version-policy VERSION_POLICY_NAME Run command on the selection instead of all projects. Adds all projects with the specified version policy, and all projects that depend on them, to the current - selection. + selection. Additional use of any selection commands + will further expand the selection. -v, --verbose Display the logs during the build, rather than just displaying the build status summary --ignore-hooks Skips execution of the \\"eventHooks\\" scripts defined From 945f2738cf1f4cc824c99f0a538a9af7efcfa8a3 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 18:53:50 -0800 Subject: [PATCH 13/23] Revise names --- apps/rush-lib/src/api/RushConfiguration.ts | 2 +- .../src/api/RushConfigurationProject.ts | 66 ++++++++++--------- .../src/cli/scriptActions/BulkScriptAction.ts | 34 +++++----- apps/rush-lib/src/logic/PublishUtilities.ts | 10 +-- apps/rush-lib/src/logic/Selection.ts | 24 +++---- apps/rush-lib/src/logic/TaskSelector.ts | 2 +- .../src/logic/buildCache/ProjectBuildCache.ts | 2 +- .../installManager/WorkspaceInstallManager.ts | 2 +- .../rush-lib/src/logic/test/Selection.test.ts | 46 ++++++------- 9 files changed, 96 insertions(+), 92 deletions(-) diff --git a/apps/rush-lib/src/api/RushConfiguration.ts b/apps/rush-lib/src/api/RushConfiguration.ts index b927f813b2f..966e3b99369 100644 --- a/apps/rush-lib/src/api/RushConfiguration.ts +++ b/apps/rush-lib/src/api/RushConfiguration.ts @@ -1669,7 +1669,7 @@ export class RushConfiguration { const depProject: RushConfigurationProject | undefined = this.projectsByName.get(dependencyName); if (depProject) { - depProject.downstreamDependencyProjectSet.add(packageName); + depProject.consumingProjectNames.add(packageName); } }); } diff --git a/apps/rush-lib/src/api/RushConfigurationProject.ts b/apps/rush-lib/src/api/RushConfigurationProject.ts index f7bf6b0df36..3883ebce7ea 100644 --- a/apps/rush-lib/src/api/RushConfigurationProject.ts +++ b/apps/rush-lib/src/api/RushConfigurationProject.ts @@ -54,9 +54,9 @@ export class RushConfigurationProject { private _shouldPublish: boolean; private _skipRushCheck: boolean; private _publishFolder: string; - private _downstreamDependencyProjects: Set; - private _localDependencyProjects: ReadonlySet | undefined; - private _localDependentProjects: ReadonlySet | undefined; + private _consumingProjectNames: Set; + private _dependencyProjects: ReadonlySet | undefined; + private _consumingProjects: ReadonlySet | undefined; private readonly _rushConfiguration: RushConfiguration; /** @internal */ @@ -145,7 +145,7 @@ export class RushConfigurationProject { } this._shouldPublish = !!projectJson.shouldPublish; this._skipRushCheck = !!projectJson.skipRushCheck; - this._downstreamDependencyProjects = new Set(); + this._consumingProjectNames = new Set(); this._versionPolicyName = projectJson.versionPolicyName; this._publishFolder = this._projectFolder; @@ -227,54 +227,58 @@ export class RushConfigurationProject { } /** - * A list of projects within the Rush configuration which directly depend on this package. - * @deprecated Use downstreamDependencyProjectSet instead + * An array of projects within the Rush configuration which directly depend on this package. + * @deprecated Use localDependentProjectSet instead */ public get downstreamDependencyProjects(): string[] { - return [...this._downstreamDependencyProjects]; + return [...this._consumingProjectNames]; } /** - * A set of projects within the Rush configuration which directly depend on this package. + * A set of projects within the Rush configuration which directly consume this package. + * Writable because it is mutated by RushConfiguration during initialization. + * @internal */ - public get downstreamDependencyProjectSet(): Set { - return this._downstreamDependencyProjects; + public get consumingProjectNames(): Set { + return this._consumingProjectNames; } /** - * A map of projects within the Rush configuration which are directly depended on by this project + * An array of projects within the Rush configuration which this project declares as dependencies. * @deprecated Use localDependencyProjectSet instead */ public get localDependencyProjects(): ReadonlyArray { - return [...this.localDependencyProjectSet]; + return [...this.dependencyProjects]; } /** - * The set of projects within the Rush configuration which are directly depended on by this project + * The set of projects within the Rush configuration which this project declares as dependencies. */ - public get localDependencyProjectSet(): ReadonlySet { - if (!this._localDependencyProjects) { + public get dependencyProjects(): ReadonlySet { + if (!this._dependencyProjects) { const self: RushConfigurationProject = this; - this._localDependencyProjects = new Set( + this._dependencyProjects = new Set( (function* () { - yield* self._getLocalDependencyProjects(self.packageJson.dependencies); - yield* self._getLocalDependencyProjects(self.packageJson.devDependencies); - yield* self._getLocalDependencyProjects(self.packageJson.optionalDependencies); + yield* self._getDependencyProjects(self.packageJson.dependencies); + yield* self._getDependencyProjects(self.packageJson.devDependencies); + yield* self._getDependencyProjects(self.packageJson.optionalDependencies); })() ); } - return this._localDependencyProjects; + return this._dependencyProjects; } /** - * The set of projects withint he rush configuration which directly depend on this project. - * Excludes those that declare this project as a cyclicDependencyProject + * The set of projects within the Rush configuration which declare this project as a dependency. + * Excludes those that declare this project as a `cyclicDependencyProject`. + * + * The counterpart to `localDependencyProjectSet`. */ - public get localDependentProjectSet(): ReadonlySet { - if (!this._localDependentProjects) { - this._localDependentProjects = new Set(this._getLocalDependentProjects()); + public get consumingProjects(): ReadonlySet { + if (!this._consumingProjects) { + this._consumingProjects = new Set(this._getConsumingProjects()); } - return this._localDependentProjects; + return this._consumingProjects; } /** @@ -393,7 +397,7 @@ export class RushConfigurationProject { * Compute the local rush projects that this project immediately depends on, * according to the specific dependency group from package.json */ - private *_getLocalDependencyProjects( + private *_getDependencyProjects( dependencies: IPackageJsonDependencyTable = {} ): Iterable { for (const dependency of Object.keys(dependencies)) { @@ -423,14 +427,14 @@ export class RushConfigurationProject { } /** - * Compute the local rush projects that immediately depend on this project + * Compute the local rush projects that declare this project as a dependency */ - private *_getLocalDependentProjects(): Iterable { - for (const projectName of this.downstreamDependencyProjectSet) { + private *_getConsumingProjects(): Iterable { + for (const projectName of this.consumingProjectNames) { const localProject: RushConfigurationProject | undefined = this._rushConfiguration.getProjectByName( projectName ); - if (localProject && localProject.localDependencyProjectSet.has(this)) { + if (localProject && localProject.dependencyProjects.has(this)) { yield localProject; } } diff --git a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts index 183016101b7..e0d31e3b5c5 100644 --- a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts +++ b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts @@ -64,8 +64,8 @@ export class BulkScriptAction extends BaseScriptAction { private _onlyProject!: CommandLineStringListParameter; private _toProject!: CommandLineStringListParameter; private _toExceptProject!: CommandLineStringListParameter; - private _affectedByProject!: CommandLineStringListParameter; - private _affectedByExceptProject!: CommandLineStringListParameter; + private _impactedByProject!: CommandLineStringListParameter; + private _impactedByExceptProject!: CommandLineStringListParameter; private _fromVersionPolicy!: CommandLineStringListParameter; private _toVersionPolicy!: CommandLineStringListParameter; private _verboseParameter!: CommandLineFlagParameter; @@ -140,22 +140,22 @@ export class BulkScriptAction extends BaseScriptAction { // --to-except Selection.directDependenciesOf(this.evaluateProjects(this._toExceptProject)), // --from / --from-version-policy - Selection.expandAllDependents(fromProjects) + Selection.expandAllConsumers(fromProjects) ); // These projects will not have their dependencies included - const affectedByProjects: Set = Selection.union( - // --affected-by - this.evaluateProjects(this._affectedByProject), - // --affected-by-except - Selection.directDependentsOf(this.evaluateProjects(this._affectedByExceptProject)) + const impactedByProjects: Set = Selection.union( + // --impacted-by + this.evaluateProjects(this._impactedByProject), + // --impacted-by-except + Selection.directConsumersOf(this.evaluateProjects(this._impactedByExceptProject)) ); const selection: Set = Selection.union( onlyProjects, Selection.expandAllDependencies(toProjects), // Only dependents of these projects, not dependencies - Selection.expandAllDependents(affectedByProjects) + Selection.expandAllConsumers(impactedByProjects) ); const taskSelector: TaskSelector = new TaskSelector({ @@ -271,25 +271,25 @@ export class BulkScriptAction extends BaseScriptAction { completions: this._getProjectNames.bind(this) }); - this._affectedByProject = this.defineStringListParameter({ - parameterLongName: '--affected-by', - parameterShortName: '-a', + this._impactedByProject = this.defineStringListParameter({ + parameterLongName: '--impacted-by', + parameterShortName: '-i', argumentName: 'PROJECT', description: 'Run command on the selection instead of all projects. ' + - 'Add the specified project and all projects that would be affected by a change to it to the current selection. ' + + 'Add the specified project and all projects that would be impacted by a change to it to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + 'Additional use of any selection commands will further expand the selection.', completions: this._getProjectNames.bind(this) }); - this._affectedByExceptProject = this.defineStringListParameter({ - parameterLongName: '--affected-by-except', - parameterShortName: '-A', + this._impactedByExceptProject = this.defineStringListParameter({ + parameterLongName: '--impacted-by-except', + parameterShortName: '-I', argumentName: 'PROJECT', description: 'Run command on the selection instead of all projects. ' + - 'Add all projects that would be affected by a change to the specified project (except the project itself) to the current selection. ' + + 'Add all projects that would be impacted by a change to the specified project (except the project itself) to the current selection. ' + '"." can be used as shorthand to specify the project in the current working directory. ' + 'Additional use of any selection commands will further expand the selection.', completions: this._getProjectNames.bind(this) diff --git a/apps/rush-lib/src/logic/PublishUtilities.ts b/apps/rush-lib/src/logic/PublishUtilities.ts index 70e4114aab0..09f8cbd2389 100644 --- a/apps/rush-lib/src/logic/PublishUtilities.ts +++ b/apps/rush-lib/src/logic/PublishUtilities.ts @@ -85,7 +85,7 @@ export class PublishUtilities { const change: IChangeInfo = allChanges[packageName]; const project: RushConfigurationProject = allPackages.get(packageName)!; const pkg: IPackageJson = project.packageJson; - const deps: Set = project.downstreamDependencyProjectSet; + const deps: Set = project.consumingProjectNames; // Write the new version expected for the change. const skipVersionBump: boolean = PublishUtilities._shouldSkipVersionBump( @@ -596,13 +596,13 @@ export class PublishUtilities { projectsToExclude?: Set ): void { const packageName: string = change.packageName; - const downstreamNames: Set = allPackages.get(packageName)!.downstreamDependencyProjectSet; + const downstream: ReadonlySet = allPackages.get(packageName)!.consumingProjects; // Iterate through all downstream dependencies for the package. - if (downstreamNames) { + if (downstream) { if (change.changeType! >= ChangeType.hotfix || (prereleaseToken && prereleaseToken.hasValue)) { - for (const depName of downstreamNames) { - const pkg: IPackageJson = allPackages.get(depName)!.packageJson; + for (const dependency of downstream) { + const pkg: IPackageJson = dependency.packageJson; PublishUtilities._updateDownstreamDependency( pkg.name, diff --git a/apps/rush-lib/src/logic/Selection.ts b/apps/rush-lib/src/logic/Selection.ts index 8b6e8774f9b..1a9dda0f238 100644 --- a/apps/rush-lib/src/logic/Selection.ts +++ b/apps/rush-lib/src/logic/Selection.ts @@ -7,8 +7,8 @@ * @internal */ export interface IPartialProject> { - localDependencyProjectSet: ReadonlySet; - localDependentProjectSet: ReadonlySet; + dependencyProjects: ReadonlySet; + consumingProjects: ReadonlySet; } /** @@ -35,8 +35,8 @@ export function expandAllDependencies>(input: Itera /** * Computes a set that contains the input projects and all projects that directly or indirectly depend on them. */ -export function expandAllDependents>(input: Iterable): Set { - return expandAll(input, expandDependentsStep); +export function expandAllConsumers>(input: Iterable): Set { + return expandAll(input, expandConsumers); } /** @@ -44,16 +44,16 @@ export function expandAllDependents>(input: Iterabl */ export function* directDependenciesOf>(input: Iterable): Iterable { for (const item of input) { - yield* item.localDependencyProjectSet; + yield* item.dependencyProjects; } } /** - * Iterates the projects that directly depend on the listed projects. May contain duplicates. + * Iterates the projects that declare any of the listed projects as a dependency. May contain duplicates. */ -export function* directDependentsOf>(input: Iterable): Iterable { +export function* directConsumersOf>(input: Iterable): Iterable { for (const item of input) { - yield* item.localDependentProjectSet; + yield* item.consumingProjects; } } @@ -82,15 +82,15 @@ function* generateConcatenation(...sets: Iterable[]): Iterable { * Adds all dependencies of the specified project to the target set. */ function expandDependenciesStep>(project: T, targetSet: Set): void { - for (const dep of project.localDependencyProjectSet) { + for (const dep of project.dependencyProjects) { targetSet.add(dep); } } /** - * Adds all project that depend on the specified project to the target set. + * Adds all projects that declare the specified project as a dependency to the target set. */ -function expandDependentsStep>(project: T, targetSet: Set): void { - for (const dep of project.localDependentProjectSet) { +function expandConsumers>(project: T, targetSet: Set): void { + for (const dep of project.consumingProjects) { targetSet.add(dep); } } diff --git a/apps/rush-lib/src/logic/TaskSelector.ts b/apps/rush-lib/src/logic/TaskSelector.ts index e045a11b33d..e806ef18452 100644 --- a/apps/rush-lib/src/logic/TaskSelector.ts +++ b/apps/rush-lib/src/logic/TaskSelector.ts @@ -82,7 +82,7 @@ export class TaskSelector { } function* getDependencyTaskNames(project: RushConfigurationProject): Iterable { - for (const dep of project.localDependencyProjectSet) { + for (const dep of project.dependencyProjects) { // Only add relationships for projects in the set if (projects.has(dep)) { yield ProjectBuilder.getTaskName(dep); diff --git a/apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts b/apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts index a721aa9b56a..938be97750a 100644 --- a/apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts +++ b/apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts @@ -301,7 +301,7 @@ export class ProjectBuildCache { return undefined; } else { projectStates.push(projectState); - for (const dependency of projectToProcess.localDependencyProjectSet) { + for (const dependency of projectToProcess.dependencyProjects) { if (!projectsThatHaveBeenProcessed.has(dependency)) { newProjectsToProcess.add(dependency); } diff --git a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts index 7ceb63177a2..0471ddedfeb 100644 --- a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts +++ b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts @@ -535,7 +535,7 @@ export class WorkspaceInstallManager extends BaseInstallManager { for (const dep of deps) { yield dep.packageName; } - })(project.localDependencyProjectSet) + })(project.dependencyProjects) ); // Loop through non-local dependencies. Skip peer dependencies because they're only a constraint diff --git a/apps/rush-lib/src/logic/test/Selection.test.ts b/apps/rush-lib/src/logic/test/Selection.test.ts index be2f7bc4f1d..f6fe8e18322 100644 --- a/apps/rush-lib/src/logic/test/Selection.test.ts +++ b/apps/rush-lib/src/logic/test/Selection.test.ts @@ -6,66 +6,66 @@ import { union, intersection, expandAllDependencies, - expandAllDependents + expandAllConsumers } from '../Selection'; interface ISimpleGraphable extends IPartialProject { - localDependentProjectSet: Set; + consumingProjects: Set; toString(): string; } const projectA: ISimpleGraphable = { - localDependencyProjectSet: new Set(), - localDependentProjectSet: new Set(), + dependencyProjects: new Set(), + consumingProjects: new Set(), toString() { return 'A'; } }; const projectB: ISimpleGraphable = { - localDependencyProjectSet: new Set(), - localDependentProjectSet: new Set(), + dependencyProjects: new Set(), + consumingProjects: new Set(), toString() { return 'B'; } }; const projectC: ISimpleGraphable = { - localDependencyProjectSet: new Set(), - localDependentProjectSet: new Set(), + dependencyProjects: new Set(), + consumingProjects: new Set(), toString() { return 'C'; } }; const projectD: ISimpleGraphable = { - localDependencyProjectSet: new Set([projectA, projectB]), - localDependentProjectSet: new Set(), + dependencyProjects: new Set([projectA, projectB]), + consumingProjects: new Set(), toString() { return 'D'; } }; const projectE: ISimpleGraphable = { - localDependencyProjectSet: new Set([projectC, projectD]), - localDependentProjectSet: new Set(), + dependencyProjects: new Set([projectC, projectD]), + consumingProjects: new Set(), toString() { return 'E'; } }; const projectF: ISimpleGraphable = { - localDependencyProjectSet: new Set([projectE]), - localDependentProjectSet: new Set(), + dependencyProjects: new Set([projectE]), + consumingProjects: new Set(), toString() { return 'F'; } }; const projectG: ISimpleGraphable = { - localDependencyProjectSet: new Set(), - localDependentProjectSet: new Set(), + dependencyProjects: new Set(), + consumingProjects: new Set(), toString() { return 'G'; } }; const projectH: ISimpleGraphable = { - localDependencyProjectSet: new Set([projectF, projectG]), - localDependentProjectSet: new Set(), + dependencyProjects: new Set([projectF, projectG]), + consumingProjects: new Set(), toString() { return 'H'; } @@ -84,8 +84,8 @@ const nodes: Set = new Set([ // Populate the bidirectional graph for (const node of nodes) { - for (const dep of node.localDependencyProjectSet) { - dep.localDependentProjectSet.add(node); + for (const dep of node.dependencyProjects) { + dep.consumingProjects.add(node); } } @@ -187,17 +187,17 @@ describe('expandAllDependencies', () => { describe('expandAllDependents', () => { it('expands at least one level of dependents', () => { - const result: ReadonlySet = expandAllDependents([projectF]); + const result: ReadonlySet = expandAllConsumers([projectF]); expect(result).toMatchSet(new Set([projectF, projectH])); }); it('expands all levels of dependents', () => { - const result: ReadonlySet = expandAllDependents([projectC]); + const result: ReadonlySet = expandAllConsumers([projectC]); expect(result).toMatchSet(new Set([projectC, projectE, projectF, projectH])); }); it('handles multiple inputs', () => { - const result: ReadonlySet = expandAllDependents([projectC, projectB]); + const result: ReadonlySet = expandAllConsumers([projectC, projectB]); expect(result).toMatchSet(new Set([projectB, projectC, projectD, projectE, projectF, projectH])); }); From be52f2131a1c0a6778308b426b19c94bed189528 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 18:53:59 -0800 Subject: [PATCH 14/23] Update API, snapshot --- .../CommandLineHelp.test.ts.snap | 30 +++++++++---------- common/reviews/api/rush-lib.api.md | 7 +++-- 2 files changed, 19 insertions(+), 18 deletions(-) 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 bf6343bbb2d..d5d32db2d45 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 @@ -111,7 +111,7 @@ Optional arguments: exports[`CommandLineHelp prints the help for each action: build 1`] = ` "usage: rush build [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] [-f PROJECT] - [-o PROJECT] [-a PROJECT] [-A PROJECT] + [-o PROJECT] [-i PROJECT] [-I PROJECT] [--to-version-policy VERSION_POLICY_NAME] [--from-version-policy VERSION_POLICY_NAME] [-v] [-c] [--ignore-hooks] [-s] [-m] @@ -169,17 +169,17 @@ Optional arguments: shorthand to specify the project in the current working directory. Additional use of any selection commands will further expand the selection. - -a PROJECT, --affected-by PROJECT + -i PROJECT, --impacted-by PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that would - be affected by a change to it to the current + be impacted by a change to it to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. Additional use of any selection commands will further expand the selection. - -A PROJECT, --affected-by-except PROJECT + -I PROJECT, --impacted-by-except PROJECT Run command on the selection instead of all projects. - Add all projects that would be affected by a change + Add all projects that would be impacted by a change to the specified project (except the project itself) to the current selection. \\".\\" can be used as shorthand to specify the project in the current @@ -327,7 +327,7 @@ Optional arguments: exports[`CommandLineHelp prints the help for each action: import-strings 1`] = ` "usage: rush import-strings [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] - [-f PROJECT] [-o PROJECT] [-a PROJECT] [-A PROJECT] + [-f PROJECT] [-o PROJECT] [-i PROJECT] [-I PROJECT] [--to-version-policy VERSION_POLICY_NAME] [--from-version-policy VERSION_POLICY_NAME] [-v] [--ignore-hooks] @@ -377,17 +377,17 @@ Optional arguments: shorthand to specify the project in the current working directory. Additional use of any selection commands will further expand the selection. - -a PROJECT, --affected-by PROJECT + -i PROJECT, --impacted-by PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that would - be affected by a change to it to the current + be impacted by a change to it to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. Additional use of any selection commands will further expand the selection. - -A PROJECT, --affected-by-except PROJECT + -I PROJECT, --impacted-by-except PROJECT Run command on the selection instead of all projects. - Add all projects that would be affected by a change + Add all projects that would be impacted by a change to the specified project (except the project itself) to the current selection. \\".\\" can be used as shorthand to specify the project in the current @@ -698,7 +698,7 @@ Optional arguments: exports[`CommandLineHelp prints the help for each action: rebuild 1`] = ` "usage: rush rebuild [-h] [-p COUNT] [-t PROJECT] [-T PROJECT] [-f PROJECT] - [-o PROJECT] [-a PROJECT] [-A PROJECT] + [-o PROJECT] [-i PROJECT] [-I PROJECT] [--to-version-policy VERSION_POLICY_NAME] [--from-version-policy VERSION_POLICY_NAME] [-v] [--ignore-hooks] [-s] [-m] @@ -753,17 +753,17 @@ Optional arguments: shorthand to specify the project in the current working directory. Additional use of any selection commands will further expand the selection. - -a PROJECT, --affected-by PROJECT + -i PROJECT, --impacted-by PROJECT Run command on the selection instead of all projects. Add the specified project and all projects that would - be affected by a change to it to the current + be impacted by a change to it to the current selection. \\".\\" can be used as shorthand to specify the project in the current working directory. Additional use of any selection commands will further expand the selection. - -A PROJECT, --affected-by-except PROJECT + -I PROJECT, --impacted-by-except PROJECT Run command on the selection instead of all projects. - Add all projects that would be affected by a change + Add all projects that would be impacted by a change to the specified project (except the project itself) to the current selection. \\".\\" can be used as shorthand to specify the project in the current diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index ae93776ff89..5eb3b5b3948 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -412,16 +412,17 @@ export class RushConfigurationProject { // // @internal constructor(projectJson: IRushConfigurationProjectJson, rushConfiguration: RushConfiguration, tempProjectName: string); + // @internal + get consumingProjectNames(): Set; + get consumingProjects(): ReadonlySet; get cyclicDependencyProjects(): Set; + get dependencyProjects(): ReadonlySet; // @deprecated get downstreamDependencyProjects(): string[]; - get downstreamDependencyProjectSet(): Set; // @beta get isMainProject(): boolean; // @deprecated get localDependencyProjects(): ReadonlyArray; - get localDependencyProjectSet(): ReadonlySet; - get localDependentProjectSet(): ReadonlySet; // @deprecated get packageJson(): IPackageJson; // @beta From 8343173a992eb8b4362ca279d374b7b4638463a5 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Fri, 29 Jan 2021 19:05:17 -0800 Subject: [PATCH 15/23] Improve wording of changelogs --- .../@microsoft/rush/rework-deps_2021-01-08-01-48.json | 2 +- .../@microsoft/rush/rework-deps_2021-01-08-01-49.json | 11 +++++++++++ .../@microsoft/rush/rework-deps_2021-01-08-01-50.json | 11 +++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 common/changes/@microsoft/rush/rework-deps_2021-01-08-01-49.json create mode 100644 common/changes/@microsoft/rush/rework-deps_2021-01-08-01-50.json diff --git a/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json index 16d0b0af64c..ec45a23dba8 100644 --- a/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json +++ b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-48.json @@ -2,7 +2,7 @@ "changes": [ { "packageName": "@microsoft/rush", - "comment": "Add `--to-except` command line option to BulkScriptAction to build all dependencies of the target project, but not the project itself. This option is intended for use with the future `--watch` option.\nAdd `--affected-by` and `--affected-by-except` options to build only projects that are directly affected by changes to the specified project.", + "comment": "Add new command-line parameters for bulk commands: \"--to-except\", \"--from\", \"--only\", \"--impacted-by\", \"--impacted-by-except\", and \"--from-version-policy\" (GitHub #2354)", "type": "none" } ], diff --git a/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-49.json b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-49.json new file mode 100644 index 00000000000..f4152d7e623 --- /dev/null +++ b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-49.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "Change the short name for \"--changed-projects-only\" to be \"-c\" (so that \"-o\" can be used for the new \"--only\" parameter)", + "type": "none" + } + ], + "packageName": "@microsoft/rush", + "email": "dmichon-msft@users.noreply.github.com" +} \ No newline at end of file diff --git a/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-50.json b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-50.json new file mode 100644 index 00000000000..b0d183ba76a --- /dev/null +++ b/common/changes/@microsoft/rush/rework-deps_2021-01-08-01-50.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "Change the \"--from\" parameter so that it now includes all dependencies as people expected. To skip dependencies, use the new \"--impacted-by\" parameter. (GitHub issue #1447)", + "type": "none" + } + ], + "packageName": "@microsoft/rush", + "email": "dmichon-msft@users.noreply.github.com" +} \ No newline at end of file From 964c69b69301a8824635f7620ef11337606d67da Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 19:05:28 -0800 Subject: [PATCH 16/23] Class-ify Selection --- .../rush-lib/src/cli/actions/InstallAction.ts | 2 +- .../src/cli/scriptActions/BulkScriptAction.ts | 2 +- apps/rush-lib/src/logic/Selection.ts | 75 ++++++++++--------- .../rush-lib/src/logic/test/Selection.test.ts | 10 +-- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/apps/rush-lib/src/cli/actions/InstallAction.ts b/apps/rush-lib/src/cli/actions/InstallAction.ts index 5e3a2845df2..1203013a1c5 100644 --- a/apps/rush-lib/src/cli/actions/InstallAction.ts +++ b/apps/rush-lib/src/cli/actions/InstallAction.ts @@ -7,7 +7,7 @@ import { BaseInstallAction } from './BaseInstallAction'; import { IInstallManagerOptions } from '../../logic/base/BaseInstallManager'; import { RushCommandLineParser } from '../RushCommandLineParser'; import { RushConfigurationProject } from '../../api/RushConfigurationProject'; -import * as Selection from '../../logic/Selection'; +import { Selection } from '../../logic/Selection'; export class InstallAction extends BaseInstallAction { protected _toFlag!: CommandLineStringListParameter; diff --git a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts index e0d31e3b5c5..b0719b6e823 100644 --- a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts +++ b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts @@ -26,7 +26,7 @@ import { EnvironmentVariableNames } from '../../api/EnvironmentConfiguration'; import { LastLinkFlag, LastLinkFlagFactory } from '../../api/LastLinkFlag'; import { IRushConfigurationProjectJson, RushConfigurationProject } from '../../api/RushConfigurationProject'; import { BuildCacheConfiguration } from '../../api/BuildCacheConfiguration'; -import * as Selection from '../../logic/Selection'; +import { Selection } from '../../logic/Selection'; /** * Constructor parameters for BulkScriptAction. diff --git a/apps/rush-lib/src/logic/Selection.ts b/apps/rush-lib/src/logic/Selection.ts index 1a9dda0f238..8158fa0eba3 100644 --- a/apps/rush-lib/src/logic/Selection.ts +++ b/apps/rush-lib/src/logic/Selection.ts @@ -12,48 +12,53 @@ export interface IPartialProject> { } /** - * Computes the intersection of two or more sets. + * This namespace contains functions for manipulating sets of projects */ -export function intersection(first: Iterable, ...rest: ReadonlySet[]): Set { - return new Set(generateIntersection(first, ...rest)); -} +export class Selection { + /** + * Computes the intersection of two or more sets. + */ + public static intersection(first: Iterable, ...rest: ReadonlySet[]): Set { + return new Set(generateIntersection(first, ...rest)); + } -/** - * Computes the union of two or more sets. - */ -export function union(...sets: Iterable[]): Set { - return new Set(generateConcatenation(...sets)); -} + /** + * Computes the union of two or more sets. + */ + public static union(...sets: Iterable[]): Set { + return new Set(generateConcatenation(...sets)); + } -/** - * Computes a set that contains the input projects and all the direct and indirect dependencies thereof. - */ -export function expandAllDependencies>(input: Iterable): Set { - return expandAll(input, expandDependenciesStep); -} + /** + * Computes a set that contains the input projects and all the direct and indirect dependencies thereof. + */ + public static expandAllDependencies>(input: Iterable): Set { + return expandAll(input, expandDependenciesStep); + } -/** - * Computes a set that contains the input projects and all projects that directly or indirectly depend on them. - */ -export function expandAllConsumers>(input: Iterable): Set { - return expandAll(input, expandConsumers); -} + /** + * Computes a set that contains the input projects and all projects that directly or indirectly depend on them. + */ + public static expandAllConsumers>(input: Iterable): Set { + return expandAll(input, expandConsumers); + } -/** - * Iterates the direct dependencies of the listed projects. May contain duplicates. - */ -export function* directDependenciesOf>(input: Iterable): Iterable { - for (const item of input) { - yield* item.dependencyProjects; + /** + * Iterates the direct dependencies of the listed projects. May contain duplicates. + */ + public static *directDependenciesOf>(input: Iterable): Iterable { + for (const item of input) { + yield* item.dependencyProjects; + } } -} -/** - * Iterates the projects that declare any of the listed projects as a dependency. May contain duplicates. - */ -export function* directConsumersOf>(input: Iterable): Iterable { - for (const item of input) { - yield* item.consumingProjects; + /** + * Iterates the projects that declare any of the listed projects as a dependency. May contain duplicates. + */ + public static *directConsumersOf>(input: Iterable): Iterable { + for (const item of input) { + yield* item.consumingProjects; + } } } diff --git a/apps/rush-lib/src/logic/test/Selection.test.ts b/apps/rush-lib/src/logic/test/Selection.test.ts index f6fe8e18322..d13948d2356 100644 --- a/apps/rush-lib/src/logic/test/Selection.test.ts +++ b/apps/rush-lib/src/logic/test/Selection.test.ts @@ -1,13 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. -import { - IPartialProject, - union, - intersection, - expandAllDependencies, - expandAllConsumers -} from '../Selection'; +import { IPartialProject, Selection } from '../Selection'; + +const { union, intersection, expandAllDependencies, expandAllConsumers } = Selection; interface ISimpleGraphable extends IPartialProject { consumingProjects: Set; From 02e23a5137668274d0352e73b147742301ec7c69 Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 19:19:52 -0800 Subject: [PATCH 17/23] Adjust names, revert some generators --- .../src/api/RushConfigurationProject.ts | 30 ++++++++++--------- .../src/cli/actions/BaseRushAction.ts | 2 +- .../rush-lib/src/cli/actions/InstallAction.ts | 4 +-- .../src/cli/scriptActions/BulkScriptAction.ts | 12 ++++---- .../installManager/WorkspaceInstallManager.ts | 6 +--- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/apps/rush-lib/src/api/RushConfigurationProject.ts b/apps/rush-lib/src/api/RushConfigurationProject.ts index 3883ebce7ea..cdee6830369 100644 --- a/apps/rush-lib/src/api/RushConfigurationProject.ts +++ b/apps/rush-lib/src/api/RushConfigurationProject.ts @@ -17,6 +17,7 @@ import { PackageJsonEditor } from './PackageJsonEditor'; import { RushConstants } from '../logic/RushConstants'; import { PackageNameParsers } from './PackageNameParsers'; import { DependencySpecifier, DependencySpecifierType } from '../logic/DependencySpecifier'; +import { Selection } from '../logic/Selection'; /** * This represents the JSON data object for a project entry in the rush.json configuration file. @@ -256,13 +257,10 @@ export class RushConfigurationProject { */ public get dependencyProjects(): ReadonlySet { if (!this._dependencyProjects) { - const self: RushConfigurationProject = this; - this._dependencyProjects = new Set( - (function* () { - yield* self._getDependencyProjects(self.packageJson.dependencies); - yield* self._getDependencyProjects(self.packageJson.devDependencies); - yield* self._getDependencyProjects(self.packageJson.optionalDependencies); - })() + this._dependencyProjects = Selection.union( + this._getDependencyProjects(this.packageJson.dependencies), + this._getDependencyProjects(this.packageJson.devDependencies), + this._getDependencyProjects(this.packageJson.optionalDependencies) ); } return this._dependencyProjects; @@ -276,7 +274,7 @@ export class RushConfigurationProject { */ public get consumingProjects(): ReadonlySet { if (!this._consumingProjects) { - this._consumingProjects = new Set(this._getConsumingProjects()); + this._consumingProjects = this._getConsumingProjects(); } return this._consumingProjects; } @@ -397,9 +395,10 @@ export class RushConfigurationProject { * Compute the local rush projects that this project immediately depends on, * according to the specific dependency group from package.json */ - private *_getDependencyProjects( + private _getDependencyProjects( dependencies: IPackageJsonDependencyTable = {} - ): Iterable { + ): Set { + const dependencyProjects: Set = new Set(); for (const dependency of Object.keys(dependencies)) { // Skip if we can't find the local project or it's a cyclic dependency const localProject: RushConfigurationProject | undefined = this._rushConfiguration.getProjectByName( @@ -415,28 +414,31 @@ export class RushConfigurationProject { case DependencySpecifierType.Version: case DependencySpecifierType.Range: if (semver.satisfies(localProject.packageJson.version, dependencySpecifier.versionSpecifier)) { - yield localProject; + dependencyProjects.add(localProject); } break; case DependencySpecifierType.Workspace: - yield localProject; + dependencyProjects.add(localProject); break; } } } + return dependencyProjects; } /** * Compute the local rush projects that declare this project as a dependency */ - private *_getConsumingProjects(): Iterable { + private _getConsumingProjects(): Set { + const consumingProjects: Set = new Set(); for (const projectName of this.consumingProjectNames) { const localProject: RushConfigurationProject | undefined = this._rushConfiguration.getProjectByName( projectName ); if (localProject && localProject.dependencyProjects.has(this)) { - yield localProject; + consumingProjects.add(localProject); } } + return consumingProjects; } } diff --git a/apps/rush-lib/src/cli/actions/BaseRushAction.ts b/apps/rush-lib/src/cli/actions/BaseRushAction.ts index a9ab3fe6eb4..5e852d6358b 100644 --- a/apps/rush-lib/src/cli/actions/BaseRushAction.ts +++ b/apps/rush-lib/src/cli/actions/BaseRushAction.ts @@ -131,7 +131,7 @@ export abstract class BaseRushAction extends BaseConfiglessRushAction { return super.onExecute(); } - protected *evaluateProjects( + protected *evaluateProjectParameter( projectsParameters: CommandLineStringListParameter ): Iterable { const packageJsonLookup: PackageJsonLookup = new PackageJsonLookup(); diff --git a/apps/rush-lib/src/cli/actions/InstallAction.ts b/apps/rush-lib/src/cli/actions/InstallAction.ts index 1203013a1c5..ae7e63274bd 100644 --- a/apps/rush-lib/src/cli/actions/InstallAction.ts +++ b/apps/rush-lib/src/cli/actions/InstallAction.ts @@ -76,11 +76,11 @@ export class InstallAction extends BaseInstallAction { protected buildInstallOptions(): IInstallManagerOptions { const toProjects: Set = Selection.union( - this.evaluateProjects(this._toFlag), + this.evaluateProjectParameter(this._toFlag), this.evaluateVersionPolicyProjects(this._toVersionPolicy) ); const fromProjects: Set = Selection.union( - this.evaluateProjects(this._fromFlag), + this.evaluateProjectParameter(this._fromFlag), this.evaluateVersionPolicyProjects(this._fromVersionPolicy) ); diff --git a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts index b0719b6e823..0e18d90686f 100644 --- a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts +++ b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts @@ -121,12 +121,12 @@ export class BulkScriptAction extends BaseScriptAction { | undefined = await BuildCacheConfiguration.loadFromDefaultPathAsync(terminal, this.rushConfiguration); // Include exactly these projects (--only) - const onlyProjects: Iterable = this.evaluateProjects(this._onlyProject); + const onlyProjects: Iterable = this.evaluateProjectParameter(this._onlyProject); // Include all projects that depend on these projects, and all dependencies thereof const fromProjects: Set = Selection.union( // --from - this.evaluateProjects(this._fromProject), + this.evaluateProjectParameter(this._fromProject), // --from-version-policy this.evaluateVersionPolicyProjects(this._fromVersionPolicy) ); @@ -134,11 +134,11 @@ export class BulkScriptAction extends BaseScriptAction { // Include dependencies of these projects const toProjects: Set = Selection.union( // --to - this.evaluateProjects(this._toProject), + this.evaluateProjectParameter(this._toProject), // --to-version-policy this.evaluateVersionPolicyProjects(this._toVersionPolicy), // --to-except - Selection.directDependenciesOf(this.evaluateProjects(this._toExceptProject)), + Selection.directDependenciesOf(this.evaluateProjectParameter(this._toExceptProject)), // --from / --from-version-policy Selection.expandAllConsumers(fromProjects) ); @@ -146,9 +146,9 @@ export class BulkScriptAction extends BaseScriptAction { // These projects will not have their dependencies included const impactedByProjects: Set = Selection.union( // --impacted-by - this.evaluateProjects(this._impactedByProject), + this.evaluateProjectParameter(this._impactedByProject), // --impacted-by-except - Selection.directConsumersOf(this.evaluateProjects(this._impactedByExceptProject)) + Selection.directConsumersOf(this.evaluateProjectParameter(this._impactedByExceptProject)) ); const selection: Set = Selection.union( diff --git a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts index 0471ddedfeb..8e4c9836f76 100644 --- a/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts +++ b/apps/rush-lib/src/logic/installManager/WorkspaceInstallManager.ts @@ -531,11 +531,7 @@ export class WorkspaceInstallManager extends BaseInstallManager { } const localDependencyProjectNames: Set = new Set( - (function* (deps: Iterable): Iterable { - for (const dep of deps) { - yield dep.packageName; - } - })(project.dependencyProjects) + [...project.dependencyProjects].map((x) => x.packageName) ); // Loop through non-local dependencies. Skip peer dependencies because they're only a constraint From 0652a86309cd86a5d9dda9b34ee3488d27baa3fc Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 19:21:39 -0800 Subject: [PATCH 18/23] Revert task runner logging detail --- .../src/logic/taskRunner/TaskRunner.ts | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/apps/rush-lib/src/logic/taskRunner/TaskRunner.ts b/apps/rush-lib/src/logic/taskRunner/TaskRunner.ts index 1ac8e83be53..73f4ad287d4 100644 --- a/apps/rush-lib/src/logic/taskRunner/TaskRunner.ts +++ b/apps/rush-lib/src/logic/taskRunner/TaskRunner.ts @@ -156,28 +156,10 @@ export class TaskRunner { if (!this._quietMode) { const plural: string = this._tasks.length === 1 ? '' : 's'; this._terminal.writeStdoutLine(`Selected ${this._tasks.length} project${plural}:`); - const maxNameLength: number = this._tasks.reduce((max, task) => Math.max(max, task.name.length), 0); this._terminal.writeStdoutLine( this._tasks - .sort((x, y) => { - const diff: number = (y.criticalPathLength || 0) - (x.criticalPathLength || 0); - if (diff !== 0) { - return diff; - } - if (x.name < y.name) { - return -1; - } - if (x.name > y.name) { - return 1; - } - return 0; - }) - .map((x) => { - if (x.criticalPathLength !== undefined) { - return ` ${x.name.padEnd(maxNameLength, ' ')} (Depth: ${x.criticalPathLength})`; - } - return ` ${x.name}`; - }) + .map((x) => ` ${x.name}`) + .sort() .join('\n') ); this._terminal.writeStdoutLine(''); From fea38508c14467a7b67f9d25d59ba2b2f8d4f7df Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 19:30:06 -0800 Subject: [PATCH 19/23] Fix comments --- apps/rush-lib/src/api/RushConfigurationProject.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/rush-lib/src/api/RushConfigurationProject.ts b/apps/rush-lib/src/api/RushConfigurationProject.ts index cdee6830369..4106eb98f78 100644 --- a/apps/rush-lib/src/api/RushConfigurationProject.ts +++ b/apps/rush-lib/src/api/RushConfigurationProject.ts @@ -246,7 +246,7 @@ export class RushConfigurationProject { /** * An array of projects within the Rush configuration which this project declares as dependencies. - * @deprecated Use localDependencyProjectSet instead + * @deprecated Use `dependencyProjects` instead */ public get localDependencyProjects(): ReadonlyArray { return [...this.dependencyProjects]; @@ -270,7 +270,7 @@ export class RushConfigurationProject { * The set of projects within the Rush configuration which declare this project as a dependency. * Excludes those that declare this project as a `cyclicDependencyProject`. * - * The counterpart to `localDependencyProjectSet`. + * The counterpart to `dependencyProjects`. */ public get consumingProjects(): ReadonlySet { if (!this._consumingProjects) { From 2b7ca63836aa48f07370d2342bfdb246b25c229a Mon Sep 17 00:00:00 2001 From: David Michon Date: Fri, 29 Jan 2021 19:31:14 -0800 Subject: [PATCH 20/23] Fix other missing rename --- apps/rush-lib/src/logic/test/Selection.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/rush-lib/src/logic/test/Selection.test.ts b/apps/rush-lib/src/logic/test/Selection.test.ts index d13948d2356..d8f1a0af001 100644 --- a/apps/rush-lib/src/logic/test/Selection.test.ts +++ b/apps/rush-lib/src/logic/test/Selection.test.ts @@ -181,7 +181,7 @@ describe('expandAllDependencies', () => { }); }); -describe('expandAllDependents', () => { +describe('expandAllConsumers', () => { it('expands at least one level of dependents', () => { const result: ReadonlySet = expandAllConsumers([projectF]); From c533efa0493d8ffcb204dffe5f52947e9e4a6a41 Mon Sep 17 00:00:00 2001 From: David Michon Date: Mon, 1 Feb 2021 11:08:57 -0800 Subject: [PATCH 21/23] Revise documentation comments --- .../src/api/RushConfigurationProject.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/apps/rush-lib/src/api/RushConfigurationProject.ts b/apps/rush-lib/src/api/RushConfigurationProject.ts index 4106eb98f78..efa50967d90 100644 --- a/apps/rush-lib/src/api/RushConfigurationProject.ts +++ b/apps/rush-lib/src/api/RushConfigurationProject.ts @@ -177,7 +177,7 @@ export class RushConfigurationProject { /** * The relative path of the folder that contains the project to be built by Rush. * - * Example: `libraries\my-project` + * Example: `libraries/my-project` */ public get projectRelativeFolder(): string { return this._projectRelativeFolder; @@ -229,7 +229,8 @@ export class RushConfigurationProject { /** * An array of projects within the Rush configuration which directly depend on this package. - * @deprecated Use localDependentProjectSet instead + * @deprecated Use `consumingProjectNames` instead, as it has Set semantics, which better reflect the nature + * of the data. */ public get downstreamDependencyProjects(): string[] { return [...this._consumingProjectNames]; @@ -237,8 +238,10 @@ export class RushConfigurationProject { /** * A set of projects within the Rush configuration which directly consume this package. - * Writable because it is mutated by RushConfiguration during initialization. * @internal + * + * @remarks + * Writable because it is mutated by RushConfiguration during initialization. */ public get consumingProjectNames(): Set { return this._consumingProjectNames; @@ -246,7 +249,8 @@ export class RushConfigurationProject { /** * An array of projects within the Rush configuration which this project declares as dependencies. - * @deprecated Use `dependencyProjects` instead + * @deprecated Use `dependencyProjects` instead, as it has Set semantics, which better reflect the nature + * of the data. */ public get localDependencyProjects(): ReadonlyArray { return [...this.dependencyProjects]; @@ -254,6 +258,10 @@ export class RushConfigurationProject { /** * The set of projects within the Rush configuration which this project declares as dependencies. + * + * @remarks + * Can be used recursively to walk the project dependency graph to find all projects that are directly or indirectly + * referenced from this project. */ public get dependencyProjects(): ReadonlySet { if (!this._dependencyProjects) { @@ -270,7 +278,9 @@ export class RushConfigurationProject { * The set of projects within the Rush configuration which declare this project as a dependency. * Excludes those that declare this project as a `cyclicDependencyProject`. * - * The counterpart to `dependencyProjects`. + * @remarks + * This field is the counterpart to `dependencyProjects`, and can be used recursively to walk the project dependency + * graph to find all projects which will be impacted by changes to this project. */ public get consumingProjects(): ReadonlySet { if (!this._consumingProjects) { From 4cc060f0692852f9004bee51ab9a7a03afb7f622 Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Mon, 1 Feb 2021 11:44:39 -0800 Subject: [PATCH 22/23] Some improvements for the CLI descriptions --- .../src/cli/scriptActions/BulkScriptAction.ts | 77 ++-- .../CommandLineHelp.test.ts.snap | 354 ++++++++++-------- 2 files changed, 254 insertions(+), 177 deletions(-) diff --git a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts index 0e18d90686f..18403a10fce 100644 --- a/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts +++ b/apps/rush-lib/src/cli/scriptActions/BulkScriptAction.ts @@ -230,10 +230,11 @@ export class BulkScriptAction extends BaseScriptAction { parameterShortName: '-t', argumentName: 'PROJECT', description: - 'Run command on the selection instead of all projects. ' + - 'Adds the specified project and all its dependencies to the current selection. ' + - '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of any selection commands will further expand the selection.', + 'Normally all projects in the monorepo will be processed;' + + ' adding this parameter will instead select a subset of projects.' + + ' Each "--to" parameter expands this selection to include PROJECT and all its dependencies.' + + ' "." can be used as shorthand for the project in the current working directory.' + + ' For details, refer to the website article "Selecting subsets of projects".', completions: this._getProjectNames.bind(this) }); this._toExceptProject = this.defineStringListParameter({ @@ -241,10 +242,12 @@ export class BulkScriptAction extends BaseScriptAction { parameterShortName: '-T', argumentName: 'PROJECT', description: - 'Run command on the selection instead of all projects. ' + - 'Adds all dependencies of the specified project to the current selection. ' + - '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of any selection commands will further expand the selection.', + 'Normally all projects in the monorepo will be processed;' + + ' adding this parameter will instead select a subset of projects.' + + ' Each "--to-except" parameter expands this selection to include all dependencies of PROJECT,' + + ' but not PROJECT itself.' + + ' "." can be used as shorthand for the project in the current working directory.' + + ' For details, refer to the website article "Selecting subsets of projects".', completions: this._getProjectNames.bind(this) }); @@ -253,10 +256,12 @@ export class BulkScriptAction extends BaseScriptAction { parameterShortName: '-f', argumentName: 'PROJECT', description: - 'Run command on the selection instead of all projects. ' + - 'Add the specified project and all projects that depend on it, and all the dependencies of those projects, to the current selection. ' + - '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of any selection commands will further expand the selection.', + 'Normally all projects in the monorepo will be processed;' + + ' adding this parameter will instead select a subset of projects.' + + ' Each "--from" parameter expands this selection to include PROJECT and all projects that depend on it,' + + ' plus all dependencies of this set.' + + ' "." can be used as shorthand for the project in the current working directory.' + + ' For details, refer to the website article "Selecting subsets of projects".', completions: this._getProjectNames.bind(this) }); this._onlyProject = this.defineStringListParameter({ @@ -264,10 +269,12 @@ export class BulkScriptAction extends BaseScriptAction { parameterShortName: '-o', argumentName: 'PROJECT', description: - 'Run command on the selection instead of all projects. ' + - 'Add the specified project (and only the specified project) to the current selection. ' + - '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of any selection commands will further expand the selection.', + 'Normally all projects in the monorepo will be processed;' + + ' adding this parameter will instead select a subset of projects.' + + ' Each "--only" parameter expands this selection to include PROJECT; its dependencies are not added.' + + ' "." can be used as shorthand for the project in the current working directory.' + + ' Note that this parameter is "unsafe" as it may produce a selection that excludes some dependencies.' + + ' For details, refer to the website article "Selecting subsets of projects".', completions: this._getProjectNames.bind(this) }); @@ -276,10 +283,13 @@ export class BulkScriptAction extends BaseScriptAction { parameterShortName: '-i', argumentName: 'PROJECT', description: - 'Run command on the selection instead of all projects. ' + - 'Add the specified project and all projects that would be impacted by a change to it to the current selection. ' + - '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of any selection commands will further expand the selection.', + 'Normally all projects in the monorepo will be processed;' + + ' adding this parameter will instead select a subset of projects.' + + ' Each "--impacted-by" parameter expands this selection to include PROJECT and any projects that' + + ' depend on PROJECT (and thus might be broken by changes to PROJECT).' + + ' "." can be used as shorthand for the project in the current working directory.' + + ' Note that this parameter is "unsafe" as it may produce a selection that excludes some dependencies.' + + ' For details, refer to the website article "Selecting subsets of projects".', completions: this._getProjectNames.bind(this) }); @@ -288,10 +298,13 @@ export class BulkScriptAction extends BaseScriptAction { parameterShortName: '-I', argumentName: 'PROJECT', description: - 'Run command on the selection instead of all projects. ' + - 'Add all projects that would be impacted by a change to the specified project (except the project itself) to the current selection. ' + - '"." can be used as shorthand to specify the project in the current working directory. ' + - 'Additional use of any selection commands will further expand the selection.', + 'Normally all projects in the monorepo will be processed;' + + ' adding this parameter will instead select a subset of projects.' + + ' Each "--impacted-by-except" parameter works the same as "--impacted-by" except that PROJECT itself' + + ' is not added to the selection.' + + ' "." can be used as shorthand for the project in the current working directory.' + + ' Note that this parameter is "unsafe" as it may produce a selection that excludes some dependencies.' + + ' For details, refer to the website article "Selecting subsets of projects".', completions: this._getProjectNames.bind(this) }); @@ -299,17 +312,21 @@ export class BulkScriptAction extends BaseScriptAction { parameterLongName: '--to-version-policy', argumentName: 'VERSION_POLICY_NAME', description: - 'Run command on the selection instead of all projects. ' + - 'Adds all projects with the specified version policy, and all dependencies thereof, to the current selection. ' + - 'Additional use of any selection commands will further expand the selection.' + 'Normally all projects in the monorepo will be processed;' + + ' adding this parameter will instead select a subset of projects.' + + ' The "--to-version-policy" parameter is equivalent to specifying "--to" for each of the projects' + + ' belonging to VERSION_POLICY_NAME.' + + ' For details, refer to the website article "Selecting subsets of projects".' }); this._fromVersionPolicy = this.defineStringListParameter({ parameterLongName: '--from-version-policy', argumentName: 'VERSION_POLICY_NAME', description: - 'Run command on the selection instead of all projects. ' + - 'Adds all projects with the specified version policy, and all projects that depend on them, to the current selection. ' + - 'Additional use of any selection commands will further expand the selection.' + 'Normally all projects in the monorepo will be processed;' + + ' adding this parameter will instead select a subset of projects.' + + ' The "--from-version-policy" parameter is equivalent to specifying "--from" for each of the projects' + + ' belonging to VERSION_POLICY_NAME.' + + ' For details, refer to the website article "Selecting subsets of projects".' }); this._verboseParameter = this.defineFlagParameter({ 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 d5d32db2d45..1b2b510c28f 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 @@ -141,62 +141,82 @@ Optional arguments: cores. This parameter may alternatively be specified via the RUSH_PARALLELISM environment variable. -t PROJECT, --to PROJECT - Run command on the selection instead of all projects. - Adds the specified project and all its dependencies - to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--to\\" parameter expands + this selection to include PROJECT and all its + dependencies. \\".\\" can be used as shorthand for the + project in the current working directory. For details, + refer to the website article \\"Selecting subsets of + projects\\". -T PROJECT, --to-except PROJECT - Run command on the selection instead of all projects. - Adds all dependencies of the specified project to the - current selection. \\".\\" can be used as shorthand to - specify the project in the current working directory. - Additional use of any selection commands will further - expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--to-except\\" parameter + expands this selection to include all dependencies of + PROJECT, but not PROJECT itself. \\".\\" can be used as + shorthand for the project in the current working + directory. For details, refer to the website article + \\"Selecting subsets of projects\\". -f PROJECT, --from PROJECT - Run command on the selection instead of all projects. - Add the specified project and all projects that - depend on it, and all the dependencies of those - projects, to the current selection. \\".\\" can be used - as shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--from\\" parameter expands + this selection to include PROJECT and all projects + that depend on it, plus all dependencies of this set. + \\".\\" can be used as shorthand for the project in the + current working directory. For details, refer to the + website article \\"Selecting subsets of projects\\". -o PROJECT, --only PROJECT - Run command on the selection instead of all projects. - Add the specified project (and only the specified - project) to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--only\\" parameter expands + this selection to include PROJECT; its dependencies + are not added. \\".\\" can be used as shorthand for the + project in the current working directory. Note that + this parameter is \\"unsafe\\" as it may produce a + selection that excludes some dependencies. For + details, refer to the website article \\"Selecting + subsets of projects\\". -i PROJECT, --impacted-by PROJECT - Run command on the selection instead of all projects. - Add the specified project and all projects that would - be impacted by a change to it to the current - selection. \\".\\" can be used as shorthand to specify - the project in the current working directory. - Additional use of any selection commands will further - expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--impacted-by\\" parameter + expands this selection to include PROJECT and any + projects that depend on PROJECT (and thus might be + broken by changes to PROJECT). \\".\\" can be used as + shorthand for the project in the current working + directory. Note that this parameter is \\"unsafe\\" as it + may produce a selection that excludes some + dependencies. For details, refer to the website + article \\"Selecting subsets of projects\\". -I PROJECT, --impacted-by-except PROJECT - Run command on the selection instead of all projects. - Add all projects that would be impacted by a change - to the specified project (except the project itself) - to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--impacted-by-except\\" + parameter works the same as \\"--impacted-by\\" except + that PROJECT itself is not added to the selection. \\". + \\" can be used as shorthand for the project in the + current working directory. Note that this parameter + is \\"unsafe\\" as it may produce a selection that + excludes some dependencies. For details, refer to the + website article \\"Selecting subsets of projects\\". --to-version-policy VERSION_POLICY_NAME - Run command on the selection instead of all projects. - Adds all projects with the specified version policy, - and all dependencies thereof, to the current - selection. Additional use of any selection commands - will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. The \\"--to-version-policy\\" + parameter is equivalent to specifying \\"--to\\" for each + of the projects belonging to VERSION_POLICY_NAME. For + details, refer to the website article \\"Selecting + subsets of projects\\". --from-version-policy VERSION_POLICY_NAME - Run command on the selection instead of all projects. - Adds all projects with the specified version policy, - and all projects that depend on them, to the current - selection. Additional use of any selection commands - will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. The \\"--from-version-policy\\" + parameter is equivalent to specifying \\"--from\\" for + each of the projects belonging to VERSION_POLICY_NAME. + For details, refer to the website article \\"Selecting + subsets of projects\\". -v, --verbose Display the logs during the build, rather than just displaying the build status summary -c, --changed-projects-only @@ -349,62 +369,82 @@ Optional arguments: cores. This parameter may alternatively be specified via the RUSH_PARALLELISM environment variable. -t PROJECT, --to PROJECT - Run command on the selection instead of all projects. - Adds the specified project and all its dependencies - to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--to\\" parameter expands + this selection to include PROJECT and all its + dependencies. \\".\\" can be used as shorthand for the + project in the current working directory. For details, + refer to the website article \\"Selecting subsets of + projects\\". -T PROJECT, --to-except PROJECT - Run command on the selection instead of all projects. - Adds all dependencies of the specified project to the - current selection. \\".\\" can be used as shorthand to - specify the project in the current working directory. - Additional use of any selection commands will further - expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--to-except\\" parameter + expands this selection to include all dependencies of + PROJECT, but not PROJECT itself. \\".\\" can be used as + shorthand for the project in the current working + directory. For details, refer to the website article + \\"Selecting subsets of projects\\". -f PROJECT, --from PROJECT - Run command on the selection instead of all projects. - Add the specified project and all projects that - depend on it, and all the dependencies of those - projects, to the current selection. \\".\\" can be used - as shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--from\\" parameter expands + this selection to include PROJECT and all projects + that depend on it, plus all dependencies of this set. + \\".\\" can be used as shorthand for the project in the + current working directory. For details, refer to the + website article \\"Selecting subsets of projects\\". -o PROJECT, --only PROJECT - Run command on the selection instead of all projects. - Add the specified project (and only the specified - project) to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--only\\" parameter expands + this selection to include PROJECT; its dependencies + are not added. \\".\\" can be used as shorthand for the + project in the current working directory. Note that + this parameter is \\"unsafe\\" as it may produce a + selection that excludes some dependencies. For + details, refer to the website article \\"Selecting + subsets of projects\\". -i PROJECT, --impacted-by PROJECT - Run command on the selection instead of all projects. - Add the specified project and all projects that would - be impacted by a change to it to the current - selection. \\".\\" can be used as shorthand to specify - the project in the current working directory. - Additional use of any selection commands will further - expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--impacted-by\\" parameter + expands this selection to include PROJECT and any + projects that depend on PROJECT (and thus might be + broken by changes to PROJECT). \\".\\" can be used as + shorthand for the project in the current working + directory. Note that this parameter is \\"unsafe\\" as it + may produce a selection that excludes some + dependencies. For details, refer to the website + article \\"Selecting subsets of projects\\". -I PROJECT, --impacted-by-except PROJECT - Run command on the selection instead of all projects. - Add all projects that would be impacted by a change - to the specified project (except the project itself) - to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--impacted-by-except\\" + parameter works the same as \\"--impacted-by\\" except + that PROJECT itself is not added to the selection. \\". + \\" can be used as shorthand for the project in the + current working directory. Note that this parameter + is \\"unsafe\\" as it may produce a selection that + excludes some dependencies. For details, refer to the + website article \\"Selecting subsets of projects\\". --to-version-policy VERSION_POLICY_NAME - Run command on the selection instead of all projects. - Adds all projects with the specified version policy, - and all dependencies thereof, to the current - selection. Additional use of any selection commands - will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. The \\"--to-version-policy\\" + parameter is equivalent to specifying \\"--to\\" for each + of the projects belonging to VERSION_POLICY_NAME. For + details, refer to the website article \\"Selecting + subsets of projects\\". --from-version-policy VERSION_POLICY_NAME - Run command on the selection instead of all projects. - Adds all projects with the specified version policy, - and all projects that depend on them, to the current - selection. Additional use of any selection commands - will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. The \\"--from-version-policy\\" + parameter is equivalent to specifying \\"--from\\" for + each of the projects belonging to VERSION_POLICY_NAME. + For details, refer to the website article \\"Selecting + subsets of projects\\". -v, --verbose Display the logs during the build, rather than just displaying the build status summary --ignore-hooks Skips execution of the \\"eventHooks\\" scripts defined @@ -725,62 +765,82 @@ Optional arguments: cores. This parameter may alternatively be specified via the RUSH_PARALLELISM environment variable. -t PROJECT, --to PROJECT - Run command on the selection instead of all projects. - Adds the specified project and all its dependencies - to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--to\\" parameter expands + this selection to include PROJECT and all its + dependencies. \\".\\" can be used as shorthand for the + project in the current working directory. For details, + refer to the website article \\"Selecting subsets of + projects\\". -T PROJECT, --to-except PROJECT - Run command on the selection instead of all projects. - Adds all dependencies of the specified project to the - current selection. \\".\\" can be used as shorthand to - specify the project in the current working directory. - Additional use of any selection commands will further - expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--to-except\\" parameter + expands this selection to include all dependencies of + PROJECT, but not PROJECT itself. \\".\\" can be used as + shorthand for the project in the current working + directory. For details, refer to the website article + \\"Selecting subsets of projects\\". -f PROJECT, --from PROJECT - Run command on the selection instead of all projects. - Add the specified project and all projects that - depend on it, and all the dependencies of those - projects, to the current selection. \\".\\" can be used - as shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--from\\" parameter expands + this selection to include PROJECT and all projects + that depend on it, plus all dependencies of this set. + \\".\\" can be used as shorthand for the project in the + current working directory. For details, refer to the + website article \\"Selecting subsets of projects\\". -o PROJECT, --only PROJECT - Run command on the selection instead of all projects. - Add the specified project (and only the specified - project) to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--only\\" parameter expands + this selection to include PROJECT; its dependencies + are not added. \\".\\" can be used as shorthand for the + project in the current working directory. Note that + this parameter is \\"unsafe\\" as it may produce a + selection that excludes some dependencies. For + details, refer to the website article \\"Selecting + subsets of projects\\". -i PROJECT, --impacted-by PROJECT - Run command on the selection instead of all projects. - Add the specified project and all projects that would - be impacted by a change to it to the current - selection. \\".\\" can be used as shorthand to specify - the project in the current working directory. - Additional use of any selection commands will further - expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--impacted-by\\" parameter + expands this selection to include PROJECT and any + projects that depend on PROJECT (and thus might be + broken by changes to PROJECT). \\".\\" can be used as + shorthand for the project in the current working + directory. Note that this parameter is \\"unsafe\\" as it + may produce a selection that excludes some + dependencies. For details, refer to the website + article \\"Selecting subsets of projects\\". -I PROJECT, --impacted-by-except PROJECT - Run command on the selection instead of all projects. - Add all projects that would be impacted by a change - to the specified project (except the project itself) - to the current selection. \\".\\" can be used as - shorthand to specify the project in the current - working directory. Additional use of any selection - commands will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. Each \\"--impacted-by-except\\" + parameter works the same as \\"--impacted-by\\" except + that PROJECT itself is not added to the selection. \\". + \\" can be used as shorthand for the project in the + current working directory. Note that this parameter + is \\"unsafe\\" as it may produce a selection that + excludes some dependencies. For details, refer to the + website article \\"Selecting subsets of projects\\". --to-version-policy VERSION_POLICY_NAME - Run command on the selection instead of all projects. - Adds all projects with the specified version policy, - and all dependencies thereof, to the current - selection. Additional use of any selection commands - will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. The \\"--to-version-policy\\" + parameter is equivalent to specifying \\"--to\\" for each + of the projects belonging to VERSION_POLICY_NAME. For + details, refer to the website article \\"Selecting + subsets of projects\\". --from-version-policy VERSION_POLICY_NAME - Run command on the selection instead of all projects. - Adds all projects with the specified version policy, - and all projects that depend on them, to the current - selection. Additional use of any selection commands - will further expand the selection. + Normally all projects in the monorepo will be + processed; adding this parameter will instead select + a subset of projects. The \\"--from-version-policy\\" + parameter is equivalent to specifying \\"--from\\" for + each of the projects belonging to VERSION_POLICY_NAME. + For details, refer to the website article \\"Selecting + subsets of projects\\". -v, --verbose Display the logs during the build, rather than just displaying the build status summary --ignore-hooks Skips execution of the \\"eventHooks\\" scripts defined From 2605f50047b3fb4b929a399f35c007de8e6759ba Mon Sep 17 00:00:00 2001 From: Pete Gonzalez <4673363+octogonz@users.noreply.github.com> Date: Mon, 1 Feb 2021 11:51:47 -0800 Subject: [PATCH 23/23] Add an underscore prefix to @internal method --- apps/rush-lib/src/api/RushConfiguration.ts | 2 +- .../src/api/RushConfigurationProject.ts | 23 ++++++++----------- apps/rush-lib/src/logic/PublishUtilities.ts | 2 +- common/reviews/api/rush-lib.api.md | 2 +- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/apps/rush-lib/src/api/RushConfiguration.ts b/apps/rush-lib/src/api/RushConfiguration.ts index 966e3b99369..50fca5d25a7 100644 --- a/apps/rush-lib/src/api/RushConfiguration.ts +++ b/apps/rush-lib/src/api/RushConfiguration.ts @@ -1669,7 +1669,7 @@ export class RushConfiguration { const depProject: RushConfigurationProject | undefined = this.projectsByName.get(dependencyName); if (depProject) { - depProject.consumingProjectNames.add(packageName); + depProject._consumingProjectNames.add(packageName); } }); } diff --git a/apps/rush-lib/src/api/RushConfigurationProject.ts b/apps/rush-lib/src/api/RushConfigurationProject.ts index efa50967d90..1cccab91bab 100644 --- a/apps/rush-lib/src/api/RushConfigurationProject.ts +++ b/apps/rush-lib/src/api/RushConfigurationProject.ts @@ -55,11 +55,19 @@ export class RushConfigurationProject { private _shouldPublish: boolean; private _skipRushCheck: boolean; private _publishFolder: string; - private _consumingProjectNames: Set; private _dependencyProjects: ReadonlySet | undefined; private _consumingProjects: ReadonlySet | undefined; private readonly _rushConfiguration: RushConfiguration; + /** + * A set of projects within the Rush configuration which directly consume this package. + * + * @remarks + * Writable because it is mutated by RushConfiguration during initialization. + * @internal + */ + public readonly _consumingProjectNames: Set; + /** @internal */ public constructor( projectJson: IRushConfigurationProjectJson, @@ -236,17 +244,6 @@ export class RushConfigurationProject { return [...this._consumingProjectNames]; } - /** - * A set of projects within the Rush configuration which directly consume this package. - * @internal - * - * @remarks - * Writable because it is mutated by RushConfiguration during initialization. - */ - public get consumingProjectNames(): Set { - return this._consumingProjectNames; - } - /** * An array of projects within the Rush configuration which this project declares as dependencies. * @deprecated Use `dependencyProjects` instead, as it has Set semantics, which better reflect the nature @@ -441,7 +438,7 @@ export class RushConfigurationProject { */ private _getConsumingProjects(): Set { const consumingProjects: Set = new Set(); - for (const projectName of this.consumingProjectNames) { + for (const projectName of this._consumingProjectNames) { const localProject: RushConfigurationProject | undefined = this._rushConfiguration.getProjectByName( projectName ); diff --git a/apps/rush-lib/src/logic/PublishUtilities.ts b/apps/rush-lib/src/logic/PublishUtilities.ts index 09f8cbd2389..7c722a5eebd 100644 --- a/apps/rush-lib/src/logic/PublishUtilities.ts +++ b/apps/rush-lib/src/logic/PublishUtilities.ts @@ -85,7 +85,7 @@ export class PublishUtilities { const change: IChangeInfo = allChanges[packageName]; const project: RushConfigurationProject = allPackages.get(packageName)!; const pkg: IPackageJson = project.packageJson; - const deps: Set = project.consumingProjectNames; + const deps: Set = project._consumingProjectNames; // Write the new version expected for the change. const skipVersionBump: boolean = PublishUtilities._shouldSkipVersionBump( diff --git a/common/reviews/api/rush-lib.api.md b/common/reviews/api/rush-lib.api.md index 5eb3b5b3948..6992483f76d 100644 --- a/common/reviews/api/rush-lib.api.md +++ b/common/reviews/api/rush-lib.api.md @@ -413,7 +413,7 @@ export class RushConfigurationProject { // @internal constructor(projectJson: IRushConfigurationProjectJson, rushConfiguration: RushConfiguration, tempProjectName: string); // @internal - get consumingProjectNames(): Set; + readonly _consumingProjectNames: Set; get consumingProjects(): ReadonlySet; get cyclicDependencyProjects(): Set; get dependencyProjects(): ReadonlySet;