Skip to content

Commit 4fd3fc7

Browse files
committed
Follow-ups to #5123
1 parent ded23d1 commit 4fd3fc7

5 files changed

Lines changed: 318 additions & 240 deletions

File tree

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22
// See LICENSE in the project root for license information.
33

4-
import type {
5-
CommandLineStringListParameter,
6-
IRequiredCommandLineStringParameter
7-
} from '@rushstack/ts-command-line';
4+
import type { IRequiredCommandLineStringParameter } from '@rushstack/ts-command-line';
85
import path from 'path';
9-
import type { RushConfigurationProject } from '../../api/RushConfigurationProject';
106
import { HotlinkManager } from '../../utilities/HotlinkManager';
117
import { BaseRushAction, type IBaseRushActionOptions } from './BaseRushAction';
12-
import { Async } from '@rushstack/node-core-library';
13-
import { RushConstants } from '../../logic/RushConstants';
148

159
export abstract class BaseHotlinkPackageAction extends BaseRushAction {
16-
protected readonly _projectList: CommandLineStringListParameter;
1710
protected readonly _pathParameter: IRequiredCommandLineStringParameter;
1811

1912
protected constructor(options: IBaseRushActionOptions) {
@@ -27,59 +20,16 @@ export abstract class BaseHotlinkPackageAction extends BaseRushAction {
2720
'The path of folder of a project outside of this Rush repo, whose installation will be simulated using' +
2821
' node_modules symlinks ("hotlinks"). This folder is the symlink target.'
2922
});
30-
31-
this._projectList = this.defineStringListParameter({
32-
parameterLongName: '--project',
33-
required: false,
34-
argumentName: 'PROJECT',
35-
description:
36-
'A list of Rush project names that will be hotlinked to the "--path" folder. ' +
37-
'If not specified, the default is the project of the current working directory.'
38-
});
3923
}
4024

4125
protected abstract connectPackageAsync(
42-
consumerPackage: RushConfigurationProject,
4326
linkedPackagePath: string,
4427
hotlinkManager: HotlinkManager
4528
): Promise<void>;
4629

47-
protected async getProjectsToLinkAsync(): Promise<Set<RushConfigurationProject>> {
48-
const projectsToLink: Set<RushConfigurationProject> = new Set();
49-
const projectNames: readonly string[] = this._projectList.values;
50-
51-
if (projectNames.length > 0) {
52-
for (const projectName of projectNames) {
53-
const project: RushConfigurationProject | undefined =
54-
this.rushConfiguration.getProjectByName(projectName);
55-
if (!project) {
56-
throw new Error(`The project "${projectName}" was not found in "${RushConstants.rushPackageName}"`);
57-
}
58-
projectsToLink.add(project);
59-
}
60-
} else {
61-
const currentProject: RushConfigurationProject | undefined =
62-
this.rushConfiguration.tryGetProjectForPath(process.cwd());
63-
if (!currentProject) {
64-
throw new Error(`No Rush project was found in the current working directory`);
65-
}
66-
projectsToLink.add(currentProject);
67-
}
68-
69-
return projectsToLink;
70-
}
71-
7230
protected async runAsync(): Promise<void> {
7331
const hotlinkManager: HotlinkManager = HotlinkManager.loadFromRushConfiguration(this.rushConfiguration);
7432
const linkedPackagePath: string = path.resolve(process.cwd(), this._pathParameter.value);
75-
const projectsToLink: Set<RushConfigurationProject> = await this.getProjectsToLinkAsync();
76-
77-
await Async.forEachAsync(
78-
projectsToLink,
79-
async (project) => {
80-
await this.connectPackageAsync(project, linkedPackagePath, hotlinkManager);
81-
},
82-
{ concurrency: 5 }
83-
);
33+
await this.connectPackageAsync(linkedPackagePath, hotlinkManager);
8434
}
8535
}

libraries/rush-lib/src/cli/actions/BridgePackageAction.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import type { CommandLineStringParameter } from '@rushstack/ts-command-line';
55

66
import type { RushCommandLineParser } from '../RushCommandLineParser';
7-
import type { RushConfigurationProject } from '../../api/RushConfigurationProject';
87
import { BaseHotlinkPackageAction } from './BaseHotlinkPackageAction';
98
import type { HotlinkManager } from '../../utilities/HotlinkManager';
109
import { BRIDGE_PACKAGE_ACTION_NAME, LINK_PACKAGE_ACTION_NAME } from '../../utilities/actionNameConstants';
10+
import { RushConstants } from '../../logic/RushConstants';
11+
import type { Subspace } from '../../api/Subspace';
1112

