Skip to content

Commit ded23d1

Browse files
L-Quniclantonoctogonz
authored
5123 followups (#5182)
* Make LinkType a string union. * Remove RushConnectError. * Remove the 'path' dependency. * fixup! Remove the 'path' dependency. * Asyncify BaseLinkManager._createSymlinkAsync. * Replace FileSystem.createSymbolicLinkFolderAsync with BaseLinkManager._createSymlinkAsync, which handles quirks between Windows and non-Windows. * Clean up some logic around paths existing. * Plumb terminal around from parser. * Stop constructing a new terminal in RushConnnect. * Rename IRushLinkFileState to IRushLinkFileStateJson. * Clean up the RushConnect API some more. * Future-proof a FileSystem reference. * Limit concurrency in a few places. * fixup! Limit concurrency in a few places. * Clean up a few variable names. * Clean up BaseSymlinkPackageAction. * Refactor of the links file. * fixup! Replace FileSystem.createSymbolicLinkFolderAsync with BaseLinkManager._createSymlinkAsync, which handles quirks between Windows and non-Windows. * fixup! Refactor of the links file. * fixup! Clean up the RushConnect API some more. * fixup! Clean up the RushConnect API some more. * Some wordsmithing of link- and bridge-package commands. * fixup! Refactor of the links file. * More wordsmithing. * fixup! Some wordsmithing of link- and bridge-package commands. * Rush change. * Update libraries/rush-lib/src/api/test/__snapshots__/RushCommandLine.test.ts.snap * Update libraries/rush-lib/src/cli/actions/BridgePackageAction.ts * Rename RushConnect --> HotlinkManager Rename BaseSymlinkPackageAction --> BaseHotlinkPackageAction * Update docs to use hotlink terminology * Rename rush-project-link-state.json --> rush-hotlink-state.json * Update snapshots --------- Co-authored-by: Ian Clanton-Thuon <iclanton@users.noreply.github.com> Co-authored-by: Pete Gonzalez <4673363+octogonz@users.noreply.github.com>
1 parent 875d3de commit ded23d1

35 files changed

Lines changed: 816 additions & 707 deletions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"comment": "",
5+
"type": "none",
6+
"packageName": "@microsoft/rush"
7+
}
8+
],
9+
"packageName": "@microsoft/rush",
10+
"email": "iclanton@users.noreply.github.com"
11+
}