1213
export class BridgePackageAction extends BaseHotlinkPackageAction {
1314
private readonly _version: CommandLineStringParameter;
15+
private readonly _subspaceName: CommandLineStringParameter;
1416

1517
public constructor(parser: RushCommandLineParser) {
1618
super({
@@ -31,17 +33,22 @@ export class BridgePackageAction extends BaseHotlinkPackageAction {
3133
this._version = this.defineStringParameter({
3234
parameterLongName: '--version',
3335
argumentName: 'SEMVER_RANGE',
36+
defaultValue: '*',
3437
description:
3538
'Specify which installed versions should be hotlinked. If omitted, the default is all versions ("*).'
3639
});
40+
41+
this._subspaceName = this.defineStringParameter({
42+
parameterLongName: '--subspace',
43+
argumentName: 'SUBSPACE',
44+
defaultValue: RushConstants.defaultSubspaceName,
45+
description: 'The name of the subspace to use for the bridge package.'
46+
});
3747
}
3848

39-
public async connectPackageAsync(
40-
consumerPackage: RushConfigurationProject,
41-
linkedPackagePath: string,
42-
hotlinkManager: HotlinkManager
43-
): Promise<void> {
44-
const version: string | undefined = this._version.value;
45-
await hotlinkManager.bridgePackageAsync(this.terminal, consumerPackage, linkedPackagePath, version);
49+
public async connectPackageAsync(linkedPackagePath: string, hotlinkManager: HotlinkManager): Promise<void> {
50+
const version: string = this._version.value!;
51+
const subspace: Subspace = this.rushConfiguration.getSubspace(this._subspaceName.value!);
52+
await hotlinkManager.bridgePackageAsync(this.terminal, subspace, linkedPackagePath, version);
4653
}
4754
}

libraries/rush-lib/src/cli/actions/LinkPackageAction.ts

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@ import type { RushConfigurationProject } from '../../api/RushConfigurationProjec
66
import { BaseHotlinkPackageAction } from './BaseHotlinkPackageAction';
77
import type { HotlinkManager } from '../../utilities/HotlinkManager';
88
import { BRIDGE_PACKAGE_ACTION_NAME, LINK_PACKAGE_ACTION_NAME } from '../../utilities/actionNameConstants';
9+
import type { CommandLineStringListParameter } from '@rushstack/ts-command-line';
10+
import { RushConstants } from '../../logic/RushConstants';
11+
import { Async } from '@rushstack/node-core-library';
912

1013
export class LinkPackageAction extends BaseHotlinkPackageAction {
14+
protected readonly _projectList: CommandLineStringListParameter;
15+
1116
public constructor(parser: RushCommandLineParser) {
1217
super({
1318
actionName: LINK_PACKAGE_ACTION_NAME,
@@ -24,13 +29,50 @@ export class LinkPackageAction extends BaseHotlinkPackageAction {
2429
' including indirect dependencies.',
2530
parser
2631
});
32+
33+
this._projectList = this.defineStringListParameter({
34+
parameterLongName: '--project',
35+
required: false,
36+
argumentName: 'PROJECT',
37+
description:
38+
'A list of Rush project names that will be hotlinked to the "--path" folder. ' +
39+
'If not specified, the default is the project of the current working directory.'
40+
});
41+
}
42+
43+
protected async getProjectsToLinkAsync(): Promise<Set<RushConfigurationProject>> {
44+
const projectsToLink: Set<RushConfigurationProject> = new Set();
45+
const projectNames: readonly string[] = this._projectList.values;
46+
47+
if (projectNames.length > 0) {
48+
for (const projectName of projectNames) {
49+
const project: RushConfigurationProject | undefined =
50+
this.rushConfiguration.getProjectByName(projectName);
51+
if (!project) {
52+
throw new Error(`The project "${projectName}" was not found in "${RushConstants.rushPackageName}"`);
53+
}
54+
projectsToLink.add(project);
55+
}
56+
} else {
57+
const currentProject: RushConfigurationProject | undefined =
58+
this.rushConfiguration.tryGetProjectForPath(process.cwd());
59+
if (!currentProject) {
60+
throw new Error(`No Rush project was found in the current working directory`);
61+
}
62+
projectsToLink.add(currentProject);
63+
}
64+
65+
return projectsToLink;
2766
}
2867

29-
public async connectPackageAsync(
30-
consumerPackage: RushConfigurationProject,
31-
linkedPackagePath: string,
32-
hotlinkManager: HotlinkManager
33-
): Promise<void> {
34-
await hotlinkManager.linkPackageAsync(this.terminal, consumerPackage, linkedPackagePath);
68+
public async connectPackageAsync(linkedPackagePath: string, hotlinkManager: HotlinkManager): Promise<void> {
69+
const projectsToLink: Set<RushConfigurationProject> = await this.getProjectsToLinkAsync();
70+
await Async.forEachAsync(
71+
projectsToLink,
72+
async (project) => {
73+
await hotlinkManager.linkPackageAsync(this.terminal, project, linkedPackagePath);
74+
},
75+
{ concurrency: 5 }
76+
);
3577
}
3678
}

libraries/rush-lib/src/schemas/rush-hotlink-state.schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@
3636
"type": "string"
3737
},
3838

39+
"affectedPnpmVirtualStoreFolderNames": {
40+
"types": "array",
41+
"items": {
42+
"type": "string"
43+
}
44+
},
45+
3946
"linkType": {
4047
"type": "string",
4148
"enum": ["LinkPackage", "BridgePackage"]

0 commit comments

Comments
 (0)