common/reviews/api/rush-lib.api.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,22 +1372,23 @@ export class RushConstants {
13721372
// @deprecated
13731373
static readonly pinnedVersionsFilename: 'pinned-versions.json';
13741374
static readonly pnpmConfigFilename: 'pnpm-config.json';
1375-
static readonly pnpmDependenciesFolderName: '.pnpm';
13761375
static readonly pnpmfileGlobalFilename: 'global-pnpmfile.cjs';
13771376
static readonly pnpmfileV1Filename: 'pnpmfile.js';
13781377
static readonly pnpmfileV6Filename: '.pnpmfile.cjs';
13791378
static readonly pnpmModulesFilename: '.modules.yaml';
13801379
static readonly pnpmPatchesCommonFolderName: `pnpm-patches`;
13811380
static readonly pnpmPatchesFolderName: 'patches';
1381+
static readonly pnpmSyncFilename: '.pnpm-sync.json';
13821382
static readonly pnpmV3ShrinkwrapFilename: 'pnpm-lock.yaml';
1383+
static readonly pnpmVirtualStoreFolderName: '.pnpm';
13831384
static readonly projectImpactGraphFilename: 'project-impact-graph.yaml';
13841385
static readonly projectRushFolderName: '.rush';
13851386
static readonly projectShrinkwrapFilename: 'shrinkwrap-deps.json';
13861387
static readonly rebuildCommandName: 'rebuild';
13871388
static readonly repoStateFilename: 'repo-state.json';
13881389
static readonly rushAlertsConfigFilename: 'rush-alerts.json';
1390+
static readonly rushHotlinkStateFilename: 'rush-hotlink-state.json';
13891391
static readonly rushJsonFilename: 'rush.json';
1390-
static readonly rushLinkStateFilename: 'rush-link-state.json';
13911392
static readonly rushLogsFolderName: 'rush-logs';
13921393
static readonly rushPackageName: '@microsoft/rush';
13931394
static readonly rushPluginManifestFilename: 'rush-plugin-manifest.json';

libraries/rush-lib/src/api/RushProjectConfiguration.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type { IPhase } from './CommandLineConfiguration';
1212
import { OverlappingPathAnalyzer } from '../utilities/OverlappingPathAnalyzer';
1313
import schemaJson from '../schemas/rush-project.schema.json';
1414
import anythingSchemaJson from '../schemas/rush-project.schema.json';
15-
import { RushConnect } from '../utilities/RushConnect';
15+
import { HotlinkManager } from '../utilities/HotlinkManager';
1616
import type { RushConfiguration } from './RushConfiguration';
1717

1818
/**
@@ -349,10 +349,9 @@ export class RushProjectConfiguration {
349349
): string | undefined {
350350
const rushConfiguration: RushConfiguration | undefined = this.project.rushConfiguration;
351351
if (rushConfiguration) {
352-
const rushConnect: RushConnect = RushConnect.loadFromLinkStateFile(rushConfiguration);
353-
const subspaceNameList: string[] = Object.keys(rushConnect.rushLinkState ?? {});
354-
if (subspaceNameList.includes(this.project.subspace.subspaceName)) {
355-
return 'Caching has been disabled for this project because it is a linked package.';
352+
const hotlinkManager: HotlinkManager = HotlinkManager.loadFromRushConfiguration(rushConfiguration);
353+
if (hotlinkManager.hasAnyHotlinksInSubspace(this.project.subspace.subspaceName)) {
354+
return 'Caching has been disabled for this project because it is in a subspace with hotlinked dependencies.';
356355
}
357356
}
358357

libraries/rush-lib/src/api/test/__snapshots__/RushCommandLine.test.ts.snap

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,23 +1141,23 @@ Object {
11411141
"actionName": "bridge-package",
11421142
"parameters": Array [
11431143
Object {
1144-
"description": "The folder path of a locally built project, whose installation will be simulated using node_modules symlinks. This folder will be the target of the symlinks.",
1144+
"description": "The path of folder of a project outside of this Rush repo, whose installation will be simulated using node_modules symlinks (\\"hotlinks\\"). This folder is the symlink target.",
11451145
"environmentVariable": undefined,
11461146
"kind": "String",
11471147
"longName": "--path",
11481148
"required": true,
11491149
"shortName": undefined,
11501150
},
11511151
Object {
1152-
"description": "A list of Rush project names to connect to the external package. If not specified, uses the project in the current working directory.",
1152+
"description": "A list of Rush project names that will be hotlinked to the \\"--path\\" folder. If not specified, the default is the project of the current working directory.",
11531153
"environmentVariable": undefined,
11541154
"kind": "StringList",
11551155
"longName": "--project",
11561156
"required": false,
11571157
"shortName": undefined,
11581158
},
11591159
Object {
1160-
"description": "It will directly replace the output for the specified version of the package, which requires you to have that package installed under the specified name in advance.",
1160+
"description": "Specify which installed versions should be hotlinked. If omitted, the default is all versions (\\"*).",
11611161
"environmentVariable": undefined,
11621162
"kind": "String",
11631163
"longName": "--version",
@@ -1170,15 +1170,15 @@ Object {
11701170
"actionName": "link-package",
11711171
"parameters": Array [
11721172
Object {
1173-
"description": "The folder path of a locally built project, whose installation will be simulated using node_modules symlinks. This folder will be the target of the symlinks.",
1173+
"description": "The path of folder of a project outside of this Rush repo, whose installation will be simulated using node_modules symlinks (\\"hotlinks\\"). This folder is the symlink target.",
11741174
"environmentVariable": undefined,
11751175
"kind": "String",
11761176
"longName": "--path",
11771177
"required": true,
11781178
"shortName": undefined,
11791179
},
11801180
Object {
1181-
"description": "A list of Rush project names to connect to the external package. If not specified, uses the project in the current working directory.",
1181+
"description": "A list of Rush project names that will be hotlinked to the \\"--path\\" folder. If not specified, the default is the project of the current working directory.",
11821182
"environmentVariable": undefined,
11831183
"kind": "StringList",
11841184
"longName": "--project",

libraries/rush-lib/src/cli/RushXCommandLine.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export class RushXCommandLine {
228228
const { configuration: experiments } = rushConfiguration?.experimentsConfiguration;
229229

230230
if (experiments?.usePnpmSyncForInjectedDependencies) {
231-
const pnpmSyncJsonPath: string = packageFolder + '/node_modules/.pnpm-sync.json';
231+
const pnpmSyncJsonPath: string = `${packageFolder}/${RushConstants.nodeModulesFolderName}/${RushConstants.pnpmSyncFilename}`;
232232
if (await FileSystem.existsAsync(pnpmSyncJsonPath)) {
233233
const { PackageExtractor } = await import(
234234
/* webpackChunkName: 'PackageExtractor' */

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
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 { ConsoleTerminalProvider, Terminal } from '@rushstack/terminal';
54
import type { CommandLineFlagParameter, CommandLineStringParameter } from '@rushstack/ts-command-line';
65

76
import type { RushCommandLineParser } from '../RushCommandLineParser';
87
import { BaseRushAction } from './BaseRushAction';
98
import { RushAlerts } from '../../utilities/RushAlerts';
109

1110
export class AlertAction extends BaseRushAction {
12-
private readonly _terminal: Terminal;
1311
private readonly _snoozeParameter: CommandLineStringParameter;
1412
private readonly _snoozeTimeFlagParameter: CommandLineFlagParameter;
1513

@@ -23,7 +21,6 @@ export class AlertAction extends BaseRushAction {
2321
' The alert definitions can be found in the rush-alerts.json config file.',
2422
parser
2523
});
26-
this._terminal = new Terminal(new ConsoleTerminalProvider({ verboseEnabled: parser.isDebug }));
2724

2825
this._snoozeParameter = this.defineStringParameter({
2926
parameterLongName: '--snooze',
@@ -41,7 +38,7 @@ export class AlertAction extends BaseRushAction {
4138
public async runAsync(): Promise<void> {
4239
const rushAlerts: RushAlerts = await RushAlerts.loadFromConfigurationAsync(
4340
this.rushConfiguration,
44-
this._terminal
41+
this.terminal
4542
);
4643
const snoozeAlertId: string | undefined = this._snoozeParameter.value;
4744
if (snoozeAlertId) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export abstract class BaseAddAndRemoveAction extends BaseRushAction {
7979
/* webpackChunkName: 'PackageJsonUpdater' */ '../../logic/PackageJsonUpdater'
8080
);
8181
const updater: PackageJsonUpdaterType.PackageJsonUpdater = new packageJsonUpdater.PackageJsonUpdater(
82+
this.terminal,
8283
this.rushConfiguration,
8384
this.rushGlobalFolder
8485
);

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
// See LICENSE in the project root for license information.
33

44
import type { IRequiredCommandLineStringParameter } from '@rushstack/ts-command-line';
5-
import type { ITerminal } from '@rushstack/terminal';
65

76
import { BaseRushAction, type IBaseRushActionOptions } from './BaseRushAction';
87
import { Autoinstaller } from '../../logic/Autoinstaller';
98

109
export abstract class BaseAutoinstallerAction extends BaseRushAction {
1110
protected readonly _name: IRequiredCommandLineStringParameter;
12-
protected readonly _terminal: ITerminal;
1311

1412
public constructor(options: IBaseRushActionOptions) {
1513
super(options);
@@ -21,8 +19,6 @@ export abstract class BaseAutoinstallerAction extends BaseRushAction {
2119
description:
2220
'The name of the autoinstaller, which must be one of the folders under common/autoinstallers.'
2321
});
24-
25-
this._terminal = this.parser.terminal;
2622
}
2723

2824
protected abstract prepareAsync(autoinstaller: Autoinstaller): Promise<void>;
@@ -37,7 +33,7 @@ export abstract class BaseAutoinstallerAction extends BaseRushAction {
3733

3834
await this.prepareAsync(autoinstaller);
3935

40-
this._terminal.writeLine();
41-
this._terminal.writeLine('Success.');
36+
this.terminal.writeLine();
37+
this.terminal.writeLine('Success.');
4238
}
4339
}

libraries/rush-lib/src/cli/actions/BaseSymlinkPackageAction.ts renamed to libraries/rush-lib/src/cli/actions/BaseHotlinkPackageAction.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
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 { CommandLineStringListParameter, CommandLineStringParameter } from '@rushstack/ts-command-line';
4+
import type {
5+
CommandLineStringListParameter,
6+
IRequiredCommandLineStringParameter
7+
} from '@rushstack/ts-command-line';
58
import path from 'path';
69
import type { RushConfigurationProject } from '../../api/RushConfigurationProject';
7-
import { RushConnect } from '../../utilities/RushConnect';
10+
import { HotlinkManager } from '../../utilities/HotlinkManager';
811
import { BaseRushAction, type IBaseRushActionOptions } from './BaseRushAction';
912
import { Async } from '@rushstack/node-core-library';
13+
import { RushConstants } from '../../logic/RushConstants';
1014

11-
export abstract class BaseSymlinkPackageAction extends BaseRushAction {
15+
export abstract class BaseHotlinkPackageAction extends BaseRushAction {
1216
protected readonly _projectList: CommandLineStringListParameter;
13-
protected readonly _pathParameter: CommandLineStringParameter;
17+
protected readonly _pathParameter: IRequiredCommandLineStringParameter;
1418

1519
protected constructor(options: IBaseRushActionOptions) {
1620
super(options);
@@ -20,24 +24,24 @@ export abstract class BaseSymlinkPackageAction extends BaseRushAction {
2024
argumentName: 'PATH',
2125
required: true,
2226
description:
23-
'The folder path of a locally built project, whose installation will be simulated using node_modules' +
24-
' symlinks. This folder will be the target of the symlinks.'
27+
'The path of folder of a project outside of this Rush repo, whose installation will be simulated using' +
28+
' node_modules symlinks ("hotlinks"). This folder is the symlink target.'
2529
});
2630

2731
this._projectList = this.defineStringListParameter({
2832
parameterLongName: '--project',
2933
required: false,
3034
argumentName: 'PROJECT',
3135
description:
32-
'A list of Rush project names to connect to the external package. ' +
33-
'If not specified, uses the project in the current working directory.'
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.'
3438
});
3539
}
3640

3741
protected abstract connectPackageAsync(
3842
consumerPackage: RushConfigurationProject,
3943
linkedPackagePath: string,
40-
rushConnect: RushConnect
44+
hotlinkManager: HotlinkManager
4145
): Promise<void>;
4246

4347
protected async getProjectsToLinkAsync(): Promise<Set<RushConfigurationProject>> {
@@ -49,7 +53,7 @@ export abstract class BaseSymlinkPackageAction extends BaseRushAction {
4953
const project: RushConfigurationProject | undefined =
5054
this.rushConfiguration.getProjectByName(projectName);
5155
if (!project) {
52-
throw new Error(`The project "${projectName}" was not found in the "rush.json"`);
56+
throw new Error(`The project "${projectName}" was not found in "${RushConstants.rushPackageName}"`);
5357
}
5458
projectsToLink.add(project);
5559
}
@@ -66,12 +70,16 @@ export abstract class BaseSymlinkPackageAction extends BaseRushAction {
6670
}
6771

6872
protected async runAsync(): Promise<void> {
69-
const rushConnect: RushConnect = RushConnect.loadFromLinkStateFile(this.rushConfiguration);
70-
const linkedPackagePath: string = path.resolve(this._pathParameter.value!);
73+
const hotlinkManager: HotlinkManager = HotlinkManager.loadFromRushConfiguration(this.rushConfiguration);
74+
const linkedPackagePath: string = path.resolve(process.cwd(), this._pathParameter.value);
7175
const projectsToLink: Set<RushConfigurationProject> = await this.getProjectsToLinkAsync();
7276

73-
await Async.forEachAsync(projectsToLink, async (project) => {
74-
await this.connectPackageAsync(project, linkedPackagePath, rushConnect);
75-
});
77+
await Async.forEachAsync(
78+
projectsToLink,
79+
async (project) => {
80+
await this.connectPackageAsync(project, linkedPackagePath, hotlinkManager);
81+
},
82+
{ concurrency: 5 }
83+
);
7684
}
7785
}

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type {
88
IRequiredCommandLineIntegerParameter
99
} from '@rushstack/ts-command-line';
1010
import { AlreadyReportedError } from '@rushstack/node-core-library';
11-
import { type ITerminal, Colorize } from '@rushstack/terminal';
11+
import { Colorize } from '@rushstack/terminal';
1212

1313
import { BaseRushAction, type IBaseRushActionOptions } from './BaseRushAction';
1414
import { Event } from '../../api/EventHooks';
@@ -37,7 +37,6 @@ interface ISubspaceInstallationData {
3737
* This is the common base class for InstallAction and UpdateAction.
3838
*/
3939
export abstract class BaseInstallAction extends BaseRushAction {
40-
protected readonly _terminal: ITerminal;
4140
protected readonly _variantParameter: CommandLineStringParameter;
4241
protected readonly _purgeParameter: CommandLineFlagParameter;
4342
protected readonly _bypassPolicyParameter: CommandLineFlagParameter;
@@ -56,8 +55,6 @@ export abstract class BaseInstallAction extends BaseRushAction {
5655
public constructor(options: IBaseRushActionOptions) {
5756
super(options);
5857

59-
this._terminal = options.parser.terminal;
60-
6158
this._purgeParameter = this.defineFlagParameter({
6259
parameterLongName: '--purge',
6360
parameterShortName: '-p',
@@ -126,8 +123,8 @@ export abstract class BaseInstallAction extends BaseRushAction {
126123
this.rushConfiguration.subspacesConfiguration?.preventSelectingAllSubspaces &&
127124
!this._selectionParameters?.didUserSelectAnything()
128125
) {
129-
this._terminal.writeLine();
130-
this._terminal.writeLine(
126+
this.terminal.writeLine();
127+
this.terminal.writeLine(
131128
Colorize.red(
132129
`The subspaces preventSelectingAllSubspaces configuration is enabled, which enforces installation for a specified set of subspace,` +
133130
` passed by the "${SUBSPACE_LONG_ARG_NAME}" parameter or selected from targeted projects using any project selector.`
@@ -177,13 +174,13 @@ export abstract class BaseInstallAction extends BaseRushAction {
177174
if (selectedSubspaces) {
178175
// Check each subspace for version inconsistencies
179176
for (const subspace of selectedSubspaces) {
180-
VersionMismatchFinder.ensureConsistentVersions(this.rushConfiguration, this._terminal, {
177+
VersionMismatchFinder.ensureConsistentVersions(this.rushConfiguration, this.terminal, {
181178
subspace,
182179
variant
183180
});
184181
}
185182
} else {
186-
VersionMismatchFinder.ensureConsistentVersions(this.rushConfiguration, this._terminal, {
183+
VersionMismatchFinder.ensureConsistentVersions(this.rushConfiguration, this.terminal, {
187184
subspace: undefined,
188185
variant
189186
});

0 commit comments

Comments
 (0)