diff --git a/libraries/rush-lib/src/api/ApprovedPackagesConfiguration.ts b/libraries/rush-lib/src/api/ApprovedPackagesConfiguration.ts index 6bbb3b7b412..867370ada20 100644 --- a/libraries/rush-lib/src/api/ApprovedPackagesConfiguration.ts +++ b/libraries/rush-lib/src/api/ApprovedPackagesConfiguration.ts @@ -59,13 +59,13 @@ const _jsonSchema: JsonSchema = JsonSchema.fromLoadedObject(schemaJson); export class ApprovedPackagesConfiguration { public items: ApprovedPackagesItem[] = []; - private _itemsByName: Map = new Map(); + #itemsByName: Map = new Map(); - private _loadedJson!: IApprovedPackagesJson; - private _jsonFilename: string; + #loadedJson!: IApprovedPackagesJson; + #jsonFilename: string; public constructor(jsonFilename: string) { - this._jsonFilename = jsonFilename; + this.#jsonFilename = jsonFilename; this.clear(); } @@ -73,8 +73,8 @@ export class ApprovedPackagesConfiguration { * Clears all the settings, returning to an empty state. */ public clear(): void { - this._itemsByName.clear(); - this._loadedJson = { + this.#itemsByName.clear(); + this.#loadedJson = { // Ensure this comes first in the key ordering $schema: '', packages: [] @@ -82,16 +82,16 @@ export class ApprovedPackagesConfiguration { } public getItemByName(packageName: string): ApprovedPackagesItem | undefined { - return this._itemsByName.get(packageName); + return this.#itemsByName.get(packageName); } public addOrUpdatePackage(packageName: string, reviewCategory: string): boolean { let changed: boolean = false; - let item: ApprovedPackagesItem | undefined = this._itemsByName.get(packageName); + let item: ApprovedPackagesItem | undefined = this.#itemsByName.get(packageName); if (!item) { item = new ApprovedPackagesItem(packageName); - this._addItem(item); + this.#addItem(item); changed = true; } @@ -107,7 +107,7 @@ export class ApprovedPackagesConfiguration { * If the file exists, calls loadFromFile(). */ public tryLoadFromFile(approvedPackagesPolicyEnabled: boolean): boolean { - if (!FileSystem.exists(this._jsonFilename)) { + if (!FileSystem.exists(this.#jsonFilename)) { return false; } @@ -116,7 +116,7 @@ export class ApprovedPackagesConfiguration { if (!approvedPackagesPolicyEnabled) { // eslint-disable-next-line no-console console.log( - `Warning: Ignoring "${path.basename(this._jsonFilename)}" because the` + + `Warning: Ignoring "${path.basename(this.#jsonFilename)}" because the` + ` "approvedPackagesPolicy" setting was not specified in ${RushConstants.rushJsonFilename}` ); } @@ -129,14 +129,14 @@ export class ApprovedPackagesConfiguration { */ public loadFromFile(): void { const approvedPackagesJson: IApprovedPackagesJson = JsonFile.loadAndValidate( - this._jsonFilename, + this.#jsonFilename, _jsonSchema ); this.clear(); for (const browserPackage of approvedPackagesJson.packages) { - this._addItemJson(browserPackage, this._jsonFilename); + this.#addItemJson(browserPackage, this.#jsonFilename); } } @@ -148,9 +148,9 @@ export class ApprovedPackagesConfiguration { // (which passed schema validation). // eslint-disable-next-line dot-notation - this._loadedJson['$schema'] = JsonSchemaUrls.approvedPackages; + this.#loadedJson['$schema'] = JsonSchemaUrls.approvedPackages; - this._loadedJson.packages = []; + this.#loadedJson.packages = []; this.items.sort((a: ApprovedPackagesItem, b: ApprovedPackagesItem) => { return a.packageName.localeCompare(b.packageName); @@ -166,11 +166,11 @@ export class ApprovedPackagesConfiguration { allowedCategories: allowedCategories }; - this._loadedJson.packages.push(itemJson); + this.#loadedJson.packages.push(itemJson); } // Save the file - let body: string = JsonFile.stringify(this._loadedJson); + let body: string = JsonFile.stringify(this.#loadedJson); // Unindent the allowedCategories array to improve readability body = body.replace(/("allowedCategories": +\[)([^\]]+)/g, (substring: string, ...args: string[]) => { @@ -180,7 +180,7 @@ export class ApprovedPackagesConfiguration { // Add a header body = '// DO NOT ADD COMMENTS IN THIS FILE. They will be lost when the Rush tool resaves it.\n' + body; - FileSystem.writeFile(this._jsonFilename, body, { + FileSystem.writeFile(this.#jsonFilename, body, { convertLineEndings: NewlineKind.CrLf }); } @@ -188,8 +188,8 @@ export class ApprovedPackagesConfiguration { /** * Helper function only used by the constructor when loading the file. */ - private _addItemJson(itemJson: IApprovedPackagesItemJson, jsonFilename: string): void { - if (this._itemsByName.has(itemJson.name)) { + #addItemJson(itemJson: IApprovedPackagesItemJson, jsonFilename: string): void { + if (this.#itemsByName.has(itemJson.name)) { throw new Error( `Error loading package review file ${jsonFilename}:\n` + ` the name "${itemJson.name}" appears more than once` @@ -202,18 +202,18 @@ export class ApprovedPackagesConfiguration { item.allowedCategories.add(allowedCategory); } } - this._addItem(item); + this.#addItem(item); } /** * Helper function that adds an already created ApprovedPackagesItem to the * list and set. */ - private _addItem(item: ApprovedPackagesItem): void { - if (this._itemsByName.has(item.packageName)) { + #addItem(item: ApprovedPackagesItem): void { + if (this.#itemsByName.has(item.packageName)) { throw new InternalError('Duplicate key'); } this.items.push(item); - this._itemsByName.set(item.packageName, item); + this.#itemsByName.set(item.packageName, item); } } diff --git a/libraries/rush-lib/src/api/ChangeFile.ts b/libraries/rush-lib/src/api/ChangeFile.ts index 1de74ec139a..3fe26f50f43 100644 --- a/libraries/rush-lib/src/api/ChangeFile.ts +++ b/libraries/rush-lib/src/api/ChangeFile.ts @@ -15,8 +15,8 @@ import { Git } from '../logic/Git'; * This class represents a single change file. */ export class ChangeFile { - private _changeFileData: IChangeFile; - private _rushConfiguration: RushConfiguration; + #changeFileData: IChangeFile; + #rushConfiguration: RushConfiguration; /** * @internal @@ -30,8 +30,8 @@ export class ChangeFile { throw new Error(`rushConfiguration does not have a value`); } - this._changeFileData = changeFileData; - this._rushConfiguration = rushConfiguration; + this.#changeFileData = changeFileData; + this.#rushConfiguration = rushConfiguration; } /** @@ -39,7 +39,7 @@ export class ChangeFile { * @param data - change information */ public addChange(data: IChangeInfo): void { - this._changeFileData.changes.push(data); + this.#changeFileData.changes.push(data); } /** @@ -48,7 +48,7 @@ export class ChangeFile { */ public getChanges(packageName: string): IChangeInfo[] { const changes: IChangeInfo[] = []; - for (const info of this._changeFileData.changes) { + for (const info of this.#changeFileData.changes) { if (info.packageName === packageName) { changes.push(info); } @@ -63,7 +63,7 @@ export class ChangeFile { */ public writeSync(): string { const filePath: string = this.generatePath(); - JsonFile.save(this._changeFileData, filePath, { + JsonFile.save(this.#changeFileData, filePath, { ensureFolderExists: true }); return filePath; @@ -76,7 +76,7 @@ export class ChangeFile { */ public generatePath(): string { let branch: string | undefined = undefined; - const git: Git = new Git(this._rushConfiguration); + const git: Git = new Git(this.#rushConfiguration); const repoInfo: gitInfo.GitRepoInfo | undefined = git.getGitInfo(); branch = repoInfo && repoInfo.branch; if (!branch) { @@ -89,13 +89,13 @@ export class ChangeFile { // flag rarely had any effect, and a second invocation would silently clobber the // change file written by the first one. See GitHub issue #2195. // example filename: yourbranchname_2017-05-01-20-20-30.json - const timestamp: string | undefined = this._getTimestamp(true); + const timestamp: string | undefined = this.#getTimestamp(true); const filename: string = branch - ? this._escapeFilename(`${branch}_${timestamp}.json`) + ? this.#escapeFilename(`${branch}_${timestamp}.json`) : `${timestamp}.json`; const filePath: string = path.join( - this._rushConfiguration.changesFolder, - ...this._changeFileData.packageName.split('/'), + this.#rushConfiguration.changesFolder, + ...this.#changeFileData.packageName.split('/'), filename ); return filePath; @@ -105,7 +105,7 @@ export class ChangeFile { * Gets the current time, formatted as YYYY-MM-DD-HH-MM * When useSeconds is true, the seconds are appended as well: YYYY-MM-DD-HH-MM-SS */ - private _getTimestamp(useSeconds: boolean = false): string | undefined { + #getTimestamp(useSeconds: boolean = false): string | undefined { // Create a date string with the current time // dateString === "2016-10-19T22:47:49.606Z" @@ -137,7 +137,7 @@ export class ChangeFile { return undefined; } - private _escapeFilename(filename: string, replacer: string = '-'): string { + #escapeFilename(filename: string, replacer: string = '-'): string { // Removes / ? < > \ : * | ", really anything that isn't a letter, number, '.' '_' or '-' const badCharacters: RegExp = /[^a-zA-Z0-9._-]/g; return filename.replace(badCharacters, replacer); diff --git a/libraries/rush-lib/src/api/CobuildConfiguration.ts b/libraries/rush-lib/src/api/CobuildConfiguration.ts index e397018ca44..b32caf977ee 100644 --- a/libraries/rush-lib/src/api/CobuildConfiguration.ts +++ b/libraries/rush-lib/src/api/CobuildConfiguration.ts @@ -76,9 +76,9 @@ export class CobuildConfiguration { */ public readonly cobuildWithoutCacheAllowed: boolean; - private _cobuildLockProvider: ICobuildLockProvider | undefined; - private readonly _cobuildLockProviderFactory: CobuildLockProviderFactory; - private readonly _cobuildJson: ICobuildJson; + #cobuildLockProvider: ICobuildLockProvider | undefined; + readonly #cobuildLockProviderFactory: CobuildLockProviderFactory; + readonly #cobuildJson: ICobuildJson; private constructor(options: ICobuildConfigurationOptions) { const { cobuildJson, cobuildLockProviderFactory, rushConfiguration } = options; @@ -91,8 +91,8 @@ export class CobuildConfiguration { this.cobuildWithoutCacheAllowed = rushConfiguration.experimentsConfiguration.configuration.allowCobuildWithoutCache ?? false; - this._cobuildLockProviderFactory = cobuildLockProviderFactory; - this._cobuildJson = cobuildJson; + this.#cobuildLockProviderFactory = cobuildLockProviderFactory; + this.#cobuildJson = cobuildJson; } /** @@ -127,25 +127,25 @@ export class CobuildConfiguration { public async createLockProviderAsync(terminal: ITerminal): Promise { if (this.cobuildFeatureEnabled) { terminal.writeLine(`Running cobuild (runner ${this.cobuildContextId}/${this.cobuildRunnerId})`); - const cobuildLockProvider: ICobuildLockProvider = await this._cobuildLockProviderFactory( - this._cobuildJson + const cobuildLockProvider: ICobuildLockProvider = await this.#cobuildLockProviderFactory( + this.#cobuildJson ); - this._cobuildLockProvider = cobuildLockProvider; - await this._cobuildLockProvider.connectAsync(); + this.#cobuildLockProvider = cobuildLockProvider; + await this.#cobuildLockProvider.connectAsync(); } } public async destroyLockProviderAsync(): Promise { if (this.cobuildFeatureEnabled) { - await this._cobuildLockProvider?.disconnectAsync(); + await this.#cobuildLockProvider?.disconnectAsync(); } } public getCobuildLockProvider(): ICobuildLockProvider { - if (!this._cobuildLockProvider) { + if (!this.#cobuildLockProvider) { throw new Error(`Cobuild lock provider has not been created`); } - return this._cobuildLockProvider; + return this.#cobuildLockProvider; } } diff --git a/libraries/rush-lib/src/api/CommandLineConfiguration.ts b/libraries/rush-lib/src/api/CommandLineConfiguration.ts index 53b5678f4ff..8ec4b5a3dee 100644 --- a/libraries/rush-lib/src/api/CommandLineConfiguration.ts +++ b/libraries/rush-lib/src/api/CommandLineConfiguration.ts @@ -233,7 +233,7 @@ export class CommandLineConfiguration { /** * A map of bulk command names to their corresponding synthetic phase identifiers */ - private readonly _syntheticPhasesByTranslatedBulkCommandName: Map = new Map(); + readonly #syntheticPhasesByTranslatedBulkCommandName: Map = new Map(); /** * Use CommandLineConfiguration.loadFromFile() @@ -332,7 +332,7 @@ export class CommandLineConfiguration { const safePhases: Set = new Set(); const cycleDetector: Set = new Set(); for (const phase of this.phases.values()) { - this._checkForPhaseSelfCycles(phase, cycleDetector, safePhases); + this.#checkForPhaseSelfCycles(phase, cycleDetector, safePhases); } } @@ -445,7 +445,7 @@ export class CommandLineConfiguration { case RushConstants.bulkCommandKind: { // Translate the bulk command into a phased command - normalizedCommand = this._translateBulkCommandToPhasedCommand(command); + normalizedCommand = this.#translateBulkCommandToPhasedCommand(command); break; } } @@ -480,7 +480,7 @@ export class CommandLineConfiguration { let buildCommand: Command | undefined = this.commands.get(RushConstants.buildCommandName); if (!buildCommand) { // If the build command was not specified in the config file, add the default build command - buildCommand = this._translateBulkCommandToPhasedCommand(DEFAULT_BUILD_COMMAND_JSON); + buildCommand = this.#translateBulkCommandToPhasedCommand(DEFAULT_BUILD_COMMAND_JSON); buildCommand.disableBuildCache = DEFAULT_BUILD_COMMAND_JSON.disableBuildCache; buildCommandPhases = buildCommand.phases; buildCommandOriginalPhases = buildCommand.originalPhases; @@ -545,7 +545,7 @@ export class CommandLineConfiguration { if (normalizedParameter.associatedCommands) { for (const associatedCommandName of normalizedParameter.associatedCommands) { const syntheticPhase: IPhase | undefined = - this._syntheticPhasesByTranslatedBulkCommandName.get(associatedCommandName); + this.#syntheticPhasesByTranslatedBulkCommandName.get(associatedCommandName); if (syntheticPhase) { // If this parameter was associated with a bulk command, include the association // with the synthetic phase @@ -598,7 +598,7 @@ export class CommandLineConfiguration { * @param phasesInPath The current path from the start node to `phase` * @param cycleFreePhases Phases that have already been fully walked and confirmed to not be in any cycles */ - private _checkForPhaseSelfCycles( + #checkForPhaseSelfCycles( phase: IPhase, phasesInPath: Set, cycleFreePhases: Set @@ -619,7 +619,7 @@ export class CommandLineConfiguration { ); } else { phasesInPath.add(dependency); - this._checkForPhaseSelfCycles(dependency, phasesInPath, cycleFreePhases); + this.#checkForPhaseSelfCycles(dependency, phasesInPath, cycleFreePhases); phasesInPath.delete(dependency); } } @@ -709,7 +709,7 @@ export class CommandLineConfiguration { (this.additionalPathFolders as string[]).unshift(pathFolder); } - private _translateBulkCommandToPhasedCommand(command: IBulkCommandJson): IPhasedCommandConfig { + #translateBulkCommandToPhasedCommand(command: IBulkCommandJson): IPhasedCommandConfig { const phaseName: string = command.name; const phase: IPhase = { name: phaseName, @@ -730,7 +730,7 @@ export class CommandLineConfiguration { } this.phases.set(phaseName, phase); - this._syntheticPhasesByTranslatedBulkCommandName.set(command.name, phase); + this.#syntheticPhasesByTranslatedBulkCommandName.set(command.name, phase); const phases: Set = new Set([phase]); diff --git a/libraries/rush-lib/src/api/CommonVersionsConfiguration.ts b/libraries/rush-lib/src/api/CommonVersionsConfiguration.ts index 42b74f7e961..3b023bb3ded 100644 --- a/libraries/rush-lib/src/api/CommonVersionsConfiguration.ts +++ b/libraries/rush-lib/src/api/CommonVersionsConfiguration.ts @@ -65,10 +65,10 @@ const _jsonSchema: JsonSchema = JsonSchema.fromLoadedObject(schemaJson); * @public */ export class CommonVersionsConfiguration { - private _preferredVersions: ProtectableMap; - private _allowedAlternativeVersions: ProtectableMap; - private _modified: boolean = false; - private _commonVersionsJsonHasEnsureConsistentVersionsProperty: boolean; + #preferredVersions: ProtectableMap; + #allowedAlternativeVersions: ProtectableMap; + #modified: boolean = false; + #commonVersionsJsonHasEnsureConsistentVersionsProperty: boolean; /** * Get the absolute file path of the common-versions.json file. @@ -126,10 +126,10 @@ export class CommonVersionsConfiguration { filePath: string, rushConfiguration: RushConfiguration | undefined ) { - this._preferredVersions = new ProtectableMap({ - onSet: this._onSetPreferredVersions.bind(this) + this.#preferredVersions = new ProtectableMap({ + onSet: this.#onSetPreferredVersions.bind(this) }); - this.preferredVersions = this._preferredVersions.protectedView; + this.preferredVersions = this.#preferredVersions.protectedView; if (commonVersionsJson && commonVersionsJson.implicitlyPreferredVersions !== undefined) { this.implicitlyPreferredVersions = commonVersionsJson.implicitlyPreferredVersions; @@ -137,10 +137,10 @@ export class CommonVersionsConfiguration { this.implicitlyPreferredVersions = undefined; } - this._allowedAlternativeVersions = new ProtectableMap({ - onSet: this._onSetAllowedAlternativeVersions.bind(this) + this.#allowedAlternativeVersions = new ProtectableMap({ + onSet: this.#onSetAllowedAlternativeVersions.bind(this) }); - this.allowedAlternativeVersions = this._allowedAlternativeVersions.protectedView; + this.allowedAlternativeVersions = this.#allowedAlternativeVersions.protectedView; const subspacesFeatureEnabled: boolean | undefined = rushConfiguration?.subspacesFeatureEnabled; const rushJsonEnsureConsistentVersions: boolean | undefined = @@ -165,7 +165,7 @@ export class CommonVersionsConfiguration { this.ensureConsistentVersions = commonVersionsEnsureConsistentVersions ?? rushJsonEnsureConsistentVersions ?? false; - this._commonVersionsJsonHasEnsureConsistentVersionsProperty = + this.#commonVersionsJsonHasEnsureConsistentVersionsProperty = commonVersionsEnsureConsistentVersions !== undefined; if (commonVersionsJson) { @@ -224,7 +224,7 @@ export class CommonVersionsConfiguration { public getPreferredVersionsHash(): string { // Sort so that the hash is stable const orderedPreferredVersions: Map = new Map( - this._preferredVersions.protectedView + this.#preferredVersions.protectedView ); Sort.sortMapKeys(orderedPreferredVersions); @@ -238,12 +238,12 @@ export class CommonVersionsConfiguration { * @deprecated Use {@link CommonVersionsConfiguration.saveAsync} method instead. */ public save(): boolean { - if (this._modified) { - JsonFile.save(this._serialize(), this.filePath, { + if (this.#modified) { + JsonFile.save(this.#serialize(), this.filePath, { updateExistingFile: true, ignoreUndefinedValues: true }); - this._modified = false; + this.#modified = false; return true; } @@ -254,12 +254,12 @@ export class CommonVersionsConfiguration { * Writes the "common-versions.json" file to disk, using the filename that was passed to loadFromFile(). */ public async saveAsync(): Promise { - if (this._modified) { - await JsonFile.saveAsync(this._serialize(), this.filePath, { + if (this.#modified) { + await JsonFile.saveAsync(this.#serialize(), this.filePath, { updateExistingFile: true, ignoreUndefinedValues: true }); - this._modified = false; + this.#modified = false; return true; } @@ -275,38 +275,38 @@ export class CommonVersionsConfiguration { return allPreferredVersions; } - private _onSetPreferredVersions( + #onSetPreferredVersions( source: ProtectableMap, key: string, value: string ): string { PackageNameParsers.permissive.validate(key); - this._modified = true; + this.#modified = true; return value; } - private _onSetAllowedAlternativeVersions( + #onSetAllowedAlternativeVersions( source: ProtectableMap, key: string, value: string[] ): string[] { PackageNameParsers.permissive.validate(key); - this._modified = true; + this.#modified = true; return value; } - private _serialize(): ICommonVersionsJson { + #serialize(): ICommonVersionsJson { let preferredVersions: ICommonVersionsJsonVersionMap | undefined; - if (this._preferredVersions.size) { + if (this.#preferredVersions.size) { preferredVersions = _serializeTable(this.preferredVersions); } let allowedAlternativeVersions: ICommonVersionsJsonVersionsMap | undefined; - if (this._allowedAlternativeVersions.size) { + if (this.#allowedAlternativeVersions.size) { allowedAlternativeVersions = _serializeTable( this.allowedAlternativeVersions ) as ICommonVersionsJsonVersionsMap; @@ -317,7 +317,7 @@ export class CommonVersionsConfiguration { preferredVersions, implicitlyPreferredVersions: this.implicitlyPreferredVersions, allowedAlternativeVersions, - ensureConsistentVersions: this._commonVersionsJsonHasEnsureConsistentVersionsProperty + ensureConsistentVersions: this.#commonVersionsJsonHasEnsureConsistentVersionsProperty ? this.ensureConsistentVersions : undefined }; diff --git a/libraries/rush-lib/src/api/CustomTipsConfiguration.ts b/libraries/rush-lib/src/api/CustomTipsConfiguration.ts index 8bc12a439e8..b416496f1a8 100644 --- a/libraries/rush-lib/src/api/CustomTipsConfiguration.ts +++ b/libraries/rush-lib/src/api/CustomTipsConfiguration.ts @@ -311,7 +311,7 @@ export class CustomTipsConfiguration { const severityOfOriginalMessage: CustomTipSeverity = CustomTipsConfiguration.customTipRegistry[tipId].severity; - this._writeMessageWithPipes(terminal, severityOfOriginalMessage, tipId); + this.#writeMessageWithPipes(terminal, severityOfOriginalMessage, tipId); } /** @@ -322,7 +322,7 @@ export class CustomTipsConfiguration { * @internal */ public _showInfoTip(terminal: ITerminal, tipId: CustomTipId): void { - this._writeMessageWithPipes(terminal, CustomTipSeverity.Info, tipId); + this.#writeMessageWithPipes(terminal, CustomTipSeverity.Info, tipId); } /** @@ -333,7 +333,7 @@ export class CustomTipsConfiguration { * @internal */ public _showWarningTip(terminal: ITerminal, tipId: CustomTipId): void { - this._writeMessageWithPipes(terminal, CustomTipSeverity.Warning, tipId); + this.#writeMessageWithPipes(terminal, CustomTipSeverity.Warning, tipId); } /** @@ -344,10 +344,10 @@ export class CustomTipsConfiguration { * @internal */ public _showErrorTip(terminal: ITerminal, tipId: CustomTipId): void { - this._writeMessageWithPipes(terminal, CustomTipSeverity.Error, tipId); + this.#writeMessageWithPipes(terminal, CustomTipSeverity.Error, tipId); } - private _writeMessageWithPipes(terminal: ITerminal, severity: CustomTipSeverity, tipId: CustomTipId): void { + #writeMessageWithPipes(terminal: ITerminal, severity: CustomTipSeverity, tipId: CustomTipId): void { const customTipJsonItem: ICustomTipItemJson | undefined = this.providedCustomTipsByTipId.get(tipId); if (customTipJsonItem) { let writeFunction: diff --git a/libraries/rush-lib/src/api/EventHooks.ts b/libraries/rush-lib/src/api/EventHooks.ts index d53fdd365ad..26395ca73a5 100644 --- a/libraries/rush-lib/src/api/EventHooks.ts +++ b/libraries/rush-lib/src/api/EventHooks.ts @@ -43,17 +43,17 @@ export enum Event { * @beta */ export class EventHooks { - private _hooks: Map; + #hooks: Map; /** * @internal */ public constructor(eventHooksJson: IEventHooksJson) { - this._hooks = new Map(); + this.#hooks = new Map(); for (const [name, eventHooks] of Object.entries(eventHooksJson)) { const eventName: Event | undefined = Enum.tryGetValueByKey(Event, name); if (eventName) { - this._hooks.set(eventName, [...eventHooks]); + this.#hooks.set(eventName, [...eventHooks]); } } } @@ -63,6 +63,6 @@ export class EventHooks { * @param event - Rush event */ public get(event: Event): string[] { - return this._hooks.get(event) || []; + return this.#hooks.get(event) || []; } } diff --git a/libraries/rush-lib/src/api/LastInstallFlag.ts b/libraries/rush-lib/src/api/LastInstallFlag.ts index a0af3df9dd8..61e29ccc040 100644 --- a/libraries/rush-lib/src/api/LastInstallFlag.ts +++ b/libraries/rush-lib/src/api/LastInstallFlag.ts @@ -90,7 +90,7 @@ export class LastInstallFlag extends FlagFile> { * Returns true if the file exists and the contents match the current state. */ public override async isValidAsync(): Promise { - return await this._isValidAsync(false, {}); + return await this.#isValidAsync(false, {}); } /** @@ -102,10 +102,10 @@ export class LastInstallFlag extends FlagFile> { public async checkValidAndReportStoreIssuesAsync( options: ILockfileValidityCheckOptions & { rushVerb: string } ): Promise { - return this._isValidAsync(true, options); + return this.#isValidAsync(true, options); } - private async _isValidAsync( + async #isValidAsync( checkValidAndReportStoreIssues: boolean, { rushVerb = 'update', statePropertiesToIgnore }: ILockfileValidityCheckOptions = {} ): Promise { diff --git a/libraries/rush-lib/src/api/PackageJsonEditor.ts b/libraries/rush-lib/src/api/PackageJsonEditor.ts index c9baeb73e0f..a19c06658ff 100644 --- a/libraries/rush-lib/src/api/PackageJsonEditor.ts +++ b/libraries/rush-lib/src/api/PackageJsonEditor.ts @@ -22,29 +22,29 @@ export enum DependencyType { * @public */ export class PackageJsonDependency { - private _version: string; - private _onChange: () => void; + #version: string; + #onChange: () => void; public readonly name: string; public readonly dependencyType: DependencyType; public constructor(name: string, version: string, type: DependencyType, onChange: () => void) { this.name = name; - this._version = version; + this.#version = version; this.dependencyType = type; - this._onChange = onChange; + this.#onChange = onChange; } public get version(): string { - return this._version; + return this.#version; } public setVersion(newVersion: string): void { if (!semver.valid(newVersion) && !semver.validRange(newVersion)) { throw new Error(`Cannot set version to invalid value: "${newVersion}"`); } - this._version = newVersion; - this._onChange(); + this.#version = newVersion; + this.#onChange(); } } @@ -52,19 +52,19 @@ export class PackageJsonDependency { * @public */ export class PackageJsonDependencyMeta { - private _injected: boolean; - private _onChange: () => void; + #injected: boolean; + #onChange: () => void; public readonly name: string; public constructor(name: string, injected: boolean, onChange: () => void) { this.name = name; - this._injected = injected; - this._onChange = onChange; + this.#injected = injected; + this.#onChange = onChange; } public get injected(): boolean { - return this._injected; + return this.#injected; } } @@ -72,20 +72,20 @@ export class PackageJsonDependencyMeta { * @public */ export class PackageJsonEditor { - private readonly _dependencies: Map; + readonly #dependencies: Map; // NOTE: The "devDependencies" section is tracked separately because sometimes people // will specify a specific version for development, while *also* specifying a broader // SemVer range in one of the other fields for consumers. Thus "dependencies", "optionalDependencies", // and "peerDependencies" are mutually exclusive, but "devDependencies" is not. - private readonly _devDependencies: Map; + readonly #devDependencies: Map; - private readonly _dependenciesMeta: Map; + readonly #dependenciesMeta: Map; // NOTE: The "resolutions" field is a yarn specific feature that controls package // resolution override within yarn. - private readonly _resolutions: Map; - private _modified: boolean; - private _sourceData: IPackageJson; + readonly #resolutions: Map; + #modified: boolean; + #sourceData: IPackageJson; public readonly filePath: string; @@ -94,8 +94,8 @@ export class PackageJsonEditor { */ protected constructor(filepath: string, data: IPackageJson) { this.filePath = filepath; - this._sourceData = data; - this._modified = false; + this.#sourceData = data; + this.#modified = false; const { dependencies = {}, @@ -106,7 +106,7 @@ export class PackageJsonEditor { dependenciesMeta = {} } = data; - const _onChange: () => void = this._onChange.bind(this); + const _onChange: () => void = this.#onChange.bind(this); const optionalDependenciesSet: Set = new Set(Object.keys(optionalDependencies)); const peerDependenciesSet: Set = new Set(Object.keys(peerDependencies)); @@ -154,27 +154,27 @@ export class PackageJsonEditor { new PackageJsonDependency(packageName, version, DependencyType.Peer, _onChange) ]); - this._dependencies = new Map([ + this.#dependencies = new Map([ ...dependenciesMapEntries, ...optionalDependenciesMapEntries, ...peerDependenciesMapEntries ]); - this._devDependencies = new Map( + this.#devDependencies = new Map( Object.entries(devDependencies).map(([packageName, version]) => [ packageName, new PackageJsonDependency(packageName, version, DependencyType.Dev, _onChange) ]) ); - this._resolutions = new Map( + this.#resolutions = new Map( Object.entries(resolutions).map(([packageName, version]) => [ packageName, new PackageJsonDependency(packageName, version, DependencyType.YarnResolutions, _onChange) ]) ); - this._dependenciesMeta = new Map( + this.#dependenciesMeta = new Map( Object.entries(dependenciesMeta).map(([packageName, { injected = false }]) => [ packageName, new PackageJsonDependencyMeta(packageName, injected, _onChange) @@ -182,8 +182,8 @@ export class PackageJsonEditor { ); // (Do not sort this._resolutions because order may be significant; the RFC is unclear about that.) - Sort.sortMapKeys(this._dependencies); - Sort.sortMapKeys(this._devDependencies); + Sort.sortMapKeys(this.#dependencies); + Sort.sortMapKeys(this.#devDependencies); } catch (e) { throw new Error(`Error loading "${filepath}": ${(e as Error).message}`); } @@ -207,32 +207,32 @@ export class PackageJsonEditor { } public get name(): string { - return this._sourceData.name; + return this.#sourceData.name; } public get version(): string { - return this._sourceData.version; + return this.#sourceData.version; } /** * The list of dependencies of type DependencyType.Regular, DependencyType.Optional, or DependencyType.Peer. */ public get dependencyList(): ReadonlyArray { - return [...this._dependencies.values()]; + return [...this.#dependencies.values()]; } /** * The list of dependencies of type DependencyType.Dev. */ public get devDependencyList(): ReadonlyArray { - return [...this._devDependencies.values()]; + return [...this.#devDependencies.values()]; } /** * The list of dependenciesMeta in package.json. */ public get dependencyMetaList(): ReadonlyArray { - return [...this._dependenciesMeta.values()]; + return [...this.#dependenciesMeta.values()]; } /** @@ -243,15 +243,15 @@ export class PackageJsonEditor { * | 0000-selective-versions-resolutions.md RFC} for details. */ public get resolutionsList(): ReadonlyArray { - return [...this._resolutions.values()]; + return [...this.#resolutions.values()]; } public tryGetDependency(packageName: string): PackageJsonDependency | undefined { - return this._dependencies.get(packageName); + return this.#dependencies.get(packageName); } public tryGetDevDependency(packageName: string): PackageJsonDependency | undefined { - return this._devDependencies.get(packageName); + return this.#devDependencies.get(packageName); } public addOrUpdateDependency( @@ -263,7 +263,7 @@ export class PackageJsonEditor { packageName, newVersion, dependencyType, - this._onChange.bind(this) + this.#onChange.bind(this) ); // Rush collapses everything that isn't a devDependency into the dependencies @@ -272,17 +272,17 @@ export class PackageJsonEditor { case DependencyType.Regular: case DependencyType.Optional: case DependencyType.Peer: { - this._dependencies.set(packageName, dependency); + this.#dependencies.set(packageName, dependency); break; } case DependencyType.Dev: { - this._devDependencies.set(packageName, dependency); + this.#devDependencies.set(packageName, dependency); break; } case DependencyType.YarnResolutions: { - this._resolutions.set(packageName, dependency); + this.#resolutions.set(packageName, dependency); break; } @@ -291,7 +291,7 @@ export class PackageJsonEditor { } } - this._modified = true; + this.#modified = true; } public removeDependency(packageName: string, dependencyType: DependencyType): void { @@ -299,17 +299,17 @@ export class PackageJsonEditor { case DependencyType.Regular: case DependencyType.Optional: case DependencyType.Peer: { - this._dependencies.delete(packageName); + this.#dependencies.delete(packageName); break; } case DependencyType.Dev: { - this._devDependencies.delete(packageName); + this.#devDependencies.delete(packageName); break; } case DependencyType.YarnResolutions: { - this._resolutions.delete(packageName); + this.#resolutions.delete(packageName); break; } @@ -318,17 +318,17 @@ export class PackageJsonEditor { } } - this._modified = true; + this.#modified = true; } /** * @deprecated Use {@link PackageJsonEditor.saveIfModifiedAsync} method instead. */ public saveIfModified(): boolean { - if (this._modified) { - this._modified = false; - this._sourceData = this._normalize(this._sourceData); - JsonFile.save(this._sourceData, this.filePath, { + if (this.#modified) { + this.#modified = false; + this.#sourceData = this.#normalize(this.#sourceData); + JsonFile.save(this.#sourceData, this.filePath, { updateExistingFile: true, jsonSyntax: JsonSyntax.Strict }); @@ -339,10 +339,10 @@ export class PackageJsonEditor { } public async saveIfModifiedAsync(): Promise { - if (this._modified) { - this._modified = false; - this._sourceData = this._normalize(this._sourceData); - await JsonFile.saveAsync(this._sourceData, this.filePath, { + if (this.#modified) { + this.#modified = false; + this.#sourceData = this.#normalize(this.#sourceData); + await JsonFile.saveAsync(this.#sourceData, this.filePath, { updateExistingFile: true, jsonSyntax: JsonSyntax.Strict }); @@ -360,13 +360,13 @@ export class PackageJsonEditor { */ public saveToObject(): IPackageJson { // Only normalize if we need to - const sourceData: IPackageJson = this._modified ? this._normalize(this._sourceData) : this._sourceData; + const sourceData: IPackageJson = this.#modified ? this.#normalize(this.#sourceData) : this.#sourceData; // Provide a clone to avoid reference back to the original data object return cloneDeep(sourceData); } - private _onChange(): void { - this._modified = true; + #onChange(): void { + this.#modified = true; } /** @@ -375,7 +375,7 @@ export class PackageJsonEditor { * it will still need to be deep-cloned to avoid propogating changes back to the * original dataset. */ - private _normalize(source: IPackageJson): IPackageJson { + #normalize(source: IPackageJson): IPackageJson { const normalizedData: IPackageJson = { ...source }; delete normalizedData.dependencies; delete normalizedData.optionalDependencies; @@ -383,10 +383,10 @@ export class PackageJsonEditor { delete normalizedData.devDependencies; delete normalizedData.resolutions; - const keys: string[] = [...this._dependencies.keys()].sort(); + const keys: string[] = [...this.#dependencies.keys()].sort(); for (const packageName of keys) { - const { dependencyType, name, version }: PackageJsonDependency = this._dependencies.get(packageName)!; + const { dependencyType, name, version }: PackageJsonDependency = this.#dependencies.get(packageName)!; switch (dependencyType) { case DependencyType.Regular: { @@ -424,9 +424,9 @@ export class PackageJsonEditor { } } - const devDependenciesKeys: string[] = [...this._devDependencies.keys()].sort(); + const devDependenciesKeys: string[] = [...this.#devDependencies.keys()].sort(); for (const packageName of devDependenciesKeys) { - const { name, version }: PackageJsonDependency = this._devDependencies.get(packageName)!; + const { name, version }: PackageJsonDependency = this.#devDependencies.get(packageName)!; if (!normalizedData.devDependencies) { normalizedData.devDependencies = {}; @@ -436,8 +436,8 @@ export class PackageJsonEditor { } // (Do not sort this._resolutions because order may be significant; the RFC is unclear about that.) - for (const packageName of this._resolutions.keys()) { - const { name, version }: PackageJsonDependency = this._resolutions.get(packageName)!; + for (const packageName of this.#resolutions.keys()) { + const { name, version }: PackageJsonDependency = this.#resolutions.get(packageName)!; if (!normalizedData.resolutions) { normalizedData.resolutions = {}; diff --git a/libraries/rush-lib/src/api/RushConfiguration.ts b/libraries/rush-lib/src/api/RushConfiguration.ts index 527ec92be93..86ae18f6778 100644 --- a/libraries/rush-lib/src/api/RushConfiguration.ts +++ b/libraries/rush-lib/src/api/RushConfiguration.ts @@ -227,7 +227,7 @@ const _jsonSchema: JsonSchema = JsonSchema.fromLoadedObject(schemaJson); * @public */ export class RushConfiguration { - private readonly _pathTrees: Map>; + readonly #pathTrees: Map>; /** * @internal @@ -235,17 +235,17 @@ export class RushConfiguration { public _currentVariantJsonLoadingPromise: Promise | undefined; // Lazily loaded when the projects() getter is called. - private _projects: RushConfigurationProject[] | undefined; + #projects: RushConfigurationProject[] | undefined; // Lazily loaded when the projectsByName() getter is called. - private _projectsByName: Map | undefined; + #projectsByName: Map | undefined; // Lazily loaded when the projectsByTag() getter is called. - private _projectsByTag: ReadonlyMap> | undefined; + #projectsByTag: ReadonlyMap> | undefined; // subspaceName -> subspace - private readonly _subspacesByName: Map; - private readonly _subspaces: Subspace[] = []; + readonly #subspacesByName: Map; + readonly #subspaces: Subspace[] = []; /** * The name of the package manager being used to install dependencies @@ -663,7 +663,7 @@ export class RushConfiguration { this.subspacesConfiguration = SubspacesConfiguration.tryLoadFromDefaultLocation(this); this.subspacesFeatureEnabled = !!this.subspacesConfiguration?.subspacesEnabled; - this._subspacesByName = new Map(); + this.#subspacesByName = new Map(); const experimentsConfigFile: string = path.join( this.commonRushConfigFolder, @@ -880,14 +880,14 @@ export class RushConfiguration { this.variants = variants; - this._pathTrees = new Map(); + this.#pathTrees = new Map(); } - private _initializeAndValidateLocalProjects(): void { - this._projects = []; - this._projectsByName = new Map(); - this._subspacesByName.clear(); - this._subspaces.length = 0; + #initializeAndValidateLocalProjects(): void { + this.#projects = []; + this.#projectsByName = new Map(); + this.#subspacesByName.clear(); + this.#subspaces.length = 0; // Build the subspaces map const subspaceNames: string[] = []; @@ -910,10 +910,10 @@ export class RushConfiguration { rushConfiguration: this, splitWorkspaceCompatibility }); - this._subspacesByName.set(subspaceName, subspace); - this._subspaces.push(subspace); + this.#subspacesByName.set(subspaceName, subspace); + this.#subspaces.push(subspace); } - const defaultSubspace: Subspace | undefined = this._subspacesByName.get( + const defaultSubspace: Subspace | undefined = this.#subspacesByName.get( RushConstants.defaultSubspaceName ); if (!defaultSubspace) { @@ -938,7 +938,7 @@ export class RushConfiguration { let subspace: Subspace | undefined = undefined; if (this.subspacesFeatureEnabled) { if (projectJson.subspaceName) { - subspace = this._subspacesByName.get(projectJson.subspaceName); + subspace = this.#subspacesByName.get(projectJson.subspaceName); if (subspace === undefined) { throw new Error( `The project "${projectJson.packageName}" in ${RushConstants.rushJsonFilename} references` + @@ -960,17 +960,17 @@ export class RushConfiguration { }); subspace._addProject(project); - this._projects.push(project); - if (this._projectsByName.has(project.packageName)) { + this.#projects.push(project); + if (this.#projectsByName.has(project.packageName)) { throw new Error( `The project name "${project.packageName}" was specified more than once` + ` in the ${RushConstants.rushJsonFilename} configuration file.` ); } - this._projectsByName.set(project.packageName, project); + this.#projectsByName.set(project.packageName, project); } - for (const project of this._projects) { + for (const project of this.#projects) { project.decoupledLocalDependencies.forEach((decoupledLocalDependency: string) => { if (!this.getProjectByName(decoupledLocalDependency)) { throw new Error( @@ -1191,11 +1191,11 @@ export class RushConfiguration { } public get projects(): RushConfigurationProject[] { - if (!this._projects) { - this._initializeAndValidateLocalProjects(); + if (!this.#projects) { + this.#initializeAndValidateLocalProjects(); } - return this._projects!; + return this.#projects!; } /** @@ -1203,8 +1203,8 @@ export class RushConfiguration { */ public get defaultSubspace(): Subspace { // TODO: Enable the default subspace to be obtained without initializing the full set of all projects - if (!this._projects) { - this._initializeAndValidateLocalProjects(); + if (!this.#projects) { + this.#initializeAndValidateLocalProjects(); } const defaultSubspace: Subspace | undefined = this.tryGetSubspace(RushConstants.defaultSubspaceName); if (!defaultSubspace) { @@ -1218,20 +1218,20 @@ export class RushConfiguration { * @beta */ public get subspaces(): readonly Subspace[] { - if (!this._projects) { - this._initializeAndValidateLocalProjects(); + if (!this.#projects) { + this.#initializeAndValidateLocalProjects(); } - return this._subspaces; + return this.#subspaces; } /** * @beta */ public tryGetSubspace(subspaceName: string): Subspace | undefined { - if (!this._projects) { - this._initializeAndValidateLocalProjects(); + if (!this.#projects) { + this.#initializeAndValidateLocalProjects(); } - const subspace: Subspace | undefined = this._subspacesByName.get(subspaceName); + const subspace: Subspace | undefined = this.#subspacesByName.get(subspaceName); if (!subspace) { // If the name is not even valid, that is more important information than if the subspace doesn't exist SubspacesConfiguration.requireValidSubspaceName( @@ -1258,8 +1258,8 @@ export class RushConfiguration { * @beta */ public getSubspacesForProjects(projects: Iterable): ReadonlySet { - if (!this._projects) { - this._initializeAndValidateLocalProjects(); + if (!this.#projects) { + this.#initializeAndValidateLocalProjects(); } const subspaceSet: Set = new Set(); @@ -1274,11 +1274,11 @@ export class RushConfiguration { * @beta */ public get projectsByName(): ReadonlyMap { - if (!this._projectsByName) { - this._initializeAndValidateLocalProjects(); + if (!this.#projectsByName) { + this.#initializeAndValidateLocalProjects(); } - return this._projectsByName!; + return this.#projectsByName!; } /** @@ -1286,7 +1286,7 @@ export class RushConfiguration { * @beta */ public get projectsByTag(): ReadonlyMap> { - if (!this._projectsByTag) { + if (!this.#projectsByTag) { const projectsByTag: Map> = new Map(); for (const project of this.projects) { for (const tag of project.tags) { @@ -1297,9 +1297,9 @@ export class RushConfiguration { collection.add(project); } } - this._projectsByTag = projectsByTag; + this.#projectsByTag = projectsByTag; } - return this._projectsByTag; + return this.#projectsByTag; } /** @@ -1324,7 +1324,7 @@ export class RushConfiguration { */ public async getCurrentlyInstalledVariantAsync(): Promise { if (!this._currentVariantJsonLoadingPromise) { - this._currentVariantJsonLoadingPromise = this._loadCurrentVariantJsonAsync(); + this._currentVariantJsonLoadingPromise = this.#loadCurrentVariantJsonAsync(); } return (await this._currentVariantJsonLoadingPromise)?.variant ?? undefined; @@ -1445,9 +1445,9 @@ export class RushConfiguration { * @beta */ public getProjectLookupForRoot(rootPath: string): LookupByPath { - let pathTree: LookupByPath | undefined = this._pathTrees.get(rootPath); + let pathTree: LookupByPath | undefined = this.#pathTrees.get(rootPath); if (!pathTree) { - this._pathTrees.set(rootPath, (pathTree = new LookupByPath())); + this.#pathTrees.set(rootPath, (pathTree = new LookupByPath())); for (const project of this.projects) { const relativePath: string = path.relative(rootPath, project.projectFolder); pathTree.setItemFromSegments(LookupByPath.iteratePathSegments(relativePath, path.sep), project); @@ -1474,7 +1474,7 @@ export class RushConfiguration { return undefined; } - private async _loadCurrentVariantJsonAsync(): Promise { + async #loadCurrentVariantJsonAsync(): Promise { try { return await JsonFile.loadAsync(this.currentVariantJsonFilePath); } catch (e) { diff --git a/libraries/rush-lib/src/api/RushConfigurationProject.ts b/libraries/rush-lib/src/api/RushConfigurationProject.ts index e80dce4bbde..505ce8cdcc3 100644 --- a/libraries/rush-lib/src/api/RushConfigurationProject.ts +++ b/libraries/rush-lib/src/api/RushConfigurationProject.ts @@ -66,12 +66,12 @@ export interface IRushConfigurationProjectOptions { * @public */ export class RushConfigurationProject { - private readonly _shouldPublish: boolean; + readonly #shouldPublish: boolean; - private _versionPolicy: VersionPolicy | undefined = undefined; - private _dependencyProjects: Set | undefined = undefined; - private _consumingProjects: Set | undefined = undefined; - private _packageJson: IPackageJson; + #versionPolicy: VersionPolicy | undefined = undefined; + #dependencyProjects: Set | undefined = undefined; + #consumingProjects: Set | undefined = undefined; + #packageJson: IPackageJson; /** * The name of the NPM package. An error is reported if this name is not @@ -139,7 +139,7 @@ export class RushConfigurationProject { * The parsed NPM "package.json" file from projectFolder. */ public get packageJson(): IPackageJson { - return this._packageJson; + return this.#packageJson; } /** @@ -242,7 +242,7 @@ export class RushConfigurationProject { try { const packageJsonText: string = FileSystem.readFile(packageJsonFilename); // JSON.parse is native and runs in less than 1/2 the time of jju.parse. package.json is required to be strict JSON by NodeJS. - this._packageJson = JSON.parse(packageJsonText); + this.#packageJson = JSON.parse(packageJsonText); } catch (error) { if (FileSystem.isNotExistError(error as Error)) { throw new Error(`Could not find package.json for ${packageName} at ${packageJsonFilename}`); @@ -300,8 +300,8 @@ export class RushConfigurationProject { filename: packageJsonFilename, onSaved: (newObject) => { // Just update the in-memory copy, don't bother doing the validation again - this._packageJson = newObject; - this._dependencyProjects = undefined; // Reset the cached dependency projects + this.#packageJson = newObject; + this.#dependencyProjects = undefined; // Reset the cached dependency projects } }); @@ -324,11 +324,11 @@ export class RushConfigurationProject { this.decoupledLocalDependencies.add(cyclicDependencyProject); } } - this._shouldPublish = !!projectJson.shouldPublish; + this.#shouldPublish = !!projectJson.shouldPublish; this.skipRushCheck = !!projectJson.skipRushCheck; this.versionPolicyName = projectJson.versionPolicyName; - if (this._shouldPublish && this.packageJson.private) { + if (this.#shouldPublish && this.packageJson.private) { throw new Error( `The project "${packageName}" specifies "shouldPublish": true, ` + `but the package.json file specifies "private": true.` @@ -402,9 +402,9 @@ export class RushConfigurationProject { * referenced from this project. */ public get dependencyProjects(): ReadonlySet { - let dependencyProjects: Set | undefined = this._dependencyProjects; + let dependencyProjects: Set | undefined = this.#dependencyProjects; if (!dependencyProjects) { - this._dependencyProjects = dependencyProjects = new Set(); + this.#dependencyProjects = dependencyProjects = new Set(); const { packageJson } = this; for (const dependencySet of [ packageJson.dependencies, @@ -454,23 +454,23 @@ export class RushConfigurationProject { * graph to find all projects which will be impacted by changes to this project. */ public get consumingProjects(): ReadonlySet { - if (!this._consumingProjects) { + if (!this.#consumingProjects) { // Force initialize all dependency relationships // This needs to operate on every project in the set because the relationships are only specified // in the consuming project const { projects } = this.rushConfiguration; for (const project of projects) { - project._consumingProjects = new Set(); + project.#consumingProjects = new Set(); } for (const project of projects) { for (const dependency of project.dependencyProjects) { - dependency._consumingProjects!.add(project); + dependency.#consumingProjects!.add(project); } } } - return this._consumingProjects!; + return this.#consumingProjects!; } /** @@ -479,7 +479,7 @@ export class RushConfigurationProject { * should be published during `rush publish`. */ public get shouldPublish(): boolean { - return this._shouldPublish || !!this.versionPolicyName; + return this.#shouldPublish || !!this.versionPolicyName; } /** @@ -487,14 +487,14 @@ export class RushConfigurationProject { * @beta */ public get versionPolicy(): VersionPolicy | undefined { - if (!this._versionPolicy) { + if (!this.#versionPolicy) { if (this.versionPolicyName && this.rushConfiguration.versionPolicyConfiguration) { - this._versionPolicy = this.rushConfiguration.versionPolicyConfiguration.getVersionPolicy( + this.#versionPolicy = this.rushConfiguration.versionPolicyConfiguration.getVersionPolicy( this.versionPolicyName ); } } - return this._versionPolicy; + return this.#versionPolicy; } /** diff --git a/libraries/rush-lib/src/api/RushPluginsConfiguration.ts b/libraries/rush-lib/src/api/RushPluginsConfiguration.ts index 9d3908fb601..7d67b2b6ebb 100644 --- a/libraries/rush-lib/src/api/RushPluginsConfiguration.ts +++ b/libraries/rush-lib/src/api/RushPluginsConfiguration.ts @@ -24,18 +24,18 @@ interface IRushPluginsConfigurationJson { const _jsonSchema: JsonSchema = JsonSchema.fromLoadedObject(schemaJson); export class RushPluginsConfiguration { - private _jsonFilename: string; + #jsonFilename: string; public readonly configuration: Readonly; public constructor(jsonFilename: string) { - this._jsonFilename = jsonFilename; + this.#jsonFilename = jsonFilename; this.configuration = { plugins: [] }; - if (FileSystem.exists(this._jsonFilename)) { - this.configuration = JsonFile.loadAndValidate(this._jsonFilename, _jsonSchema); + if (FileSystem.exists(this.#jsonFilename)) { + this.configuration = JsonFile.loadAndValidate(this.#jsonFilename, _jsonSchema); } } } diff --git a/libraries/rush-lib/src/api/RushProjectConfiguration.ts b/libraries/rush-lib/src/api/RushProjectConfiguration.ts index 50f71ce1785..ad877338b9b 100644 --- a/libraries/rush-lib/src/api/RushProjectConfiguration.ts +++ b/libraries/rush-lib/src/api/RushProjectConfiguration.ts @@ -299,7 +299,7 @@ export class RushProjectConfiguration { public readonly operationSettingsByOperationName: ReadonlyMap>; - private readonly _validationCache: WeakSet = new WeakSet(); + readonly #validationCache: WeakSet = new WeakSet(); private constructor( project: RushConfigurationProject, @@ -321,7 +321,7 @@ export class RushProjectConfiguration { */ public validatePhaseConfiguration(phases: Iterable, terminal: ITerminal): void { // Don't repeatedly validate the same set of phases for the same project. - if (this._validationCache.has(phases)) { + if (this.#validationCache.has(phases)) { return; } @@ -397,7 +397,7 @@ export class RushProjectConfiguration { } } - this._validationCache.add(phases); + this.#validationCache.add(phases); if (hasErrors) { throw new AlreadyReportedError(); diff --git a/libraries/rush-lib/src/api/SaveCallbackPackageJsonEditor.ts b/libraries/rush-lib/src/api/SaveCallbackPackageJsonEditor.ts index cf4f5028b47..9b319a4387c 100644 --- a/libraries/rush-lib/src/api/SaveCallbackPackageJsonEditor.ts +++ b/libraries/rush-lib/src/api/SaveCallbackPackageJsonEditor.ts @@ -12,12 +12,12 @@ export interface IFromObjectOptions { } export class SaveCallbackPackageJsonEditor extends PackageJsonEditor { - private readonly _onSaved: ((newObject: IPackageJson) => void) | undefined; + readonly #onSaved: ((newObject: IPackageJson) => void) | undefined; private constructor(options: IFromObjectOptions) { super(options.filename, options.object); - this._onSaved = options.onSaved; + this.#onSaved = options.onSaved; } public static fromObjectWithCallback(options: IFromObjectOptions): SaveCallbackPackageJsonEditor { @@ -26,8 +26,8 @@ export class SaveCallbackPackageJsonEditor extends PackageJsonEditor { public override async saveIfModifiedAsync(): Promise { const modified: boolean = await super.saveIfModifiedAsync(); - if (this._onSaved) { - this._onSaved(this.saveToObject()); + if (this.#onSaved) { + this.#onSaved(this.saveToObject()); } return modified; diff --git a/libraries/rush-lib/src/api/Subspace.ts b/libraries/rush-lib/src/api/Subspace.ts index 49f00faa943..0f9583f9f7f 100644 --- a/libraries/rush-lib/src/api/Subspace.ts +++ b/libraries/rush-lib/src/api/Subspace.ts @@ -44,21 +44,21 @@ interface IPackageJsonLite extends Omit {} */ export class Subspace { public readonly subspaceName: string; - private readonly _rushConfiguration: RushConfiguration; - private readonly _projects: RushConfigurationProject[] = []; - private readonly _splitWorkspaceCompatibility: boolean; - private _commonVersionsConfiguration: CommonVersionsConfiguration | undefined = undefined; + readonly #rushConfiguration: RushConfiguration; + readonly #projects: RushConfigurationProject[] = []; + readonly #splitWorkspaceCompatibility: boolean; + #commonVersionsConfiguration: CommonVersionsConfiguration | undefined = undefined; - private _detail: ISubspaceDetail | undefined; + #detail: ISubspaceDetail | undefined; - private _cachedPnpmOptions: PnpmOptionsConfiguration | undefined = undefined; + #cachedPnpmOptions: PnpmOptionsConfiguration | undefined = undefined; // If true, then _cachedPnpmOptions has been initialized. - private _cachedPnpmOptionsInitialized: boolean = false; + #cachedPnpmOptionsInitialized: boolean = false; public constructor(options: ISubspaceOptions) { this.subspaceName = options.subspaceName; - this._rushConfiguration = options.rushConfiguration; - this._splitWorkspaceCompatibility = options.splitWorkspaceCompatibility; + this.#rushConfiguration = options.rushConfiguration; + this.#splitWorkspaceCompatibility = options.splitWorkspaceCompatibility; } /** @@ -66,7 +66,7 @@ export class Subspace { * @beta */ public getProjects(): RushConfigurationProject[] { - return this._projects; + return this.#projects; } /** @@ -74,19 +74,19 @@ export class Subspace { * @beta */ public getPnpmOptions(): PnpmOptionsConfiguration | undefined { - if (!this._cachedPnpmOptionsInitialized) { + if (!this.#cachedPnpmOptionsInitialized) { // Calculate these outside the try/catch block since their error messages shouldn't be annotated: const subspaceTempFolder: string = this.getSubspaceTempFolderPath(); try { - this._cachedPnpmOptions = PnpmOptionsConfiguration.loadFromJsonFileOrThrow( + this.#cachedPnpmOptions = PnpmOptionsConfiguration.loadFromJsonFileOrThrow( this.getPnpmConfigFilePath(), subspaceTempFolder ); - this._cachedPnpmOptionsInitialized = true; + this.#cachedPnpmOptionsInitialized = true; } catch (e) { if (FileSystem.isNotExistError(e as Error)) { - this._cachedPnpmOptions = undefined; - this._cachedPnpmOptionsInitialized = true; + this.#cachedPnpmOptions = undefined; + this.#cachedPnpmOptionsInitialized = true; } else { throw new Error( `The subspace "${this.subspaceName}" has an invalid pnpm-config.json file:\n` + e.message @@ -94,12 +94,12 @@ export class Subspace { } } } - return this._cachedPnpmOptions; + return this.#cachedPnpmOptions; } - private _ensureDetail(): ISubspaceDetail { - if (!this._detail) { - const rushConfiguration: RushConfiguration = this._rushConfiguration; + #ensureDetail(): ISubspaceDetail { + if (!this.#detail) { + const rushConfiguration: RushConfiguration = this.#rushConfiguration; let subspaceConfigFolderPath: string; let subspacePnpmPatchesFolderPath: string; @@ -118,7 +118,7 @@ export class Subspace { subspaceConfigFolderPath = standardSubspaceConfigFolder; - if (this._splitWorkspaceCompatibility && this.subspaceName.startsWith('split_')) { + if (this.#splitWorkspaceCompatibility && this.subspaceName.startsWith('split_')) { if (FileSystem.exists(standardSubspaceConfigFolder + '/pnpm-lock.yaml')) { throw new Error( `The split workspace subspace "${this.subspaceName}" cannot use a common/config folder: ` + @@ -126,13 +126,13 @@ export class Subspace { ); } - if (this._projects.length !== 1) { + if (this.#projects.length !== 1) { throw new Error( - `The split workspace subspace "${this.subspaceName}" contains ${this._projects.length}` + + `The split workspace subspace "${this.subspaceName}" contains ${this.#projects.length}` + ` projects; there must be exactly one project.` ); } - const project: RushConfigurationProject = this._projects[0]; + const project: RushConfigurationProject = this.#projects[0]; subspaceConfigFolderPath = `${project.projectFolder}/subspace/${this.subspaceName}`; @@ -184,7 +184,7 @@ export class Subspace { const parsedPath: path.ParsedPath = path.parse(tempShrinkwrapFilePath); const tempShrinkwrapPreinstallFilePath: string = `${parsedPath.dir}/${parsedPath.name}-preinstall${parsedPath.ext}`; - this._detail = { + this.#detail = { subspaceConfigFolderPath, subspacePnpmPatchesFolderPath, subspaceTempFolderPath, @@ -192,7 +192,7 @@ export class Subspace { tempShrinkwrapPreinstallFilePath }; } - return this._detail; + return this.#detail; } /** @@ -228,7 +228,7 @@ export class Subspace { * @beta */ public getSubspaceConfigFolderPath(): string { - return this._ensureDetail().subspaceConfigFolderPath; + return this.#ensureDetail().subspaceConfigFolderPath; } /** @@ -239,7 +239,7 @@ export class Subspace { * @beta */ public getSubspacePnpmPatchesFolderPath(): string { - return this._ensureDetail().subspacePnpmPatchesFolderPath; + return this.#ensureDetail().subspacePnpmPatchesFolderPath; } /** @@ -250,7 +250,7 @@ export class Subspace { * @beta */ public getSubspaceTempFolderPath(): string { - return this._ensureDetail().subspaceTempFolderPath; + return this.#ensureDetail().subspaceTempFolderPath; } /** @@ -265,7 +265,7 @@ export class Subspace { * @beta */ public getTempShrinkwrapFilename(): string { - return this._ensureDetail().tempShrinkwrapFilePath; + return this.#ensureDetail().tempShrinkwrapFilePath; } /** @@ -286,7 +286,7 @@ export class Subspace { * @beta */ public getTempShrinkwrapPreinstallFilePath(): string { - return this._ensureDetail().tempShrinkwrapPreinstallFilePath; + return this.#ensureDetail().tempShrinkwrapPreinstallFilePath; } /** @@ -319,14 +319,14 @@ export class Subspace { */ public getCommonVersions(variant?: string): CommonVersionsConfiguration { const commonVersionsFilePath: string = this.getCommonVersionsFilePath(variant); - if (!this._commonVersionsConfiguration) { - this._commonVersionsConfiguration = CommonVersionsConfiguration.loadFromFile( + if (!this.#commonVersionsConfiguration) { + this.#commonVersionsConfiguration = CommonVersionsConfiguration.loadFromFile( commonVersionsFilePath, - this._rushConfiguration + this.#rushConfiguration ); } - return this._commonVersionsConfiguration; + return this.#commonVersionsConfiguration; } /** @@ -343,7 +343,7 @@ export class Subspace { // Fallback to ensureConsistentVersions in rush.json if the setting is not defined in // the common-versions.json file - return this._rushConfiguration.ensureConsistentVersions; + return this.#rushConfiguration.ensureConsistentVersions; } /** @@ -378,7 +378,7 @@ export class Subspace { */ public getCommittedShrinkwrapFilePath(variant?: string): string { const subspaceConfigFolderPath: string = this.getVariantDependentSubspaceConfigFolderPath(variant); - return `${subspaceConfigFolderPath}/${this._rushConfiguration.shrinkwrapFilename}`; + return `${subspaceConfigFolderPath}/${this.#rushConfiguration.shrinkwrapFilename}`; } /** @@ -391,7 +391,7 @@ export class Subspace { public getPnpmfilePath(variant?: string): string { const subspaceConfigFolderPath: string = this.getVariantDependentSubspaceConfigFolderPath(variant); - const pnpmFilename: string = (this._rushConfiguration.packageManagerWrapper as PnpmPackageManager) + const pnpmFilename: string = (this.#rushConfiguration.packageManagerWrapper as PnpmPackageManager) .pnpmfileFilename; return `${subspaceConfigFolderPath}/${pnpmFilename}`; @@ -407,7 +407,7 @@ export class Subspace { /** @internal */ public _addProject(project: RushConfigurationProject): void { - this._projects.push(project); + this.#projects.push(project); } /** @@ -444,7 +444,7 @@ export class Subspace { const relatedProjects: RushConfigurationProject[] = []; const subspacePnpmfileShimSettings: ISubspacePnpmfileShimSettings = - SubspacePnpmfileConfiguration.getSubspacePnpmfileShimSettings(this._rushConfiguration, this, variant); + SubspacePnpmfileConfiguration.getSubspacePnpmfileShimSettings(this.#rushConfiguration, this, variant); for (const rushProject of this.getProjects()) { const injectedDependencies: Array = @@ -468,7 +468,7 @@ export class Subspace { } const allWorkspaceProjectSet: Set = new Set( - this._rushConfiguration.projects.map((rushProject) => rushProject.packageName) + this.#rushConfiguration.projects.map((rushProject) => rushProject.packageName) ); // get all related package.json diff --git a/libraries/rush-lib/src/api/VersionPolicy.ts b/libraries/rush-lib/src/api/VersionPolicy.ts index b738ba487d0..0266e61b2be 100644 --- a/libraries/rush-lib/src/api/VersionPolicy.ts +++ b/libraries/rush-lib/src/api/VersionPolicy.ts @@ -24,7 +24,7 @@ import { cloneDeep } from '../utilities/objectUtilities'; * @internalRemarks * This is a copy of the semver ReleaseType enum, but with the `none` value added and * the `premajor` and `prepatch` omitted. - * See {@link LockStepVersionPolicy._getReleaseType}. + * See `LockStepVersionPolicy.#getReleaseType`. * * TODO: Consider supporting `premajor` and `prepatch` in the future. */ @@ -124,11 +124,11 @@ export abstract class VersionPolicy { */ public readonly _json: IVersionPolicyJson; - private get _versionFormatForCommit(): VersionFormatForCommit { + get #versionFormatForCommit(): VersionFormatForCommit { return this._json.dependencies?.versionFormatForCommit ?? 'original'; } - private get _versionFormatForPublish(): VersionFormatForPublish { + get #versionFormatForPublish(): VersionFormatForPublish { return this._json.dependencies?.versionFormatForPublish ?? 'original'; } @@ -227,7 +227,7 @@ export abstract class VersionPolicy { const packageJsonEditor: PackageJsonEditor | undefined = updateDependenciesBeforePublish( packageName, configuration, - this._versionFormatForPublish + this.#versionFormatForPublish ); packageJsonEditor?.saveIfModified(); @@ -244,7 +244,7 @@ export abstract class VersionPolicy { const packageJsonEditor: PackageJsonEditor | undefined = updateDependenciesBeforePublish( packageName, configuration, - this._versionFormatForPublish + this.#versionFormatForPublish ); await packageJsonEditor?.saveIfModifiedAsync(); @@ -257,7 +257,7 @@ export abstract class VersionPolicy { const packageJsonEditor: PackageJsonEditor | undefined = updateDependenciesBeforeCommit( packageName, configuration, - this._versionFormatForCommit + this.#versionFormatForCommit ); packageJsonEditor?.saveIfModified(); @@ -274,7 +274,7 @@ export abstract class VersionPolicy { const packageJsonEditor: PackageJsonEditor | undefined = updateDependenciesBeforeCommit( packageName, configuration, - this._versionFormatForCommit + this.#versionFormatForCommit ); await packageJsonEditor?.saveIfModifiedAsync(); @@ -290,7 +290,7 @@ export class LockStepVersionPolicy extends VersionPolicy { * @internal */ declare public readonly _json: ILockStepVersionJson; - private _version: semver.SemVer; + #version: semver.SemVer; /** * The type of bump for next bump. @@ -316,14 +316,14 @@ export class LockStepVersionPolicy extends VersionPolicy { */ public constructor(versionPolicyJson: ILockStepVersionJson) { super(versionPolicyJson); - this._version = new semver.SemVer(versionPolicyJson.version); + this.#version = new semver.SemVer(versionPolicyJson.version); } /** * The value of the lockstep version */ public get version(): string { - return this._version.format(); + return this.#version.format(); } /** @@ -334,16 +334,16 @@ export class LockStepVersionPolicy extends VersionPolicy { */ public ensure(project: IPackageJson, force?: boolean): IPackageJson | undefined { const packageVersion: semver.SemVer = new semver.SemVer(project.version); - const compareResult: number = packageVersion.compare(this._version); + const compareResult: number = packageVersion.compare(this.#version); if (compareResult === 0) { return undefined; } else if (compareResult > 0 && !force) { const errorMessage: string = `Version ${project.version} in package ${project.name}` + - ` is higher than locked version ${this._version.format()}.`; + ` is higher than locked version ${this.#version.format()}.`; throw new Error(errorMessage); } - return this._updatePackageVersion(project, this._version); + return this.#updatePackageVersion(project, this.#version); } /** @@ -360,7 +360,7 @@ export class LockStepVersionPolicy extends VersionPolicy { return; } - this._version.inc(this._getReleaseType(nextBump), identifier); + this.#version.inc(this.#getReleaseType(nextBump), identifier); this._json.version = this.version; } @@ -370,10 +370,10 @@ export class LockStepVersionPolicy extends VersionPolicy { */ public update(newVersionString: string): boolean { const newVersion: semver.SemVer = new semver.SemVer(newVersionString); - if (!newVersion || this._version === newVersion) { + if (!newVersion || this.#version === newVersion) { return false; } - this._version = newVersion; + this.#version = newVersion; this._json.version = this.version; return true; } @@ -386,18 +386,18 @@ export class LockStepVersionPolicy extends VersionPolicy { */ public validate(versionString: string, packageName: string): void { const versionToTest: semver.SemVer = new semver.SemVer(versionString, false); - if (this._version.compare(versionToTest) !== 0) { + if (this.#version.compare(versionToTest) !== 0) { throw new Error(`Invalid version ${versionString} in ${packageName}`); } } - private _updatePackageVersion(project: IPackageJson, newVersion: semver.SemVer): IPackageJson { + #updatePackageVersion(project: IPackageJson, newVersion: semver.SemVer): IPackageJson { const updatedProject: IPackageJson = cloneDeep(project); updatedProject.version = newVersion.format(); return updatedProject; } - private _getReleaseType(bumpType: BumpType): semver.ReleaseType { + #getReleaseType(bumpType: BumpType): semver.ReleaseType { // Eventually we should just use ReleaseType and get rid of bump type. return BumpType[bumpType] as semver.ReleaseType; } diff --git a/libraries/rush-lib/src/api/VersionPolicyConfiguration.ts b/libraries/rush-lib/src/api/VersionPolicyConfiguration.ts index 16d1804561c..a96f230c3cf 100644 --- a/libraries/rush-lib/src/api/VersionPolicyConfiguration.ts +++ b/libraries/rush-lib/src/api/VersionPolicyConfiguration.ts @@ -71,7 +71,7 @@ const _jsonSchema: JsonSchema = JsonSchema.fromLoadedObject(schemaJson); * @public */ export class VersionPolicyConfiguration { - private _jsonFileName: string; + #jsonFileName: string; /** * Gets all the version policies @@ -82,9 +82,9 @@ export class VersionPolicyConfiguration { * @internal */ public constructor(jsonFileName: string) { - this._jsonFileName = jsonFileName; + this.#jsonFileName = jsonFileName; this.versionPolicies = new Map(); - this._loadFile(); + this.#loadFile(); } /** @@ -144,7 +144,7 @@ export class VersionPolicyConfiguration { } }); } - this._saveFile(!!shouldCommit); + this.#saveFile(!!shouldCommit); } /** @@ -162,15 +162,15 @@ export class VersionPolicyConfiguration { if (lockStepVersionPolicy.update(newVersion)) { // eslint-disable-next-line no-console console.log(`\nUpdate version policy ${versionPolicyName} from ${previousVersion} to ${newVersion}`); - this._saveFile(!!shouldCommit); + this.#saveFile(!!shouldCommit); } } - private _loadFile(): void { - if (!FileSystem.exists(this._jsonFileName)) { + #loadFile(): void { + if (!FileSystem.exists(this.#jsonFileName)) { return; } - const versionPolicyJson: IVersionPolicyJson[] = JsonFile.loadAndValidate(this._jsonFileName, _jsonSchema); + const versionPolicyJson: IVersionPolicyJson[] = JsonFile.loadAndValidate(this.#jsonFileName, _jsonSchema); versionPolicyJson.forEach((policyJson) => { const policy: VersionPolicy | undefined = VersionPolicy.load(policyJson); @@ -180,13 +180,13 @@ export class VersionPolicyConfiguration { }); } - private _saveFile(shouldCommit: boolean): void { + #saveFile(shouldCommit: boolean): void { const versionPolicyJson: IVersionPolicyJson[] = []; this.versionPolicies.forEach((versionPolicy) => { versionPolicyJson.push(versionPolicy._json); }); if (shouldCommit) { - JsonFile.save(versionPolicyJson, this._jsonFileName, { updateExistingFile: true }); + JsonFile.save(versionPolicyJson, this.#jsonFileName, { updateExistingFile: true }); } } } diff --git a/libraries/rush-lib/src/cli/RushCommandLineParser.ts b/libraries/rush-lib/src/cli/RushCommandLineParser.ts index 47f2b3a640b..1546b9cce3e 100644 --- a/libraries/rush-lib/src/cli/RushCommandLineParser.ts +++ b/libraries/rush-lib/src/cli/RushCommandLineParser.ts @@ -81,19 +81,19 @@ export class RushCommandLineParser extends CommandLineParser { public readonly rushSession: RushSession; public readonly pluginManager: PluginManager; - private readonly _debugParameter: CommandLineFlagParameter; - private readonly _quietParameter: CommandLineFlagParameter; - private readonly _restrictConsoleOutput: boolean = RushCommandLineParser.shouldRestrictConsoleOutput(); - private readonly _rushOptions: IRushCommandLineParserOptions; - private readonly _terminalProvider: ConsoleTerminalProvider; - private readonly _terminal: Terminal; - private readonly _autocreateBuildCommand: boolean; + readonly #debugParameter: CommandLineFlagParameter; + readonly #quietParameter: CommandLineFlagParameter; + readonly #restrictConsoleOutput: boolean = RushCommandLineParser.shouldRestrictConsoleOutput(); + readonly #rushOptions: IRushCommandLineParserOptions; + readonly #terminalProvider: ConsoleTerminalProvider; + readonly #terminal: Terminal; + readonly #autocreateBuildCommand: boolean; /** * The current working directory that was used to find the Rush configuration. */ public get cwd(): string { - return this._rushOptions.cwd; + return this.#rushOptions.cwd; } public constructor(options?: Partial) { @@ -111,30 +111,30 @@ export class RushCommandLineParser extends CommandLineParser { enableTabCompletionAction: true }); - this._debugParameter = this.defineFlagParameter({ + this.#debugParameter = this.defineFlagParameter({ parameterLongName: '--debug', parameterShortName: '-d', description: 'Show the full call stack if an error occurs while executing the tool' }); - this._quietParameter = this.defineFlagParameter({ + this.#quietParameter = this.defineFlagParameter({ parameterLongName: '--quiet', parameterShortName: '-q', description: 'Hide rush startup information' }); const terminalProvider: ConsoleTerminalProvider = new ConsoleTerminalProvider(); - this._terminalProvider = terminalProvider; - const terminal: Terminal = new Terminal(this._terminalProvider); - this._terminal = terminal; - this._rushOptions = this._normalizeOptions(options || {}); - const { cwd, alreadyReportedNodeTooNewError, builtInPluginConfigurations } = this._rushOptions; + this.#terminalProvider = terminalProvider; + const terminal: Terminal = new Terminal(this.#terminalProvider); + this.#terminal = terminal; + this.#rushOptions = this.#normalizeOptions(options || {}); + const { cwd, alreadyReportedNodeTooNewError, builtInPluginConfigurations } = this.#rushOptions; let rushJsonFilePath: string | undefined; try { rushJsonFilePath = RushConfiguration.tryFindRushJsonLocation({ startingFolder: cwd, - showVerbose: !this._restrictConsoleOutput + showVerbose: !this.#restrictConsoleOutput }); initializeDotEnv(terminal, rushJsonFilePath); @@ -163,7 +163,7 @@ export class RushCommandLineParser extends CommandLineParser { rushConfiguration: this.rushConfiguration, terminal, builtInPluginConfigurations, - restrictConsoleOutput: this._restrictConsoleOutput, + restrictConsoleOutput: this.#restrictConsoleOutput, rushGlobalFolder: this.rushGlobalFolder }); @@ -175,13 +175,13 @@ export class RushCommandLineParser extends CommandLineParser { ); // If the plugin has a build command, we don't need to autocreate the default build command. - this._autocreateBuildCommand = !hasBuildCommandInPlugin; + this.#autocreateBuildCommand = !hasBuildCommandInPlugin; - this._populateActions(); + this.#populateActions(); for (const { commandLineConfiguration, pluginLoader } of pluginCommandLineConfigurations) { try { - this._addCommandLineConfigActions(commandLineConfiguration); + this.#addCommandLineConfigActions(commandLineConfiguration); } catch (e) { this._reportErrorAndSetExitCode( new Error( @@ -195,15 +195,15 @@ export class RushCommandLineParser extends CommandLineParser { } public get isDebug(): boolean { - return this._debugParameter.value; + return this.#debugParameter.value; } public get isQuiet(): boolean { - return this._quietParameter.value; + return this.#quietParameter.value; } public get terminal(): ITerminal { - return this._terminal; + return this.#terminal; } /** @@ -235,7 +235,7 @@ export class RushCommandLineParser extends CommandLineParser { public override async executeAsync(args?: string[]): Promise { // debugParameter will be correctly parsed during super.executeAsync(), so manually parse here. - this._terminalProvider.verboseEnabled = this._terminalProvider.debugEnabled = + this.#terminalProvider.verboseEnabled = this.#terminalProvider.debugEnabled = process.argv.indexOf('--debug') >= 0; await measureAsyncFn('rush:initializeUnassociatedPlugins', () => @@ -253,12 +253,12 @@ export class RushCommandLineParser extends CommandLineParser { // -- if it falsely appears to succeed, we could merge bad PRs, publish empty packages, etc. process.exitCode = 1; - if (this._debugParameter.value) { + if (this.#debugParameter.value) { InternalError.breakInDebugger = true; } try { - await this._wrapOnExecuteAsync(); + await this.#wrapOnExecuteAsync(); // TODO: rushConfiguration is typed as "!: RushConfiguration" here, but can sometimes be undefined if (this.rushConfiguration) { @@ -274,10 +274,10 @@ export class RushCommandLineParser extends CommandLineParser { // only display alerts when certain specific actions are triggered if (RushAlerts.alertTriggerActions.includes(actionName)) { - this._terminal.writeDebugLine('Checking Rush alerts...'); + this.#terminal.writeDebugLine('Checking Rush alerts...'); const rushAlerts: RushAlerts = await RushAlerts.loadFromConfigurationAsync( this.rushConfiguration, - this._terminal + this.#terminal ); // Print out alerts if have after each successful command actions await rushAlerts.printAlertsAsync(); @@ -289,8 +289,8 @@ export class RushCommandLineParser extends CommandLineParser { } // Generally the RushAlerts implementation should handle its own error reporting; if not, // clarify the source, since the Rush Alerts behavior is nondeterministic and may not repro easily: - this._terminal.writeErrorLine(`\nAn unexpected error was encountered by the Rush alerts feature:`); - this._terminal.writeErrorLine(error.message); + this.#terminal.writeErrorLine(`\nAn unexpected error was encountered by the Rush alerts feature:`); + this.#terminal.writeErrorLine(error.message); throw new AlreadyReportedError(); } } @@ -305,7 +305,7 @@ export class RushCommandLineParser extends CommandLineParser { await this.telemetry?.ensureFlushedAsync(); } - private _normalizeOptions(options: Partial): IRushCommandLineParserOptions { + #normalizeOptions(options: Partial): IRushCommandLineParserOptions { return { cwd: options.cwd || process.cwd(), alreadyReportedNodeTooNewError: options.alreadyReportedNodeTooNewError || false, @@ -313,7 +313,7 @@ export class RushCommandLineParser extends CommandLineParser { }; } - private async _wrapOnExecuteAsync(): Promise { + async #wrapOnExecuteAsync(): Promise { if (this.rushConfiguration) { this.telemetry = new Telemetry(this.rushConfiguration, this.rushSession); } @@ -327,7 +327,7 @@ export class RushCommandLineParser extends CommandLineParser { } } - private _populateActions(): void { + #populateActions(): void { try { // Alphabetical order this.addAction(new AddAction(this)); @@ -357,13 +357,13 @@ export class RushCommandLineParser extends CommandLineParser { this.addAction(new BridgePackageAction(this)); this.addAction(new LinkPackageAction(this)); - this._populateScriptActions(); + this.#populateScriptActions(); } catch (error) { this._reportErrorAndSetExitCode(error as Error); } } - private _populateScriptActions(): void { + #populateScriptActions(): void { // If there is not a rush.json file, we still want "build" and "rebuild" to appear in the // command-line help let commandLineConfigFilePath: string | undefined; @@ -375,23 +375,23 @@ export class RushCommandLineParser extends CommandLineParser { } // If a build action is already added by a plugin, we don't want to add a default "build" script - const doNotIncludeDefaultBuildCommands: boolean = !this._autocreateBuildCommand; + const doNotIncludeDefaultBuildCommands: boolean = !this.#autocreateBuildCommand; const commandLineConfiguration: CommandLineConfiguration = CommandLineConfiguration.loadFromFileOrDefault( commandLineConfigFilePath, doNotIncludeDefaultBuildCommands ); - this._addCommandLineConfigActions(commandLineConfiguration); + this.#addCommandLineConfigActions(commandLineConfiguration); } - private _addCommandLineConfigActions(commandLineConfiguration: CommandLineConfiguration): void { + #addCommandLineConfigActions(commandLineConfiguration: CommandLineConfiguration): void { // Register each custom command for (const command of commandLineConfiguration.commands.values()) { - this._addCommandLineConfigAction(commandLineConfiguration, command); + this.#addCommandLineConfigAction(commandLineConfiguration, command); } } - private _addCommandLineConfigAction( + #addCommandLineConfigAction( commandLineConfiguration: CommandLineConfiguration, command: Command ): void { @@ -404,12 +404,12 @@ export class RushCommandLineParser extends CommandLineParser { switch (command.commandKind) { case RushConstants.globalCommandKind: { - this._addGlobalScriptAction(commandLineConfiguration, command); + this.#addGlobalScriptAction(commandLineConfiguration, command); break; } case RushConstants.phasedCommandKind: { - this._addPhasedCommandLineConfigAction(commandLineConfiguration, command); + this.#addPhasedCommandLineConfigAction(commandLineConfiguration, command); break; } @@ -421,7 +421,7 @@ export class RushCommandLineParser extends CommandLineParser { } } - private _getSharedCommandActionOptions( + #getSharedCommandActionOptions( commandLineConfiguration: CommandLineConfiguration, command: TCommand ): IBaseScriptActionOptions { @@ -437,7 +437,7 @@ export class RushCommandLineParser extends CommandLineParser { }; } - private _addGlobalScriptAction( + #addGlobalScriptAction( commandLineConfiguration: CommandLineConfiguration, command: IGlobalCommandConfig ): void { @@ -452,7 +452,7 @@ export class RushCommandLineParser extends CommandLineParser { } const sharedCommandOptions: IBaseScriptActionOptions = - this._getSharedCommandActionOptions(commandLineConfiguration, command); + this.#getSharedCommandActionOptions(commandLineConfiguration, command); this.addAction( new GlobalScriptAction({ @@ -465,12 +465,12 @@ export class RushCommandLineParser extends CommandLineParser { ); } - private _addPhasedCommandLineConfigAction( + #addPhasedCommandLineConfigAction( commandLineConfiguration: CommandLineConfiguration, command: IPhasedCommandConfig ): void { const baseCommandOptions: IBaseScriptActionOptions = - this._getSharedCommandActionOptions(commandLineConfiguration, command); + this.#getSharedCommandActionOptions(commandLineConfiguration, command); const { enableParallelism, @@ -525,7 +525,7 @@ export class RushCommandLineParser extends CommandLineParser { console.error(`\n${message}`); } - if (this._debugParameter.value) { + if (this.#debugParameter.value) { // If catchSyncErrors() called this, then show a call stack similar to what Node.js // would show for an uncaught error // eslint-disable-next-line no-console diff --git a/libraries/rush-lib/src/cli/actions/AddAction.ts b/libraries/rush-lib/src/cli/actions/AddAction.ts index db67f19ea0c..5eb0784c65f 100644 --- a/libraries/rush-lib/src/cli/actions/AddAction.ts +++ b/libraries/rush-lib/src/cli/actions/AddAction.ts @@ -22,11 +22,11 @@ const EXACT_FLAG_NAME: '--exact' = '--exact'; const CARET_FLAG_NAME: '--caret' = '--caret'; export class AddAction extends BaseAddAndRemoveAction { - private readonly _exactFlag: CommandLineFlagParameter; - private readonly _caretFlag: CommandLineFlagParameter; - private readonly _devDependencyFlag: CommandLineFlagParameter; - private readonly _peerDependencyFlag: CommandLineFlagParameter; - private readonly _makeConsistentFlag: CommandLineFlagParameter; + readonly #exactFlag: CommandLineFlagParameter; + readonly #caretFlag: CommandLineFlagParameter; + readonly #devDependencyFlag: CommandLineFlagParameter; + readonly #peerDependencyFlag: CommandLineFlagParameter; + readonly #makeConsistentFlag: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { const documentation: string = [ @@ -52,29 +52,29 @@ export class AddAction extends BaseAddAndRemoveAction { ` To add multiple packages, write "rush add ${PACKAGE_PARAMETER_NAME} foo ${PACKAGE_PARAMETER_NAME} bar".` }); - this._exactFlag = this.defineFlagParameter({ + this.#exactFlag = this.defineFlagParameter({ parameterLongName: EXACT_FLAG_NAME, description: 'If specified, the SemVer specifier added to the' + ' package.json will be an exact version (e.g. without tilde or caret).' }); - this._caretFlag = this.defineFlagParameter({ + this.#caretFlag = this.defineFlagParameter({ parameterLongName: CARET_FLAG_NAME, description: 'If specified, the SemVer specifier added to the' + ' package.json will be a prepended with a "caret" specifier ("^").' }); - this._devDependencyFlag = this.defineFlagParameter({ + this.#devDependencyFlag = this.defineFlagParameter({ parameterLongName: '--dev', description: 'If specified, the package will be added to the "devDependencies" section of the package.json' }); - this._peerDependencyFlag = this.defineFlagParameter({ + this.#peerDependencyFlag = this.defineFlagParameter({ parameterLongName: '--peer', description: 'If specified, the package will be added to the "peerDependencies" section of the package.json' }); - this._makeConsistentFlag = this.defineFlagParameter({ + this.#makeConsistentFlag = this.defineFlagParameter({ parameterLongName: MAKE_CONSISTENT_FLAG_NAME, parameterShortName: '-m', description: @@ -86,9 +86,9 @@ export class AddAction extends BaseAddAndRemoveAction { public async getUpdateOptionsAsync(): Promise { const projects: RushConfigurationProject[] = super.getProjects(); - if (this._caretFlag.value && this._exactFlag.value) { + if (this.#caretFlag.value && this.#exactFlag.value) { throw new Error( - `Only one of "${this._caretFlag.longName}" and "${this._exactFlag.longName}" should be specified` + `Only one of "${this.#caretFlag.longName}" and "${this.#exactFlag.longName}" should be specified` ); } @@ -127,18 +127,18 @@ export class AddAction extends BaseAddAndRemoveAction { */ let rangeStyle: SemVerStyle; if (version && version !== 'latest') { - if (this._exactFlag.value || this._caretFlag.value) { + if (this.#exactFlag.value || this.#caretFlag.value) { throw new Error( - `The "${this._caretFlag.longName}" and "${this._exactFlag.longName}" flags may not be specified if a ` + + `The "${this.#caretFlag.longName}" and "${this.#exactFlag.longName}" flags may not be specified if a ` + `version is provided in the ${this._packageNameListParameter.longName} specifier. In this case "${version}" was provided.` ); } rangeStyle = SemVerStyle.Passthrough; } else { - rangeStyle = this._caretFlag.value + rangeStyle = this.#caretFlag.value ? SemVerStyle.Caret - : this._exactFlag.value + : this.#exactFlag.value ? SemVerStyle.Exact : SemVerStyle.Tilde; } @@ -155,9 +155,9 @@ export class AddAction extends BaseAddAndRemoveAction { return { projects, packagesToUpdate: packagesToAdd, - devDependency: this._devDependencyFlag.value, - peerDependency: this._peerDependencyFlag.value, - updateOtherPackages: this._makeConsistentFlag.value, + devDependency: this.#devDependencyFlag.value, + peerDependency: this.#peerDependencyFlag.value, + updateOtherPackages: this.#makeConsistentFlag.value, skipUpdate: this._skipUpdateFlag.value, debugInstall: this.parser.isDebug, actionName: this.actionName, diff --git a/libraries/rush-lib/src/cli/actions/AlertAction.ts b/libraries/rush-lib/src/cli/actions/AlertAction.ts index 052220c06b0..5a56e637dce 100644 --- a/libraries/rush-lib/src/cli/actions/AlertAction.ts +++ b/libraries/rush-lib/src/cli/actions/AlertAction.ts @@ -8,8 +8,8 @@ import { BaseRushAction } from './BaseRushAction'; import { RushAlerts } from '../../utilities/RushAlerts'; export class AlertAction extends BaseRushAction { - private readonly _snoozeParameter: CommandLineStringParameter; - private readonly _snoozeTimeFlagParameter: CommandLineFlagParameter; + readonly #snoozeParameter: CommandLineStringParameter; + readonly #snoozeTimeFlagParameter: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -22,14 +22,14 @@ export class AlertAction extends BaseRushAction { parser }); - this._snoozeParameter = this.defineStringParameter({ + this.#snoozeParameter = this.defineStringParameter({ parameterLongName: '--snooze', parameterShortName: '-s', argumentName: 'ALERT_ID', description: 'Temporarily suspend the specified alert for one week' }); - this._snoozeTimeFlagParameter = this.defineFlagParameter({ + this.#snoozeTimeFlagParameter = this.defineFlagParameter({ parameterLongName: '--forever', description: 'Combined with "--snooze", causes that alert to be suspended permanently' }); @@ -40,9 +40,9 @@ export class AlertAction extends BaseRushAction { this.rushConfiguration, this.terminal ); - const snoozeAlertId: string | undefined = this._snoozeParameter.value; + const snoozeAlertId: string | undefined = this.#snoozeParameter.value; if (snoozeAlertId) { - const snoozeTimeFlag: boolean = this._snoozeTimeFlagParameter.value; + const snoozeTimeFlag: boolean = this.#snoozeTimeFlagParameter.value; await rushAlerts.snoozeAlertsByAlertIdAsync(snoozeAlertId, snoozeTimeFlag); } await rushAlerts.printAllAlertsAsync(); diff --git a/libraries/rush-lib/src/cli/actions/BaseInstallAction.ts b/libraries/rush-lib/src/cli/actions/BaseInstallAction.ts index b13b34fe681..2f0c9f9b447 100644 --- a/libraries/rush-lib/src/cli/actions/BaseInstallAction.ts +++ b/libraries/rush-lib/src/cli/actions/BaseInstallAction.ts @@ -269,7 +269,7 @@ export abstract class BaseInstallAction extends BaseRushAction { }; } - await this._doInstallAsync( + await this.#doInstallAsync( installManagerFactoryModule, purgeManager, installManagerOptionsForInstall @@ -277,7 +277,7 @@ export abstract class BaseInstallAction extends BaseRushAction { } } else { // Simple case when subspacesFeatureEnabled=false - await this._doInstallAsync(installManagerFactoryModule, purgeManager, { + await this.#doInstallAsync(installManagerFactoryModule, purgeManager, { ...installManagerOptions, subspace: this.rushConfiguration.defaultSubspace }); @@ -291,7 +291,7 @@ export abstract class BaseInstallAction extends BaseRushAction { ); stopwatch.stop(); - this._collectTelemetry(stopwatch, installManagerOptions, installSuccessful); + this.#collectTelemetry(stopwatch, installManagerOptions, installSuccessful); this.parser.flushTelemetry(); this.eventHooksManager.handle( Event.postRushInstall, @@ -317,7 +317,7 @@ export abstract class BaseInstallAction extends BaseRushAction { ); } - private async _doInstallAsync( + async #doInstallAsync( installManagerFactoryModule: typeof import('../../logic/InstallManagerFactory'), purgeManager: PurgeManager, installManagerOptions: IInstallManagerOptions @@ -333,7 +333,7 @@ export abstract class BaseInstallAction extends BaseRushAction { await measureAsyncFn('rush:installManager:doInstallAsync', () => installManager.doInstallAsync()); } - private _collectTelemetry( + #collectTelemetry( stopwatch: Stopwatch, installManagerOptions: Omit, success: boolean diff --git a/libraries/rush-lib/src/cli/actions/BaseRushAction.ts b/libraries/rush-lib/src/cli/actions/BaseRushAction.ts index 256224d10f4..fc92b4ac237 100644 --- a/libraries/rush-lib/src/cli/actions/BaseRushAction.ts +++ b/libraries/rush-lib/src/cli/actions/BaseRushAction.ts @@ -39,7 +39,7 @@ export interface IBaseRushActionOptions extends ICommandLineActionOptions { * can be used without a rush.json configuration. */ export abstract class BaseConfiglessRushAction extends CommandLineAction implements IRushCommand { - private _safeForSimultaneousRushProcesses: boolean; + #safeForSimultaneousRushProcesses: boolean; protected readonly rushConfiguration: RushConfiguration | undefined; protected readonly terminal: ITerminal; @@ -53,7 +53,7 @@ export abstract class BaseConfiglessRushAction extends CommandLineAction impleme const { parser, safeForSimultaneousRushProcesses } = options; this.parser = parser; const { rushConfiguration, terminal, rushSession, rushGlobalFolder } = parser; - this._safeForSimultaneousRushProcesses = !!safeForSimultaneousRushProcesses; + this.#safeForSimultaneousRushProcesses = !!safeForSimultaneousRushProcesses; this.rushConfiguration = rushConfiguration; this.terminal = terminal; this.rushSession = rushSession; @@ -61,10 +61,10 @@ export abstract class BaseConfiglessRushAction extends CommandLineAction impleme } protected override async onExecuteAsync(): Promise { - this._ensureEnvironment(); + this.#ensureEnvironment(); if (this.rushConfiguration) { - if (!this._safeForSimultaneousRushProcesses) { + if (!this.#safeForSimultaneousRushProcesses) { if (!LockFile.tryAcquire(this.rushConfiguration.commonTempFolder, 'rush')) { this.terminal.writeLine( Colorize.red(`Another Rush command is already running in this repository.`) @@ -87,7 +87,7 @@ export abstract class BaseConfiglessRushAction extends CommandLineAction impleme */ protected abstract runAsync(): Promise; - private _ensureEnvironment(): void { + #ensureEnvironment(): void { if (this.rushConfiguration) { // eslint-disable-next-line dot-notation let environmentPath: string | undefined = process.env['PATH']; @@ -105,14 +105,14 @@ export abstract class BaseConfiglessRushAction extends CommandLineAction impleme * The base class that most Rush command-line actions should extend. */ export abstract class BaseRushAction extends BaseConfiglessRushAction { - private _eventHooksManager: EventHooksManager | undefined; + #eventHooksManager: EventHooksManager | undefined; protected get eventHooksManager(): EventHooksManager { - if (!this._eventHooksManager) { - this._eventHooksManager = new EventHooksManager(this.rushConfiguration); + if (!this.#eventHooksManager) { + this.#eventHooksManager = new EventHooksManager(this.rushConfiguration); } - return this._eventHooksManager; + return this.#eventHooksManager; } protected declare readonly rushConfiguration: RushConfiguration; @@ -122,13 +122,13 @@ export abstract class BaseRushAction extends BaseConfiglessRushAction { throw Utilities.getRushConfigNotFoundError(); } - this._throwPluginErrorIfNeed(); + this.#throwPluginErrorIfNeed(); await measureAsyncFn(`${PERF_PREFIX}:initializePluginsAsync`, () => this.parser.pluginManager.tryInitializeAssociatedCommandPluginsAsync(this.actionName) ); - this._throwPluginErrorIfNeed(); + this.#throwPluginErrorIfNeed(); const { hooks: sessionHooks } = this.rushSession; await measureAsyncFn(`${PERF_PREFIX}:initializePlugins`, async () => { @@ -145,7 +145,7 @@ export abstract class BaseRushAction extends BaseConfiglessRushAction { * If an error is encountered while trying to load plugins, it is saved in the `PluginManager.error` * property, so we can defer throwing it until when `_throwPluginErrorIfNeed()` is called. */ - private _throwPluginErrorIfNeed(): void { + #throwPluginErrorIfNeed(): void { // If the plugin configuration is broken, these three commands are used to fix the problem: // // "rush update" diff --git a/libraries/rush-lib/src/cli/actions/BridgePackageAction.ts b/libraries/rush-lib/src/cli/actions/BridgePackageAction.ts index a380251c099..029ef34e34c 100644 --- a/libraries/rush-lib/src/cli/actions/BridgePackageAction.ts +++ b/libraries/rush-lib/src/cli/actions/BridgePackageAction.ts @@ -16,8 +16,8 @@ import type { Subspace } from '../../api/Subspace'; import type { RushConfigurationProject } from '../../api/RushConfigurationProject'; export class BridgePackageAction extends BaseHotlinkPackageAction { - private readonly _versionParameter: IRequiredCommandLineStringParameter; - private readonly _subspaceNamesParameter: CommandLineStringListParameter; + readonly #versionParameter: IRequiredCommandLineStringParameter; + readonly #subspaceNamesParameter: CommandLineStringListParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -35,23 +35,23 @@ export class BridgePackageAction extends BaseHotlinkPackageAction { parser }); - this._versionParameter = this.defineStringParameter({ + this.#versionParameter = this.defineStringParameter({ parameterLongName: '--version', argumentName: 'SEMVER_RANGE', defaultValue: '*', description: 'Specify which installed versions should be hotlinked.' }); - this._subspaceNamesParameter = this.defineStringListParameter({ + this.#subspaceNamesParameter = this.defineStringListParameter({ parameterLongName: '--subspace', argumentName: 'SUBSPACE_NAME', description: 'The name of the subspace to use for the hotlinked package.' }); } - private _getSubspacesToBridgeAsync(): Set { + #getSubspacesToBridgeAsync(): Set { const subspaceToBridge: Set = new Set(); - const subspaceNames: readonly string[] = this._subspaceNamesParameter.values; + const subspaceNames: readonly string[] = this.#subspaceNamesParameter.values; if (subspaceNames.length > 0) { for (const subspaceName of subspaceNames) { @@ -79,8 +79,8 @@ export class BridgePackageAction extends BaseHotlinkPackageAction { linkedPackagePath: string, hotlinkManager: HotlinkManager ): Promise { - const version: string = this._versionParameter.value; - const subspaces: Set = await this._getSubspacesToBridgeAsync(); + const version: string = this.#versionParameter.value; + const subspaces: Set = await this.#getSubspacesToBridgeAsync(); await Async.forEachAsync( subspaces, async (subspace) => { diff --git a/libraries/rush-lib/src/cli/actions/ChangeAction.ts b/libraries/rush-lib/src/cli/actions/ChangeAction.ts index fed5bb1f8f5..8830df2936f 100644 --- a/libraries/rush-lib/src/cli/actions/ChangeAction.ts +++ b/libraries/rush-lib/src/cli/actions/ChangeAction.ts @@ -36,20 +36,20 @@ const BULK_MESSAGE_LONG_NAME: string = '--message'; const BULK_BUMP_TYPE_LONG_NAME: string = '--bump-type'; export class ChangeAction extends BaseRushAction { - private readonly _git: Git; - private readonly _verifyParameter: CommandLineFlagParameter; - private readonly _verifyAllParameter: CommandLineFlagParameter; - private readonly _noFetchParameter: CommandLineFlagParameter; - private readonly _targetBranchParameter: CommandLineStringParameter; - private readonly _changeEmailParameter: CommandLineStringParameter; - private readonly _bulkChangeParameter: CommandLineFlagParameter; - private readonly _bulkChangeMessageParameter: CommandLineStringParameter; - private readonly _bulkChangeBumpTypeParameter: CommandLineChoiceParameter; - private readonly _overwriteFlagParameter: CommandLineFlagParameter; - private readonly _commitChangesFlagParameter: CommandLineFlagParameter; - private readonly _commitChangesMessageStringParameter: CommandLineStringParameter; - - private _targetBranchName: string | undefined; + readonly #git: Git; + readonly #verifyParameter: CommandLineFlagParameter; + readonly #verifyAllParameter: CommandLineFlagParameter; + readonly #noFetchParameter: CommandLineFlagParameter; + readonly #targetBranchParameter: CommandLineStringParameter; + readonly #changeEmailParameter: CommandLineStringParameter; + readonly #bulkChangeParameter: CommandLineFlagParameter; + readonly #bulkChangeMessageParameter: CommandLineStringParameter; + readonly #bulkChangeBumpTypeParameter: CommandLineChoiceParameter; + readonly #overwriteFlagParameter: CommandLineFlagParameter; + readonly #commitChangesFlagParameter: CommandLineFlagParameter; + readonly #commitChangesMessageStringParameter: CommandLineStringParameter; + + #targetBranchName: string | undefined; public constructor(parser: RushCommandLineParser) { const documentation: string = [ @@ -91,15 +91,15 @@ export class ChangeAction extends BaseRushAction { parser }); - this._git = new Git(this.rushConfiguration); + this.#git = new Git(this.rushConfiguration); - this._verifyParameter = this.defineFlagParameter({ + this.#verifyParameter = this.defineFlagParameter({ parameterLongName: '--verify', parameterShortName: '-v', description: 'Verify the change file has been generated and that it is a valid JSON file' }); - this._verifyAllParameter = this.defineFlagParameter({ + this.#verifyAllParameter = this.defineFlagParameter({ parameterLongName: '--verify-all', description: 'Validate all change files in the repository, not just those added in the current branch. ' + @@ -107,12 +107,12 @@ export class ChangeAction extends BaseRushAction { 'in a lockstepped version policy. Requires the "strictChangefileValidation" experiment to be enabled.' }); - this._noFetchParameter = this.defineFlagParameter({ + this.#noFetchParameter = this.defineFlagParameter({ parameterLongName: '--no-fetch', description: 'Skips fetching the baseline branch before running "git diff" to detect changes.' }); - this._targetBranchParameter = this.defineStringParameter({ + this.#targetBranchParameter = this.defineStringParameter({ parameterLongName: '--target-branch', parameterShortName: '-b', argumentName: 'BRANCH', @@ -122,26 +122,26 @@ export class ChangeAction extends BaseRushAction { 'is compared against the "main" branch.' }); - this._overwriteFlagParameter = this.defineFlagParameter({ + this.#overwriteFlagParameter = this.defineFlagParameter({ parameterLongName: '--overwrite', description: `If a changefile already exists, overwrite without prompting ` + `(or erroring in ${BULK_LONG_NAME} mode).` }); - this._commitChangesFlagParameter = this.defineFlagParameter({ + this.#commitChangesFlagParameter = this.defineFlagParameter({ parameterLongName: '--commit', parameterShortName: '-c', description: `If this flag is specified generated changefiles will be commited automatically.` }); - this._commitChangesMessageStringParameter = this.defineStringParameter({ + this.#commitChangesMessageStringParameter = this.defineStringParameter({ parameterLongName: '--commit-message', argumentName: 'COMMIT_MESSAGE', description: `If this parameter is specified generated changefiles will be commited automatically with the specified commit message.` }); - this._changeEmailParameter = this.defineStringParameter({ + this.#changeEmailParameter = this.defineStringParameter({ parameterLongName: '--email', argumentName: 'EMAIL', description: @@ -149,7 +149,7 @@ export class ChangeAction extends BaseRushAction { 'will be detected or prompted for in interactive mode.' }); - this._bulkChangeParameter = this.defineFlagParameter({ + this.#bulkChangeParameter = this.defineFlagParameter({ parameterLongName: BULK_LONG_NAME, description: 'If this flag is specified, apply the same change message and bump type to all changed projects. ' + @@ -157,39 +157,39 @@ export class ChangeAction extends BaseRushAction { `${BULK_LONG_NAME} parameter is specified` }); - this._bulkChangeMessageParameter = this.defineStringParameter({ + this.#bulkChangeMessageParameter = this.defineStringParameter({ parameterLongName: BULK_MESSAGE_LONG_NAME, argumentName: 'MESSAGE', description: `The message to apply to all changed projects if the ${BULK_LONG_NAME} flag is provided.` }); - this._bulkChangeBumpTypeParameter = this.defineChoiceParameter({ + this.#bulkChangeBumpTypeParameter = this.defineChoiceParameter({ parameterLongName: BULK_BUMP_TYPE_LONG_NAME, - alternatives: [...Object.keys(this._getBumpOptions())], + alternatives: [...Object.keys(this.#getBumpOptions())], description: `The bump type to apply to all changed projects if the ${BULK_LONG_NAME} flag is provided.` }); } public async runAsync(): Promise { - if (this._verifyAllParameter.value) { + if (this.#verifyAllParameter.value) { const incompatibleParameters: ( | CommandLineFlagParameter | CommandLineStringParameter | CommandLineChoiceParameter )[] = [ - this._verifyParameter, - this._bulkChangeParameter, - this._bulkChangeMessageParameter, - this._bulkChangeBumpTypeParameter, - this._overwriteFlagParameter, - this._commitChangesFlagParameter + this.#verifyParameter, + this.#bulkChangeParameter, + this.#bulkChangeMessageParameter, + this.#bulkChangeBumpTypeParameter, + this.#overwriteFlagParameter, + this.#commitChangesFlagParameter ]; const errors: string[] = incompatibleParameters .filter((parameter) => parameter.value) .map( (parameter) => `The ${parameter.longName} parameter cannot be provided with the ` + - `${this._verifyAllParameter.longName} parameter` + `${this.#verifyAllParameter.longName} parameter` ); if (errors.length > 0) { errors.forEach((error) => { @@ -198,30 +198,30 @@ export class ChangeAction extends BaseRushAction { throw new AlreadyReportedError(); } - await this._validateAllChangeFilesAsync(); + await this.#validateAllChangeFilesAsync(); return; } - const targetBranch: string = await this._getTargetBranchAsync(); + const targetBranch: string = await this.#getTargetBranchAsync(); this.terminal.writeLine(`The target branch is ${targetBranch}`); - if (this._verifyParameter.value) { + if (this.#verifyParameter.value) { const incompatibleParameters: ( | CommandLineFlagParameter | CommandLineStringParameter | CommandLineChoiceParameter )[] = [ - this._bulkChangeParameter, - this._bulkChangeMessageParameter, - this._bulkChangeBumpTypeParameter, - this._overwriteFlagParameter, - this._commitChangesFlagParameter + this.#bulkChangeParameter, + this.#bulkChangeMessageParameter, + this.#bulkChangeBumpTypeParameter, + this.#overwriteFlagParameter, + this.#commitChangesFlagParameter ]; const errors: string[] = incompatibleParameters .map((parameter) => { return parameter.value ? `The ${parameter.longName} parameter cannot be provided with the ` + - `${this._verifyParameter.longName} parameter` + `${this.#verifyParameter.longName} parameter` : ''; }) .filter((error) => error !== ''); @@ -232,51 +232,51 @@ export class ChangeAction extends BaseRushAction { throw new AlreadyReportedError(); } - await this._verifyAsync(); + await this.#verifyAsync(); return; } - const sortedProjectList: string[] = (await this._getChangedProjectNamesAsync()).sort(); + const sortedProjectList: string[] = (await this.#getChangedProjectNamesAsync()).sort(); if (sortedProjectList.length === 0) { - this._logNoChangeFileRequired(); - await this._warnUnstagedChangesAsync(); + this.#logNoChangeFileRequired(); + await this.#warnUnstagedChangesAsync(); return; } - await this._warnUnstagedChangesAsync(); + await this.#warnUnstagedChangesAsync(); let changeFileData: Map = new Map(); let interactiveMode: boolean = false; - if (this._bulkChangeParameter.value) { + if (this.#bulkChangeParameter.value) { if ( - !this._bulkChangeBumpTypeParameter.value || - (!this._bulkChangeMessageParameter.value && - this._bulkChangeBumpTypeParameter.value !== ChangeType[ChangeType.none]) + !this.#bulkChangeBumpTypeParameter.value || + (!this.#bulkChangeMessageParameter.value && + this.#bulkChangeBumpTypeParameter.value !== ChangeType[ChangeType.none]) ) { throw new Error( - `The ${this._bulkChangeBumpTypeParameter.longName} and ${this._bulkChangeMessageParameter.longName} ` + - `parameters must provided if the ${this._bulkChangeParameter.longName} flag is provided. If the value ` + + `The ${this.#bulkChangeBumpTypeParameter.longName} and ${this.#bulkChangeMessageParameter.longName} ` + + `parameters must provided if the ${this.#bulkChangeParameter.longName} flag is provided. If the value ` + `"${ChangeType[ChangeType.none]}" is provided to the ${ - this._bulkChangeBumpTypeParameter.longName + this.#bulkChangeBumpTypeParameter.longName } ` + - `parameter, the ${this._bulkChangeMessageParameter.longName} parameter may be omitted.` + `parameter, the ${this.#bulkChangeMessageParameter.longName} parameter may be omitted.` ); } - const email: string | undefined = this._changeEmailParameter.value || this._detectEmail(); + const email: string | undefined = this.#changeEmailParameter.value || this.#detectEmail(); if (!email) { throw new Error( "Unable to detect Git email and an email address wasn't provided using the " + - `${this._changeEmailParameter.longName} parameter.` + `${this.#changeEmailParameter.longName} parameter.` ); } const errors: string[] = []; - const comment: string = this._bulkChangeMessageParameter.value || ''; - const changeType: string = this._bulkChangeBumpTypeParameter.value; + const comment: string = this.#bulkChangeMessageParameter.value || ''; + const changeType: string = this.#bulkChangeBumpTypeParameter.value; for (const packageName of sortedProjectList) { - const allowedBumpTypes: string[] = Object.keys(this._getBumpOptions(packageName)); + const allowedBumpTypes: string[] = Object.keys(this.#getBumpOptions(packageName)); let projectChangeType: string = changeType; if (allowedBumpTypes.length === 0) { projectChangeType = ChangeType[ChangeType.none]; @@ -307,27 +307,27 @@ export class ChangeAction extends BaseRushAction { throw new AlreadyReportedError(); } - } else if (this._bulkChangeBumpTypeParameter.value || this._bulkChangeMessageParameter.value) { + } else if (this.#bulkChangeBumpTypeParameter.value || this.#bulkChangeMessageParameter.value) { throw new Error( - `The ${this._bulkChangeParameter.longName} flag must be provided with the ` + - `${this._bulkChangeBumpTypeParameter.longName} and ${this._bulkChangeMessageParameter.longName} parameters.` + `The ${this.#bulkChangeParameter.longName} flag must be provided with the ` + + `${this.#bulkChangeBumpTypeParameter.longName} and ${this.#bulkChangeMessageParameter.longName} parameters.` ); } else { interactiveMode = true; const existingChangeComments: Map = ChangeFiles.getChangeComments( this.terminal, - await this._getChangeFilesSinceBaseBranchAsync() + await this.#getChangeFilesSinceBaseBranchAsync() ); - changeFileData = await this._promptForChangeFileDataAsync( + changeFileData = await this.#promptForChangeFileDataAsync( sortedProjectList, existingChangeComments ); - if (this._isEmailRequired(changeFileData)) { - const email: string = this._changeEmailParameter.value - ? this._changeEmailParameter.value - : await this._detectOrAskForEmailAsync(); + if (this.#isEmailRequired(changeFileData)) { + const email: string = this.#changeEmailParameter.value + ? this.#changeEmailParameter.value + : await this.#detectOrAskForEmailAsync(); changeFileData.forEach((changeFile: IChangeFile) => { changeFile.email = this.rushConfiguration.getProjectByName(changeFile.packageName)?.versionPolicy ?.includeEmailInChangeFile @@ -338,19 +338,19 @@ export class ChangeAction extends BaseRushAction { } let changefiles: string[]; try { - changefiles = await this._writeChangeFilesAsync( + changefiles = await this.#writeChangeFilesAsync( changeFileData, - this._overwriteFlagParameter.value, + this.#overwriteFlagParameter.value, interactiveMode ); } catch (error) { throw new Error(`There was an error creating a change file: ${(error as Error).toString()}`); } - if (this._commitChangesFlagParameter.value || this._commitChangesMessageStringParameter.value) { + if (this.#commitChangesFlagParameter.value || this.#commitChangesMessageStringParameter.value) { if (changefiles && changefiles.length !== 0) { - await this._git.stageAndCommitGitChangesAsync( + await this.#git.stageAndCommitGitChangesAsync( changefiles, - this._commitChangesMessageStringParameter.value || + this.#commitChangesMessageStringParameter.value || this.rushConfiguration.gitChangefilesCommitMessage || 'Rush change', this.terminal @@ -361,7 +361,7 @@ export class ChangeAction extends BaseRushAction { } } - private _generateHostMap(): Map { + #generateHostMap(): Map { const hostMap: Map = new Map(); for (const project of this.rushConfiguration.projects) { let hostProjectName: string = project.packageName; @@ -376,8 +376,8 @@ export class ChangeAction extends BaseRushAction { return hostMap; } - private async _verifyAsync(): Promise { - const changedProjectNames: string[] = await this._getChangedProjectNamesAsync(); + async #verifyAsync(): Promise { + const changedProjectNames: string[] = await this.#getChangedProjectNamesAsync(); const strictValidation: boolean | undefined = this.rushConfiguration.experimentsConfiguration.configuration.strictChangefileValidation; @@ -388,12 +388,12 @@ export class ChangeAction extends BaseRushAction { if (strictValidation) { filesToValidate = await changeFilesInstance.getAllChangeFilesAsync(); } else { - filesToValidate = await this._getChangeFilesSinceBaseBranchAsync(); + filesToValidate = await this.#getChangeFilesSinceBaseBranchAsync(); } if (changedProjectNames.length > 0 || filesToValidate.length > 0) { const deletedProjectNames: Set | undefined = strictValidation - ? await this._getDeletedProjectNamesAsync() + ? await this.#getDeletedProjectNamesAsync() : undefined; await changeFilesInstance.validateAsync({ @@ -403,26 +403,26 @@ export class ChangeAction extends BaseRushAction { deletedProjectNames }); } else { - this._logNoChangeFileRequired(); + this.#logNoChangeFileRequired(); } } - private async _getTargetBranchAsync(): Promise { - if (!this._targetBranchName) { - this._targetBranchName = - this._targetBranchParameter.value || (await this._git.getRemoteDefaultBranchAsync()); + async #getTargetBranchAsync(): Promise { + if (!this.#targetBranchName) { + this.#targetBranchName = + this.#targetBranchParameter.value || (await this.#git.getRemoteDefaultBranchAsync()); } - return this._targetBranchName; + return this.#targetBranchName; } - private async _getChangedProjectNamesAsync(): Promise { + async #getChangedProjectNamesAsync(): Promise { const projectChangeAnalyzer: ProjectChangeAnalyzer = new ProjectChangeAnalyzer(this.rushConfiguration); const changedProjects: Set = await projectChangeAnalyzer.getChangedProjectsAsync({ - targetBranchName: await this._getTargetBranchAsync(), + targetBranchName: await this.#getTargetBranchAsync(), terminal: this.terminal, - shouldFetch: !this._noFetchParameter.value, + shouldFetch: !this.#noFetchParameter.value, // Lockfile evaluation will expand the set of projects that request change files // Not enabling, since this would be a breaking change includeExternalDependencies: false, @@ -431,7 +431,7 @@ export class ChangeAction extends BaseRushAction { // Exclude version-only changes to prevent 'rush version --bump' from triggering 'rush change --verify' excludeVersionOnlyChanges: true }); - const projectHostMap: Map = this._generateHostMap(); + const projectHostMap: Map = this.#generateHostMap(); const changedProjectNames: Set = new Set(); for (const changedProject of changedProjects) { @@ -446,17 +446,17 @@ export class ChangeAction extends BaseRushAction { return Array.from(changedProjectNames); } - private async _validateAllChangeFilesAsync(): Promise { + async #validateAllChangeFilesAsync(): Promise { if (!this.rushConfiguration.experimentsConfiguration.configuration.strictChangefileValidation) { throw new Error( - `The ${this._verifyAllParameter.longName} parameter requires the ` + + `The ${this.#verifyAllParameter.longName} parameter requires the ` + '"strictChangefileValidation" experiment to be enabled.' ); } const changeFiles: ChangeFiles = new ChangeFiles(this.rushConfiguration); const allChangeFiles: string[] = await changeFiles.getAllChangeFilesAsync(); - const deletedProjectNames: Set = await this._getDeletedProjectNamesAsync(); + const deletedProjectNames: Set = await this.#getDeletedProjectNamesAsync(); await changeFiles.validateAsync({ terminal: this.terminal, filesToValidate: allChangeFiles, @@ -469,15 +469,15 @@ export class ChangeAction extends BaseRushAction { * Compares the current rush.json project list against the target branch to find * projects that were removed. */ - private async _getDeletedProjectNamesAsync(): Promise> { + async #getDeletedProjectNamesAsync(): Promise> { const repoRoot: string = getRepoRoot(this.rushConfiguration.rushJsonFolder); - const targetBranch: string = await this._getTargetBranchAsync(); - const mergeBase: string = await this._git.getMergeBaseAsync(targetBranch, this.terminal); + const targetBranch: string = await this.#getTargetBranchAsync(); + const mergeBase: string = await this.#git.getMergeBaseAsync(targetBranch, this.terminal); let oldRushJsonContent: string; try { const rushJsonRelativePath: string = path.relative(repoRoot, this.rushConfiguration.rushJsonFile); - oldRushJsonContent = await this._git.getBlobContentAsync({ + oldRushJsonContent = await this.#git.getBlobContentAsync({ blobSpec: `${mergeBase}:${rushJsonRelativePath}`, repositoryRoot: repoRoot }); @@ -500,11 +500,11 @@ export class ChangeAction extends BaseRushAction { return deletedProjectNames; } - private async _getChangeFilesSinceBaseBranchAsync(): Promise { + async #getChangeFilesSinceBaseBranchAsync(): Promise { const repoRoot: string = getRepoRoot(this.rushConfiguration.rushJsonFolder); const relativeChangesFolder: string = path.relative(repoRoot, this.rushConfiguration.changesFolder); - const targetBranch: string = await this._getTargetBranchAsync(); - const changedFiles: string[] = await this._git.getChangedFilesAsync( + const targetBranch: string = await this.#getTargetBranchAsync(); + const changedFiles: string[] = await this.#git.getChangedFilesAsync( targetBranch, this.terminal, true, @@ -522,14 +522,14 @@ export class ChangeAction extends BaseRushAction { /** * The main loop which prompts the user for information on changed projects. */ - private async _promptForChangeFileDataAsync( + async #promptForChangeFileDataAsync( sortedProjectList: string[], existingChangeComments: Map ): Promise> { const changedFileData: Map = new Map(); for (const projectName of sortedProjectList) { - const changeInfo: IChangeInfo | undefined = await this._askQuestionsAsync( + const changeInfo: IChangeInfo | undefined = await this.#askQuestionsAsync( projectName, existingChangeComments ); @@ -555,7 +555,7 @@ export class ChangeAction extends BaseRushAction { /** * Asks all questions which are needed to generate changelist for a project. */ - private async _askQuestionsAsync( + async #askQuestionsAsync( packageName: string, existingChangeComments: Map ): Promise { @@ -585,17 +585,17 @@ export class ChangeAction extends BaseRushAction { if (appendComment === 'skip') { return undefined; } else { - return await this._promptForCommentsAsync(packageName); + return await this.#promptForCommentsAsync(packageName); } } else { - return await this._promptForCommentsAsync(packageName); + return await this.#promptForCommentsAsync(packageName); } } - private async _promptForCommentsAsync( + async #promptForCommentsAsync( packageName: string ): Promise { - const bumpOptions: { [type: string]: string } = this._getBumpOptions(packageName); + const bumpOptions: { [type: string]: string } = this.#getBumpOptions(packageName); const { default: input } = await import('@inquirer/input'); const comment: string = await input({ message: `Describe changes, or ENTER if no changes:` }); @@ -626,7 +626,7 @@ export class ChangeAction extends BaseRushAction { } } - private _getBumpOptions(packageName?: string): { [type: string]: string } { + #getBumpOptions(packageName?: string): { [type: string]: string } { let bumpOptions: { [type: string]: string } = this.rushConfiguration && this.rushConfiguration.hotfixChangeEnabled ? { @@ -667,7 +667,7 @@ export class ChangeAction extends BaseRushAction { return bumpOptions; } - private _isEmailRequired(changeFileData: Map): boolean { + #isEmailRequired(changeFileData: Map): boolean { return [...changeFileData.values()].some( (changeFile) => !!this.rushConfiguration.getProjectByName(changeFile.packageName)?.versionPolicy @@ -679,14 +679,14 @@ export class ChangeAction extends BaseRushAction { * Will determine a user's email by first detecting it from their Git config, * or will ask for it if it is not found or the Git config is wrong. */ - private async _detectOrAskForEmailAsync(): Promise { + async #detectOrAskForEmailAsync(): Promise { return ( - (await this._detectAndConfirmEmailAsync()) || - (await this._promptForEmailAsync()) + (await this.#detectAndConfirmEmailAsync()) || + (await this.#promptForEmailAsync()) ); } - private _detectEmail(): string | undefined { + #detectEmail(): string | undefined { try { return child_process .execSync('git config user.email') @@ -702,8 +702,8 @@ export class ChangeAction extends BaseRushAction { * Detects the user's email address from their Git configuration, prompts the user to approve the * detected email. It returns undefined if it cannot be detected. */ - private async _detectAndConfirmEmailAsync(): Promise { - const email: string | undefined = this._detectEmail(); + async #detectAndConfirmEmailAsync(): Promise { + const email: string | undefined = this.#detectEmail(); if (email) { const { default: confirm } = await import('@inquirer/confirm'); @@ -720,7 +720,7 @@ export class ChangeAction extends BaseRushAction { /** * Asks the user for their email address */ - private async _promptForEmailAsync(): Promise { + async #promptForEmailAsync(): Promise { const { default: input } = await import('@inquirer/input'); return await input({ message: 'What is your email address?', @@ -730,9 +730,9 @@ export class ChangeAction extends BaseRushAction { }); } - private async _warnUnstagedChangesAsync(): Promise { + async #warnUnstagedChangesAsync(): Promise { try { - const hasUnstagedChanges: boolean = await this._git.hasUnstagedChangesAsync(); + const hasUnstagedChanges: boolean = await this.#git.hasUnstagedChangesAsync(); if (hasUnstagedChanges) { this.terminal.writeLine( '\n' + @@ -750,14 +750,14 @@ export class ChangeAction extends BaseRushAction { /** * Writes change files to the common/changes folder. Will prompt for overwrite if file already exists. */ - private async _writeChangeFilesAsync( + async #writeChangeFilesAsync( changeFileData: Map, overwrite: boolean, interactiveMode: boolean ): Promise { const writtenFiles: string[] = []; await changeFileData.forEach(async (changeFile: IChangeFile) => { - const writtenFile: string | undefined = await this._writeChangeFileAsync( + const writtenFile: string | undefined = await this.#writeChangeFileAsync( changeFile, overwrite, interactiveMode @@ -769,7 +769,7 @@ export class ChangeAction extends BaseRushAction { return writtenFiles; } - private async _writeChangeFileAsync( + async #writeChangeFileAsync( changeFileData: IChangeFile, overwrite: boolean, interactiveMode: boolean @@ -782,19 +782,19 @@ export class ChangeAction extends BaseRushAction { const shouldWrite: boolean = !fileExists || overwrite || - (interactiveMode ? await this._promptForOverwriteAsync(filePath) : false); + (interactiveMode ? await this.#promptForOverwriteAsync(filePath) : false); if (!interactiveMode && fileExists && !overwrite) { throw new Error(`Changefile ${filePath} already exists`); } if (shouldWrite) { - this._writeFile(filePath, output, shouldWrite && fileExists); + this.#writeFile(filePath, output, shouldWrite && fileExists); return filePath; } } - private async _promptForOverwriteAsync( + async #promptForOverwriteAsync( filePath: string ): Promise { const { default: confirm } = await import('@inquirer/confirm'); @@ -813,7 +813,7 @@ export class ChangeAction extends BaseRushAction { /** * Writes a file to disk, ensuring the directory structure up to that point exists */ - private _writeFile(fileName: string, output: string, isOverwrite: boolean): void { + #writeFile(fileName: string, output: string, isOverwrite: boolean): void { FileSystem.writeFile(fileName, output, { ensureFolderExists: true }); if (isOverwrite) { this.terminal.writeLine(`Overwrote file: ${fileName}`); @@ -822,7 +822,7 @@ export class ChangeAction extends BaseRushAction { } } - private _logNoChangeFileRequired(): void { + #logNoChangeFileRequired(): void { this.terminal.writeLine('No changes were detected to relevant packages on this branch. Nothing to do.'); } } diff --git a/libraries/rush-lib/src/cli/actions/CheckAction.ts b/libraries/rush-lib/src/cli/actions/CheckAction.ts index fcf752b0657..5bc423c5c19 100644 --- a/libraries/rush-lib/src/cli/actions/CheckAction.ts +++ b/libraries/rush-lib/src/cli/actions/CheckAction.ts @@ -10,10 +10,10 @@ import { VersionMismatchFinder } from '../../logic/versionMismatch/VersionMismat import { getVariantAsync, VARIANT_PARAMETER } from '../../api/Variants'; export class CheckAction extends BaseRushAction { - private readonly _jsonFlag: CommandLineFlagParameter; - private readonly _verboseFlag: CommandLineFlagParameter; - private readonly _subspaceParameter: CommandLineStringParameter | undefined; - private readonly _variantParameter: CommandLineStringParameter; + readonly #jsonFlag: CommandLineFlagParameter; + readonly #verboseFlag: CommandLineFlagParameter; + readonly #subspaceParameter: CommandLineStringParameter | undefined; + readonly #variantParameter: CommandLineStringParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -28,17 +28,17 @@ export class CheckAction extends BaseRushAction { parser }); - this._jsonFlag = this.defineFlagParameter({ + this.#jsonFlag = this.defineFlagParameter({ parameterLongName: '--json', description: 'If this flag is specified, output will be in JSON format.' }); - this._verboseFlag = this.defineFlagParameter({ + this.#verboseFlag = this.defineFlagParameter({ parameterLongName: '--verbose', description: 'If this flag is specified, long lists of package names will not be truncated. ' + - `This has no effect if the ${this._jsonFlag.longName} flag is also specified.` + `This has no effect if the ${this.#jsonFlag.longName} flag is also specified.` }); - this._subspaceParameter = this.defineStringParameter({ + this.#subspaceParameter = this.defineStringParameter({ parameterLongName: '--subspace', argumentName: 'SUBSPACE_NAME', description: @@ -46,11 +46,11 @@ export class CheckAction extends BaseRushAction { 'consistent only within that subspace (ignoring other subspaces). This parameter is required when ' + 'the "subspacesEnabled" setting is set to true in subspaces.json.' }); - this._variantParameter = this.defineStringParameter(VARIANT_PARAMETER); + this.#variantParameter = this.defineStringParameter(VARIANT_PARAMETER); } protected async runAsync(): Promise { - if (this.rushConfiguration.subspacesFeatureEnabled && !this._subspaceParameter) { + if (this.rushConfiguration.subspacesFeatureEnabled && !this.#subspaceParameter) { throw new Error( `The --subspace parameter must be specified with "rush check" when subspaces is enabled.` ); @@ -59,7 +59,7 @@ export class CheckAction extends BaseRushAction { const currentlyInstalledVariant: string | undefined = await this.rushConfiguration.getCurrentlyInstalledVariantAsync(); const variant: string | undefined = await getVariantAsync( - this._variantParameter, + this.#variantParameter, this.rushConfiguration, true ); @@ -67,17 +67,17 @@ export class CheckAction extends BaseRushAction { this.terminal.writeWarningLine( Colorize.yellow( `Variant '${currentlyInstalledVariant}' has been installed, but 'rush check' is currently checking the default variant. ` + - `Use 'rush ${this.actionName} ${this._variantParameter.longName} '${currentlyInstalledVariant}' to check the current installation.` + `Use 'rush ${this.actionName} ${this.#variantParameter.longName} '${currentlyInstalledVariant}' to check the current installation.` ) ); } VersionMismatchFinder.rushCheck(this.rushConfiguration, this.terminal, { variant, - printAsJson: this._jsonFlag.value, - truncateLongPackageNameLists: !this._verboseFlag.value, - subspace: this._subspaceParameter?.value - ? this.rushConfiguration.getSubspace(this._subspaceParameter.value) + printAsJson: this.#jsonFlag.value, + truncateLongPackageNameLists: !this.#verboseFlag.value, + subspace: this.#subspaceParameter?.value + ? this.rushConfiguration.getSubspace(this.#subspaceParameter.value) : this.rushConfiguration.defaultSubspace }); } diff --git a/libraries/rush-lib/src/cli/actions/DeployAction.ts b/libraries/rush-lib/src/cli/actions/DeployAction.ts index ebbf57c7eeb..62c9c33da88 100644 --- a/libraries/rush-lib/src/cli/actions/DeployAction.ts +++ b/libraries/rush-lib/src/cli/actions/DeployAction.ts @@ -21,13 +21,13 @@ import type { import type { RushConfigurationProject } from '../../api/RushConfigurationProject'; export class DeployAction extends BaseRushAction { - private readonly _logger: ILogger; - private readonly _scenario: CommandLineStringParameter; - private readonly _project: CommandLineStringParameter; - private readonly _overwrite: CommandLineFlagParameter; - private readonly _targetFolder: CommandLineStringParameter; - private readonly _createArchivePath: CommandLineStringParameter; - private readonly _createArchiveOnly: CommandLineFlagParameter; + readonly #logger: ILogger; + readonly #scenario: CommandLineStringParameter; + readonly #project: CommandLineStringParameter; + readonly #overwrite: CommandLineFlagParameter; + readonly #targetFolder: CommandLineStringParameter; + readonly #createArchivePath: CommandLineStringParameter; + readonly #createArchiveOnly: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -47,9 +47,9 @@ export class DeployAction extends BaseRushAction { safeForSimultaneousRushProcesses: true }); - this._logger = this.rushSession.getLogger('deploy'); + this.#logger = this.rushSession.getLogger('deploy'); - this._project = this.defineStringParameter({ + this.#project = this.defineStringParameter({ parameterLongName: '--project', parameterShortName: '-p', argumentName: 'PROJECT_NAME', @@ -58,7 +58,7 @@ export class DeployAction extends BaseRushAction { ' "deploymentProjectNames" setting in the deployment config file.' }); - this._scenario = this.defineStringParameter({ + this.#scenario = this.defineStringParameter({ parameterLongName: '--scenario', parameterShortName: '-s', argumentName: 'SCENARIO_NAME', @@ -68,14 +68,14 @@ export class DeployAction extends BaseRushAction { ' For example, if SCENARIO_NAME is "web", then the config file would be "common/config/rush/deploy-web.json".' }); - this._overwrite = this.defineFlagParameter({ + this.#overwrite = this.defineFlagParameter({ parameterLongName: '--overwrite', description: 'By default, deployment will fail if the target folder is not empty. SPECIFYING THIS FLAG' + ' WILL RECURSIVELY DELETE EXISTING CONTENTS OF THE TARGET FOLDER.' }); - this._targetFolder = this.defineStringParameter({ + this.#targetFolder = this.defineStringParameter({ parameterLongName: '--target-folder', parameterShortName: '-t', argumentName: 'PATH', @@ -86,7 +86,7 @@ export class DeployAction extends BaseRushAction { ' WARNING: USE CAUTION WHEN COMBINING WITH "--overwrite"' }); - this._createArchivePath = this.defineStringParameter({ + this.#createArchivePath = this.defineStringParameter({ parameterLongName: '--create-archive', argumentName: 'ARCHIVE_PATH', description: @@ -96,7 +96,7 @@ export class DeployAction extends BaseRushAction { ' to the target folder. Supported file extensions: .zip' }); - this._createArchiveOnly = this.defineFlagParameter({ + this.#createArchiveOnly = this.defineFlagParameter({ parameterLongName: '--create-archive-only', description: 'If specified, "rush deploy" will only create an archive containing the contents of the target folder.' + @@ -105,19 +105,19 @@ export class DeployAction extends BaseRushAction { } protected async runAsync(): Promise { - const scenarioName: string | undefined = this._scenario.value; + const scenarioName: string | undefined = this.#scenario.value; const { DeployScenarioConfiguration } = await import('../../logic/deploy/DeployScenarioConfiguration'); const scenarioFilePath: string = DeployScenarioConfiguration.getConfigFilePath( scenarioName, this.rushConfiguration ); const scenarioConfiguration: DeployScenarioConfiguration = DeployScenarioConfiguration.loadFromFile( - this._logger.terminal, + this.#logger.terminal, scenarioFilePath, this.rushConfiguration ); - let mainProjectName: string | undefined = this._project.value; + let mainProjectName: string | undefined = this.#project.value; if (!mainProjectName) { if (scenarioConfiguration.json.deploymentProjectNames.length === 1) { // If there is only one project, then "--project" is optional @@ -137,15 +137,15 @@ export class DeployAction extends BaseRushAction { } } - const targetRootFolder: string = this._targetFolder.value - ? path.resolve(this._targetFolder.value) + const targetRootFolder: string = this.#targetFolder.value + ? path.resolve(this.#targetFolder.value) : path.join(this.rushConfiguration.commonFolder, 'deploy'); - const createArchiveFilePath: string | undefined = this._createArchivePath.value - ? path.resolve(targetRootFolder, this._createArchivePath.value) + const createArchiveFilePath: string | undefined = this.#createArchivePath.value + ? path.resolve(targetRootFolder, this.#createArchivePath.value) : undefined; - const createArchiveOnly: boolean = this._createArchiveOnly.value; + const createArchiveOnly: boolean = this.#createArchiveOnly.value; /** * Subspaces that will be involved in deploy process. @@ -208,8 +208,8 @@ export class DeployAction extends BaseRushAction { ); const deployManager: PackageExtractor = new PackageExtractor(); await deployManager.extractAsync({ - terminal: this._logger.terminal, - overwriteExisting: !!this._overwrite.value, + terminal: this.#logger.terminal, + overwriteExisting: !!this.#overwrite.value, includeDevDependencies: scenarioConfiguration.json.includeDevDependencies, includeNpmIgnoreFiles: scenarioConfiguration.json.includeNpmIgnoreFiles, folderToCopy: scenarioConfiguration.json.folderToCopy, diff --git a/libraries/rush-lib/src/cli/actions/InitAction.ts b/libraries/rush-lib/src/cli/actions/InitAction.ts index 7eeb7480312..45be135ac4b 100644 --- a/libraries/rush-lib/src/cli/actions/InitAction.ts +++ b/libraries/rush-lib/src/cli/actions/InitAction.ts @@ -18,12 +18,12 @@ import { assetsFolderPath } from '../../utilities/PathConstants'; import { copyTemplateFileAsync } from '../../utilities/templateUtilities'; export class InitAction extends BaseConfiglessRushAction { - private readonly _overwriteParameter: CommandLineFlagParameter; - private readonly _rushExampleParameter: CommandLineFlagParameter; - private readonly _experimentsParameter: CommandLineFlagParameter; + readonly #overwriteParameter: CommandLineFlagParameter; + readonly #rushExampleParameter: CommandLineFlagParameter; + readonly #experimentsParameter: CommandLineFlagParameter; // template section name --> whether it should be commented out - private _commentedBySectionName: Map = new Map(); + #commentedBySectionName: Map = new Map(); public constructor(parser: RushCommandLineParser) { super({ @@ -35,21 +35,21 @@ export class InitAction extends BaseConfiglessRushAction { parser }); - this._overwriteParameter = this.defineFlagParameter({ + this.#overwriteParameter = this.defineFlagParameter({ parameterLongName: '--overwrite-existing', description: 'By default "rush init" will not overwrite existing config files.' + ' Specify this switch to override that. This can be useful when upgrading' + ' your repo to a newer release of Rush. WARNING: USE WITH CARE!' }); - this._rushExampleParameter = this.defineFlagParameter({ + this.#rushExampleParameter = this.defineFlagParameter({ parameterLongName: '--rush-example-repo', description: 'When copying the template config files, this uncomments fragments that are used' + ' by the "rush-example" GitHub repo, which is a sample monorepo that illustrates many Rush' + ' features. This option is primarily intended for maintaining that example.' }); - this._experimentsParameter = this.defineFlagParameter({ + this.#experimentsParameter = this.defineFlagParameter({ parameterLongName: '--include-experiments', description: 'Include features that may not be complete features, useful for demoing specific future features' + @@ -60,17 +60,17 @@ export class InitAction extends BaseConfiglessRushAction { protected async runAsync(): Promise { const initFolder: string = process.cwd(); - if (!this._overwriteParameter.value) { - if (!this._validateFolderIsEmpty(initFolder)) { + if (!this.#overwriteParameter.value) { + if (!this.#validateFolderIsEmpty(initFolder)) { throw new AlreadyReportedError(); } } - await this._copyTemplateFilesAsync(initFolder); + await this.#copyTemplateFilesAsync(initFolder); } // Check whether it's safe to run "rush init" in the current working directory. - private _validateFolderIsEmpty(initFolder: string): boolean { + #validateFolderIsEmpty(initFolder: string): boolean { if (this.rushConfiguration !== undefined) { // eslint-disable-next-line no-console console.error( @@ -113,7 +113,7 @@ export class InitAction extends BaseConfiglessRushAction { return true; } - private async _copyTemplateFilesAsync(initFolder: string): Promise { + async #copyTemplateFilesAsync(initFolder: string): Promise { // The "[dot]" base name is used for hidden files to prevent various tools from interpreting them. // For example, "npm publish" will always exclude the filename ".gitignore" const templateFilePaths: string[] = [ @@ -143,7 +143,7 @@ export class InitAction extends BaseConfiglessRushAction { const experimentalTemplateFilePaths: string[] = ['common/config/rush/rush-alerts.json']; - if (this._experimentsParameter.value) { + if (this.#experimentsParameter.value) { templateFilePaths.push(...experimentalTemplateFilePaths); } @@ -163,8 +163,8 @@ export class InitAction extends BaseConfiglessRushAction { await copyTemplateFileAsync( sourcePath, destinationPath, - this._overwriteParameter.value, - !this._rushExampleParameter.value + this.#overwriteParameter.value, + !this.#rushExampleParameter.value ); } } diff --git a/libraries/rush-lib/src/cli/actions/InitAutoinstallerAction.ts b/libraries/rush-lib/src/cli/actions/InitAutoinstallerAction.ts index aebc4408103..1fea2fb46af 100644 --- a/libraries/rush-lib/src/cli/actions/InitAutoinstallerAction.ts +++ b/libraries/rush-lib/src/cli/actions/InitAutoinstallerAction.ts @@ -10,7 +10,7 @@ import type { RushCommandLineParser } from '../RushCommandLineParser'; import { Autoinstaller } from '../../logic/Autoinstaller'; export class InitAutoinstallerAction extends BaseRushAction { - private readonly _name: IRequiredCommandLineStringParameter; + readonly #name: IRequiredCommandLineStringParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -23,7 +23,7 @@ export class InitAutoinstallerAction extends BaseRushAction { parser }); - this._name = this.defineStringParameter({ + this.#name = this.defineStringParameter({ parameterLongName: '--name', argumentName: 'AUTOINSTALLER_NAME', required: true, @@ -33,7 +33,7 @@ export class InitAutoinstallerAction extends BaseRushAction { } protected async runAsync(): Promise { - const autoinstallerName: string = this._name.value; + const autoinstallerName: string = this.#name.value; const autoinstaller: Autoinstaller = new Autoinstaller({ autoinstallerName, diff --git a/libraries/rush-lib/src/cli/actions/InitDeployAction.ts b/libraries/rush-lib/src/cli/actions/InitDeployAction.ts index 6f7d996d7e7..3c8289be84e 100644 --- a/libraries/rush-lib/src/cli/actions/InitDeployAction.ts +++ b/libraries/rush-lib/src/cli/actions/InitDeployAction.ts @@ -18,8 +18,8 @@ import { RushConstants } from '../../logic/RushConstants'; const CONFIG_TEMPLATE_PATH: string = `${assetsFolderPath}/rush-init-deploy/scenario-template.json`; export class InitDeployAction extends BaseRushAction { - private readonly _project: IRequiredCommandLineStringParameter; - private readonly _scenario: CommandLineStringParameter; + readonly #project: IRequiredCommandLineStringParameter; + readonly #scenario: CommandLineStringParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -32,7 +32,7 @@ export class InitDeployAction extends BaseRushAction { parser }); - this._project = this.defineStringParameter({ + this.#project = this.defineStringParameter({ parameterLongName: '--project', parameterShortName: '-p', argumentName: 'PROJECT_NAME', @@ -42,7 +42,7 @@ export class InitDeployAction extends BaseRushAction { ' It will be added to the "deploymentProjectNames" setting.' }); - this._scenario = this.defineStringParameter({ + this.#scenario = this.defineStringParameter({ parameterLongName: '--scenario', parameterShortName: '-s', argumentName: 'SCENARIO', @@ -55,7 +55,7 @@ export class InitDeployAction extends BaseRushAction { protected async runAsync(): Promise { const scenarioFilePath: string = DeployScenarioConfiguration.getConfigFilePath( - this._scenario.value, + this.#scenario.value, this.rushConfiguration ); @@ -70,7 +70,7 @@ export class InitDeployAction extends BaseRushAction { // eslint-disable-next-line no-console console.log(Colorize.green('Creating scenario file: ') + scenarioFilePath); - const shortProjectName: string = this._project.value; + const shortProjectName: string = this.#project.value; const rushProject: RushConfigurationProject | undefined = this.rushConfiguration.findProjectByShorthandName(shortProjectName); if (!rushProject) { diff --git a/libraries/rush-lib/src/cli/actions/InitSubspaceAction.ts b/libraries/rush-lib/src/cli/actions/InitSubspaceAction.ts index 6659ae9ac81..b8dbeb019bd 100644 --- a/libraries/rush-lib/src/cli/actions/InitSubspaceAction.ts +++ b/libraries/rush-lib/src/cli/actions/InitSubspaceAction.ts @@ -12,7 +12,7 @@ import { type ISubspacesConfigurationJson, SubspacesConfiguration } from '../../ import { copyTemplateFileAsync } from '../../utilities/templateUtilities'; export class InitSubspaceAction extends BaseRushAction { - private readonly _subspaceNameParameter: IRequiredCommandLineStringParameter; + readonly #subspaceNameParameter: IRequiredCommandLineStringParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -23,7 +23,7 @@ export class InitSubspaceAction extends BaseRushAction { parser }); - this._subspaceNameParameter = this.defineStringParameter({ + this.#subspaceNameParameter = this.defineStringParameter({ parameterLongName: '--name', parameterShortName: '-n', argumentName: 'SUBSPACE_NAME', @@ -43,10 +43,10 @@ export class InitSubspaceAction extends BaseRushAction { .subspacesConfiguration as SubspacesConfiguration; // Verify this subspace name does not already exist const existingSubspaceNames: ReadonlySet = subspacesConfiguration.subspaceNames; - const newSubspaceName: string = this._subspaceNameParameter.value; + const newSubspaceName: string = this.#subspaceNameParameter.value; if (existingSubspaceNames.has(newSubspaceName)) { throw new Error( - `The subspace name: ${this._subspaceNameParameter.value} already exists in the subspace.json file.` + `The subspace name: ${this.#subspaceNameParameter.value} already exists in the subspace.json file.` ); } if ( diff --git a/libraries/rush-lib/src/cli/actions/InstallAction.ts b/libraries/rush-lib/src/cli/actions/InstallAction.ts index ebc828c33b1..02869db9eea 100644 --- a/libraries/rush-lib/src/cli/actions/InstallAction.ts +++ b/libraries/rush-lib/src/cli/actions/InstallAction.ts @@ -12,8 +12,8 @@ import type { Subspace } from '../../api/Subspace'; import { getVariantAsync } from '../../api/Variants'; export class InstallAction extends BaseInstallAction { - private readonly _checkOnlyParameter: CommandLineFlagParameter; - private readonly _resolutionOnlyParameter: CommandLineFlagParameter | undefined; + readonly #checkOnlyParameter: CommandLineFlagParameter; + readonly #resolutionOnlyParameter: CommandLineFlagParameter | undefined; public constructor(parser: RushCommandLineParser) { super({ @@ -45,13 +45,13 @@ export class InstallAction extends BaseInstallAction { cwd: this.parser.cwd }); - this._checkOnlyParameter = this.defineFlagParameter({ + this.#checkOnlyParameter = this.defineFlagParameter({ parameterLongName: '--check-only', description: `Only check the validity of the shrinkwrap file without performing an install.` }); if (this.rushConfiguration?.isPnpm) { - this._resolutionOnlyParameter = this.defineFlagParameter({ + this.#resolutionOnlyParameter = this.defineFlagParameter({ parameterLongName: '--resolution-only', description: `Only perform dependency resolution, useful for ensuring peer dependendencies are up to date. Note that this flag is only supported when using the pnpm package manager.` }); @@ -88,8 +88,8 @@ export class InstallAction extends BaseInstallAction { selectedProjects, pnpmFilterArgumentValues: (await this._selectionParameters?.getPnpmFilterArgumentValuesAsync(this.terminal)) ?? [], - checkOnly: this._checkOnlyParameter.value, - resolutionOnly: this._resolutionOnlyParameter?.value, + checkOnly: this.#checkOnlyParameter.value, + resolutionOnly: this.#resolutionOnlyParameter?.value, beforeInstallAsync: (subspace: Subspace) => this.rushSession.hooks.beforeInstall.promise(this, subspace, variant), afterInstallAsync: (subspace: Subspace) => diff --git a/libraries/rush-lib/src/cli/actions/LinkAction.ts b/libraries/rush-lib/src/cli/actions/LinkAction.ts index eabf19c414c..52cca5068df 100644 --- a/libraries/rush-lib/src/cli/actions/LinkAction.ts +++ b/libraries/rush-lib/src/cli/actions/LinkAction.ts @@ -8,7 +8,7 @@ import type { BaseLinkManager } from '../../logic/base/BaseLinkManager'; import { BaseRushAction } from './BaseRushAction'; export class LinkAction extends BaseRushAction { - private readonly _force: CommandLineFlagParameter; + readonly #force: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -22,7 +22,7 @@ export class LinkAction extends BaseRushAction { parser }); - this._force = this.defineFlagParameter({ + this.#force = this.defineFlagParameter({ parameterLongName: '--force', parameterShortName: '-f', description: @@ -39,6 +39,6 @@ export class LinkAction extends BaseRushAction { const linkManager: BaseLinkManager = linkManagerFactoryModule.LinkManagerFactory.getLinkManager( this.rushConfiguration ); - await linkManager.createSymlinksForProjectsAsync(this._force.value); + await linkManager.createSymlinksForProjectsAsync(this.#force.value); } } diff --git a/libraries/rush-lib/src/cli/actions/LinkPackageAction.ts b/libraries/rush-lib/src/cli/actions/LinkPackageAction.ts index 1d8352811f8..260ad109747 100644 --- a/libraries/rush-lib/src/cli/actions/LinkPackageAction.ts +++ b/libraries/rush-lib/src/cli/actions/LinkPackageAction.ts @@ -41,7 +41,7 @@ export class LinkPackageAction extends BaseHotlinkPackageAction { }); } - private async _getProjectsToLinkAsync(): Promise> { + async #getProjectsToLinkAsync(): Promise> { const projectsToLink: Set = new Set(); const projectNames: readonly string[] = this._projectListParameter.values; @@ -70,7 +70,7 @@ export class LinkPackageAction extends BaseHotlinkPackageAction { linkedPackagePath: string, hotlinkManager: HotlinkManager ): Promise { - const projectsToLink: Set = await this._getProjectsToLinkAsync(); + const projectsToLink: Set = await this.#getProjectsToLinkAsync(); await Async.forEachAsync( projectsToLink, async (project) => { diff --git a/libraries/rush-lib/src/cli/actions/ListAction.ts b/libraries/rush-lib/src/cli/actions/ListAction.ts index 76583015535..124f7d7df29 100644 --- a/libraries/rush-lib/src/cli/actions/ListAction.ts +++ b/libraries/rush-lib/src/cli/actions/ListAction.ts @@ -56,12 +56,12 @@ export interface IJsonOutput { } export class ListAction extends BaseRushAction { - private readonly _version: CommandLineFlagParameter; - private readonly _path: CommandLineFlagParameter; - private readonly _fullPath: CommandLineFlagParameter; - private readonly _jsonFlag: CommandLineFlagParameter; - private readonly _detailedFlag: CommandLineFlagParameter; - private readonly _selectionParameters: SelectionParameterSet; + readonly #version: CommandLineFlagParameter; + readonly #path: CommandLineFlagParameter; + readonly #fullPath: CommandLineFlagParameter; + readonly #jsonFlag: CommandLineFlagParameter; + readonly #detailedFlag: CommandLineFlagParameter; + readonly #selectionParameters: SelectionParameterSet; public constructor(parser: RushCommandLineParser) { super({ @@ -75,7 +75,7 @@ export class ListAction extends BaseRushAction { safeForSimultaneousRushProcesses: true }); - this._version = this.defineFlagParameter({ + this.#version = this.defineFlagParameter({ parameterLongName: '--version', parameterShortName: '-v', description: @@ -83,7 +83,7 @@ export class ListAction extends BaseRushAction { 'displayed in a column along with the package name.' }); - this._path = this.defineFlagParameter({ + this.#path = this.defineFlagParameter({ parameterLongName: '--path', parameterShortName: '-p', description: @@ -91,14 +91,14 @@ export class ListAction extends BaseRushAction { 'displayed in a column along with the package name.' }); - this._fullPath = this.defineFlagParameter({ + this.#fullPath = this.defineFlagParameter({ parameterLongName: '--full-path', description: 'If this flag is specified, the project full path will ' + 'be displayed in a column along with the package name.' }); - this._detailedFlag = this.defineFlagParameter({ + this.#detailedFlag = this.defineFlagParameter({ parameterLongName: '--detailed', description: 'For the non --json view, if this flag is specified, ' + @@ -107,12 +107,12 @@ export class ListAction extends BaseRushAction { 'shouldPublish, reviewPolicy, and tags fields.' }); - this._jsonFlag = this.defineFlagParameter({ + this.#jsonFlag = this.defineFlagParameter({ parameterLongName: '--json', description: 'If this flag is specified, output will be in JSON format.' }); - this._selectionParameters = new SelectionParameterSet(this.rushConfiguration, this, { + this.#selectionParameters = new SelectionParameterSet(this.rushConfiguration, this, { gitOptions: { // Include lockfile processing since this expands the selection, and we need to select // at least the same projects selected with the same query to "rush build" @@ -128,22 +128,22 @@ export class ListAction extends BaseRushAction { protected async runAsync(): Promise { const terminal: Terminal = new Terminal(new ConsoleTerminalProvider()); const selection: Set = - await this._selectionParameters.getSelectedProjectsAsync(terminal); + await this.#selectionParameters.getSelectedProjectsAsync(terminal); Sort.sortSetBy(selection, (x: RushConfigurationProject) => x.packageName); - if (this._jsonFlag.value && this._detailedFlag.value) { + if (this.#jsonFlag.value && this.#detailedFlag.value) { throw new Error(`The parameters "--json" and "--detailed" cannot be used together.`); } - if (this._jsonFlag.value) { - this._printJson(selection); - } else if (this._version.value || this._path.value || this._fullPath.value || this._detailedFlag.value) { - await this._printListTableAsync(selection); + if (this.#jsonFlag.value) { + this.#printJson(selection); + } else if (this.#version.value || this.#path.value || this.#fullPath.value || this.#detailedFlag.value) { + await this.#printListTableAsync(selection); } else { - this._printList(selection); + this.#printList(selection); } } - private _printJson(selection: Set): void { + #printJson(selection: Set): void { const projects: IJsonEntry[] = Array.from(selection, (config: RushConfigurationProject): IJsonEntry => { let reviewCategory: undefined | string; let shouldPublish: undefined | boolean; @@ -187,32 +187,32 @@ export class ListAction extends BaseRushAction { console.log(JSON.stringify(output, undefined, 2)); } - private _printList(selection: Set): void { + #printList(selection: Set): void { for (const project of selection) { // eslint-disable-next-line no-console console.log(project.packageName); } } - private async _printListTableAsync(selection: Set): Promise { + async #printListTableAsync(selection: Set): Promise { const tableHeader: string[] = ['Project']; if (this.rushConfiguration.subspacesFeatureEnabled) { tableHeader.push('Subspace'); } - if (this._version.value || this._detailedFlag.value) { + if (this.#version.value || this.#detailedFlag.value) { tableHeader.push('Version'); } - if (this._path.value || this._detailedFlag.value) { + if (this.#path.value || this.#detailedFlag.value) { tableHeader.push('Path'); } - if (this._fullPath.value) { + if (this.#fullPath.value) { tableHeader.push('Full Path'); } - if (this._detailedFlag.value) { + if (this.#detailedFlag.value) { tableHeader.push('Version policy'); tableHeader.push('Version policy name'); tableHeader.push('Should publish'); @@ -236,19 +236,19 @@ export class ListAction extends BaseRushAction { appendToPackageRow(project.subspace.subspaceName); } - if (this._version.value || this._detailedFlag.value) { + if (this.#version.value || this.#detailedFlag.value) { appendToPackageRow(project.packageJson.version); } - if (this._path.value || this._detailedFlag.value) { + if (this.#path.value || this.#detailedFlag.value) { appendToPackageRow(project.projectRelativeFolder); } - if (this._fullPath.value) { + if (this.#fullPath.value) { appendToPackageRow(project.projectFolder); } - if (this._detailedFlag.value) { + if (this.#detailedFlag.value) { // When we HAVE a version policy let versionPolicyDefinitionName: string = ''; let versionPolicyName: string = ''; diff --git a/libraries/rush-lib/src/cli/actions/PublishAction.ts b/libraries/rush-lib/src/cli/actions/PublishAction.ts index 4363f378cfe..877eeb4eca0 100644 --- a/libraries/rush-lib/src/cli/actions/PublishAction.ts +++ b/libraries/rush-lib/src/cli/actions/PublishAction.ts @@ -32,31 +32,31 @@ import { IS_WINDOWS } from '../../utilities/executionUtilities'; import type { RushConfiguration } from '../../api/RushConfiguration'; export class PublishAction extends BaseRushAction { - private readonly _addCommitDetails: CommandLineFlagParameter; - private readonly _apply: CommandLineFlagParameter; - private readonly _includeAll: CommandLineFlagParameter; - private readonly _npmAuthToken: CommandLineStringParameter; - private readonly _npmTag: CommandLineStringParameter; - private readonly _npmAccessLevel: CommandLineChoiceParameter; - private readonly _publish: CommandLineFlagParameter; - private readonly _regenerateChangelogs: CommandLineFlagParameter; - private readonly _registryUrl: CommandLineStringParameter; - private readonly _targetBranch: CommandLineStringParameter; - private readonly _prereleaseName: CommandLineStringParameter; - private readonly _partialPrerelease: CommandLineFlagParameter; - private readonly _suffix: CommandLineStringParameter; - private readonly _force: CommandLineFlagParameter; - private readonly _versionPolicy: CommandLineStringParameter; - private readonly _applyGitTagsOnPack: CommandLineFlagParameter; - private readonly _commitId: CommandLineStringParameter; - private readonly _releaseFolder: CommandLineStringParameter; - private readonly _pack: CommandLineFlagParameter; - private readonly _ignoreGitHooksParameter: CommandLineFlagParameter; - - private _prereleaseToken!: PrereleaseToken; - private _hotfixTagOverride!: string; - private _targetNpmrcPublishFolder!: string; - private _targetNpmrcPublishPath!: string; + readonly #addCommitDetails: CommandLineFlagParameter; + readonly #apply: CommandLineFlagParameter; + readonly #includeAll: CommandLineFlagParameter; + readonly #npmAuthToken: CommandLineStringParameter; + readonly #npmTag: CommandLineStringParameter; + readonly #npmAccessLevel: CommandLineChoiceParameter; + readonly #publish: CommandLineFlagParameter; + readonly #regenerateChangelogs: CommandLineFlagParameter; + readonly #registryUrl: CommandLineStringParameter; + readonly #targetBranch: CommandLineStringParameter; + readonly #prereleaseName: CommandLineStringParameter; + readonly #partialPrerelease: CommandLineFlagParameter; + readonly #suffix: CommandLineStringParameter; + readonly #force: CommandLineFlagParameter; + readonly #versionPolicy: CommandLineStringParameter; + readonly #applyGitTagsOnPack: CommandLineFlagParameter; + readonly #commitId: CommandLineStringParameter; + readonly #releaseFolder: CommandLineStringParameter; + readonly #pack: CommandLineFlagParameter; + readonly #ignoreGitHooksParameter: CommandLineFlagParameter; + + #prereleaseToken!: PrereleaseToken; + #hotfixTagOverride!: string; + #targetNpmrcPublishFolder!: string; + #targetNpmrcPublishPath!: string; public constructor(parser: RushCommandLineParser) { super({ @@ -69,12 +69,12 @@ export class PublishAction extends BaseRushAction { parser }); - this._apply = this.defineFlagParameter({ + this.#apply = this.defineFlagParameter({ parameterLongName: '--apply', parameterShortName: '-a', description: 'If this flag is specified, the change requests will be applied to package.json files.' }); - this._targetBranch = this.defineStringParameter({ + this.#targetBranch = this.defineStringParameter({ parameterLongName: '--target-branch', parameterShortName: '-b', argumentName: 'BRANCH', @@ -82,24 +82,24 @@ export class PublishAction extends BaseRushAction { 'If this flag is specified, applied changes and deleted change requests will be ' + 'committed and merged into the target branch.' }); - this._publish = this.defineFlagParameter({ + this.#publish = this.defineFlagParameter({ parameterLongName: '--publish', parameterShortName: '-p', description: 'If this flag is specified, applied changes will be published to the NPM registry.' }); - this._addCommitDetails = this.defineFlagParameter({ + this.#addCommitDetails = this.defineFlagParameter({ parameterLongName: '--add-commit-details', parameterShortName: undefined, description: 'Adds commit author and hash to the changelog.json files for each change.' }); - this._regenerateChangelogs = this.defineFlagParameter({ + this.#regenerateChangelogs = this.defineFlagParameter({ parameterLongName: '--regenerate-changelogs', parameterShortName: undefined, description: 'Regenerates all changelog files based on the current JSON content.' }); // NPM registry related parameters - this._registryUrl = this.defineStringParameter({ + this.#registryUrl = this.defineStringParameter({ parameterLongName: '--registry', parameterShortName: '-r', argumentName: 'REGISTRY', @@ -107,7 +107,7 @@ export class PublishAction extends BaseRushAction { `Publishes to a specified NPM registry. If this is specified, it will prevent the current commit will not be ` + 'tagged.' }); - this._npmAuthToken = this.defineStringParameter({ + this.#npmAuthToken = this.defineStringParameter({ parameterLongName: '--npm-auth-token', parameterShortName: '-n', argumentName: 'TOKEN', @@ -117,7 +117,7 @@ export class PublishAction extends BaseRushAction { ' safer practice is to pass the token via an environment variable and reference it from your ' + ' common/config/rush/.npmrc-publish file.' }); - this._npmTag = this.defineStringParameter({ + this.#npmTag = this.defineStringParameter({ parameterLongName: '--tag', parameterShortName: '-t', argumentName: 'TAG', @@ -126,7 +126,7 @@ export class PublishAction extends BaseRushAction { `the package is older than the current latest, so in publishing workflows for older releases, providing ` + `a tag is important. When hotfix changes are made, this parameter defaults to 'hotfix'.` }); - this._npmAccessLevel = this.defineChoiceParameter({ + this.#npmAccessLevel = this.defineChoiceParameter({ alternatives: ['public', 'restricted'], parameterLongName: '--set-access-level', parameterShortName: undefined, @@ -139,13 +139,13 @@ export class PublishAction extends BaseRushAction { }); // NPM pack tarball related parameters - this._pack = this.defineFlagParameter({ + this.#pack = this.defineFlagParameter({ parameterLongName: '--pack', description: `Packs projects into tarballs instead of publishing to npm repository. It can only be used when ` + `--include-all is specified. If this flag is specified, NPM registry related parameters will be ignored.` }); - this._releaseFolder = this.defineStringParameter({ + this.#releaseFolder = this.defineStringParameter({ parameterLongName: '--release-folder', argumentName: 'FOLDER', description: @@ -154,7 +154,7 @@ export class PublishAction extends BaseRushAction { }); // End of NPM pack tarball related parameters - this._includeAll = this.defineFlagParameter({ + this.#includeAll = this.defineFlagParameter({ parameterLongName: '--include-all', parameterShortName: undefined, description: @@ -162,42 +162,42 @@ export class PublishAction extends BaseRushAction { 'or with a specified version policy ' + 'will be published if their version is newer than published version.' }); - this._versionPolicy = this.defineStringParameter({ + this.#versionPolicy = this.defineStringParameter({ parameterLongName: '--version-policy', argumentName: 'POLICY', description: 'Version policy name. Only projects with this version policy will be published if used ' + 'with --include-all.' }); - this._prereleaseName = this.defineStringParameter({ + this.#prereleaseName = this.defineStringParameter({ parameterLongName: '--prerelease-name', argumentName: 'NAME', description: 'Bump up to a prerelease version with the provided prerelease name. Cannot be used with --suffix' }); - this._partialPrerelease = this.defineFlagParameter({ + this.#partialPrerelease = this.defineFlagParameter({ parameterLongName: '--partial-prerelease', parameterShortName: undefined, description: 'Used with --prerelease-name. Only bump packages to a prerelease version if they have changes.' }); - this._suffix = this.defineStringParameter({ + this.#suffix = this.defineStringParameter({ parameterLongName: '--suffix', argumentName: 'SUFFIX', description: 'Append a suffix to all changed versions. Cannot be used with --prerelease-name.' }); - this._force = this.defineFlagParameter({ + this.#force = this.defineFlagParameter({ parameterLongName: '--force', parameterShortName: undefined, description: 'If this flag is specified with --publish, packages will be published with --force on npm' }); - this._applyGitTagsOnPack = this.defineFlagParameter({ + this.#applyGitTagsOnPack = this.defineFlagParameter({ parameterLongName: '--apply-git-tags-on-pack', description: `If specified with --publish and --pack, git tags will be applied for packages` + ` as if a publish was being run without --pack.` }); - this._commitId = this.defineStringParameter({ + this.#commitId = this.defineStringParameter({ parameterLongName: '--commit', parameterShortName: '-c', argumentName: 'COMMIT_ID', @@ -205,7 +205,7 @@ export class PublishAction extends BaseRushAction { `Used in conjunction with git tagging -- apply git tags at the commit hash` + ` specified. If not provided, the current HEAD will be tagged.` }); - this._ignoreGitHooksParameter = this.defineFlagParameter({ + this.#ignoreGitHooksParameter = this.defineFlagParameter({ parameterLongName: '--ignore-git-hooks', description: `Skips execution of all git hooks. Make sure you know what you are skipping.` }); @@ -225,35 +225,35 @@ export class PublishAction extends BaseRushAction { ); // Example: "common\temp\publish-home" - this._targetNpmrcPublishFolder = path.join(this.rushConfiguration.commonTempFolder, 'publish-home'); + this.#targetNpmrcPublishFolder = path.join(this.rushConfiguration.commonTempFolder, 'publish-home'); // Example: "common\temp\publish-home\.npmrc" - this._targetNpmrcPublishPath = path.join(this._targetNpmrcPublishFolder, '.npmrc'); + this.#targetNpmrcPublishPath = path.join(this.#targetNpmrcPublishFolder, '.npmrc'); const allPackages: ReadonlyMap = this.rushConfiguration.projectsByName; - if (this._regenerateChangelogs.value) { + if (this.#regenerateChangelogs.value) { // eslint-disable-next-line no-console console.log('Regenerating changelogs'); ChangelogGenerator.regenerateChangelogs(allPackages, this.rushConfiguration); return; } - this._validate(); + this.#validate(); - this._addNpmPublishHome(this.rushConfiguration.isPnpm); + this.#addNpmPublishHome(this.rushConfiguration.isPnpm); const git: Git = new Git(this.rushConfiguration); - const publishGit: PublishGit = new PublishGit(git, this._targetBranch.value); - if (this._includeAll.value) { - await this._publishAllAsync(publishGit, allPackages); + const publishGit: PublishGit = new PublishGit(git, this.#targetBranch.value); + if (this.#includeAll.value) { + await this.#publishAllAsync(publishGit, allPackages); } else { - this._prereleaseToken = new PrereleaseToken( - this._prereleaseName.value, - this._suffix.value, - this._partialPrerelease.value + this.#prereleaseToken = new PrereleaseToken( + this.#prereleaseName.value, + this.#suffix.value, + this.#partialPrerelease.value ); - await this._publishChangesAsync(git, publishGit, allPackages); + await this.#publishChangesAsync(git, publishGit, allPackages); } // eslint-disable-next-line no-console @@ -263,25 +263,25 @@ export class PublishAction extends BaseRushAction { /** * Validate some input parameters */ - private _validate(): void { - if (this._pack.value && !this._includeAll.value) { + #validate(): void { + if (this.#pack.value && !this.#includeAll.value) { throw new Error('--pack can only be used with --include-all'); } - if (this._releaseFolder.value && !this._pack.value) { + if (this.#releaseFolder.value && !this.#pack.value) { throw new Error(`--release-folder can only be used with --pack`); } - if (this._applyGitTagsOnPack.value && !this._pack.value) { - throw new Error(`${this._applyGitTagsOnPack.longName} must be used with ${this._pack.longName}`); + if (this.#applyGitTagsOnPack.value && !this.#pack.value) { + throw new Error(`${this.#applyGitTagsOnPack.longName} must be used with ${this.#pack.longName}`); } } - private async _publishChangesAsync( + async #publishChangesAsync( git: Git, publishGit: PublishGit, allPackages: ReadonlyMap ): Promise { const changeManager: ChangeManager = new ChangeManager(this.rushConfiguration); - await changeManager.loadAsync(this._prereleaseToken, this._addCommitDetails.value); + await changeManager.loadAsync(this.#prereleaseToken, this.#addCommitDetails.value); if (changeManager.hasChanges()) { const orderedChanges: IChangeInfo[] = changeManager.packageChanges; @@ -290,29 +290,29 @@ export class PublishAction extends BaseRushAction { // Make changes in temp branch. await publishGit.checkoutAsync(tempBranchName, true); - await this._setDependenciesBeforePublishAsync(); + await this.#setDependenciesBeforePublishAsync(); // Make changes to package.json and change logs. - changeManager.apply(this._apply.value); - await changeManager.updateChangelogAsync(this.terminal, this._apply.value); + changeManager.apply(this.#apply.value); + await changeManager.updateChangelogAsync(this.terminal, this.#apply.value); - await this._setDependenciesBeforeCommitAsync(); + await this.#setDependenciesBeforeCommitAsync(); if (await git.hasUncommittedChangesAsync()) { // Stage, commit, and push the changes to remote temp branch. await publishGit.addChangesAsync(':/*'); await publishGit.commitAsync( this.rushConfiguration.gitVersionBumpCommitMessage || DEFAULT_PACKAGE_UPDATE_MESSAGE, - !this._ignoreGitHooksParameter.value + !this.#ignoreGitHooksParameter.value ); - await publishGit.pushAsync(tempBranchName, !this._ignoreGitHooksParameter.value); + await publishGit.pushAsync(tempBranchName, !this.#ignoreGitHooksParameter.value); - await this._setDependenciesBeforePublishAsync(); + await this.#setDependenciesBeforePublishAsync(); // Override tag parameter if there is a hotfix change. for (const change of orderedChanges) { if (change.changeType === ChangeType.hotfix) { - this._hotfixTagOverride = 'hotfix'; + this.#hotfixTagOverride = 'hotfix'; break; } } @@ -322,8 +322,8 @@ export class PublishAction extends BaseRushAction { if (change.changeType && change.changeType > ChangeType.dependency) { const project: RushConfigurationProject | undefined = allPackages.get(change.packageName); if (project) { - if (!(await this._packageExistsAsync(project))) { - await this._npmPublishAsync(change.packageName, project.publishFolder); + if (!(await this.#packageExistsAsync(project))) { + await this.#npmPublishAsync(change.packageName, project.publishFolder); } else { // eslint-disable-next-line no-console console.log(`Skip ${change.packageName}. Package exists.`); @@ -335,38 +335,38 @@ export class PublishAction extends BaseRushAction { } } - await this._setDependenciesBeforeCommitAsync(); + await this.#setDependenciesBeforeCommitAsync(); // Create and push appropriate Git tags. - await this._gitAddTagsAsync(publishGit, orderedChanges); - await publishGit.pushAsync(tempBranchName, !this._ignoreGitHooksParameter.value); + await this.#gitAddTagsAsync(publishGit, orderedChanges); + await publishGit.pushAsync(tempBranchName, !this.#ignoreGitHooksParameter.value); // Now merge to target branch. - await publishGit.checkoutAsync(this._targetBranch.value!); - await publishGit.pullAsync(!this._ignoreGitHooksParameter.value); - await publishGit.mergeAsync(tempBranchName, !this._ignoreGitHooksParameter.value); - await publishGit.pushAsync(this._targetBranch.value!, !this._ignoreGitHooksParameter.value); - await publishGit.deleteBranchAsync(tempBranchName, true, !this._ignoreGitHooksParameter.value); + await publishGit.checkoutAsync(this.#targetBranch.value!); + await publishGit.pullAsync(!this.#ignoreGitHooksParameter.value); + await publishGit.mergeAsync(tempBranchName, !this.#ignoreGitHooksParameter.value); + await publishGit.pushAsync(this.#targetBranch.value!, !this.#ignoreGitHooksParameter.value); + await publishGit.deleteBranchAsync(tempBranchName, true, !this.#ignoreGitHooksParameter.value); } else { - await publishGit.checkoutAsync(this._targetBranch.value!); - await publishGit.deleteBranchAsync(tempBranchName, false, !this._ignoreGitHooksParameter.value); + await publishGit.checkoutAsync(this.#targetBranch.value!); + await publishGit.deleteBranchAsync(tempBranchName, false, !this.#ignoreGitHooksParameter.value); } } } - private async _publishAllAsync( + async #publishAllAsync( git: PublishGit, allPackages: ReadonlyMap ): Promise { // eslint-disable-next-line no-console - console.log(`Rush publish starts with includeAll and version policy ${this._versionPolicy.value}`); + console.log(`Rush publish starts with includeAll and version policy ${this.#versionPolicy.value}`); let updated: boolean = false; for (const [packageName, packageConfig] of allPackages) { if ( packageConfig.shouldPublish && - (!this._versionPolicy.value || this._versionPolicy.value === packageConfig.versionPolicyName) + (!this.#versionPolicy.value || this.#versionPolicy.value === packageConfig.versionPolicyName) ) { const applyTagAsync: (apply: boolean) => Promise = async (apply: boolean): Promise => { if (!apply) { @@ -385,22 +385,22 @@ export class PublishAction extends BaseRushAction { } await git.addTagAsync( - !!this._publish.value, + !!this.#publish.value, packageName, packageVersion, - this._commitId.value, - this._prereleaseName.value + this.#commitId.value, + this.#prereleaseName.value ); updated = true; }; - if (this._pack.value) { + if (this.#pack.value) { // packs to tarball instead of publishing to NPM repository - await this._npmPackAsync(packageName, packageConfig); - await applyTagAsync(this._applyGitTagsOnPack.value); - } else if (this._force.value || !(await this._packageExistsAsync(packageConfig))) { + await this.#npmPackAsync(packageName, packageConfig); + await applyTagAsync(this.#applyGitTagsOnPack.value); + } else if (this.#force.value || !(await this.#packageExistsAsync(packageConfig))) { // Publish to npm repository - await this._npmPublishAsync(packageName, packageConfig.publishFolder); + await this.#npmPublishAsync(packageName, packageConfig.publishFolder); await applyTagAsync(true); } else { // eslint-disable-next-line no-console @@ -410,11 +410,11 @@ export class PublishAction extends BaseRushAction { } if (updated) { - await git.pushAsync(this._targetBranch.value!, !this._ignoreGitHooksParameter.value); + await git.pushAsync(this.#targetBranch.value!, !this.#ignoreGitHooksParameter.value); } } - private async _gitAddTagsAsync(git: PublishGit, orderedChanges: IChangeInfo[]): Promise { + async #gitAddTagsAsync(git: PublishGit, orderedChanges: IChangeInfo[]): Promise { for (const change of orderedChanges) { if ( change.changeType && @@ -422,35 +422,35 @@ export class PublishAction extends BaseRushAction { this.rushConfiguration.projectsByName.get(change.packageName)!.shouldPublish ) { await git.addTagAsync( - !!this._publish.value && !this._registryUrl.value, + !!this.#publish.value && !this.#registryUrl.value, change.packageName, change.newVersion!, - this._commitId.value, - this._prereleaseName.value + this.#commitId.value, + this.#prereleaseName.value ); } } } - private async _npmPublishAsync(packageName: string, packagePath: string): Promise { + async #npmPublishAsync(packageName: string, packagePath: string): Promise { const env: { [key: string]: string | undefined } = PublishUtilities.getEnvArgs(); const args: string[] = ['publish']; if (this.rushConfiguration.projectsByName.get(packageName)!.shouldPublish) { - this._addSharedNpmConfig(env, args); + this.#addSharedNpmConfig(env, args); - if (this._npmTag.value) { - args.push(`--tag`, this._npmTag.value); - } else if (this._hotfixTagOverride) { - args.push(`--tag`, this._hotfixTagOverride); + if (this.#npmTag.value) { + args.push(`--tag`, this.#npmTag.value); + } else if (this.#hotfixTagOverride) { + args.push(`--tag`, this.#hotfixTagOverride); } - if (this._force.value) { + if (this.#force.value) { args.push(`--force`); } - if (this._npmAccessLevel.value) { - args.push(`--access`, this._npmAccessLevel.value); + if (this.#npmAccessLevel.value) { + args.push(`--access`, this.#npmAccessLevel.value); } if (this.rushConfiguration.isPnpm) { @@ -468,10 +468,10 @@ export class PublishAction extends BaseRushAction { : this.rushConfiguration.packageManagerToolFilename; // If the auth token was specified via the command line, avoid printing it on the console - const secretSubstring: string | undefined = this._npmAuthToken.value; + const secretSubstring: string | undefined = this.#npmAuthToken.value; await PublishUtilities.execCommandAsync({ - shouldExecute: this._publish.value, + shouldExecute: this.#publish.value, command: packageManagerToolFilename, args, workingDirectory: packagePath, @@ -481,10 +481,10 @@ export class PublishAction extends BaseRushAction { } } - private async _packageExistsAsync(packageConfig: RushConfigurationProject): Promise { + async #packageExistsAsync(packageConfig: RushConfigurationProject): Promise { const env: { [key: string]: string | undefined } = PublishUtilities.getEnvArgs(); const args: string[] = []; - this._addSharedNpmConfig(env, args); + this.#addSharedNpmConfig(env, args); const publishedVersions: string[] = await Npm.getPublishedVersionsAsync( packageConfig.packageName, @@ -515,24 +515,24 @@ export class PublishAction extends BaseRushAction { return publishedVersions.indexOf(normalizedVersion) >= 0; } - private async _npmPackAsync(packageName: string, project: RushConfigurationProject): Promise { + async #npmPackAsync(packageName: string, project: RushConfigurationProject): Promise { const args: string[] = ['pack']; const env: { [key: string]: string | undefined } = PublishUtilities.getEnvArgs(); await PublishUtilities.execCommandAsync({ - shouldExecute: this._publish.value, + shouldExecute: this.#publish.value, command: this.rushConfiguration.packageManagerToolFilename, args, workingDirectory: project.publishFolder, environment: env }); - if (this._publish.value) { + if (this.#publish.value) { // Copy the tarball the release folder - const tarballName: string = this._calculateTarballName(project); + const tarballName: string = this.#calculateTarballName(project); const tarballPath: string = path.join(project.publishFolder, tarballName); - const destFolder: string = this._releaseFolder.value - ? this._releaseFolder.value + const destFolder: string = this.#releaseFolder.value + ? this.#releaseFolder.value : path.join(this.rushConfiguration.commonTempFolder, 'artifacts', 'packages'); FileSystem.move({ @@ -543,7 +543,7 @@ export class PublishAction extends BaseRushAction { } } - private _calculateTarballName(project: RushConfigurationProject): string { + #calculateTarballName(project: RushConfigurationProject): string { // Same logic as how npm forms the tarball name const packageName: string = project.packageName; const name: string = packageName[0] === '@' ? packageName.substr(1).replace(/\//g, '-') : packageName; @@ -556,12 +556,12 @@ export class PublishAction extends BaseRushAction { } } - private async _setDependenciesBeforePublishAsync(): Promise { + async #setDependenciesBeforePublishAsync(): Promise { const rushConfiguration: RushConfiguration = this.rushConfiguration; await Async.forEachAsync( rushConfiguration.projects, async ({ versionPolicy, versionPolicyName, packageName }) => { - if (!this._versionPolicy.value || this._versionPolicy.value === versionPolicyName) { + if (!this.#versionPolicy.value || this.#versionPolicy.value === versionPolicyName) { await versionPolicy?.setDependenciesBeforePublishAsync(packageName, rushConfiguration); } }, @@ -569,12 +569,12 @@ export class PublishAction extends BaseRushAction { ); } - private async _setDependenciesBeforeCommitAsync(): Promise { + async #setDependenciesBeforeCommitAsync(): Promise { const rushConfiguration: RushConfiguration = this.rushConfiguration; await Async.forEachAsync( rushConfiguration.projects, async ({ versionPolicy, versionPolicyName, packageName }) => { - if (!this._versionPolicy.value || this._versionPolicy.value === versionPolicyName) { + if (!this.#versionPolicy.value || this.#versionPolicy.value === versionPolicyName) { await versionPolicy?.setDependenciesBeforeCommitAsync(packageName, rushConfiguration); } }, @@ -582,38 +582,38 @@ export class PublishAction extends BaseRushAction { ); } - private _addNpmPublishHome(supportEnvVarFallbackSyntax: boolean): void { + #addNpmPublishHome(supportEnvVarFallbackSyntax: boolean): void { // Create "common\temp\publish-home" folder, if it doesn't exist - Utilities.createFolderWithRetry(this._targetNpmrcPublishFolder); + Utilities.createFolderWithRetry(this.#targetNpmrcPublishFolder); // Copy down the committed "common\config\rush\.npmrc-publish" file, if there is one Utilities.syncNpmrc({ sourceNpmrcFolder: this.rushConfiguration.commonRushConfigFolder, - targetNpmrcFolder: this._targetNpmrcPublishFolder, + targetNpmrcFolder: this.#targetNpmrcPublishFolder, useNpmrcPublish: true, supportEnvVarFallbackSyntax }); } - private _addSharedNpmConfig(env: { [key: string]: string | undefined }, args: string[]): void { + #addSharedNpmConfig(env: { [key: string]: string | undefined }, args: string[]): void { const userHomeEnvVariable: string = IS_WINDOWS ? 'USERPROFILE' : 'HOME'; let registry: string = '//registry.npmjs.org/'; // Check if .npmrc file exists in "common\temp\publish-home" - if (FileSystem.exists(this._targetNpmrcPublishPath)) { + if (FileSystem.exists(this.#targetNpmrcPublishPath)) { // Redirect userHomeEnvVariable, NPM will use config in "common\temp\publish-home\.npmrc" - env[userHomeEnvVariable] = this._targetNpmrcPublishFolder; + env[userHomeEnvVariable] = this.#targetNpmrcPublishFolder; } // Check if registryUrl and token are specified via command-line - if (this._registryUrl.value) { - const registryUrl: string = this._registryUrl.value; + if (this.#registryUrl.value) { + const registryUrl: string = this.#registryUrl.value; env['npm_config_registry'] = registryUrl; // eslint-disable-line dot-notation registry = registryUrl.substring(registryUrl.indexOf('//')); } - if (this._npmAuthToken.value) { - args.push(`--${registry}:_authToken=${this._npmAuthToken.value}`); + if (this.#npmAuthToken.value) { + args.push(`--${registry}:_authToken=${this.#npmAuthToken.value}`); } } } diff --git a/libraries/rush-lib/src/cli/actions/PurgeAction.ts b/libraries/rush-lib/src/cli/actions/PurgeAction.ts index 3f8e0d223ff..00a3c6b485a 100644 --- a/libraries/rush-lib/src/cli/actions/PurgeAction.ts +++ b/libraries/rush-lib/src/cli/actions/PurgeAction.ts @@ -12,7 +12,7 @@ import { UnlinkManager } from '../../logic/UnlinkManager'; import { PURGE_ACTION_NAME } from '../../utilities/actionNameConstants'; export class PurgeAction extends BaseRushAction { - private readonly _unsafeParameter: CommandLineFlagParameter; + readonly #unsafeParameter: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -25,7 +25,7 @@ export class PurgeAction extends BaseRushAction { parser }); - this._unsafeParameter = this.defineFlagParameter({ + this.#unsafeParameter = this.defineFlagParameter({ parameterLongName: '--unsafe', description: '(UNSAFE!) Also delete shared files such as the package manager instances stored in' + @@ -42,7 +42,7 @@ export class PurgeAction extends BaseRushAction { await unlinkManager.unlinkAsync(/*force:*/ true); - if (this._unsafeParameter.value!) { + if (this.#unsafeParameter.value!) { purgeManager.purgeUnsafe(); } else { purgeManager.purgeNormal(); diff --git a/libraries/rush-lib/src/cli/actions/ScanAction.ts b/libraries/rush-lib/src/cli/actions/ScanAction.ts index 3fd04e7a12e..5f634b32dcd 100644 --- a/libraries/rush-lib/src/cli/actions/ScanAction.ts +++ b/libraries/rush-lib/src/cli/actions/ScanAction.ts @@ -27,8 +27,8 @@ export interface IJsonOutput { } export class ScanAction extends BaseConfiglessRushAction { - private readonly _jsonFlag: CommandLineFlagParameter; - private readonly _allFlag: CommandLineFlagParameter; + readonly #jsonFlag: CommandLineFlagParameter; + readonly #allFlag: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -49,11 +49,11 @@ export class ScanAction extends BaseConfiglessRushAction { parser }); - this._jsonFlag = this.defineFlagParameter({ + this.#jsonFlag = this.defineFlagParameter({ parameterLongName: '--json', description: 'If this flag is specified, output will be in JSON format.' }); - this._allFlag = this.defineFlagParameter({ + this.#allFlag = this.defineFlagParameter({ parameterLongName: '--all', description: 'If this flag is specified, output will list all detected dependencies.' }); @@ -207,10 +207,10 @@ export class ScanAction extends BaseConfiglessRushAction { unusedDependencies: unusedDependencies }; - if (this._jsonFlag.value) { + if (this.#jsonFlag.value) { // eslint-disable-next-line no-console console.log(JSON.stringify(output, undefined, 2)); - } else if (this._allFlag.value) { + } else if (this.#allFlag.value) { if (detectedPackageNames.length !== 0) { // eslint-disable-next-line no-console console.log('Dependencies that seem to be imported by this project:'); diff --git a/libraries/rush-lib/src/cli/actions/UpdateAction.ts b/libraries/rush-lib/src/cli/actions/UpdateAction.ts index 5fc74900e09..ead2347597d 100644 --- a/libraries/rush-lib/src/cli/actions/UpdateAction.ts +++ b/libraries/rush-lib/src/cli/actions/UpdateAction.ts @@ -12,8 +12,8 @@ import type { Subspace } from '../../api/Subspace'; import { getVariantAsync } from '../../api/Variants'; export class UpdateAction extends BaseInstallAction { - private readonly _fullParameter: CommandLineFlagParameter; - private readonly _recheckParameter: CommandLineFlagParameter; + readonly #fullParameter: CommandLineFlagParameter; + readonly #recheckParameter: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -50,7 +50,7 @@ export class UpdateAction extends BaseInstallAction { }); } - this._fullParameter = this.defineFlagParameter({ + this.#fullParameter = this.defineFlagParameter({ parameterLongName: '--full', description: 'Normally "rush update" tries to preserve your existing installed versions' + @@ -60,7 +60,7 @@ export class UpdateAction extends BaseInstallAction { ' to the latest SemVer-compatible version. This should be done periodically by a person' + ' or robot whose role is to deal with potential upgrade regressions.' }); - this._recheckParameter = this.defineFlagParameter({ + this.#recheckParameter = this.defineFlagParameter({ parameterLongName: '--recheck', description: 'If the shrinkwrap file appears to already satisfy the package.json files,' + @@ -98,8 +98,8 @@ export class UpdateAction extends BaseInstallAction { bypassPolicyAllowed: true, bypassPolicy: this._bypassPolicyParameter.value!, noLink: this._noLinkParameter.value!, - fullUpgrade: this._fullParameter.value!, - recheckShrinkwrap: this._recheckParameter.value!, + fullUpgrade: this.#fullParameter.value!, + recheckShrinkwrap: this.#recheckParameter.value!, offline: this._offlineParameter.value!, networkConcurrency: this._networkConcurrencyParameter.value, collectLogFile: this._debugPackageManagerParameter.value!, diff --git a/libraries/rush-lib/src/cli/actions/UpdateCloudCredentialsAction.ts b/libraries/rush-lib/src/cli/actions/UpdateCloudCredentialsAction.ts index 97a792c9916..40f6b660eb3 100644 --- a/libraries/rush-lib/src/cli/actions/UpdateCloudCredentialsAction.ts +++ b/libraries/rush-lib/src/cli/actions/UpdateCloudCredentialsAction.ts @@ -11,9 +11,9 @@ import { BuildCacheConfiguration } from '../../api/BuildCacheConfiguration'; import { RushConstants } from '../../logic/RushConstants'; export class UpdateCloudCredentialsAction extends BaseRushAction { - private readonly _interactiveModeFlag: CommandLineFlagParameter; - private readonly _credentialParameter: CommandLineStringParameter; - private readonly _deleteFlag: CommandLineFlagParameter; + readonly #interactiveModeFlag: CommandLineFlagParameter; + readonly #credentialParameter: CommandLineStringParameter; + readonly #deleteFlag: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -26,17 +26,17 @@ export class UpdateCloudCredentialsAction extends BaseRushAction { parser }); - this._interactiveModeFlag = this.defineFlagParameter({ + this.#interactiveModeFlag = this.defineFlagParameter({ parameterLongName: '--interactive', parameterShortName: '-i', description: 'Run the credential update operation in interactive mode, if supported by the provider.' }); - this._credentialParameter = this.defineStringParameter({ + this.#credentialParameter = this.defineStringParameter({ parameterLongName: '--credential', argumentName: 'CREDENTIAL_STRING', description: 'A static credential, to be cached.' }); - this._deleteFlag = this.defineFlagParameter({ + this.#deleteFlag = this.defineFlagParameter({ parameterLongName: '--delete', parameterShortName: '-d', description: 'If specified, delete stored credentials.' @@ -53,10 +53,10 @@ export class UpdateCloudCredentialsAction extends BaseRushAction { this.rushSession ); - if (this._deleteFlag.value) { - if (this._interactiveModeFlag.value || this._credentialParameter.value !== undefined) { + if (this.#deleteFlag.value) { + if (this.#interactiveModeFlag.value || this.#credentialParameter.value !== undefined) { terminal.writeErrorLine( - `If the ${this._deleteFlag.longName} is provided, no other parameters may be provided.` + `If the ${this.#deleteFlag.longName} is provided, no other parameters may be provided.` ); throw new AlreadyReportedError(); } else if (buildCacheConfiguration.cloudCacheProvider) { @@ -64,24 +64,24 @@ export class UpdateCloudCredentialsAction extends BaseRushAction { } else { terminal.writeLine('A cloud build cache is not configured; there is nothing to delete.'); } - } else if (this._interactiveModeFlag.value && this._credentialParameter.value !== undefined) { + } else if (this.#interactiveModeFlag.value && this.#credentialParameter.value !== undefined) { terminal.writeErrorLine( - `Both the ${this._interactiveModeFlag.longName} and the ` + - `${this._credentialParameter.longName} parameters were provided. Only one ` + + `Both the ${this.#interactiveModeFlag.longName} and the ` + + `${this.#credentialParameter.longName} parameters were provided. Only one ` + 'or the other may be used at a time.' ); throw new AlreadyReportedError(); - } else if (this._interactiveModeFlag.value) { + } else if (this.#interactiveModeFlag.value) { if (buildCacheConfiguration.cloudCacheProvider) { await buildCacheConfiguration.cloudCacheProvider.updateCachedCredentialInteractiveAsync(terminal); } else { terminal.writeLine('A cloud build cache is not configured. Credentials are not required.'); } - } else if (this._credentialParameter.value !== undefined) { + } else if (this.#credentialParameter.value !== undefined) { if (buildCacheConfiguration.cloudCacheProvider) { await buildCacheConfiguration.cloudCacheProvider.updateCachedCredentialAsync( terminal, - this._credentialParameter.value + this.#credentialParameter.value ); } else { terminal.writeErrorLine('A cloud build cache is not configured. Credentials are not supported.'); @@ -89,9 +89,9 @@ export class UpdateCloudCredentialsAction extends BaseRushAction { } } else { terminal.writeErrorLine( - `One of the ${this._interactiveModeFlag.longName} parameter, the ` + - `${this._credentialParameter.longName} parameter, or the ` + - `${this._deleteFlag.longName} parameter must be provided.` + `One of the ${this.#interactiveModeFlag.longName} parameter, the ` + + `${this.#credentialParameter.longName} parameter, or the ` + + `${this.#deleteFlag.longName} parameter must be provided.` ); throw new AlreadyReportedError(); } diff --git a/libraries/rush-lib/src/cli/actions/UpgradeInteractiveAction.ts b/libraries/rush-lib/src/cli/actions/UpgradeInteractiveAction.ts index 273b67ba91b..e589e21e90a 100644 --- a/libraries/rush-lib/src/cli/actions/UpgradeInteractiveAction.ts +++ b/libraries/rush-lib/src/cli/actions/UpgradeInteractiveAction.ts @@ -10,9 +10,9 @@ import type * as InteractiveUpgraderType from '../../logic/InteractiveUpgrader'; import { getVariantAsync, VARIANT_PARAMETER } from '../../api/Variants'; export class UpgradeInteractiveAction extends BaseRushAction { - private _makeConsistentFlag: CommandLineFlagParameter; - private _skipUpdateFlag: CommandLineFlagParameter; - private readonly _variantParameter: CommandLineStringParameter; + #makeConsistentFlag: CommandLineFlagParameter; + #skipUpdateFlag: CommandLineFlagParameter; + readonly #variantParameter: CommandLineStringParameter; public constructor(parser: RushCommandLineParser) { const documentation: string[] = [ @@ -32,20 +32,20 @@ export class UpgradeInteractiveAction extends BaseRushAction { parser }); - this._makeConsistentFlag = this.defineFlagParameter({ + this.#makeConsistentFlag = this.defineFlagParameter({ parameterLongName: '--make-consistent', description: 'When upgrading dependencies from a single project, also upgrade dependencies from other projects.' }); - this._skipUpdateFlag = this.defineFlagParameter({ + this.#skipUpdateFlag = this.defineFlagParameter({ parameterLongName: '--skip-update', parameterShortName: '-s', description: 'If specified, the "rush update" command will not be run after updating the package.json files.' }); - this._variantParameter = this.defineStringParameter(VARIANT_PARAMETER); + this.#variantParameter = this.defineStringParameter(VARIANT_PARAMETER); } public async runAsync(): Promise { @@ -64,13 +64,13 @@ export class UpgradeInteractiveAction extends BaseRushAction { ); const variant: string | undefined = await getVariantAsync( - this._variantParameter, + this.#variantParameter, this.rushConfiguration, true ); const shouldMakeConsistent: boolean = this.rushConfiguration.defaultSubspace.shouldEnsureConsistentVersions(variant) || - this._makeConsistentFlag.value; + this.#makeConsistentFlag.value; const { projects, depsToUpgrade } = await interactiveUpgrader.upgradeAsync(); @@ -78,7 +78,7 @@ export class UpgradeInteractiveAction extends BaseRushAction { projects, packagesToAdd: depsToUpgrade.packages, updateOtherPackages: shouldMakeConsistent, - skipUpdate: this._skipUpdateFlag.value, + skipUpdate: this.#skipUpdateFlag.value, debugInstall: this.parser.isDebug, variant }); diff --git a/libraries/rush-lib/src/cli/actions/VersionAction.ts b/libraries/rush-lib/src/cli/actions/VersionAction.ts index 6eff2c1176d..97e21909acd 100644 --- a/libraries/rush-lib/src/cli/actions/VersionAction.ts +++ b/libraries/rush-lib/src/cli/actions/VersionAction.ts @@ -22,15 +22,15 @@ export const DEFAULT_PACKAGE_UPDATE_MESSAGE: string = 'Bump versions [skip ci]'; export const DEFAULT_CHANGELOG_UPDATE_MESSAGE: string = 'Update changelogs [skip ci]'; export class VersionAction extends BaseRushAction { - private readonly _ensureVersionPolicy: CommandLineFlagParameter; - private readonly _overrideVersion: CommandLineStringParameter; - private readonly _bumpVersion: CommandLineFlagParameter; - private readonly _versionPolicy: CommandLineStringParameter; - private readonly _bypassPolicy: CommandLineFlagParameter; - private readonly _targetBranch: CommandLineStringParameter; - private readonly _overwriteBump: CommandLineStringParameter; - private readonly _prereleaseIdentifier: CommandLineStringParameter; - private readonly _ignoreGitHooksParameter: CommandLineFlagParameter; + readonly #ensureVersionPolicy: CommandLineFlagParameter; + readonly #overrideVersion: CommandLineStringParameter; + readonly #bumpVersion: CommandLineFlagParameter; + readonly #versionPolicy: CommandLineStringParameter; + readonly #bypassPolicy: CommandLineFlagParameter; + readonly #targetBranch: CommandLineStringParameter; + readonly #overwriteBump: CommandLineStringParameter; + readonly #prereleaseIdentifier: CommandLineStringParameter; + readonly #ignoreGitHooksParameter: CommandLineFlagParameter; public constructor(parser: RushCommandLineParser) { super({ @@ -40,37 +40,37 @@ export class VersionAction extends BaseRushAction { parser }); - this._targetBranch = this.defineStringParameter({ + this.#targetBranch = this.defineStringParameter({ parameterLongName: '--target-branch', parameterShortName: '-b', argumentName: 'BRANCH', description: 'If this flag is specified, changes will be committed and merged into the target branch.' }); - this._ensureVersionPolicy = this.defineFlagParameter({ + this.#ensureVersionPolicy = this.defineFlagParameter({ parameterLongName: '--ensure-version-policy', description: 'Updates package versions if needed to satisfy version policies.' }); - this._overrideVersion = this.defineStringParameter({ + this.#overrideVersion = this.defineStringParameter({ parameterLongName: '--override-version', argumentName: 'NEW_VERSION', description: 'Override the version in the specified --version-policy. ' + 'This setting only works for lock-step version policy and when --ensure-version-policy is specified.' }); - this._bumpVersion = this.defineFlagParameter({ + this.#bumpVersion = this.defineFlagParameter({ parameterLongName: '--bump', description: 'Bumps package version based on version policies.' }); - this._bypassPolicy = this.defineFlagParameter({ + this.#bypassPolicy = this.defineFlagParameter({ parameterLongName: RushConstants.bypassPolicyFlagLongName, description: 'Overrides "gitPolicy" enforcement (use honorably!)' }); - this._versionPolicy = this.defineStringParameter({ + this.#versionPolicy = this.defineStringParameter({ parameterLongName: '--version-policy', argumentName: 'POLICY', description: 'The name of the version policy' }); - this._overwriteBump = this.defineStringParameter({ + this.#overwriteBump = this.defineStringParameter({ parameterLongName: '--override-bump', argumentName: 'BUMPTYPE', description: @@ -78,7 +78,7 @@ export class VersionAction extends BaseRushAction { 'Valid BUMPTYPE values include: prerelease, patch, preminor, minor, major. ' + 'This setting only works for lock-step version policy in bump action.' }); - this._prereleaseIdentifier = this.defineStringParameter({ + this.#prereleaseIdentifier = this.defineStringParameter({ parameterLongName: '--override-prerelease-id', argumentName: 'ID', description: @@ -88,7 +88,7 @@ export class VersionAction extends BaseRushAction { 'This setting increases to new prerelease id when "--bump" is provided but only replaces the ' + 'prerelease name when "--ensure-version-policy" is provided.' }); - this._ignoreGitHooksParameter = this.defineFlagParameter({ + this.#ignoreGitHooksParameter = this.defineFlagParameter({ parameterLongName: '--ignore-git-hooks', description: `Skips execution of all git hooks. Make sure you know what you are skipping.` }); @@ -100,13 +100,13 @@ export class VersionAction extends BaseRushAction { for (const subspace of this.rushConfiguration.subspaces) { await PolicyValidator.validatePolicyAsync(this.rushConfiguration, subspace, currentlyInstalledVariant, { bypassPolicyAllowed: true, - bypassPolicy: this._bypassPolicy.value + bypassPolicy: this.#bypassPolicy.value }); } const git: Git = new Git(this.rushConfiguration); const userEmail: string = await git.getGitEmailAsync(); - this._validateInput(); + this.#validateInput(); const versionManagerModule: typeof VersionManagerType = await import( /* webpackChunkName: 'VersionManager' */ '../../logic/VersionManager' @@ -117,76 +117,76 @@ export class VersionAction extends BaseRushAction { this.rushConfiguration.versionPolicyConfiguration ); - if (this._ensureVersionPolicy.value) { - this._overwritePolicyVersionIfNeeded(); + if (this.#ensureVersionPolicy.value) { + this.#overwritePolicyVersionIfNeeded(); const tempBranch: string = 'version/ensure-' + new Date().getTime(); versionManager.ensure( - this._versionPolicy.value, + this.#versionPolicy.value, true, - !!this._overrideVersion.value || !!this._prereleaseIdentifier.value + !!this.#overrideVersion.value || !!this.#prereleaseIdentifier.value ); const updatedPackages: Map = versionManager.updatedProjects; if (updatedPackages.size > 0) { // eslint-disable-next-line no-console console.log(`${updatedPackages.size} packages are getting updated.`); - await this._gitProcessAsync(tempBranch, this._targetBranch.value, currentlyInstalledVariant); + await this.#gitProcessAsync(tempBranch, this.#targetBranch.value, currentlyInstalledVariant); } - } else if (this._bumpVersion.value) { + } else if (this.#bumpVersion.value) { const tempBranch: string = 'version/bump-' + new Date().getTime(); await versionManager.bumpAsync( this.terminal, - this._versionPolicy.value, - this._overwriteBump.value ? Enum.getValueByKey(BumpType, this._overwriteBump.value) : undefined, - this._prereleaseIdentifier.value, + this.#versionPolicy.value, + this.#overwriteBump.value ? Enum.getValueByKey(BumpType, this.#overwriteBump.value) : undefined, + this.#prereleaseIdentifier.value, true ); - await this._gitProcessAsync(tempBranch, this._targetBranch.value, currentlyInstalledVariant); + await this.#gitProcessAsync(tempBranch, this.#targetBranch.value, currentlyInstalledVariant); } } - private _overwritePolicyVersionIfNeeded(): void { - if (!this._overrideVersion.value && !this._prereleaseIdentifier.value) { + #overwritePolicyVersionIfNeeded(): void { + if (!this.#overrideVersion.value && !this.#prereleaseIdentifier.value) { // No need to overwrite policy version return; } - if (this._overrideVersion.value && this._prereleaseIdentifier.value) { + if (this.#overrideVersion.value && this.#prereleaseIdentifier.value) { throw new Error( `The parameters "--override-version" and "--override-prerelease-id" cannot be used together.` ); } - if (this._versionPolicy.value) { + if (this.#versionPolicy.value) { const versionConfig: VersionPolicyConfiguration = this.rushConfiguration.versionPolicyConfiguration; const policy: LockStepVersionPolicy = versionConfig.getVersionPolicy( - this._versionPolicy.value + this.#versionPolicy.value ) as LockStepVersionPolicy; if (!policy || !policy.isLockstepped) { throw new Error(`The lockstep version policy "${policy.policyName}" is not found.`); } let newVersion: string | undefined = undefined; - if (this._overrideVersion.value) { - newVersion = this._overrideVersion.value; - } else if (this._prereleaseIdentifier.value) { + if (this.#overrideVersion.value) { + newVersion = this.#overrideVersion.value; + } else if (this.#prereleaseIdentifier.value) { const newPolicyVersion: semver.SemVer = new semver.SemVer(policy.version); if (newPolicyVersion.prerelease.length) { // Update 1.5.0-alpha.10 to 1.5.0-beta.10 // For example, if we are parsing "1.5.0-alpha.10" then the newPolicyVersion.prerelease array // would contain [ "alpha", 10 ], so we would replace "alpha" with "beta" newPolicyVersion.prerelease = [ - this._prereleaseIdentifier.value, + this.#prereleaseIdentifier.value, ...newPolicyVersion.prerelease.slice(1) ]; } else { // Update 1.5.0 to 1.5.0-beta // Since there is no length, we can just set to a new array - newPolicyVersion.prerelease = [this._prereleaseIdentifier.value]; + newPolicyVersion.prerelease = [this.#prereleaseIdentifier.value]; } newVersion = newPolicyVersion.format(); } if (newVersion) { - versionConfig.update(this._versionPolicy.value, newVersion, true); + versionConfig.update(this.#versionPolicy.value, newVersion, true); } } else { throw new Error( @@ -195,12 +195,12 @@ export class VersionAction extends BaseRushAction { } } - private _validateInput(): void { - if (this._bumpVersion.value && this._ensureVersionPolicy.value) { + #validateInput(): void { + if (this.#bumpVersion.value && this.#ensureVersionPolicy.value) { throw new Error('Please choose --bump or --ensure-version-policy but not together.'); } - if (this._overwriteBump.value && !Enum.tryGetValueByKey(BumpType, this._overwriteBump.value)) { + if (this.#overwriteBump.value && !Enum.tryGetValueByKey(BumpType, this.#overwriteBump.value)) { throw new Error( 'The value of override-bump is not valid. ' + 'Valid values include prerelease, patch, preminor, minor, and major' @@ -208,7 +208,7 @@ export class VersionAction extends BaseRushAction { } } - private _validateResult(variant: string | undefined): void { + #validateResult(variant: string | undefined): void { // Load the config from file to avoid using inconsistent in-memory data. const rushConfig: RushConfiguration = RushConfiguration.loadFromConfigurationFile( this.rushConfiguration.rushJsonFile @@ -234,13 +234,13 @@ export class VersionAction extends BaseRushAction { } } - private async _gitProcessAsync( + async #gitProcessAsync( tempBranch: string, targetBranch: string | undefined, variant: string | undefined ): Promise { // Validate the result before commit. - this._validateResult(variant); + this.#validateResult(variant); const git: Git = new Git(this.rushConfiguration); const publishGit: PublishGit = new PublishGit(git, targetBranch); @@ -262,7 +262,7 @@ export class VersionAction extends BaseRushAction { await publishGit.addChangesAsync(':/**/CHANGELOG.md'); await publishGit.commitAsync( this.rushConfiguration.gitChangeLogUpdateCommitMessage || DEFAULT_CHANGELOG_UPDATE_MESSAGE, - !this._ignoreGitHooksParameter.value + !this.#ignoreGitHooksParameter.value ); } @@ -276,25 +276,25 @@ export class VersionAction extends BaseRushAction { await publishGit.addChangesAsync(':/**/package.json'); await publishGit.commitAsync( this.rushConfiguration.gitVersionBumpCommitMessage || DEFAULT_PACKAGE_UPDATE_MESSAGE, - !this._ignoreGitHooksParameter.value + !this.#ignoreGitHooksParameter.value ); } if (changeLogUpdated || packageJsonUpdated) { - await publishGit.pushAsync(tempBranch, !this._ignoreGitHooksParameter.value, false); + await publishGit.pushAsync(tempBranch, !this.#ignoreGitHooksParameter.value, false); // Now merge to target branch. await publishGit.fetchAsync(); await publishGit.checkoutAsync(targetBranch); - await publishGit.pullAsync(!this._ignoreGitHooksParameter.value); - await publishGit.mergeAsync(tempBranch, !this._ignoreGitHooksParameter.value); - await publishGit.pushAsync(targetBranch, !this._ignoreGitHooksParameter.value, false); - await publishGit.deleteBranchAsync(tempBranch, true, !this._ignoreGitHooksParameter.value); + await publishGit.pullAsync(!this.#ignoreGitHooksParameter.value); + await publishGit.mergeAsync(tempBranch, !this.#ignoreGitHooksParameter.value); + await publishGit.pushAsync(targetBranch, !this.#ignoreGitHooksParameter.value, false); + await publishGit.deleteBranchAsync(tempBranch, true, !this.#ignoreGitHooksParameter.value); } else { // skip commits await publishGit.fetchAsync(); await publishGit.checkoutAsync(targetBranch); - await publishGit.deleteBranchAsync(tempBranch, false, !this._ignoreGitHooksParameter.value); + await publishGit.deleteBranchAsync(tempBranch, false, !this.#ignoreGitHooksParameter.value); } } } diff --git a/libraries/rush-lib/src/cli/parsing/SelectionParameterSet.ts b/libraries/rush-lib/src/cli/parsing/SelectionParameterSet.ts index 758fbb5737b..96f81580383 100644 --- a/libraries/rush-lib/src/cli/parsing/SelectionParameterSet.ts +++ b/libraries/rush-lib/src/cli/parsing/SelectionParameterSet.ts @@ -43,20 +43,20 @@ interface ISelectionParameterSetOptions { * It is a separate component such that unrelated actions can share the same parameters. */ export class SelectionParameterSet { - private readonly _rushConfiguration: RushConfiguration; + readonly #rushConfiguration: RushConfiguration; - private readonly _fromProject: CommandLineStringListParameter; - private readonly _impactedByProject: CommandLineStringListParameter; - private readonly _impactedByExceptProject: CommandLineStringListParameter; - private readonly _onlyProject: CommandLineStringListParameter; - private readonly _toProject: CommandLineStringListParameter; - private readonly _toExceptProject: CommandLineStringListParameter; - private readonly _subspaceParameter: CommandLineStringParameter | undefined; + readonly #fromProject: CommandLineStringListParameter; + readonly #impactedByProject: CommandLineStringListParameter; + readonly #impactedByExceptProject: CommandLineStringListParameter; + readonly #onlyProject: CommandLineStringListParameter; + readonly #toProject: CommandLineStringListParameter; + readonly #toExceptProject: CommandLineStringListParameter; + readonly #subspaceParameter: CommandLineStringParameter | undefined; - private readonly _fromVersionPolicy: CommandLineStringListParameter; - private readonly _toVersionPolicy: CommandLineStringListParameter; + readonly #fromVersionPolicy: CommandLineStringListParameter; + readonly #toVersionPolicy: CommandLineStringListParameter; - private readonly _selectorParserByScope: Map>; + readonly #selectorParserByScope: Map>; public constructor( rushConfiguration: RushConfiguration, @@ -64,7 +64,7 @@ export class SelectionParameterSet { options: ISelectionParameterSetOptions ) { const { gitOptions, includeSubspaceSelector, cwd } = options; - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; const selectorParsers: Map> = new Map< string, @@ -79,7 +79,7 @@ export class SelectionParameterSet { selectorParsers.set('subspace', new SubspaceSelectorParser(rushConfiguration)); selectorParsers.set('path', new PathProjectSelectorParser(rushConfiguration, cwd)); - this._selectorParserByScope = selectorParsers; + this.#selectorParserByScope = selectorParsers; const getCompletionsAsync: () => Promise = async (): Promise => { const completions: string[] = ['.']; @@ -97,7 +97,7 @@ export class SelectionParameterSet { return completions; }; - this._toProject = action.defineStringListParameter({ + this.#toProject = action.defineStringListParameter({ parameterLongName: '--to', parameterShortName: '-t', argumentName: 'PROJECT', @@ -109,7 +109,7 @@ export class SelectionParameterSet { ' For details, refer to the website article "Selecting subsets of projects".', getCompletionsAsync }); - this._toExceptProject = action.defineStringListParameter({ + this.#toExceptProject = action.defineStringListParameter({ parameterLongName: '--to-except', parameterShortName: '-T', argumentName: 'PROJECT', @@ -123,7 +123,7 @@ export class SelectionParameterSet { getCompletionsAsync }); - this._fromProject = action.defineStringListParameter({ + this.#fromProject = action.defineStringListParameter({ parameterLongName: '--from', parameterShortName: '-f', argumentName: 'PROJECT', @@ -136,7 +136,7 @@ export class SelectionParameterSet { ' For details, refer to the website article "Selecting subsets of projects".', getCompletionsAsync }); - this._onlyProject = action.defineStringListParameter({ + this.#onlyProject = action.defineStringListParameter({ parameterLongName: '--only', parameterShortName: '-o', argumentName: 'PROJECT', @@ -150,7 +150,7 @@ export class SelectionParameterSet { getCompletionsAsync }); - this._impactedByProject = action.defineStringListParameter({ + this.#impactedByProject = action.defineStringListParameter({ parameterLongName: '--impacted-by', parameterShortName: '-i', argumentName: 'PROJECT', @@ -165,7 +165,7 @@ export class SelectionParameterSet { getCompletionsAsync }); - this._impactedByExceptProject = action.defineStringListParameter({ + this.#impactedByExceptProject = action.defineStringListParameter({ parameterLongName: '--impacted-by-except', parameterShortName: '-I', argumentName: 'PROJECT', @@ -180,7 +180,7 @@ export class SelectionParameterSet { getCompletionsAsync }); - this._toVersionPolicy = action.defineStringListParameter({ + this.#toVersionPolicy = action.defineStringListParameter({ parameterLongName: '--to-version-policy', argumentName: 'VERSION_POLICY_NAME', description: @@ -190,7 +190,7 @@ export class SelectionParameterSet { ' belonging to VERSION_POLICY_NAME.' + ' For details, refer to the website article "Selecting subsets of projects".' }); - this._fromVersionPolicy = action.defineStringListParameter({ + this.#fromVersionPolicy = action.defineStringListParameter({ parameterLongName: '--from-version-policy', argumentName: 'VERSION_POLICY_NAME', description: @@ -202,7 +202,7 @@ export class SelectionParameterSet { }); if (includeSubspaceSelector) { - this._subspaceParameter = action.defineStringParameter({ + this.#subspaceParameter = action.defineStringParameter({ parameterLongName: SUBSPACE_LONG_ARG_NAME, argumentName: 'SUBSPACE_NAME', description: @@ -220,19 +220,19 @@ export class SelectionParameterSet { * such as `rush install --from thing-that-everything-depends-on`. */ public didUserSelectAnything(): boolean { - if (this._subspaceParameter?.value) { + if (this.#subspaceParameter?.value) { return true; } return [ - this._impactedByProject, - this._impactedByExceptProject, - this._onlyProject, - this._toProject, - this._fromProject, - this._toExceptProject, - this._fromVersionPolicy, - this._toVersionPolicy + this.#impactedByProject, + this.#impactedByExceptProject, + this.#onlyProject, + this.#toProject, + this.#fromProject, + this.#toExceptProject, + this.#fromVersionPolicy, + this.#toVersionPolicy ].some((x) => x.values.length > 0); } @@ -246,30 +246,30 @@ export class SelectionParameterSet { allowEmptySelection?: boolean ): Promise> { // Hack out the old version-policy parameters - for (const value of this._fromVersionPolicy.values) { - (this._fromProject.values as string[]).push(`version-policy:${value}`); + for (const value of this.#fromVersionPolicy.values) { + (this.#fromProject.values as string[]).push(`version-policy:${value}`); } - for (const value of this._toVersionPolicy.values) { - (this._toProject.values as string[]).push(`version-policy:${value}`); + for (const value of this.#toVersionPolicy.values) { + (this.#toProject.values as string[]).push(`version-policy:${value}`); } const selectors: CommandLineStringListParameter[] = [ - this._onlyProject, - this._fromProject, - this._toProject, - this._toExceptProject, - this._impactedByProject, - this._impactedByExceptProject + this.#onlyProject, + this.#fromProject, + this.#toProject, + this.#toExceptProject, + this.#impactedByProject, + this.#impactedByExceptProject ]; // Check if any of the selection parameters have a value specified on the command line const isSelectionSpecified: boolean = selectors.some((param: CommandLineStringListParameter) => param.values.length > 0) || - !!this._subspaceParameter?.value; + !!this.#subspaceParameter?.value; // If no selection parameters are specified, return everything if (!isSelectionSpecified) { - return allowEmptySelection ? new Set() : new Set(this._rushConfiguration.projects); + return allowEmptySelection ? new Set() : new Set(this.#rushConfiguration.projects); } const [ @@ -287,14 +287,14 @@ export class SelectionParameterSet { impactedByExceptProjects ] = await Promise.all( selectors.map((param: CommandLineStringListParameter) => { - return this._evaluateProjectParameterAsync(param, terminal); + return this.#evaluateProjectParameterAsync(param, terminal); }) ); let subspaceProjects: Iterable = []; - if (this._subspaceParameter?.value) { - if (!this._rushConfiguration.subspacesFeatureEnabled) { + if (this.#subspaceParameter?.value) { + if (!this.#rushConfiguration.subspacesFeatureEnabled) { // eslint-disable-next-line no-console console.log(); // eslint-disable-next-line no-console @@ -307,7 +307,7 @@ export class SelectionParameterSet { throw new AlreadyReportedError(); } - const subspace: Subspace = this._rushConfiguration.getSubspace(this._subspaceParameter.value); + const subspace: Subspace = this.#rushConfiguration.getSubspace(this.#subspaceParameter.value); subspaceProjects = subspace.getProjects(); } @@ -352,20 +352,20 @@ export class SelectionParameterSet { const args: string[] = []; // Include exactly these projects (--only) - for (const project of await this._evaluateProjectParameterAsync(this._onlyProject, terminal)) { + for (const project of await this.#evaluateProjectParameterAsync(this.#onlyProject, terminal)) { args.push(project.packageName); } // Include all projects that depend on these projects, and all dependencies thereof const fromProjects: Set = Selection.union( // --from - await this._evaluateProjectParameterAsync(this._fromProject, terminal) + await this.#evaluateProjectParameterAsync(this.#fromProject, terminal) ); // All specified projects and all projects that they depend on for (const project of Selection.union( // --to - await this._evaluateProjectParameterAsync(this._toProject, terminal), + await this.#evaluateProjectParameterAsync(this.#toProject, terminal), // --from / --from-version-policy Selection.expandAllConsumers(fromProjects) )) { @@ -374,20 +374,20 @@ export class SelectionParameterSet { // --to-except // All projects that the project directly or indirectly declares as a dependency - for (const project of await this._evaluateProjectParameterAsync(this._toExceptProject, terminal)) { + for (const project of await this.#evaluateProjectParameterAsync(this.#toExceptProject, terminal)) { args.push(`${project.packageName}^...`); } // --impacted-by // The project and all projects directly or indirectly declare it as a dependency - for (const project of await this._evaluateProjectParameterAsync(this._impactedByProject, terminal)) { + for (const project of await this.#evaluateProjectParameterAsync(this.#impactedByProject, terminal)) { args.push(`...${project.packageName}`); } // --impacted-by-except // All projects that directly or indirectly declare the specified project as a dependency - for (const project of await this._evaluateProjectParameterAsync( - this._impactedByExceptProject, + for (const project of await this.#evaluateProjectParameterAsync( + this.#impactedByExceptProject, terminal )) { args.push(`...^${project.packageName}`); @@ -401,15 +401,15 @@ export class SelectionParameterSet { */ public getTelemetry(): { [key: string]: string } { return { - command_from: `${this._fromProject.values.length > 0}`, - command_impactedBy: `${this._impactedByProject.values.length > 0}`, - command_impactedByExcept: `${this._impactedByExceptProject.values.length > 0}`, - command_only: `${this._onlyProject.values.length > 0}`, - command_to: `${this._toProject.values.length > 0}`, - command_toExcept: `${this._toExceptProject.values.length > 0}`, - - command_fromVersionPolicy: `${this._fromVersionPolicy.values.length > 0}`, - command_toVersionPolicy: `${this._toVersionPolicy.values.length > 0}` + command_from: `${this.#fromProject.values.length > 0}`, + command_impactedBy: `${this.#impactedByProject.values.length > 0}`, + command_impactedByExcept: `${this.#impactedByExceptProject.values.length > 0}`, + command_only: `${this.#onlyProject.values.length > 0}`, + command_to: `${this.#toProject.values.length > 0}`, + command_toExcept: `${this.#toExceptProject.values.length > 0}`, + + command_fromVersionPolicy: `${this.#fromVersionPolicy.values.length > 0}`, + command_toVersionPolicy: `${this.#toVersionPolicy.values.length > 0}` }; } @@ -417,7 +417,7 @@ export class SelectionParameterSet { * Computes the referents of parameters that accept a project identifier. * Handles '.', unscoped names, and scoped names. */ - private async _evaluateProjectParameterAsync( + async #evaluateProjectParameterAsync( listParameter: CommandLineStringListParameter, terminal: ITerminal ): Promise> { @@ -456,12 +456,12 @@ export class SelectionParameterSet { } const handler: ISelectorParser | undefined = - this._selectorParserByScope.get(scope); + this.#selectorParserByScope.get(scope); if (!handler) { terminal.writeErrorLine( `Unsupported selector prefix "${scope}" passed to "${parameterName}": "${rawSelector}".` + ` Supported prefixes: ${Array.from( - this._selectorParserByScope.keys(), + this.#selectorParserByScope.keys(), (selectorParserScope: string) => `"${selectorParserScope}:"` ).join(', ')}` ); diff --git a/libraries/rush-lib/src/cli/scriptActions/GlobalScriptAction.ts b/libraries/rush-lib/src/cli/scriptActions/GlobalScriptAction.ts index 231508a66c7..421bd5adeaf 100644 --- a/libraries/rush-lib/src/cli/scriptActions/GlobalScriptAction.ts +++ b/libraries/rush-lib/src/cli/scriptActions/GlobalScriptAction.ts @@ -43,40 +43,40 @@ export interface IGlobalScriptActionOptions extends IBaseScriptActionOptions { - private readonly _shellCommand: string; - private readonly _autoinstallerName: string; - private readonly _autoinstallerFullPath: string; - private readonly _providedByPlugin: boolean; + readonly #shellCommand: string; + readonly #autoinstallerName: string; + readonly #autoinstallerFullPath: string; + readonly #providedByPlugin: boolean; - private _customParametersByLongName: ReadonlyMap | undefined; - private _isHandled: boolean = false; + #customParametersByLongName: ReadonlyMap | undefined; + #isHandled: boolean = false; public constructor(options: IGlobalScriptActionOptions) { super(options); const { shellCommand, providedByPlugin, autoinstallerName = '' } = options; - this._shellCommand = shellCommand; - this._providedByPlugin = providedByPlugin; - this._autoinstallerName = autoinstallerName; + this.#shellCommand = shellCommand; + this.#providedByPlugin = providedByPlugin; + this.#autoinstallerName = autoinstallerName; - if (this._autoinstallerName) { - Autoinstaller.validateName(this._autoinstallerName); + if (this.#autoinstallerName) { + Autoinstaller.validateName(this.#autoinstallerName); // Example: .../common/autoinstallers/my-task - this._autoinstallerFullPath = path.join( + this.#autoinstallerFullPath = path.join( this.rushConfiguration.commonAutoinstallersFolder, - this._autoinstallerName + this.#autoinstallerName ); - if (!FileSystem.exists(this._autoinstallerFullPath)) { + if (!FileSystem.exists(this.#autoinstallerFullPath)) { throw new Error( `The custom command "${this.actionName}" specifies an "autoinstallerName" setting` + ' but the path does not exist: ' + - this._autoinstallerFullPath + this.#autoinstallerFullPath ); } // Example: .../common/autoinstallers/my-task/package.json - const packageJsonPath: string = path.join(this._autoinstallerFullPath, 'package.json'); + const packageJsonPath: string = path.join(this.#autoinstallerFullPath, 'package.json'); if (!FileSystem.exists(packageJsonPath)) { throw new Error( `The custom command "${this.actionName}" specifies an "autoinstallerName" setting` + @@ -87,15 +87,15 @@ export class GlobalScriptAction extends BaseScriptAction { const packageJson: IPackageJson = JsonFile.load(packageJsonPath); - if (packageJson.name !== this._autoinstallerName) { + if (packageJson.name !== this.#autoinstallerName) { throw new Error( `The custom command "${this.actionName}" specifies an "autoinstallerName" setting,` + - ` but the package.json file's "name" field is not "${this._autoinstallerName}": ` + + ` but the package.json file's "name" field is not "${this.#autoinstallerName}": ` + packageJsonPath ); } } else { - this._autoinstallerFullPath = ''; + this.#autoinstallerFullPath = ''; } this.defineScriptParameters(); @@ -105,7 +105,7 @@ export class GlobalScriptAction extends BaseScriptAction { * {@inheritDoc IGlobalCommand.setHandled} */ public setHandled(): void { - this._isHandled = true; + this.#isHandled = true; } /** @@ -114,15 +114,15 @@ export class GlobalScriptAction extends BaseScriptAction { public getCustomParametersByLongName( longName: string ): TParameter { - if (!this._customParametersByLongName) { + if (!this.#customParametersByLongName) { const map: Map = new Map(); for (const [parameterJson, parameter] of this.customParameters) { map.set(parameterJson.longName, parameter); } - this._customParametersByLongName = map; + this.#customParametersByLongName = map; } - const parameter: CommandLineParameter | undefined = this._customParametersByLongName.get(longName); + const parameter: CommandLineParameter | undefined = this.#customParametersByLongName.get(longName); if (!parameter) { throw new Error( `The command "${this.actionName}" does not have a custom parameter with long name "${longName}".` @@ -132,9 +132,9 @@ export class GlobalScriptAction extends BaseScriptAction { return parameter as TParameter; } - private async _prepareAutoinstallerNameAsync(): Promise { + async #prepareAutoinstallerNameAsync(): Promise { const autoInstaller: Autoinstaller = new Autoinstaller({ - autoinstallerName: this._autoinstallerName, + autoinstallerName: this.#autoinstallerName, rushConfiguration: this.rushConfiguration, rushGlobalFolder: this.rushGlobalFolder }); @@ -158,11 +158,11 @@ export class GlobalScriptAction extends BaseScriptAction { // If a plugin hook called setHandled(), the command has been fully handled. // Skip the default shell command execution. - if (this._isHandled) { + if (this.#isHandled) { return; } - if (this._providedByPlugin) { + if (this.#providedByPlugin) { throw new Error( `The custom command "${this.actionName}" is a "${RushConstants.globalPluginCommandKind}" command, ` + 'meaning its implementation must be provided entirely by a Rush plugin. However, no plugin ' + @@ -171,7 +171,7 @@ export class GlobalScriptAction extends BaseScriptAction { ); } - if (this._shellCommand === '') { + if (this.#shellCommand === '') { throw new Error( `The custom command "${this.actionName}" has an empty "shellCommand" value, but no plugin ` + 'called setHandled() for this command. An empty "shellCommand" is intended for global ' + @@ -182,12 +182,12 @@ export class GlobalScriptAction extends BaseScriptAction { const additionalPathFolders: string[] = this.commandLineConfiguration?.additionalPathFolders.slice() || []; - if (this._autoinstallerName) { + if (this.#autoinstallerName) { await measureAsyncFn('rush:globalScriptAction:prepareAutoinstaller', () => - this._prepareAutoinstallerNameAsync() + this.#prepareAutoinstallerNameAsync() ); - const autoinstallerNameBinPath: string = path.join(this._autoinstallerFullPath, 'node_modules', '.bin'); + const autoinstallerNameBinPath: string = path.join(this.#autoinstallerFullPath, 'node_modules', '.bin'); additionalPathFolders.push(autoinstallerNameBinPath); } @@ -208,7 +208,7 @@ export class GlobalScriptAction extends BaseScriptAction { customParameterValues[i] = customParameterValue; } - let shellCommand: string = this._shellCommand; + let shellCommand: string = this.#shellCommand; if (customParameterValues.length > 0) { shellCommand += ' ' + customParameterValues.join(' '); } @@ -216,9 +216,9 @@ export class GlobalScriptAction extends BaseScriptAction { const shellCommandTokenContext: IShellCommandTokenContext | undefined = this.commandLineConfiguration?.shellCommandTokenContext; if (shellCommandTokenContext) { - shellCommand = this._expandShellCommandWithTokens(shellCommand, shellCommandTokenContext); + shellCommand = this.#expandShellCommandWithTokens(shellCommand, shellCommandTokenContext); } - this._rejectAnyTokensInShellCommand(shellCommand, shellCommandTokenContext); + this.#rejectAnyTokensInShellCommand(shellCommand, shellCommandTokenContext); const stopwatch: Stopwatch = Stopwatch.start(); @@ -257,7 +257,7 @@ export class GlobalScriptAction extends BaseScriptAction { } } - private _expandShellCommandWithTokens( + #expandShellCommandWithTokens( shellCommand: string, tokenContext: IShellCommandTokenContext ): string { @@ -268,7 +268,7 @@ export class GlobalScriptAction extends BaseScriptAction { return expandedShellCommand; } - private _rejectAnyTokensInShellCommand( + #rejectAnyTokensInShellCommand( shellCommand: string, tokenContext?: IShellCommandTokenContext ): void { diff --git a/libraries/rush-lib/src/cli/scriptActions/PhasedScriptAction.ts b/libraries/rush-lib/src/cli/scriptActions/PhasedScriptAction.ts index 7b79e36e081..dd3378cdac0 100644 --- a/libraries/rush-lib/src/cli/scriptActions/PhasedScriptAction.ts +++ b/libraries/rush-lib/src/cli/scriptActions/PhasedScriptAction.ts @@ -132,33 +132,33 @@ export class PhasedScriptAction extends BaseScriptAction i public readonly hooks: PhasedCommandHooks; public readonly sessionAbortController: AbortController; - private readonly _enableParallelism: boolean; - private readonly _allowOversubscription: boolean; - private readonly _isIncrementalBuildAllowed: boolean; - private readonly _disableBuildCache: boolean; - private readonly _originalPhases: ReadonlySet; - private readonly _initialPhases: ReadonlySet; - private readonly _watchPhases: ReadonlySet; - private readonly _watchDebounceMs: number; - private readonly _alwaysWatch: boolean; - private readonly _alwaysInstall: boolean | undefined; - private readonly _includeAllProjectsInWatchGraph: boolean; - private readonly _terminal: ITerminal; - - private readonly _changedProjectsOnlyParameter: CommandLineFlagParameter | undefined; - private readonly _selectionParameters: SelectionParameterSet; - private readonly _verboseParameter: CommandLineFlagParameter; - private readonly _parallelismParameter: CommandLineStringParameter | undefined; - private readonly _ignoreHooksParameter: CommandLineFlagParameter; - private readonly _watchParameter: CommandLineFlagParameter | undefined; - private readonly _timelineParameter: CommandLineFlagParameter | undefined; - private readonly _cobuildPlanParameter: CommandLineFlagParameter | undefined; - private readonly _installParameter: CommandLineFlagParameter | undefined; - private readonly _variantParameter: CommandLineStringParameter | undefined; - private readonly _noIPCParameter: CommandLineFlagParameter | undefined; - private readonly _nodeDiagnosticDirParameter: CommandLineStringParameter; - private readonly _debugBuildCacheIdsParameter: CommandLineFlagParameter; - private readonly _includePhaseDeps: CommandLineFlagParameter | undefined; + readonly #enableParallelism: boolean; + readonly #allowOversubscription: boolean; + readonly #isIncrementalBuildAllowed: boolean; + readonly #disableBuildCache: boolean; + readonly #originalPhases: ReadonlySet; + readonly #initialPhases: ReadonlySet; + readonly #watchPhases: ReadonlySet; + readonly #watchDebounceMs: number; + readonly #alwaysWatch: boolean; + readonly #alwaysInstall: boolean | undefined; + readonly #includeAllProjectsInWatchGraph: boolean; + readonly #terminal: ITerminal; + + readonly #changedProjectsOnlyParameter: CommandLineFlagParameter | undefined; + readonly #selectionParameters: SelectionParameterSet; + readonly #verboseParameter: CommandLineFlagParameter; + readonly #parallelismParameter: CommandLineStringParameter | undefined; + readonly #ignoreHooksParameter: CommandLineFlagParameter; + readonly #watchParameter: CommandLineFlagParameter | undefined; + readonly #timelineParameter: CommandLineFlagParameter | undefined; + readonly #cobuildPlanParameter: CommandLineFlagParameter | undefined; + readonly #installParameter: CommandLineFlagParameter | undefined; + readonly #variantParameter: CommandLineStringParameter | undefined; + readonly #noIPCParameter: CommandLineFlagParameter | undefined; + readonly #nodeDiagnosticDirParameter: CommandLineStringParameter; + readonly #debugBuildCacheIdsParameter: CommandLineFlagParameter; + readonly #includePhaseDeps: CommandLineFlagParameter | undefined; public constructor(options: IPhasedScriptActionOptions) { super(options); @@ -176,25 +176,25 @@ export class PhasedScriptAction extends BaseScriptAction i includeAllProjectsInWatchGraph, phases } = options; - this._enableParallelism = enableParallelism; - this._allowOversubscription = allowOversubscription; - this._isIncrementalBuildAllowed = incremental; - this._disableBuildCache = disableBuildCache; - this._originalPhases = originalPhases; - this._initialPhases = initialPhases; - this._watchPhases = watchPhases; - this._watchDebounceMs = watchDebounceMs; - this._alwaysWatch = alwaysWatch; - this._alwaysInstall = alwaysInstall; - this._includeAllProjectsInWatchGraph = includeAllProjectsInWatchGraph; + this.#enableParallelism = enableParallelism; + this.#allowOversubscription = allowOversubscription; + this.#isIncrementalBuildAllowed = incremental; + this.#disableBuildCache = disableBuildCache; + this.#originalPhases = originalPhases; + this.#initialPhases = initialPhases; + this.#watchPhases = watchPhases; + this.#watchDebounceMs = watchDebounceMs; + this.#alwaysWatch = alwaysWatch; + this.#alwaysInstall = alwaysInstall; + this.#includeAllProjectsInWatchGraph = includeAllProjectsInWatchGraph; this._runsBeforeInstall = false; this.sessionAbortController = new AbortController(); this.hooks = new PhasedCommandHooks(); - this._terminal = new Terminal(this.rushSession.terminalProvider); + this.#terminal = new Terminal(this.rushSession.terminalProvider); - this._parallelismParameter = this._enableParallelism + this.#parallelismParameter = this.#enableParallelism ? this.defineStringParameter({ parameterLongName: '--parallelism', parameterShortName: '-p', @@ -208,20 +208,20 @@ export class PhasedScriptAction extends BaseScriptAction i }) : undefined; - this._timelineParameter = this.defineFlagParameter({ + this.#timelineParameter = this.defineFlagParameter({ parameterLongName: '--timeline', description: 'After the build is complete, print additional statistics and CPU usage information,' + ' including an ASCII chart of the start and stop times for each operation.' }); - this._cobuildPlanParameter = this.defineFlagParameter({ + this.#cobuildPlanParameter = this.defineFlagParameter({ parameterLongName: '--log-cobuild-plan', description: '(EXPERIMENTAL) Before the build starts, log information about the cobuild state. This will include information about ' + 'clusters and the projects that are part of each cluster.' }); - this._selectionParameters = new SelectionParameterSet(this.rushConfiguration, this, { + this.#selectionParameters = new SelectionParameterSet(this.rushConfiguration, this, { gitOptions: { // Include lockfile processing since this expands the selection, and we need to select // at least the same projects selected with the same query to "rush build" @@ -233,13 +233,13 @@ export class PhasedScriptAction extends BaseScriptAction i cwd: this.parser.cwd }); - this._verboseParameter = this.defineFlagParameter({ + this.#verboseParameter = this.defineFlagParameter({ parameterLongName: '--verbose', parameterShortName: '-v', description: 'Display the logs during the build, rather than just displaying the build status summary' }); - this._includePhaseDeps = this.defineFlagParameter({ + this.#includePhaseDeps = this.defineFlagParameter({ parameterLongName: '--include-phase-deps', description: 'If the selected projects are "unsafe" (missing some dependencies), add the minimal set of phase dependencies. For example, ' + @@ -247,7 +247,7 @@ export class PhasedScriptAction extends BaseScriptAction i `Using "--impacted-by A --include-phase-deps" avoids that work by performing "_phase:test" only for downstream projects.` }); - this._changedProjectsOnlyParameter = this._isIncrementalBuildAllowed + this.#changedProjectsOnlyParameter = this.#isIncrementalBuildAllowed ? this.defineFlagParameter({ parameterLongName: '--changed-projects-only', parameterShortName: '-c', @@ -260,7 +260,7 @@ export class PhasedScriptAction extends BaseScriptAction i }) : undefined; - this._ignoreHooksParameter = this.defineFlagParameter({ + this.#ignoreHooksParameter = this.defineFlagParameter({ parameterLongName: '--ignore-hooks', description: `Skips execution of the "eventHooks" scripts defined in ${RushConstants.rushJsonFilename}. ` + @@ -268,12 +268,12 @@ export class PhasedScriptAction extends BaseScriptAction i }); // Only define the parameter if it has an effect. - this._watchParameter = - this._watchPhases.size > 0 && !this._alwaysWatch + this.#watchParameter = + this.#watchPhases.size > 0 && !this.#alwaysWatch ? this.defineFlagParameter({ parameterLongName: '--watch', description: `Starts a file watcher after initial execution finishes. Will run the following phases on affected projects: ${Array.from( - this._watchPhases, + this.#watchPhases, (phase: IPhase) => phase.name ).join(', ')}` }) @@ -281,8 +281,8 @@ export class PhasedScriptAction extends BaseScriptAction i // If `this._alwaysInstall === undefined`, Rush does not define the parameter // but a repository may still define a custom parameter with the same name. - this._installParameter = - this._alwaysInstall === false + this.#installParameter = + this.#alwaysInstall === false ? this.defineFlagParameter({ parameterLongName: '--install', description: @@ -291,13 +291,13 @@ export class PhasedScriptAction extends BaseScriptAction i }) : undefined; - this._variantParameter = - this._alwaysInstall !== undefined ? this.defineStringParameter(VARIANT_PARAMETER) : undefined; + this.#variantParameter = + this.#alwaysInstall !== undefined ? this.defineStringParameter(VARIANT_PARAMETER) : undefined; const isIpcSupported: boolean = - this._watchPhases.size > 0 && + this.#watchPhases.size > 0 && !!this.rushConfiguration.experimentsConfiguration.configuration.useIPCScriptsInWatchMode; - this._noIPCParameter = isIpcSupported + this.#noIPCParameter = isIpcSupported ? this.defineFlagParameter({ parameterLongName: '--no-ipc', description: @@ -306,7 +306,7 @@ export class PhasedScriptAction extends BaseScriptAction i }) : undefined; - this._nodeDiagnosticDirParameter = this.defineStringParameter({ + this.#nodeDiagnosticDirParameter = this.defineStringParameter({ parameterLongName: '--node-diagnostic-dir', argumentName: 'DIRECTORY', description: @@ -314,7 +314,7 @@ export class PhasedScriptAction extends BaseScriptAction i 'This directory will contain a subdirectory for each project and phase.' }); - this._debugBuildCacheIdsParameter = this.defineFlagParameter({ + this.#debugBuildCacheIdsParameter = this.defineFlagParameter({ parameterLongName: '--debug-build-cache-ids', description: 'Logs information about the components of the build cache ids for individual operations. This is useful for debugging the incremental build logic.' @@ -335,7 +335,7 @@ export class PhasedScriptAction extends BaseScriptAction i subspacesFeatureEnabled, pnpmOptions: { useWorkspaces } } = this.rushConfiguration; - if (this._alwaysInstall || this._installParameter?.value) { + if (this.#alwaysInstall || this.#installParameter?.value) { await measureAsyncFn(`${PERF_PREFIX}:install`, async () => { const { doBasicInstallAsync } = await import( /* webpackChunkName: 'doBasicInstallAsync' */ @@ -343,12 +343,12 @@ export class PhasedScriptAction extends BaseScriptAction i ); const variant: string | undefined = await getVariantAsync( - this._variantParameter, + this.#variantParameter, this.rushConfiguration, true ); await doBasicInstallAsync({ - terminal: this._terminal, + terminal: this.#terminal, rushConfiguration: this.rushConfiguration, rushGlobalFolder: this.rushGlobalFolder, isDebug: this.parser.isDebug, @@ -382,16 +382,16 @@ export class PhasedScriptAction extends BaseScriptAction i }); } - measureFn(`${PERF_PREFIX}:doBeforeTask`, () => this._doBeforeTask()); + measureFn(`${PERF_PREFIX}:doBeforeTask`, () => this.#doBeforeTask()); const hooks: PhasedCommandHooks = this.hooks; - const terminal: ITerminal = this._terminal; + const terminal: ITerminal = this.#terminal; // if this is parallelizable, then use the value from the flag (undefined or a number), // if parallelism is not enabled, then restrict to 1 core const maxParallelism: number = getNumberOfCores(); - const parallelism: Parallelism = this._enableParallelism - ? parseParallelism(this._parallelismParameter?.value) + const parallelism: Parallelism = this.#enableParallelism + ? parseParallelism(this.#parallelismParameter?.value) : 1; await measureAsyncFn(`${PERF_PREFIX}:applyStandardPlugins`, async () => { @@ -407,7 +407,7 @@ export class PhasedScriptAction extends BaseScriptAction i // Forward ignored parameters to child processes as an environment variable new IgnoredParametersPlugin().apply(hooks); - const showTimeline: boolean = this._timelineParameter?.value ?? false; + const showTimeline: boolean = this.#timelineParameter?.value ?? false; if (showTimeline) { const { ConsoleTimelinePlugin } = await import( /* webpackChunkName: 'ConsoleTimelinePlugin' */ @@ -416,7 +416,7 @@ export class PhasedScriptAction extends BaseScriptAction i new ConsoleTimelinePlugin(terminal).apply(this.hooks); } - const diagnosticDir: string | undefined = this._nodeDiagnosticDirParameter.value; + const diagnosticDir: string | undefined = this.#nodeDiagnosticDirParameter.value; if (diagnosticDir) { new NodeDiagnosticDirPlugin({ diagnosticDir @@ -446,13 +446,13 @@ export class PhasedScriptAction extends BaseScriptAction i }); } - const isQuietMode: boolean = !this._verboseParameter.value; + const isQuietMode: boolean = !this.#verboseParameter.value; - const changedProjectsOnly: boolean = !!this._changedProjectsOnlyParameter?.value; + const changedProjectsOnly: boolean = !!this.#changedProjectsOnlyParameter?.value; let buildCacheConfiguration: BuildCacheConfiguration | undefined; let cobuildConfiguration: CobuildConfiguration | undefined; - if (!this._disableBuildCache) { + if (!this.#disableBuildCache) { await measureAsyncFn(`${PERF_PREFIX}:configureBuildCache`, async () => { [buildCacheConfiguration, cobuildConfiguration] = await Promise.all([ BuildCacheConfiguration.tryLoadAsync(terminal, this.rushConfiguration, this.rushSession), @@ -468,13 +468,13 @@ export class PhasedScriptAction extends BaseScriptAction i }); } - const isWatch: boolean = this._watchParameter?.value || this._alwaysWatch; - const generateFullGraph: boolean = isWatch && this._includeAllProjectsInWatchGraph; + const isWatch: boolean = this.#watchParameter?.value || this.#alwaysWatch; + const generateFullGraph: boolean = isWatch && this.#includeAllProjectsInWatchGraph; try { const projectSelection: Set = await measureAsyncFn( `${PERF_PREFIX}:getSelectedProjects`, - () => this._selectionParameters.getSelectedProjectsAsync(terminal, generateFullGraph) + () => this.#selectionParameters.getSelectedProjectsAsync(terminal, generateFullGraph) ); const customParametersByName: Map = new Map(); @@ -490,7 +490,7 @@ export class PhasedScriptAction extends BaseScriptAction i } await measureAsyncFn(`${PERF_PREFIX}:applySituationalPlugins`, async () => { - if (isWatch && this._noIPCParameter?.value === false) { + if (isWatch && this.#noIPCParameter?.value === false) { new ( await import( /* webpackChunkName: 'IPCOperationRunnerPlugin' */ '../../logic/operations/IPCOperationRunnerPlugin' @@ -521,23 +521,23 @@ export class PhasedScriptAction extends BaseScriptAction i useDirectFileTransfersForBuildCache }).apply(this.hooks); - if (this._debugBuildCacheIdsParameter.value) { + if (this.#debugBuildCacheIdsParameter.value) { new DebugHashesPlugin(terminal).apply(this.hooks); } - } else if (!this._disableBuildCache) { + } else if (!this.#disableBuildCache) { terminal.writeVerboseLine(`Incremental strategy: output preservation`); // Explicitly disabling the build cache also disables legacy skip detection. new LegacySkipPlugin({ allowWarningsInSuccessfulBuild: buildSkipWithAllowWarningsInSuccessfulBuild, terminal, changedProjectsOnly, - isIncrementalBuildAllowed: this._isIncrementalBuildAllowed + isIncrementalBuildAllowed: this.#isIncrementalBuildAllowed }).apply(this.hooks); } else { terminal.writeVerboseLine(`Incremental strategy: none (full rebuild)`); } - const showBuildPlan: boolean = this._cobuildPlanParameter?.value ?? false; + const showBuildPlan: boolean = this.#cobuildPlanParameter?.value ?? false; if (showBuildPlan) { if (!buildCacheConfiguration?.buildCacheEnabled) { @@ -567,7 +567,7 @@ export class PhasedScriptAction extends BaseScriptAction i RushProjectConfiguration.tryLoadForProjectsAsync(relevantProjects, terminal) ); - const includePhaseDeps: boolean = this._includePhaseDeps?.value ?? false; + const includePhaseDeps: boolean = this.#includePhaseDeps?.value ?? false; const createOperationsContext: ICreateOperationsContext = { buildCacheConfiguration, @@ -575,15 +575,15 @@ export class PhasedScriptAction extends BaseScriptAction i customParameters: customParametersByName, changedProjectsOnly, includePhaseDeps, - isIncrementalBuildAllowed: this._isIncrementalBuildAllowed, + isIncrementalBuildAllowed: this.#isIncrementalBuildAllowed, isWatch, rushConfiguration: this.rushConfiguration, parallelism, phaseSelection: isWatch - ? this._watchPhases + ? this.#watchPhases : includePhaseDeps - ? this._originalPhases - : this._initialPhases, + ? this.#originalPhases + : this.#initialPhases, projectSelection, generateFullGraph, projectConfigurations @@ -622,13 +622,14 @@ export class PhasedScriptAction extends BaseScriptAction i let executionTelemetryHandler: IOperationGraphTelemetry | undefined; const { telemetry: parserTelemetry } = this.parser; if (parserTelemetry) { - const { _changedProjectsOnlyParameter: changedProjectsOnlyParameter } = this; + const changedProjectsOnlyParameter: CommandLineFlagParameter | undefined = + this.#changedProjectsOnlyParameter; executionTelemetryHandler = { changedProjectsOnlyKey: changedProjectsOnlyParameter?.scopedLongName ?? changedProjectsOnlyParameter?.longName, initialExtraData: { // Fields preserved across the command invocation - ...this._selectionParameters.getTelemetry(), + ...this.#selectionParameters.getTelemetry(), ...this.getParameterStringMap() }, nameForLog: this.actionName, @@ -645,7 +646,7 @@ export class PhasedScriptAction extends BaseScriptAction i destinations: [StdioWritable.instance], parallelism, maxParallelism, - allowOversubscription: this._allowOversubscription, + allowOversubscription: this.#allowOversubscription, isWatch, pauseNextIteration: false, getInputsSnapshotAsync, @@ -671,7 +672,7 @@ export class PhasedScriptAction extends BaseScriptAction i const executeOptions: IExecuteOperationsOptions = { graph, - ignoreHooks: !!this._ignoreHooksParameter.value, + ignoreHooks: !!this.#ignoreHooksParameter.value, isWatch, stopwatch, terminal @@ -700,7 +701,7 @@ export class PhasedScriptAction extends BaseScriptAction i graph, initialSnapshot, terminal, - debounceMs: this._watchDebounceMs + debounceMs: this.#watchDebounceMs }); watcher.clearStatus(); @@ -714,7 +715,7 @@ export class PhasedScriptAction extends BaseScriptAction i } else { await measureAsyncFn(`${PERF_PREFIX}:runInitialPhases`, () => measureAsyncFn(`${PERF_PREFIX}:executeOperations`, () => - this._executeOperationsAsync(executeOptions, initialIterationOptions) + this.#executeOperationsAsync(executeOptions, initialIterationOptions) ) ); } @@ -728,7 +729,7 @@ export class PhasedScriptAction extends BaseScriptAction i /** * Runs a set of operations and reports the results. */ - private async _executeOperationsAsync( + async #executeOperationsAsync( options: IExecuteOperationsOptions, iterationOptions: IOperationGraphIterationOptions ): Promise { @@ -773,7 +774,7 @@ export class PhasedScriptAction extends BaseScriptAction i } if (!ignoreHooks) { - measureFn(`${PERF_PREFIX}:doAfterTask`, () => this._doAfterTask()); + measureFn(`${PERF_PREFIX}:doAfterTask`, () => this.#doAfterTask()); } if (!success) { @@ -781,7 +782,7 @@ export class PhasedScriptAction extends BaseScriptAction i } } - private _doBeforeTask(): void { + #doBeforeTask(): void { if ( this.actionName !== RushConstants.buildCommandName && this.actionName !== RushConstants.rebuildCommandName @@ -792,10 +793,10 @@ export class PhasedScriptAction extends BaseScriptAction i SetupChecks.validate(this.rushConfiguration); - this.eventHooksManager.handle(Event.preRushBuild, this.parser.isDebug, this._ignoreHooksParameter.value); + this.eventHooksManager.handle(Event.preRushBuild, this.parser.isDebug, this.#ignoreHooksParameter.value); } - private _doAfterTask(): void { + #doAfterTask(): void { if ( this.actionName !== RushConstants.buildCommandName && this.actionName !== RushConstants.rebuildCommandName @@ -803,6 +804,6 @@ export class PhasedScriptAction extends BaseScriptAction i // Only collects information for built-in commands like build or rebuild. return; } - this.eventHooksManager.handle(Event.postRushBuild, this.parser.isDebug, this._ignoreHooksParameter.value); + this.eventHooksManager.handle(Event.postRushBuild, this.parser.isDebug, this.#ignoreHooksParameter.value); } } diff --git a/libraries/rush-lib/src/logic/ApprovedPackagesChecker.ts b/libraries/rush-lib/src/logic/ApprovedPackagesChecker.ts index c20f3b525d9..a0f773f5de8 100644 --- a/libraries/rush-lib/src/logic/ApprovedPackagesChecker.ts +++ b/libraries/rush-lib/src/logic/ApprovedPackagesChecker.ts @@ -9,17 +9,17 @@ import type { RushConfigurationProject } from '../api/RushConfigurationProject'; import { DependencySpecifier } from './DependencySpecifier'; export class ApprovedPackagesChecker { - private readonly _rushConfiguration: RushConfiguration; - private _approvedPackagesPolicy: ApprovedPackagesPolicy; - private _filesAreOutOfDate: boolean; + readonly #rushConfiguration: RushConfiguration; + #approvedPackagesPolicy: ApprovedPackagesPolicy; + #filesAreOutOfDate: boolean; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; - this._approvedPackagesPolicy = this._rushConfiguration.approvedPackagesPolicy; - this._filesAreOutOfDate = false; + this.#rushConfiguration = rushConfiguration; + this.#approvedPackagesPolicy = this.#rushConfiguration.approvedPackagesPolicy; + this.#filesAreOutOfDate = false; - if (this._approvedPackagesPolicy.enabled) { - this._updateApprovedPackagesPolicy(); + if (this.#approvedPackagesPolicy.enabled) { + this.#updateApprovedPackagesPolicy(); } } @@ -27,7 +27,7 @@ export class ApprovedPackagesChecker { * If true, the files on disk are out of date. */ public get approvedPackagesFilesAreOutOfDate(): boolean { - return this._filesAreOutOfDate; + return this.#filesAreOutOfDate; } /** @@ -39,25 +39,25 @@ export class ApprovedPackagesChecker { * If the "approvedPackagesPolicy" feature is not enabled, then no action is taken. */ public rewriteConfigFiles(): void { - const approvedPackagesPolicy: ApprovedPackagesPolicy = this._rushConfiguration.approvedPackagesPolicy; + const approvedPackagesPolicy: ApprovedPackagesPolicy = this.#rushConfiguration.approvedPackagesPolicy; if (approvedPackagesPolicy.enabled) { approvedPackagesPolicy.browserApprovedPackages.saveToFile(); approvedPackagesPolicy.nonbrowserApprovedPackages.saveToFile(); } } - private _updateApprovedPackagesPolicy(): void { - for (const rushProject of this._rushConfiguration.projects) { + #updateApprovedPackagesPolicy(): void { + for (const rushProject of this.#rushConfiguration.projects) { const packageJson: IPackageJson = rushProject.packageJson; - this._collectDependencies(packageJson.dependencies, this._approvedPackagesPolicy, rushProject); - this._collectDependencies(packageJson.devDependencies, this._approvedPackagesPolicy, rushProject); - this._collectDependencies(packageJson.peerDependencies, this._approvedPackagesPolicy, rushProject); - this._collectDependencies(packageJson.optionalDependencies, this._approvedPackagesPolicy, rushProject); + this.#collectDependencies(packageJson.dependencies, this.#approvedPackagesPolicy, rushProject); + this.#collectDependencies(packageJson.devDependencies, this.#approvedPackagesPolicy, rushProject); + this.#collectDependencies(packageJson.peerDependencies, this.#approvedPackagesPolicy, rushProject); + this.#collectDependencies(packageJson.optionalDependencies, this.#approvedPackagesPolicy, rushProject); } } - private _collectDependencies( + #collectDependencies( dependencies: { [key: string]: string } | undefined, approvedPackagesPolicy: ApprovedPackagesPolicy, rushProject: RushConfigurationProject @@ -80,7 +80,7 @@ export class ApprovedPackagesChecker { referencedPackageName = dependencySpecifier.aliasTarget.packageName; } - const scope: string = this._rushConfiguration.packageNameParser.getScope(referencedPackageName); + const scope: string = this.#rushConfiguration.packageNameParser.getScope(referencedPackageName); // Make sure the scope isn't something like "@types" which should be ignored if (!approvedPackagesPolicy.ignoredNpmScopes.has(scope) && rushProject.reviewCategory) { @@ -102,7 +102,7 @@ export class ApprovedPackagesChecker { ); } - this._filesAreOutOfDate = this._filesAreOutOfDate || updated; + this.#filesAreOutOfDate = this.#filesAreOutOfDate || updated; } } } diff --git a/libraries/rush-lib/src/logic/Autoinstaller.ts b/libraries/rush-lib/src/logic/Autoinstaller.ts index a47dd0d89be..0b326bdc970 100644 --- a/libraries/rush-lib/src/logic/Autoinstaller.ts +++ b/libraries/rush-lib/src/logic/Autoinstaller.ts @@ -35,15 +35,15 @@ export interface IAutoinstallerOptions { export class Autoinstaller { public readonly name: string; - private readonly _rushConfiguration: RushConfiguration; - private readonly _rushGlobalFolder: RushGlobalFolder; - private readonly _restrictConsoleOutput: boolean; + readonly #rushConfiguration: RushConfiguration; + readonly #rushGlobalFolder: RushGlobalFolder; + readonly #restrictConsoleOutput: boolean; public constructor(options: IAutoinstallerOptions) { this.name = options.autoinstallerName; - this._rushConfiguration = options.rushConfiguration; - this._rushGlobalFolder = options.rushGlobalFolder; - this._restrictConsoleOutput = + this.#rushConfiguration = options.rushConfiguration; + this.#rushGlobalFolder = options.rushGlobalFolder; + this.#restrictConsoleOutput = options.restrictConsoleOutput ?? RushCommandLineParser.shouldRestrictConsoleOutput(); Autoinstaller.validateName(this.name); @@ -51,21 +51,21 @@ export class Autoinstaller { // Example: .../common/autoinstallers/my-task public get folderFullPath(): string { - return path.join(this._rushConfiguration.commonAutoinstallersFolder, this.name); + return path.join(this.#rushConfiguration.commonAutoinstallersFolder, this.name); } // Example: .../common/autoinstallers/my-task/package-lock.yaml public get shrinkwrapFilePath(): string { return path.join( - this._rushConfiguration.commonAutoinstallersFolder, + this.#rushConfiguration.commonAutoinstallersFolder, this.name, - this._rushConfiguration.shrinkwrapFilename + this.#rushConfiguration.shrinkwrapFilename ); } // Example: .../common/autoinstallers/my-task/package.json public get packageJsonPath(): string { - return path.join(this._rushConfiguration.commonAutoinstallersFolder, this.name, 'package.json'); + return path.join(this.#rushConfiguration.commonAutoinstallersFolder, this.name, 'package.json'); } public static validateName(autoinstallerName: string): void { @@ -88,19 +88,19 @@ export class Autoinstaller { } await InstallHelpers.ensureLocalPackageManagerAsync( - this._rushConfiguration, - this._rushGlobalFolder, + this.#rushConfiguration, + this.#rushGlobalFolder, RushConstants.defaultMaxInstallAttempts, - this._restrictConsoleOutput + this.#restrictConsoleOutput ); // Example: common/autoinstallers/my-task/package.json const relativePathForLogs: string = path.relative( - this._rushConfiguration.rushJsonFolder, + this.#rushConfiguration.rushJsonFolder, autoinstallerFullPath ); - this._logIfConsoleOutputIsNotRestricted(`Acquiring lock for "${relativePathForLogs}" folder...`); + this.#logIfConsoleOutputIsNotRestricted(`Acquiring lock for "${relativePathForLogs}" folder...`); const lock: LockFile = await LockFile.acquireAsync(autoinstallerFullPath, 'autoinstaller'); @@ -117,10 +117,10 @@ export class Autoinstaller { const lastInstallFlag: LastInstallFlag = new LastInstallFlag(lastInstallFlagPath, { node: process.versions.node, - packageManager: this._rushConfiguration.packageManager, - packageManagerVersion: this._rushConfiguration.packageManagerToolVersion, + packageManager: this.#rushConfiguration.packageManager, + packageManagerVersion: this.#rushConfiguration.packageManagerToolVersion, packageJson: packageJson, - rushJsonFolder: this._rushConfiguration.rushJsonFolder + rushJsonFolder: this.#rushConfiguration.rushJsonFolder }); // Example: ../common/autoinstallers/my-task/node_modules @@ -131,9 +131,9 @@ export class Autoinstaller { if (isLastInstallFlagDirty || lock.dirtyWhenAcquired) { if (FileSystem.exists(nodeModulesFolder)) { - this._logIfConsoleOutputIsNotRestricted('Deleting old files from ' + nodeModulesFolder); + this.#logIfConsoleOutputIsNotRestricted('Deleting old files from ' + nodeModulesFolder); const recycler: AsyncRecycler = new AsyncRecycler( - `${this._rushConfiguration.commonTempFolder}/${RushConstants.rushRecyclerFolderName}` + `${this.#rushConfiguration.commonTempFolder}/${RushConstants.rushRecyclerFolderName}` ); recycler.moveFolder(nodeModulesFolder); await recycler.startDeleteAllAsync(); @@ -141,17 +141,17 @@ export class Autoinstaller { // Copy: .../common/autoinstallers/my-task/.npmrc Utilities.syncNpmrc({ - sourceNpmrcFolder: this._rushConfiguration.commonRushConfigFolder, + sourceNpmrcFolder: this.#rushConfiguration.commonRushConfigFolder, targetNpmrcFolder: autoinstallerFullPath, - supportEnvVarFallbackSyntax: this._rushConfiguration.isPnpm + supportEnvVarFallbackSyntax: this.#rushConfiguration.isPnpm }); - this._logIfConsoleOutputIsNotRestricted( + this.#logIfConsoleOutputIsNotRestricted( `Installing dependencies under ${autoinstallerFullPath}...\n` ); await Utilities.executeCommandAsync({ - command: this._rushConfiguration.packageManagerToolFilename, + command: this.#rushConfiguration.packageManagerToolFilename, args: ['install', '--frozen-lockfile'], workingDirectory: autoinstallerFullPath, keepEnvironment: true @@ -165,9 +165,9 @@ export class Autoinstaller { 'If this file is deleted, Rush will assume that the node_modules folder has been cleaned and will reinstall it.' ); - this._logIfConsoleOutputIsNotRestricted('Auto install completed successfully\n'); + this.#logIfConsoleOutputIsNotRestricted('Auto install completed successfully\n'); } else { - this._logIfConsoleOutputIsNotRestricted('Autoinstaller folder is already up to date\n'); + this.#logIfConsoleOutputIsNotRestricted('Autoinstaller folder is already up to date\n'); } } finally { // Ensure the lockfile is released when we are finished. @@ -177,10 +177,10 @@ export class Autoinstaller { public async updateAsync(): Promise { await InstallHelpers.ensureLocalPackageManagerAsync( - this._rushConfiguration, - this._rushGlobalFolder, + this.#rushConfiguration, + this.#rushGlobalFolder, RushConstants.defaultMaxInstallAttempts, - this._restrictConsoleOutput + this.#restrictConsoleOutput ); const autoinstallerPackageJsonPath: string = path.join(this.folderFullPath, 'package.json'); @@ -189,7 +189,7 @@ export class Autoinstaller { throw new Error(`The specified autoinstaller path does not exist: ` + autoinstallerPackageJsonPath); } - this._logIfConsoleOutputIsNotRestricted( + this.#logIfConsoleOutputIsNotRestricted( `Updating autoinstaller package: ${autoinstallerPackageJsonPath}` ); @@ -197,16 +197,16 @@ export class Autoinstaller { if (await FileSystem.existsAsync(this.shrinkwrapFilePath)) { oldFileContents = FileSystem.readFile(this.shrinkwrapFilePath, { convertLineEndings: NewlineKind.Lf }); - this._logIfConsoleOutputIsNotRestricted('Deleting ' + this.shrinkwrapFilePath); + this.#logIfConsoleOutputIsNotRestricted('Deleting ' + this.shrinkwrapFilePath); await FileSystem.deleteFileAsync(this.shrinkwrapFilePath); - if (this._rushConfiguration.isPnpm) { + if (this.#rushConfiguration.isPnpm) { // Workaround for https://github.com/pnpm/pnpm/issues/1890 // // When "rush update-autoinstaller" is run, Rush deletes "common/autoinstallers/my-task/pnpm-lock.yaml" // so that a new lockfile will be generated. However "pnpm install" by design will try to recover // "pnpm-lock.yaml" from "my-task/node_modules/.pnpm/lock.yaml", which may prevent a full upgrade. // Deleting both files ensures that a new lockfile will always be generated. - const pnpmPackageManager: PnpmPackageManager = this._rushConfiguration + const pnpmPackageManager: PnpmPackageManager = this.#rushConfiguration .packageManagerWrapper as PnpmPackageManager; await FileSystem.deleteFileAsync( path.join(this.folderFullPath, pnpmPackageManager.internalShrinkwrapRelativePath) @@ -224,33 +224,33 @@ export class Autoinstaller { ); } - this._logIfConsoleOutputIsNotRestricted(); + this.#logIfConsoleOutputIsNotRestricted(); Utilities.syncNpmrc({ - sourceNpmrcFolder: this._rushConfiguration.commonRushConfigFolder, + sourceNpmrcFolder: this.#rushConfiguration.commonRushConfigFolder, targetNpmrcFolder: this.folderFullPath, - supportEnvVarFallbackSyntax: this._rushConfiguration.isPnpm + supportEnvVarFallbackSyntax: this.#rushConfiguration.isPnpm }); await Utilities.executeCommandAsync({ - command: this._rushConfiguration.packageManagerToolFilename, + command: this.#rushConfiguration.packageManagerToolFilename, args: ['install'], workingDirectory: this.folderFullPath, keepEnvironment: true }); - this._logIfConsoleOutputIsNotRestricted(); + this.#logIfConsoleOutputIsNotRestricted(); - if (this._rushConfiguration.packageManager === 'npm') { - this._logIfConsoleOutputIsNotRestricted(Colorize.bold('Running "npm shrinkwrap"...')); + if (this.#rushConfiguration.packageManager === 'npm') { + this.#logIfConsoleOutputIsNotRestricted(Colorize.bold('Running "npm shrinkwrap"...')); await Utilities.executeCommandAsync({ - command: this._rushConfiguration.packageManagerToolFilename, + command: this.#rushConfiguration.packageManagerToolFilename, args: ['shrinkwrap'], workingDirectory: this.folderFullPath, keepEnvironment: true }); - this._logIfConsoleOutputIsNotRestricted('"npm shrinkwrap" completed'); - this._logIfConsoleOutputIsNotRestricted(); + this.#logIfConsoleOutputIsNotRestricted('"npm shrinkwrap" completed'); + this.#logIfConsoleOutputIsNotRestricted(); } if (!(await FileSystem.existsAsync(this.shrinkwrapFilePath))) { @@ -263,17 +263,17 @@ export class Autoinstaller { convertLineEndings: NewlineKind.Lf }); if (oldFileContents !== newFileContents) { - this._logIfConsoleOutputIsNotRestricted( + this.#logIfConsoleOutputIsNotRestricted( Colorize.green('The shrinkwrap file has been updated.') + ' Please commit the updated file:' ); - this._logIfConsoleOutputIsNotRestricted(`\n ${this.shrinkwrapFilePath}`); + this.#logIfConsoleOutputIsNotRestricted(`\n ${this.shrinkwrapFilePath}`); } else { - this._logIfConsoleOutputIsNotRestricted(Colorize.green('Already up to date.')); + this.#logIfConsoleOutputIsNotRestricted(Colorize.green('Already up to date.')); } } - private _logIfConsoleOutputIsNotRestricted(message?: string): void { - if (!this._restrictConsoleOutput) { + #logIfConsoleOutputIsNotRestricted(message?: string): void { + if (!this.#restrictConsoleOutput) { // eslint-disable-next-line no-console console.log(message ?? ''); } diff --git a/libraries/rush-lib/src/logic/ChangeFiles.ts b/libraries/rush-lib/src/logic/ChangeFiles.ts index d63e011dbd7..3209198ce60 100644 --- a/libraries/rush-lib/src/logic/ChangeFiles.ts +++ b/libraries/rush-lib/src/logic/ChangeFiles.ts @@ -30,13 +30,13 @@ export class ChangeFiles { /** * Change file path relative to changes folder. */ - private _files: string[] | undefined; - private readonly _rushConfiguration: RushConfiguration; - private readonly _changesPath: string; + #files: string[] | undefined; + readonly #rushConfiguration: RushConfiguration; + readonly #changesPath: string; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; - this._changesPath = rushConfiguration.changesFolder; + this.#rushConfiguration = rushConfiguration; + this.#changesPath = rushConfiguration.changesFolder; } /** @@ -45,7 +45,7 @@ export class ChangeFiles { public async validateAsync(options: IValidateOptions): Promise { const { terminal, filesToValidate, changedProjectNames, deletedProjectNames } = options; const schema: JsonSchema = JsonSchema.fromLoadedObject(schemaJson); - const rushConfiguration: RushConfiguration = this._rushConfiguration; + const rushConfiguration: RushConfiguration = this.#rushConfiguration; const { hotfixChangeEnabled, experimentsConfiguration: { @@ -180,19 +180,19 @@ export class ChangeFiles { * Get the array of absolute paths of change files. */ public async getAllChangeFilesAsync(): Promise { - if (!this._files) { + if (!this.#files) { const { default: glob } = await import('fast-glob'); - this._files = (await glob('**/*.json', { cwd: this._changesPath, absolute: true })) || []; + this.#files = (await glob('**/*.json', { cwd: this.#changesPath, absolute: true })) || []; } - return this._files; + return this.#files; } /** * Get the path of changes folder. */ public getChangesPath(): string { - return this._changesPath; + return this.#changesPath; } /** @@ -231,15 +231,15 @@ export class ChangeFiles { { concurrency: 5 } ); - return await this._deleteFilesAsync(terminal, filesToDelete, shouldDelete); + return await this.#deleteFilesAsync(terminal, filesToDelete, shouldDelete); } else { // Delete all change files. const files: string[] = await this.getAllChangeFilesAsync(); - return await this._deleteFilesAsync(terminal, files, shouldDelete); + return await this.#deleteFilesAsync(terminal, files, shouldDelete); } } - private async _deleteFilesAsync( + async #deleteFilesAsync( terminal: ITerminal, files: string[], shouldDelete: boolean diff --git a/libraries/rush-lib/src/logic/ChangeManager.ts b/libraries/rush-lib/src/logic/ChangeManager.ts index 7b891d37b7d..b5ee07d8e58 100644 --- a/libraries/rush-lib/src/logic/ChangeManager.ts +++ b/libraries/rush-lib/src/logic/ChangeManager.ts @@ -19,17 +19,17 @@ import { ChangelogGenerator } from './ChangelogGenerator'; * can be applied to package.json and change logs. */ export class ChangeManager { - private _prereleaseToken!: PrereleaseToken; - private _orderedChanges!: IChangeInfo[]; - private _allPackages!: ReadonlyMap; - private _allChanges!: IChangeRequests; - private _changeFiles!: ChangeFiles; - private _rushConfiguration: RushConfiguration; - private _projectsToExclude: Set | undefined; + #prereleaseToken!: PrereleaseToken; + #orderedChanges!: IChangeInfo[]; + #allPackages!: ReadonlyMap; + #allChanges!: IChangeRequests; + #changeFiles!: ChangeFiles; + #rushConfiguration: RushConfiguration; + #projectsToExclude: Set | undefined; public constructor(rushConfiguration: RushConfiguration, projectsToExclude?: Set | undefined) { - this._rushConfiguration = rushConfiguration; - this._projectsToExclude = projectsToExclude; + this.#rushConfiguration = rushConfiguration; + this.#projectsToExclude = projectsToExclude; } /** @@ -41,41 +41,41 @@ export class ChangeManager { prereleaseToken: PrereleaseToken = new PrereleaseToken(), includeCommitDetails: boolean = false ): Promise { - this._allPackages = this._rushConfiguration.projectsByName; + this.#allPackages = this.#rushConfiguration.projectsByName; - this._prereleaseToken = prereleaseToken; + this.#prereleaseToken = prereleaseToken; - this._changeFiles = new ChangeFiles(this._rushConfiguration); - this._allChanges = await PublishUtilities.findChangeRequestsAsync( - this._allPackages, - this._rushConfiguration, - this._changeFiles, + this.#changeFiles = new ChangeFiles(this.#rushConfiguration); + this.#allChanges = await PublishUtilities.findChangeRequestsAsync( + this.#allPackages, + this.#rushConfiguration, + this.#changeFiles, includeCommitDetails, - this._prereleaseToken, - this._projectsToExclude + this.#prereleaseToken, + this.#projectsToExclude ); - this._orderedChanges = PublishUtilities.sortChangeRequests(this._allChanges.packageChanges); + this.#orderedChanges = PublishUtilities.sortChangeRequests(this.#allChanges.packageChanges); } public hasChanges(): boolean { return ( - (this._orderedChanges && this._orderedChanges.length > 0) || - (this._allChanges && this._allChanges.versionPolicyChanges.size > 0) + (this.#orderedChanges && this.#orderedChanges.length > 0) || + (this.#allChanges && this.#allChanges.versionPolicyChanges.size > 0) ); } public get packageChanges(): IChangeInfo[] { - return this._orderedChanges; + return this.#orderedChanges; } public get allPackages(): ReadonlyMap { - return this._allPackages; + return this.#allPackages; } public validateChanges(versionConfig: VersionPolicyConfiguration): void { - this._allChanges.packageChanges.forEach((change, projectName) => { + this.#allChanges.packageChanges.forEach((change, projectName) => { const projectInfo: RushConfigurationProject | undefined = - this._rushConfiguration.getProjectByName(projectName); + this.#rushConfiguration.getProjectByName(projectName); if (projectInfo) { if (projectInfo.versionPolicy) { projectInfo.versionPolicy.validate(change.newVersion!, projectName); @@ -95,8 +95,8 @@ export class ChangeManager { } // Update all the changed version policies - this._allChanges.versionPolicyChanges.forEach((versionPolicyChange, versionPolicyName) => { - this._rushConfiguration.versionPolicyConfiguration.update( + this.#allChanges.versionPolicyChanges.forEach((versionPolicyChange, versionPolicyName) => { + this.#rushConfiguration.versionPolicyConfiguration.update( versionPolicyName, versionPolicyChange.newVersion, shouldCommit @@ -105,12 +105,12 @@ export class ChangeManager { // Apply all changes to package.json files. const updatedPackages: Map = PublishUtilities.updatePackages( - this._allChanges, - this._allPackages, - this._rushConfiguration, + this.#allChanges, + this.#allPackages, + this.#rushConfiguration, shouldCommit, - this._prereleaseToken, - this._projectsToExclude + this.#prereleaseToken, + this.#projectsToExclude ); return updatedPackages; @@ -119,17 +119,17 @@ export class ChangeManager { public async updateChangelogAsync(terminal: ITerminal, shouldCommit: boolean): Promise { // Do not update changelog or delete the change files for prerelease. // Save them for the official release. - if (!this._prereleaseToken.hasValue) { + if (!this.#prereleaseToken.hasValue) { // Update changelogs. const updatedChangelogs: IChangelog[] = ChangelogGenerator.updateChangelogs( - this._allChanges, - this._allPackages, - this._rushConfiguration, + this.#allChanges, + this.#allPackages, + this.#rushConfiguration, shouldCommit ); // Remove the change request files only if "-a" was provided. - await this._changeFiles.deleteAllAsync(terminal, shouldCommit, updatedChangelogs); + await this.#changeFiles.deleteAllAsync(terminal, shouldCommit, updatedChangelogs); } } } diff --git a/libraries/rush-lib/src/logic/DependencyAnalyzer.ts b/libraries/rush-lib/src/logic/DependencyAnalyzer.ts index cca5a86385e..93ef26db116 100644 --- a/libraries/rush-lib/src/logic/DependencyAnalyzer.ts +++ b/libraries/rush-lib/src/logic/DependencyAnalyzer.ts @@ -31,11 +31,11 @@ export interface IDependencyAnalysis { let _dependencyAnalyzerByRushConfiguration: WeakMap | undefined; export class DependencyAnalyzer { - private _rushConfiguration: RushConfiguration; - private _analysisByVariantBySubspace: Map> | undefined; + #rushConfiguration: RushConfiguration; + #analysisByVariantBySubspace: Map> | undefined; private constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; } public static forRushConfiguration(rushConfiguration: RushConfiguration): DependencyAnalyzer { @@ -62,22 +62,22 @@ export class DependencyAnalyzer { // with a variant created by the user const variantKey: string = variant || ''; - if (!this._analysisByVariantBySubspace) { - this._analysisByVariantBySubspace = new Map(); + if (!this.#analysisByVariantBySubspace) { + this.#analysisByVariantBySubspace = new Map(); } - const subspaceToAnalyze: Subspace = subspace || this._rushConfiguration.defaultSubspace; + const subspaceToAnalyze: Subspace = subspace || this.#rushConfiguration.defaultSubspace; let analysisForVariant: WeakMap | undefined = - this._analysisByVariantBySubspace.get(variantKey); + this.#analysisByVariantBySubspace.get(variantKey); if (!analysisForVariant) { analysisForVariant = new WeakMap(); - this._analysisByVariantBySubspace.set(variantKey, analysisForVariant); + this.#analysisByVariantBySubspace.set(variantKey, analysisForVariant); } let analysisForSubspace: IDependencyAnalysis | undefined = analysisForVariant.get(subspaceToAnalyze); if (!analysisForSubspace) { - analysisForSubspace = this._getAnalysisInternal(subspaceToAnalyze, variant, addAction); + analysisForSubspace = this.#getAnalysisInternal(subspaceToAnalyze, variant, addAction); analysisForVariant.set(subspaceToAnalyze, analysisForSubspace); } @@ -91,7 +91,7 @@ export class DependencyAnalyzer { * @remarks * The result of this function is not cached. */ - private _getAnalysisInternal( + #getAnalysisInternal( subspace: Subspace, variant: string | undefined, addAction: boolean @@ -103,8 +103,8 @@ export class DependencyAnalyzer { ReadonlyArray > = commonVersionsConfiguration.allowedAlternativeVersions; - let projectsToProcess: RushConfigurationProject[] = this._rushConfiguration.projects; - if (addAction && this._rushConfiguration.subspacesFeatureEnabled) { + let projectsToProcess: RushConfigurationProject[] = this.#rushConfiguration.projects; + if (addAction && this.#rushConfiguration.subspacesFeatureEnabled) { projectsToProcess = subspace.getProjects(); } @@ -127,7 +127,7 @@ export class DependencyAnalyzer { // Is it a local project? const localProject: RushConfigurationProject | undefined = - this._rushConfiguration.getProjectByName(dependencyName); + this.#rushConfiguration.getProjectByName(dependencyName); if (localProject) { if ( !project.decoupledLocalDependencies.has(dependencyName) && diff --git a/libraries/rush-lib/src/logic/EventHooksManager.ts b/libraries/rush-lib/src/logic/EventHooksManager.ts index a7324a8f119..a3b782c6160 100644 --- a/libraries/rush-lib/src/logic/EventHooksManager.ts +++ b/libraries/rush-lib/src/logic/EventHooksManager.ts @@ -11,22 +11,22 @@ import type { RushConfiguration } from '../api/RushConfiguration'; import { EnvironmentVariableNames } from '../api/EnvironmentConfiguration'; export class EventHooksManager { - private _rushConfiguration: RushConfiguration; - private _eventHooks: EventHooks; - private _commonTempFolder: string; + #rushConfiguration: RushConfiguration; + #eventHooks: EventHooks; + #commonTempFolder: string; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; - this._eventHooks = rushConfiguration.eventHooks; - this._commonTempFolder = rushConfiguration.commonTempFolder; + this.#rushConfiguration = rushConfiguration; + this.#eventHooks = rushConfiguration.eventHooks; + this.#commonTempFolder = rushConfiguration.commonTempFolder; } public handle(event: Event, isDebug: boolean, ignoreHooks: boolean): void { - if (!this._eventHooks) { + if (!this.#eventHooks) { return; } - const scripts: string[] = this._eventHooks.get(event); + const scripts: string[] = this.#eventHooks.get(event); if (scripts.length > 0) { if (ignoreHooks) { // eslint-disable-next-line no-console @@ -40,7 +40,7 @@ export class EventHooksManager { const printEventHooksOutputToConsole: boolean | undefined = isDebug || - this._rushConfiguration.experimentsConfiguration.configuration.printEventHooksOutputToConsole; + this.#rushConfiguration.experimentsConfiguration.configuration.printEventHooksOutputToConsole; scripts.forEach((script) => { try { const environment: IEnvironment = { ...process.env }; @@ -51,9 +51,9 @@ export class EventHooksManager { environment[EnvironmentVariableNames.RUSH_INVOKED_ARGS] = JSON.stringify(process.argv); Utilities.executeLifecycleCommand(script, { - rushConfiguration: this._rushConfiguration, - workingDirectory: this._rushConfiguration.rushJsonFolder, - initCwd: this._commonTempFolder, + rushConfiguration: this.#rushConfiguration, + workingDirectory: this.#rushConfiguration.rushJsonFolder, + initCwd: this.#commonTempFolder, handleOutput: !printEventHooksOutputToConsole, initialEnvironment: environment, environmentPathOptions: { diff --git a/libraries/rush-lib/src/logic/Git.ts b/libraries/rush-lib/src/logic/Git.ts index 36386d4224d..4b4345dfca3 100644 --- a/libraries/rush-lib/src/logic/Git.ts +++ b/libraries/rush-lib/src/logic/Git.ts @@ -31,29 +31,29 @@ export interface IGetBlobOptions { } export class Git { - private readonly _rushConfiguration: RushConfiguration; - private _checkedGitPath: boolean = false; - private _gitPath: string | undefined; - private _checkedGitInfo: boolean = false; - private _gitInfo: gitInfo.GitRepoInfo | undefined; + readonly #rushConfiguration: RushConfiguration; + #checkedGitPath: boolean = false; + #gitPath: string | undefined; + #checkedGitInfo: boolean = false; + #gitInfo: gitInfo.GitRepoInfo | undefined; - private _gitEmailResult: IResultOrError | undefined = undefined; - private _gitHooksPath: IResultOrError | undefined = undefined; + #gitEmailResult: IResultOrError | undefined = undefined; + #gitHooksPath: IResultOrError | undefined = undefined; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; } /** * Returns the path to the Git binary if found. Otherwise, return undefined. */ public get gitPath(): string | undefined { - if (!this._checkedGitPath) { - this._gitPath = EnvironmentConfiguration.gitBinaryPath || Executable.tryResolve('git'); - this._checkedGitPath = true; + if (!this.#checkedGitPath) { + this.#gitPath = EnvironmentConfiguration.gitBinaryPath || Executable.tryResolve('git'); + this.#checkedGitPath = true; } - return this._gitPath; + return this.#gitPath; } public getGitPathOrThrow(): string { @@ -97,7 +97,7 @@ export class Git { public async getGitEmailAsync(): Promise { // Determine the user's account // Ex: "bob@example.com" - const { error, result } = await this._tryGetGitEmailAsync(); + const { error, result } = await this.#tryGetGitEmailAsync(); if (error) { // eslint-disable-next-line no-console console.log( @@ -127,7 +127,7 @@ export class Git { '', `If you didn't configure your email yet, try something like this:`, '', - ...GitEmailPolicy.getEmailExampleLines(this._rushConfiguration), + ...GitEmailPolicy.getEmailExampleLines(this.#rushConfiguration), '' ].join('\n') ); @@ -162,7 +162,7 @@ export class Git { /* ignore errors from true-case-path */ } const defaultHooksPath: string = path.resolve(commonGitDir, 'hooks'); - const hooksResult: IResultOrError = await this._tryGetGitHooksPathAsync(); + const hooksResult: IResultOrError = await this.#tryGetGitHooksPathAsync(); if (hooksResult.error) { // eslint-disable-next-line no-console console.log( @@ -180,7 +180,7 @@ export class Git { if (hooksResult.result) { const absoluteHooksPath: string = path.resolve( - this._rushConfiguration.rushJsonFolder, + this.#rushConfiguration.rushJsonFolder, hooksResult.result ); return absoluteHooksPath === defaultHooksPath; @@ -208,21 +208,21 @@ export class Git { * Returns undefined if rush.json is not under a Git working tree. */ public getGitInfo(): Readonly | undefined { - if (!this._checkedGitInfo) { + if (!this.#checkedGitInfo) { let repoInfo: gitInfo.GitRepoInfo | undefined; try { // gitInfo() shouldn't usually throw, but wrapping in a try/catch just in case - repoInfo = gitInfo(this._rushConfiguration.rushJsonFolder); + repoInfo = gitInfo(this.#rushConfiguration.rushJsonFolder); } catch (ex) { // if there's an error, assume we're not in a Git working tree } if (repoInfo && this.isPathUnderGitWorkingTree(repoInfo)) { - this._gitInfo = repoInfo; + this.#gitInfo = repoInfo; } - this._checkedGitInfo = true; + this.#checkedGitInfo = true; } - return this._gitInfo; + return this.#gitInfo; } public async getMergeBaseAsync( @@ -231,7 +231,7 @@ export class Git { shouldFetch: boolean = false ): Promise { if (shouldFetch) { - this._fetchRemoteBranch(targetBranch, terminal); + this.#fetchRemoteBranch(targetBranch, terminal); } const gitPath: string = this.getGitPathOrThrow(); @@ -282,7 +282,7 @@ export class Git { pathPrefix?: string ): Promise { if (!skipFetch) { - this._fetchRemoteBranch(targetBranch, terminal); + this.#fetchRemoteBranch(targetBranch, terminal); } const gitPath: string = this.getGitPathOrThrow(); @@ -320,7 +320,7 @@ export class Git { * @param rushConfiguration - rush configuration */ public async getRemoteDefaultBranchAsync(): Promise { - const repositoryUrls: string[] = this._rushConfiguration.repositoryUrls; + const repositoryUrls: string[] = this.#rushConfiguration.repositoryUrls; if (repositoryUrls.length > 0) { const gitPath: string = this.getGitPathOrThrow(); const output: string = (await this._executeGitCommandAndCaptureOutputAsync(gitPath, ['remote'])).trim(); @@ -365,7 +365,7 @@ export class Git { ); } - return `${matchingRemotes[0]}/${this._rushConfiguration.repositoryDefaultBranch}`; + return `${matchingRemotes[0]}/${this.#rushConfiguration.repositoryDefaultBranch}`; } else { const errorMessage: string = repositoryUrls.length > 1 @@ -376,7 +376,7 @@ export class Git { // eslint-disable-next-line no-console console.log(Colorize.yellow(errorMessage + 'Detected changes are likely to be incorrect.')); - return this._rushConfiguration.repositoryDefaultFullyQualifiedRemoteBranch; + return this.#rushConfiguration.repositoryDefaultFullyQualifiedRemoteBranch; } } else { // eslint-disable-next-line no-console @@ -385,7 +385,7 @@ export class Git { `A git remote URL has not been specified in ${RushConstants.rushJsonFilename}. Setting the baseline remote URL is recommended.` ) ); - return this._rushConfiguration.repositoryDefaultFullyQualifiedRemoteBranch; + return this.#rushConfiguration.repositoryDefaultFullyQualifiedRemoteBranch; } } @@ -427,7 +427,7 @@ export class Git { } public getTagSeparator(): string { - return this._rushConfiguration.gitTagSeparator || DEFAULT_GIT_TAG_SEPARATOR; + return this.#rushConfiguration.gitTagSeparator || DEFAULT_GIT_TAG_SEPARATOR; } public async getGitStatusAsync(): Promise> { @@ -524,7 +524,7 @@ export class Git { * returns user.email config */ public async tryGetGitEmailAsync(): Promise { - const { result } = await this._tryGetGitEmailAsync(); + const { result } = await this.#tryGetGitEmailAsync(); return result; } @@ -538,12 +538,12 @@ export class Git { await this._executeGitCommandAndCaptureOutputAsync( gitPath, ['add', '--', ...pattern], - this._rushConfiguration.changesFolder + this.#rushConfiguration.changesFolder ); await this._executeGitCommandAndCaptureOutputAsync( gitPath, ['commit', '-m', message, '--', ...pattern], - this._rushConfiguration.changesFolder + this.#rushConfiguration.changesFolder ); } catch (error) { terminal.writeErrorLine(`ERROR: Cannot stage and commit git changes ${(error as Error).message}`); @@ -554,45 +554,45 @@ export class Git { * Returns an object containing either the result of the `git config user.email` * command or an error. */ - private async _tryGetGitEmailAsync(): Promise> { - if (this._gitEmailResult === undefined) { + async #tryGetGitEmailAsync(): Promise> { + if (this.#gitEmailResult === undefined) { const gitPath: string = this.getGitPathOrThrow(); try { - this._gitEmailResult = { + this.#gitEmailResult = { result: ( await this._executeGitCommandAndCaptureOutputAsync(gitPath, ['config', 'user.email']) ).trim() }; } catch (e) { - this._gitEmailResult = { + this.#gitEmailResult = { error: e as Error }; } } - return this._gitEmailResult; + return this.#gitEmailResult; } - private async _tryGetGitHooksPathAsync(): Promise> { - if (this._gitHooksPath === undefined) { + async #tryGetGitHooksPathAsync(): Promise> { + if (this.#gitHooksPath === undefined) { const gitPath: string = this.getGitPathOrThrow(); try { - this._gitHooksPath = { + this.#gitHooksPath = { result: ( await this._executeGitCommandAndCaptureOutputAsync(gitPath, ['rev-parse', '--git-path', 'hooks']) ).trim() }; } catch (e) { - this._gitHooksPath = { + this.#gitHooksPath = { error: e as Error }; } } - return this._gitHooksPath; + return this.#gitHooksPath; } - private _tryFetchRemoteBranch(remoteBranchName: string): boolean { + #tryFetchRemoteBranch(remoteBranchName: string): boolean { const firstSlashIndex: number = remoteBranchName.indexOf('/'); if (firstSlashIndex === -1) { throw new Error( @@ -614,10 +614,10 @@ export class Git { return spawnResult.status === 0; } - private _fetchRemoteBranch(remoteBranchName: string, terminal: ITerminal): void { + #fetchRemoteBranch(remoteBranchName: string, terminal: ITerminal): void { // eslint-disable-next-line no-console console.log(`Checking for updates to ${remoteBranchName}...`); - const fetchResult: boolean = this._tryFetchRemoteBranch(remoteBranchName); + const fetchResult: boolean = this.#tryFetchRemoteBranch(remoteBranchName); if (!fetchResult) { terminal.writeWarningLine( `Error fetching git remote branch ${remoteBranchName}. Detected changed files may be incorrect.` @@ -631,7 +631,7 @@ export class Git { public async _executeGitCommandAndCaptureOutputAsync( gitPath: string, args: string[], - workingDirectory: string = this._rushConfiguration.rushJsonFolder + workingDirectory: string = this.#rushConfiguration.rushJsonFolder ): Promise { try { return await Utilities.executeCommandAndCaptureOutputAsync({ diff --git a/libraries/rush-lib/src/logic/InteractiveUpgrader.ts b/libraries/rush-lib/src/logic/InteractiveUpgrader.ts index a9a2e855179..ff7784fadd3 100644 --- a/libraries/rush-lib/src/logic/InteractiveUpgrader.ts +++ b/libraries/rush-lib/src/logic/InteractiveUpgrader.ts @@ -14,31 +14,31 @@ interface IUpgradeInteractiveDeps { } export class InteractiveUpgrader { - private readonly _rushConfiguration: RushConfiguration; + readonly #rushConfiguration: RushConfiguration; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; } public async upgradeAsync(): Promise { - const rushProject: RushConfigurationProject = await this._getUserSelectedProjectForUpgradeAsync(); + const rushProject: RushConfigurationProject = await this.#getUserSelectedProjectForUpgradeAsync(); const dependenciesState: INpmCheckPackageSummary[] = - await this._getPackageDependenciesStatusAsync(rushProject); + await this.#getPackageDependenciesStatusAsync(rushProject); const depsToUpgrade: IDepsToUpgradeAnswers = - await this._getUserSelectedDependenciesToUpgradeAsync(dependenciesState); + await this.#getUserSelectedDependenciesToUpgradeAsync(dependenciesState); return { projects: [rushProject], depsToUpgrade }; } - private async _getUserSelectedDependenciesToUpgradeAsync( + async #getUserSelectedDependenciesToUpgradeAsync( packages: INpmCheckPackageSummary[] ): Promise { return upgradeInteractive(packages); } - private async _getUserSelectedProjectForUpgradeAsync(): Promise { - const projects: RushConfigurationProject[] | undefined = this._rushConfiguration.projects; + async #getUserSelectedProjectForUpgradeAsync(): Promise { + const projects: RushConfigurationProject[] | undefined = this.#rushConfiguration.projects; const { default: search } = await import('@inquirer/search'); @@ -62,7 +62,7 @@ export class InteractiveUpgrader { }); } - private async _getPackageDependenciesStatusAsync( + async #getPackageDependenciesStatusAsync( rushProject: RushConfigurationProject ): Promise { const { projectFolder } = rushProject; diff --git a/libraries/rush-lib/src/logic/PackageJsonUpdater.ts b/libraries/rush-lib/src/logic/PackageJsonUpdater.ts index 3a1e4789fbb..c6e1f49cf8c 100644 --- a/libraries/rush-lib/src/logic/PackageJsonUpdater.ts +++ b/libraries/rush-lib/src/logic/PackageJsonUpdater.ts @@ -100,18 +100,18 @@ export interface IRemoveProjectOptions extends IBaseUpdateProjectOptions {} * @internal */ export class PackageJsonUpdater { - private readonly _terminal: ITerminal; - private readonly _rushConfiguration: RushConfiguration; - private readonly _rushGlobalFolder: RushGlobalFolder; + readonly #terminal: ITerminal; + readonly #rushConfiguration: RushConfiguration; + readonly #rushGlobalFolder: RushGlobalFolder; public constructor( terminal: ITerminal, rushConfiguration: RushConfiguration, rushGlobalFolder: RushGlobalFolder ) { - this._terminal = terminal; - this._rushConfiguration = rushConfiguration; - this._rushGlobalFolder = rushGlobalFolder; + this.#terminal = terminal; + this.#rushConfiguration = rushConfiguration; + this.#rushGlobalFolder = rushGlobalFolder; } /** @@ -125,7 +125,7 @@ export class PackageJsonUpdater { './DependencyAnalyzer' ); const dependencyAnalyzer: DependencyAnalyzer = DependencyAnalyzer.forRushConfiguration( - this._rushConfiguration + this.#rushConfiguration ); const { allVersionsByPackageName, @@ -138,14 +138,14 @@ export class PackageJsonUpdater { const peerDependenciesToUpdate: Record = {}; for (const { moduleName, latest: latestVersion, packageJson, devDependency } of packagesToAdd) { - const inferredRangeStyle: SemVerStyle = this._cheaplyDetectSemVerRangeStyle(packageJson); + const inferredRangeStyle: SemVerStyle = this.#cheaplyDetectSemVerRangeStyle(packageJson); const implicitlyPreferredVersion: string | undefined = implicitlyPreferredVersionByPackageName.get(moduleName); const explicitlyPreferredVersion: string | undefined = commonVersionsConfiguration.preferredVersions.get(moduleName); - const version: string = await this._getNormalizedVersionSpecAsync( + const version: string = await this.#getNormalizedVersionSpecAsync( projects, moduleName, latestVersion, @@ -161,10 +161,10 @@ export class PackageJsonUpdater { dependenciesToUpdate[moduleName] = version; } - this._terminal.writeLine( + this.#terminal.writeLine( Colorize.green(`Updating projects to use `) + moduleName + '@' + Colorize.cyan(version) ); - this._terminal.writeLine(); + this.#terminal.writeLine(); const existingSpecifiedVersions: Set | undefined = allVersionsByPackageName.get(moduleName); if ( @@ -215,10 +215,10 @@ export class PackageJsonUpdater { if (updateOtherPackages) { const mismatchFinder: VersionMismatchFinder = VersionMismatchFinder.getMismatches( - this._rushConfiguration, + this.#rushConfiguration, options ); - for (const update of this._getUpdates(mismatchFinder, allDependenciesToUpdate)) { + for (const update of this.#getUpdates(mismatchFinder, allDependenciesToUpdate)) { this.updateProject(update); allPackageUpdates.set(update.project.filePath, update.project); } @@ -229,22 +229,22 @@ export class PackageJsonUpdater { async ([filePath, project]) => { const modified: boolean = await project.saveIfModifiedAsync(); if (modified) { - this._terminal.writeLine(Colorize.green('Wrote ') + filePath); + this.#terminal.writeLine(Colorize.green('Wrote ') + filePath); } }, { concurrency: 10 } ); if (!skipUpdate) { - if (this._rushConfiguration.subspacesFeatureEnabled) { - const subspaceSet: ReadonlySet = this._rushConfiguration.getSubspacesForProjects( + if (this.#rushConfiguration.subspacesFeatureEnabled) { + const subspaceSet: ReadonlySet = this.#rushConfiguration.getSubspacesForProjects( options.projects ); for (const subspace of subspaceSet) { - await this._doUpdateAsync(debugInstall, subspace, variant); + await this.#doUpdateAsync(debugInstall, subspace, variant); } } else { - await this._doUpdateAsync(debugInstall, this._rushConfiguration.defaultSubspace, variant); + await this.#doUpdateAsync(debugInstall, this.#rushConfiguration.defaultSubspace, variant); } } } @@ -252,9 +252,9 @@ export class PackageJsonUpdater { public async doRushUpdateAsync(options: IPackageJsonUpdaterRushBaseUpdateOptions): Promise { let allPackageUpdates: IUpdateProjectOptions[] = []; if (options.actionName === 'add') { - allPackageUpdates = await this._doRushAddAsync(options as IPackageJsonUpdaterRushAddOptions); + allPackageUpdates = await this.#doRushAddAsync(options as IPackageJsonUpdaterRushAddOptions); } else if (options.actionName === 'remove') { - allPackageUpdates = await this._doRushRemoveAsync(options as IPackageJsonUpdaterRushRemoveOptions); + allPackageUpdates = await this.#doRushRemoveAsync(options as IPackageJsonUpdaterRushRemoveOptions); } else { throw new Error('only accept "rush add" or "rush remove"'); } @@ -265,36 +265,36 @@ export class PackageJsonUpdater { async ({ project }) => { const modified: boolean = await project.saveIfModifiedAsync(); if (modified) { - this._terminal.writeLine(Colorize.green('Wrote'), project.filePath); + this.#terminal.writeLine(Colorize.green('Wrote'), project.filePath); } }, { concurrency: 10 } ); if (!skipUpdate) { - if (this._rushConfiguration.subspacesFeatureEnabled) { - const subspaceSet: ReadonlySet = this._rushConfiguration.getSubspacesForProjects( + if (this.#rushConfiguration.subspacesFeatureEnabled) { + const subspaceSet: ReadonlySet = this.#rushConfiguration.getSubspacesForProjects( options.projects ); for (const subspace of subspaceSet) { - await this._doUpdateAsync(debugInstall, subspace, variant); + await this.#doUpdateAsync(debugInstall, subspace, variant); } } else { - await this._doUpdateAsync(debugInstall, this._rushConfiguration.defaultSubspace, variant); + await this.#doUpdateAsync(debugInstall, this.#rushConfiguration.defaultSubspace, variant); } } } - private async _doUpdateAsync( + async #doUpdateAsync( debugInstall: boolean, subspace: Subspace, variant: string | undefined ): Promise { - this._terminal.writeLine(); - this._terminal.writeLine(Colorize.green('Running "rush update"')); - this._terminal.writeLine(); + this.#terminal.writeLine(); + this.#terminal.writeLine(Colorize.green('Running "rush update"')); + this.#terminal.writeLine(); - const purgeManager: PurgeManager = new PurgeManager(this._rushConfiguration, this._rushGlobalFolder); + const purgeManager: PurgeManager = new PurgeManager(this.#rushConfiguration, this.#rushGlobalFolder); const installManagerOptions: IInstallManagerOptions = { debug: debugInstall, allowShrinkwrapUpdates: true, @@ -308,15 +308,15 @@ export class PackageJsonUpdater { variant, maxInstallAttempts: RushConstants.defaultMaxInstallAttempts, pnpmFilterArgumentValues: [], - selectedProjects: new Set(this._rushConfiguration.projects), + selectedProjects: new Set(this.#rushConfiguration.projects), checkOnly: false, subspace: subspace, - terminal: this._terminal + terminal: this.#terminal }; const installManager: BaseInstallManager = await InstallManagerFactory.getInstallManagerAsync( - this._rushConfiguration, - this._rushGlobalFolder, + this.#rushConfiguration, + this.#rushGlobalFolder, purgeManager, installManagerOptions ); @@ -330,7 +330,7 @@ export class PackageJsonUpdater { /** * Adds a dependency to a particular project. The core business logic for "rush add". */ - private async _doRushAddAsync( + async #doRushAddAsync( options: IPackageJsonUpdaterRushAddOptions ): Promise { const { projects } = options; @@ -340,20 +340,20 @@ export class PackageJsonUpdater { './DependencyAnalyzer' ); const dependencyAnalyzer: DependencyAnalyzer = DependencyAnalyzer.forRushConfiguration( - this._rushConfiguration + this.#rushConfiguration ); const allPackageUpdates: IUpdateProjectOptions[] = []; - const subspaceSet: ReadonlySet = this._rushConfiguration.getSubspacesForProjects(projects); + const subspaceSet: ReadonlySet = this.#rushConfiguration.getSubspacesForProjects(projects); for (const subspace of subspaceSet) { // Projects for this subspace - allPackageUpdates.push(...(await this._updateProjectsAsync(subspace, dependencyAnalyzer, options))); + allPackageUpdates.push(...(await this.#updateProjectsAsync(subspace, dependencyAnalyzer, options))); } return allPackageUpdates; } - private async _updateProjectsAsync( + async #updateProjectsAsync( subspace: Subspace, dependencyAnalyzer: DependencyAnalyzer, options: IPackageJsonUpdaterRushAddOptions @@ -372,7 +372,7 @@ export class PackageJsonUpdater { commonVersionsConfiguration }: IDependencyAnalysis = dependencyAnalyzer.getAnalysis(subspace, variant, options.actionName === 'add'); - this._terminal.writeLine(); + this.#terminal.writeLine(); const dependenciesToAddOrUpdate: Record = {}; for (const { packageName, version: initialVersion, rangeStyle } of packagesToUpdate) { const implicitlyPreferredVersion: string | undefined = @@ -381,7 +381,7 @@ export class PackageJsonUpdater { const explicitlyPreferredVersion: string | undefined = commonVersionsConfiguration.preferredVersions.get(packageName); - const version: string = await this._getNormalizedVersionSpecAsync( + const version: string = await this.#getNormalizedVersionSpecAsync( subspaceProjects, packageName, initialVersion, @@ -392,12 +392,12 @@ export class PackageJsonUpdater { ); dependenciesToAddOrUpdate[packageName] = version; - this._terminal.writeLine( + this.#terminal.writeLine( Colorize.green('Updating projects to use '), `${packageName}@`, Colorize.cyan(version) ); - this._terminal.writeLine(); + this.#terminal.writeLine(); const existingSpecifiedVersions: Set | undefined = allVersionsByPackageName.get(packageName); if ( @@ -433,13 +433,13 @@ export class PackageJsonUpdater { // we need to do a mismatch check if (updateOtherPackages) { const mismatchFinder: VersionMismatchFinder = VersionMismatchFinder.getMismatches( - this._rushConfiguration, + this.#rushConfiguration, { subspace, variant } ); - otherPackageUpdates = this._getUpdates(mismatchFinder, Object.entries(dependenciesToAddOrUpdate)); + otherPackageUpdates = this.#getUpdates(mismatchFinder, Object.entries(dependenciesToAddOrUpdate)); } this.updateProjects(otherPackageUpdates); @@ -450,7 +450,7 @@ export class PackageJsonUpdater { return allPackageUpdates; } - private _getUpdates( + #getUpdates( mismatchFinder: VersionMismatchFinder, dependenciesToUpdate: Iterable<[string, string]> ): IUpdateProjectOptions[] { @@ -481,12 +481,12 @@ export class PackageJsonUpdater { /** * Remove a dependency from a particular project. The core business logic for "rush remove". */ - private async _doRushRemoveAsync( + async #doRushRemoveAsync( options: IPackageJsonUpdaterRushRemoveOptions ): Promise { const { projects, packagesToUpdate } = options; - this._terminal.writeLine(); + this.#terminal.writeLine(); const dependenciesToRemove: Record = {}; const allPackageUpdates: IRemoveProjectOptions[] = []; @@ -568,7 +568,7 @@ export class PackageJsonUpdater { * @param rangeStyle - if this version is selected by querying registry, then this range specifier is prepended to * the selected version. */ - private async _getNormalizedVersionSpecAsync( + async #getNormalizedVersionSpecAsync( projects: RushConfigurationProject[], packageName: string, initialSpec: string | undefined, @@ -577,21 +577,21 @@ export class PackageJsonUpdater { rangeStyle: SemVerStyle, ensureConsistentVersions: boolean | undefined ): Promise { - this._terminal.writeLine(Colorize.gray(`Determining new version for dependency: ${packageName}`)); + this.#terminal.writeLine(Colorize.gray(`Determining new version for dependency: ${packageName}`)); if (initialSpec) { - this._terminal.writeLine(`Specified version selector: ${Colorize.cyan(initialSpec)}`); + this.#terminal.writeLine(`Specified version selector: ${Colorize.cyan(initialSpec)}`); } else { - this._terminal.writeLine( + this.#terminal.writeLine( `No version selector was specified, so the version will be determined automatically.` ); } - this._terminal.writeLine(); + this.#terminal.writeLine(); // if ensureConsistentVersions => reuse the pinned version // else, query the registry and use the latest that satisfies semver spec if (initialSpec) { if (initialSpec === implicitlyPreferredVersion) { - this._terminal.writeLine( + this.#terminal.writeLine( Colorize.green('Assigning "') + Colorize.cyan(initialSpec) + Colorize.green( @@ -602,7 +602,7 @@ export class PackageJsonUpdater { } if (initialSpec === explicitlyPreferredVersion) { - this._terminal.writeLine( + this.#terminal.writeLine( Colorize.green('Assigning "') + Colorize.cyan(initialSpec) + Colorize.green( @@ -615,7 +615,7 @@ export class PackageJsonUpdater { if (ensureConsistentVersions && !initialSpec) { if (implicitlyPreferredVersion) { - this._terminal.writeLine( + this.#terminal.writeLine( `Assigning the version "${Colorize.cyan(implicitlyPreferredVersion)}" for "${packageName}" ` + 'because it is already used by other projects in this repo.' ); @@ -623,7 +623,7 @@ export class PackageJsonUpdater { } if (explicitlyPreferredVersion) { - this._terminal.writeLine( + this.#terminal.writeLine( `Assigning the version "${Colorize.cyan(explicitlyPreferredVersion)}" for "${packageName}" ` + `because it is the preferred version listed in ${RushConstants.commonVersionsFilename}.` ); @@ -632,13 +632,13 @@ export class PackageJsonUpdater { } await InstallHelpers.ensureLocalPackageManagerAsync( - this._rushConfiguration, - this._rushGlobalFolder, + this.#rushConfiguration, + this.#rushGlobalFolder, RushConstants.defaultMaxInstallAttempts ); const useWorkspaces: boolean = !!( - this._rushConfiguration.pnpmOptions && this._rushConfiguration.pnpmOptions.useWorkspaces + this.#rushConfiguration.pnpmOptions && this.#rushConfiguration.pnpmOptions.useWorkspaces ); const workspacePrefix: string = 'workspace:'; @@ -648,7 +648,7 @@ export class PackageJsonUpdater { } // determine if the package is a project in the local repository and if the version exists - const localProject: RushConfigurationProject | undefined = this._tryGetLocalProject( + const localProject: RushConfigurationProject | undefined = this.#tryGetLocalProject( packageName, projects ); @@ -657,8 +657,8 @@ export class PackageJsonUpdater { let selectedVersionPrefix: string = ''; if (initialSpec && initialSpec !== 'latest') { - this._terminal.writeLine(Colorize.gray('Finding versions that satisfy the selector: ') + initialSpec); - this._terminal.writeLine(); + this.#terminal.writeLine(Colorize.gray('Finding versions that satisfy the selector: ') + initialSpec); + this.#terminal.writeLine(); if (localProject !== undefined) { const version: string = localProject.packageJson.version; @@ -681,34 +681,34 @@ export class PackageJsonUpdater { ); } } else { - this._terminal.writeLine(`Querying registry for all versions of "${packageName}"...`); + this.#terminal.writeLine(`Querying registry for all versions of "${packageName}"...`); let args: string[]; - if (this._rushConfiguration.packageManager === 'yarn') { + if (this.#rushConfiguration.packageManager === 'yarn') { args = ['info', packageName, 'versions', '--json']; } else { args = ['view', packageName, 'versions', '--json']; } const allVersions: string = await Utilities.executeCommandAndCaptureOutputAsync({ - command: this._rushConfiguration.packageManagerToolFilename, + command: this.#rushConfiguration.packageManagerToolFilename, args, - workingDirectory: this._rushConfiguration.commonTempFolder + workingDirectory: this.#rushConfiguration.commonTempFolder }); let versionList: string[]; - if (this._rushConfiguration.packageManager === 'yarn') { + if (this.#rushConfiguration.packageManager === 'yarn') { versionList = JSON.parse(allVersions).data; } else { versionList = JSON.parse(allVersions); } - this._terminal.writeLine(Colorize.gray(`Found ${versionList.length} available versions.`)); + this.#terminal.writeLine(Colorize.gray(`Found ${versionList.length} available versions.`)); for (const version of versionList) { if (semver.satisfies(version, initialSpec)) { selectedVersion = initialSpec; - this._terminal.writeLine( + this.#terminal.writeLine( `Found a version that satisfies ${initialSpec}: ${Colorize.cyan(version)}` ); break; @@ -733,19 +733,19 @@ export class PackageJsonUpdater { selectedVersion = localProject.packageJson.version; } } else { - if (!this._rushConfiguration.ensureConsistentVersions) { - this._terminal.writeLine( + if (!this.#rushConfiguration.ensureConsistentVersions) { + this.#terminal.writeLine( Colorize.gray( `The "ensureConsistentVersions" policy is NOT active, so we will assign the latest version.` ) ); - this._terminal.writeLine(); + this.#terminal.writeLine(); } - this._terminal.writeLine(`Querying NPM registry for latest version of "${packageName}"...`); + this.#terminal.writeLine(`Querying NPM registry for latest version of "${packageName}"...`); let args: string[]; - if (this._rushConfiguration.packageManager === 'yarn') { + if (this.#rushConfiguration.packageManager === 'yarn') { args = ['info', packageName, 'dist-tags.latest', '--silent']; } else { args = ['view', `${packageName}@latest`, 'version']; @@ -753,19 +753,19 @@ export class PackageJsonUpdater { selectedVersion = ( await Utilities.executeCommandAndCaptureOutputAsync({ - command: this._rushConfiguration.packageManagerToolFilename, + command: this.#rushConfiguration.packageManagerToolFilename, args, - workingDirectory: this._rushConfiguration.commonTempFolder + workingDirectory: this.#rushConfiguration.commonTempFolder }) ).trim(); } - this._terminal.writeLine(); + this.#terminal.writeLine(); - this._terminal.writeLine(`Found latest version: ${Colorize.cyan(selectedVersion)}`); + this.#terminal.writeLine(`Found latest version: ${Colorize.cyan(selectedVersion)}`); } - this._terminal.writeLine(); + this.#terminal.writeLine(); let reasonForModification: string = ''; if (selectedVersion !== '*') { @@ -797,13 +797,13 @@ export class PackageJsonUpdater { } const normalizedVersion: string = selectedVersionPrefix + selectedVersion; - this._terminal.writeLine( + this.#terminal.writeLine( Colorize.gray(`Assigning version "${normalizedVersion}" for "${packageName}"${reasonForModification}.`) ); return normalizedVersion; } - private _collectAllDownstreamDependencies( + #collectAllDownstreamDependencies( project: RushConfigurationProject ): Set { const allProjectDownstreamDependencies: Set = @@ -814,7 +814,7 @@ export class PackageJsonUpdater { ) => { for (const downstreamDependencyProject of rushProject.downstreamDependencyProjects) { const foundProject: RushConfigurationProject | undefined = - this._rushConfiguration.projectsByName.get(downstreamDependencyProject); + this.#rushConfiguration.projectsByName.get(downstreamDependencyProject); if (!foundProject) { continue; @@ -843,12 +843,12 @@ export class PackageJsonUpdater { * This function throws an error if adding the discovered local project as a dependency * would create a dependency cycle, or if it would be added to multiple projects. */ - private _tryGetLocalProject( + #tryGetLocalProject( packageName: string, projects: RushConfigurationProject[] ): RushConfigurationProject | undefined { const foundProject: RushConfigurationProject | undefined = - this._rushConfiguration.projectsByName.get(packageName); + this.#rushConfiguration.projectsByName.get(packageName); if (foundProject === undefined) { return undefined; @@ -877,7 +877,7 @@ export class PackageJsonUpdater { // Are we attempting to create a cycle? const downstreamDependencies: Set = - this._collectAllDownstreamDependencies(project); + this.#collectAllDownstreamDependencies(project); if (downstreamDependencies.has(foundProject)) { throw new Error( `Adding "${foundProject.packageName}" as a direct or indirect dependency of ` + @@ -888,7 +888,7 @@ export class PackageJsonUpdater { return foundProject; } - private _cheaplyDetectSemVerRangeStyle(version: string): SemVerStyle { + #cheaplyDetectSemVerRangeStyle(version: string): SemVerStyle { // create a swtich statement to detect the first character of the version string and determine the range style // TODO: This is a temporary solution until we have a better way to detect more complext range styles // TODO: Should we handle/care about peerDependencies? @@ -898,19 +898,19 @@ export class PackageJsonUpdater { case '^': return SemVerStyle.Caret; default: - this._terminal.writeLine( + this.#terminal.writeLine( `No SemVer range detected for version: ${version}. The exact version will be set in package.json.` ); return SemVerStyle.Exact; } } - private _normalizeDepsToUpgrade(deps: INpmCheckPackageSummary[]): IPackageForRushAdd[] { + #normalizeDepsToUpgrade(deps: INpmCheckPackageSummary[]): IPackageForRushAdd[] { return deps.map((dep) => { return { packageName: dep.moduleName, version: dep.latest, - rangeStyle: this._cheaplyDetectSemVerRangeStyle(dep.packageJson) + rangeStyle: this.#cheaplyDetectSemVerRangeStyle(dep.packageJson) }; }); } diff --git a/libraries/rush-lib/src/logic/PackageLookup.ts b/libraries/rush-lib/src/logic/PackageLookup.ts index 9b0253fc30c..79fdc36d2fa 100644 --- a/libraries/rush-lib/src/logic/PackageLookup.ts +++ b/libraries/rush-lib/src/logic/PackageLookup.ts @@ -4,10 +4,10 @@ import type { BasePackage } from './base/BasePackage'; export class PackageLookup { - private _packageMap: Map; + #packageMap: Map; public constructor() { - this._packageMap = new Map(); + this.#packageMap = new Map(); } public loadTree(root: BasePackage): void { @@ -28,13 +28,13 @@ export class PackageLookup { const key: string = current.nameAndVersion; - if (!this._packageMap.has(key)) { - this._packageMap.set(key, current); + if (!this.#packageMap.has(key)) { + this.#packageMap.set(key, current); } } } public getPackage(nameAndVersion: string): BasePackage | undefined { - return this._packageMap.get(nameAndVersion); + return this.#packageMap.get(nameAndVersion); } } diff --git a/libraries/rush-lib/src/logic/PrereleaseToken.ts b/libraries/rush-lib/src/logic/PrereleaseToken.ts index 3e564f6bcd2..0da8f1df1b7 100644 --- a/libraries/rush-lib/src/logic/PrereleaseToken.ts +++ b/libraries/rush-lib/src/logic/PrereleaseToken.ts @@ -2,9 +2,9 @@ // See LICENSE in the project root for license information. export class PrereleaseToken { - private _prereleaseName: string | undefined; - private _suffixName: string | undefined; - private _partialPrerelease: boolean; + #prereleaseName: string | undefined; + #suffixName: string | undefined; + #partialPrerelease: boolean; public readonly name: string; @@ -13,24 +13,24 @@ export class PrereleaseToken { throw new Error('Pre-release name and suffix cannot be provided at the same time.'); } this.name = prereleaseName! || suffixName!; - this._prereleaseName = prereleaseName; - this._suffixName = suffixName; - this._partialPrerelease = partialPrerelease; + this.#prereleaseName = prereleaseName; + this.#suffixName = suffixName; + this.#partialPrerelease = partialPrerelease; } public get hasValue(): boolean { - return !!this._prereleaseName || !!this._suffixName; + return !!this.#prereleaseName || !!this.#suffixName; } public get isPrerelease(): boolean { - return !!this._prereleaseName; + return !!this.#prereleaseName; } public get isSuffix(): boolean { - return !!this._suffixName; + return !!this.#suffixName; } public get isPartialPrerelease(): boolean { - return this.isPrerelease && this._partialPrerelease; + return this.isPrerelease && this.#partialPrerelease; } } diff --git a/libraries/rush-lib/src/logic/ProjectChangeAnalyzer.ts b/libraries/rush-lib/src/logic/ProjectChangeAnalyzer.ts index 3dc0fc6ed25..816a3cc51d7 100644 --- a/libraries/rush-lib/src/logic/ProjectChangeAnalyzer.ts +++ b/libraries/rush-lib/src/logic/ProjectChangeAnalyzer.ts @@ -77,12 +77,12 @@ export interface IRawRepoState { * @beta */ export class ProjectChangeAnalyzer { - private readonly _rushConfiguration: RushConfiguration; - private readonly _git: Git; + readonly #rushConfiguration: RushConfiguration; + readonly #git: Git; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; - this._git = new Git(this._rushConfiguration); + this.#rushConfiguration = rushConfiguration; + this.#git = new Git(this.#rushConfiguration); } /** @@ -93,7 +93,7 @@ export class ProjectChangeAnalyzer { public async getChangedProjectsAsync( options: IGetChangedProjectsOptions ): Promise> { - const { _rushConfiguration: rushConfiguration } = this; + const rushConfiguration: RushConfiguration = this.#rushConfiguration; const { targetBranchName, @@ -105,14 +105,14 @@ export class ProjectChangeAnalyzer { excludeVersionOnlyChanges } = options; - const gitPath: string = this._git.getGitPathOrThrow(); + const gitPath: string = this.#git.getGitPathOrThrow(); const repoRoot: string = getRepoRoot(rushConfiguration.rushJsonFolder); // if the given targetBranchName is a commit, we assume it is the merge base - const isTargetBranchACommit: boolean = await this._git.determineIfRefIsACommitAsync(targetBranchName); + const isTargetBranchACommit: boolean = await this.#git.determineIfRefIsACommitAsync(targetBranchName); const mergeCommit: string = isTargetBranchACommit ? targetBranchName - : await this._git.getMergeBaseAsync(targetBranchName, terminal, shouldFetch); + : await this.#git.getMergeBaseAsync(targetBranchName, terminal, shouldFetch); const changedFiles: Map = getRepoChanges(repoRoot, mergeCommit, gitPath); const lookup: LookupByPath = @@ -165,7 +165,7 @@ export class ProjectChangeAnalyzer { const isVersionOnlyChange: boolean = await isVersionOnlyChangeAsync( diffStatus, repoRoot, - this._git + this.#git ); if (isVersionOnlyChange) { continue; // Skip version-only package.json changes @@ -186,7 +186,7 @@ export class ProjectChangeAnalyzer { : [rushConfiguration.defaultSubspace]; const variantToUse: string | undefined = includeExternalDependencies - ? (variant ?? (await this._rushConfiguration.getCurrentlyInstalledVariantAsync())) + ? (variant ?? (await this.#rushConfiguration.getCurrentlyInstalledVariantAsync())) : undefined; await Async.forEachAsync(subspaces, async (subspace: Subspace) => { @@ -194,7 +194,7 @@ export class ProjectChangeAnalyzer { // Detect changes to pnpm catalog entries in pnpm-config.json if (rushConfiguration.isPnpm) { - await this._detectCatalogChangesAsync( + await this.#detectCatalogChangesAsync( subspace, rushConfiguration, changedFiles, @@ -245,7 +245,7 @@ export class ProjectChangeAnalyzer { throw new Error(`Unable to obtain current shrinkwrap file.`); } - const oldShrinkwrapText: string = await this._git.getBlobContentAsync({ + const oldShrinkwrapText: string = await this.#git.getBlobContentAsync({ // : syntax: https://git-scm.com/docs/gitrevisions blobSpec: `${mergeCommit}:${relativeShrinkwrapFilePath}`, repositoryRoot: repoRoot @@ -305,9 +305,9 @@ export class ProjectChangeAnalyzer { projectSelection?: ReadonlySet ): Promise { try { - const gitPath: string = this._git.getGitPathOrThrow(); + const gitPath: string = this.#git.getGitPathOrThrow(); - if (!this._git.isPathUnderGitWorkingTree()) { + if (!this.#git.isPathUnderGitWorkingTree()) { terminal.writeLine( `The Rush monorepo is not in a Git repository. Rush will proceed without incremental build support.` ); @@ -315,7 +315,7 @@ export class ProjectChangeAnalyzer { return; } - const rushConfiguration: RushConfiguration = this._rushConfiguration; + const rushConfiguration: RushConfiguration = this.#rushConfiguration; // Do not use getGitInfo().root; it is the root of the *primary* worktree, not the *current* one. const rootDirectory: string = getRepoRoot(rushConfiguration.rushJsonFolder, gitPath); @@ -379,7 +379,7 @@ export class ProjectChangeAnalyzer { } else { // Add the shrinkwrap file to every project's dependencies const currentVariant: string | undefined = - await this._rushConfiguration.getCurrentlyInstalledVariantAsync(); + await this.#rushConfiguration.getCurrentlyInstalledVariantAsync(); const shrinkwrapFile: string = Path.convertToSlashes( path.relative( @@ -392,14 +392,14 @@ export class ProjectChangeAnalyzer { } const lookupByPath: IReadonlyLookupByPath = - this._rushConfiguration.getProjectLookupForRoot(rootDirectory); + this.#rushConfiguration.getProjectLookupForRoot(rootDirectory); let filterPath: string[] = []; if ( projectSelection && projectSelection.size > 0 && - this._rushConfiguration.experimentsConfiguration.configuration.enableSubpathScan + this.#rushConfiguration.experimentsConfiguration.configuration.enableSubpathScan ) { filterPath = Array.from(projectSelection, ({ projectFolder }) => projectFolder); } @@ -476,7 +476,7 @@ export class ProjectChangeAnalyzer { rootDir: string, terminal: ITerminal ): Promise> { - const ignoreMatcher: Ignore | undefined = await this._getIgnoreMatcherForProjectAsync(project, terminal); + const ignoreMatcher: Ignore | undefined = await this.#getIgnoreMatcherForProjectAsync(project, terminal); if (!ignoreMatcher) { return unfilteredProjectData; } @@ -498,7 +498,7 @@ export class ProjectChangeAnalyzer { return filteredProjectData; } - private async _getIgnoreMatcherForProjectAsync( + async #getIgnoreMatcherForProjectAsync( project: RushConfigurationProject, terminal: ITerminal ): Promise { @@ -516,7 +516,7 @@ export class ProjectChangeAnalyzer { * Detects changes to pnpm catalog entries in a subspace's pnpm-config.json and marks * affected projects as changed. */ - private async _detectCatalogChangesAsync( + async #detectCatalogChangesAsync( subspace: Subspace, rushConfiguration: RushConfiguration, changedFiles: Map, @@ -541,7 +541,7 @@ export class ProjectChangeAnalyzer { // Maps catalogNamespace (e.g. "default", "react17") → Set of changed package names let oldCatalogs: Record> | undefined; try { - const oldPnpmConfigText: string = await this._git.getBlobContentAsync({ + const oldPnpmConfigText: string = await this.#git.getBlobContentAsync({ blobSpec: `${mergeCommit}:${pnpmConfigRelativePath}`, repositoryRoot: repoRoot }); diff --git a/libraries/rush-lib/src/logic/ProjectCommandSet.ts b/libraries/rush-lib/src/logic/ProjectCommandSet.ts index 1070f31b5f8..d7e111d6522 100644 --- a/libraries/rush-lib/src/logic/ProjectCommandSet.ts +++ b/libraries/rush-lib/src/logic/ProjectCommandSet.ts @@ -9,7 +9,7 @@ import type { IPackageJson, IPackageJsonScriptTable } from '@rushstack/node-core export class ProjectCommandSet { public readonly malformedScriptNames: string[] = []; public readonly commandNames: string[] = []; - private readonly _scriptsByName: Map = new Map(); + readonly #scriptsByName: Map = new Map(); public constructor(packageJson: IPackageJson) { const scripts: IPackageJsonScriptTable = packageJson.scripts || {}; @@ -19,7 +19,7 @@ export class ProjectCommandSet { this.malformedScriptNames.push(scriptName); } else { this.commandNames.push(scriptName); - this._scriptsByName.set(scriptName, scripts[scriptName]); + this.#scriptsByName.set(scriptName, scripts[scriptName]); } } @@ -27,7 +27,7 @@ export class ProjectCommandSet { } public tryGetScriptBody(commandName: string): string | undefined { - return this._scriptsByName.get(commandName); + return this.#scriptsByName.get(commandName); } public getScriptBody(commandName: string): string { diff --git a/libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts b/libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts index 5f23e9d6339..594dffa2450 100644 --- a/libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts +++ b/libraries/rush-lib/src/logic/ProjectImpactGraphGenerator.ts @@ -50,39 +50,39 @@ async function tryReadFileLinesAsync(filePath: string): Promise { - const filePath: string = `${this._repositoryRoot}/${RushConstants.mergeQueueIgnoreFileName}`; + async #loadGlobalExcludedGlobsAsync(): Promise { + const filePath: string = `${this.#repositoryRoot}/${RushConstants.mergeQueueIgnoreFileName}`; return await tryReadFileLinesAsync(filePath); } @@ -90,10 +90,10 @@ export class ProjectImpactGraphGenerator { * Load project excluded globs * @param projectRootRelativePath - project root relative path */ - private async _tryLoadProjectExcludedGlobsAsync( + async #tryLoadProjectExcludedGlobsAsync( projectRootRelativePath: string ): Promise { - const filePath: string = `${this._repositoryRoot}/${projectRootRelativePath}/${RushConstants.mergeQueueIgnoreFileName}`; + const filePath: string = `${this.#repositoryRoot}/${projectRootRelativePath}/${RushConstants.mergeQueueIgnoreFileName}`; const globs: string[] | undefined = await tryReadFileLinesAsync(filePath); if (globs) { @@ -112,9 +112,9 @@ export class ProjectImpactGraphGenerator { const stopwatch: Stopwatch = Stopwatch.start(); const [globalExcludedGlobs = DEFAULT_GLOBAL_EXCLUDED_GLOBS, projectEntries] = await Promise.all([ - this._loadGlobalExcludedGlobsAsync(), + this.#loadGlobalExcludedGlobsAsync(), Async.mapAsync( - this._rushConfiguration.projects, + this.#rushConfiguration.projects, async ({ packageName, consumingProjects, projectRelativeFolder }) => { const dependentList: string[] = [packageName]; for (const consumingProject of consumingProjects) { @@ -127,7 +127,7 @@ export class ProjectImpactGraphGenerator { }; const projectExcludedGlobs: string[] | undefined = - await this._tryLoadProjectExcludedGlobsAsync(projectRelativeFolder); + await this.#tryLoadProjectExcludedGlobsAsync(projectRelativeFolder); if (projectExcludedGlobs) { projectImpactGraphProjectConfiguration.excludedGlobs = projectExcludedGlobs; } @@ -142,17 +142,17 @@ export class ProjectImpactGraphGenerator { const projects: Record = Object.fromEntries(projectEntries); const content: IProjectImpactGraphFile = { globalExcludedGlobs, projects }; - await FileSystem.writeFileAsync(this._projectImpactGraphFilePath, yaml.dump(content)); + await FileSystem.writeFileAsync(this.#projectImpactGraphFilePath, yaml.dump(content)); stopwatch.stop(); - this._terminal.writeLine(); - this._terminal.writeLine( + this.#terminal.writeLine(); + this.#terminal.writeLine( Colorize.green(`Generate project impact graph successfully. (${stopwatch.toString()})`) ); } public async validateAsync(): Promise { // TODO: More validation other than just existence - return await FileSystem.existsAsync(this._projectImpactGraphFilePath); + return await FileSystem.existsAsync(this.#projectImpactGraphFilePath); } } diff --git a/libraries/rush-lib/src/logic/ProjectWatcher.ts b/libraries/rush-lib/src/logic/ProjectWatcher.ts index 0e0c9adb877..73010daed04 100644 --- a/libraries/rush-lib/src/logic/ProjectWatcher.ts +++ b/libraries/rush-lib/src/logic/ProjectWatcher.ts @@ -66,36 +66,36 @@ const KEYBIND_HELP: string = * signal is needed; actual change detection is deferred to `getInputsSnapshotAsync`. */ export class ProjectWatcher { - private readonly _debounceMs: number; - private readonly _rushConfiguration: RushConfiguration; - private readonly _terminal: ITerminal; - private readonly _graph: IOperationGraph; - - private _repoRoot: string | undefined; - private _watchers: Map | undefined; - private _closePromises: Promise[] = []; - private _debounceHandle: NodeJS.Timeout | undefined; - private _isWatching: boolean = false; - private _lastStatus: string | undefined; - private _renderedStatusLines: number = 0; - private _lastSnapshot: IInputsSnapshot | undefined; - private _stdinListening: boolean = false; - private _stdinHadRawMode: boolean | undefined; - private _onStdinDataBound: ((chunk: Buffer | string) => void) | undefined; + readonly #debounceMs: number; + readonly #rushConfiguration: RushConfiguration; + readonly #terminal: ITerminal; + readonly #graph: IOperationGraph; + + #repoRoot: string | undefined; + #watchers: Map | undefined; + #closePromises: Promise[] = []; + #debounceHandle: NodeJS.Timeout | undefined; + #isWatching: boolean = false; + #lastStatus: string | undefined; + #renderedStatusLines: number = 0; + #lastSnapshot: IInputsSnapshot | undefined; + #stdinListening: boolean = false; + #stdinHadRawMode: boolean | undefined; + #onStdinDataBound: ((chunk: Buffer | string) => void) | undefined; public constructor(options: IProjectWatcherOptions) { const { graph, debounceMs, rushConfiguration, terminal, initialSnapshot } = options; - this._graph = graph; - this._debounceMs = debounceMs; - this._rushConfiguration = rushConfiguration; - this._terminal = terminal; - this._lastSnapshot = initialSnapshot; // Seed snapshot + this.#graph = graph; + this.#debounceMs = debounceMs; + this.#rushConfiguration = rushConfiguration; + this.#terminal = terminal; + this.#lastSnapshot = initialSnapshot; // Seed snapshot const gitPath: string = new Git(rushConfiguration).getGitPathOrThrow(); - this._repoRoot = Path.convertToSlashes(getRepoRoot(rushConfiguration.rushJsonFolder, gitPath)); + this.#repoRoot = Path.convertToSlashes(getRepoRoot(rushConfiguration.rushJsonFolder, gitPath)); // Initialize stdin listener early so keybinds are available immediately - this._ensureStdin(); + this.#ensureStdin(); // Capture snapshot (if provided) prior to executing next iteration (will replace initial snapshot) graph.hooks.beforeExecuteIterationAsync.tapPromise( @@ -105,21 +105,21 @@ export class ProjectWatcher { iterationOptions: IOperationGraphIterationOptions ): Promise => { this.clearStatus(); - this._lastSnapshot = iterationOptions.inputsSnapshot; - await this._stopWatchingAsync(); + this.#lastSnapshot = iterationOptions.inputsSnapshot; + await this.#stopWatchingAsync(); } ); // Start watching once execution loop enters waiting state graph.hooks.onIdle.tap('ProjectWatcher', () => { - this._startWatching(); + this.#startWatching(); }); // Dispose stdin listener when session aborts graph.abortController.signal.addEventListener( 'abort', () => { - this._disposeStdin(); + this.#disposeStdin(); }, { once: true } ); @@ -130,14 +130,14 @@ export class ProjectWatcher { * to overwrite previously rendered lines. */ public clearStatus(): void { - this._renderedStatusLines = 0; + this.#renderedStatusLines = 0; } /** * Re-renders the most recent status line (or a default) in place. */ public rerenderStatus(): void { - this._setStatus(this._lastStatus ?? 'Waiting for changes...'); + this.#setStatus(this.#lastStatus ?? 'Waiting for changes...'); } /** @@ -145,14 +145,14 @@ export class ProjectWatcher { * and keybind help when stdin is active. Overwrites previously rendered status lines * when not mid-execution. */ - private _setStatus(status: string): void { - const graph: IOperationGraph = this._graph; + #setStatus(status: string): void { + const graph: IOperationGraph = this.#graph; const isPaused: boolean = graph.pauseNextIteration === true; const hasScheduledIteration: boolean = graph.hasScheduledIteration; const modeLabel: string = isPaused ? 'PAUSED' : 'WATCHING'; const pendingLabel: string = hasScheduledIteration ? ' PENDING' : ''; const statusLines: string[] = [`[${modeLabel}${pendingLabel}] Watch Status: ${status}`]; - if (this._stdinListening) { + if (this.#stdinListening) { const lines: string[] = []; // First line: modes lines.push( @@ -164,15 +164,15 @@ export class ProjectWatcher { } if (graph.status !== OperationStatus.Executing) { // If rendering during execution, don't try to clean previous output. - if (this._renderedStatusLines > 0) { + if (this.#renderedStatusLines > 0) { readline.cursorTo(process.stdout, 0); - readline.moveCursor(process.stdout, 0, -this._renderedStatusLines); + readline.moveCursor(process.stdout, 0, -this.#renderedStatusLines); readline.clearScreenDown(process.stdout); } - this._renderedStatusLines = statusLines.length; + this.#renderedStatusLines = statusLines.length; } - this._lastStatus = status; - this._terminal.writeLine(Colorize.bold(Colorize.cyan(statusLines.join('\n')))); + this.#lastStatus = status; + this.#terminal.writeLine(Colorize.bold(Colorize.cyan(statusLines.join('\n')))); } /** @@ -180,15 +180,15 @@ export class ProjectWatcher { * On platforms without native recursive watch support (Linux), enumerates nested * folders from the last snapshot to set up individual watchers. */ - private _startWatching(): void { - if (this._isWatching) { + #startWatching(): void { + if (this.#isWatching) { return; } - this._isWatching = true; - const sessionAbortSignal: AbortSignal = this._graph.abortController.signal; - const repoRoot: string = Path.convertToSlashes(this._rushConfiguration.rushJsonFolder); + this.#isWatching = true; + const sessionAbortSignal: AbortSignal = this.#graph.abortController.signal; + const repoRoot: string = Path.convertToSlashes(this.#rushConfiguration.rushJsonFolder); const useNativeRecursiveWatch: boolean = os.platform() === 'win32' || os.platform() === 'darwin'; - const operations: ReadonlySet = this._graph.operations; + const operations: ReadonlySet = this.#graph.operations; const projectFolders: Set = new Set(); for (const op of operations) { @@ -197,17 +197,17 @@ export class ProjectWatcher { // Derive nested folder list if on Linux (no native recursive) and snapshot available let foldersToWatch: Set = new Set(); - if (!useNativeRecursiveWatch && this._lastSnapshot) { + if (!useNativeRecursiveWatch && this.#lastSnapshot) { for (const op of operations) { const { associatedProject: rushProject } = op; const tracked: ReadonlyMap | undefined = - this._lastSnapshot.getTrackedFileHashesForOperation(rushProject); + this.#lastSnapshot.getTrackedFileHashesForOperation(rushProject); if (!tracked) { continue; } const prefixLength: number = rushProject.projectFolder.length - repoRoot.length - 1; for (const relPrefix of _enumeratePathsToWatch(tracked.keys(), prefixLength)) { - foldersToWatch.add(`${this._repoRoot}/${relPrefix}`); + foldersToWatch.add(`${this.#repoRoot}/${relPrefix}`); } } } @@ -216,7 +216,7 @@ export class ProjectWatcher { foldersToWatch = projectFolders; } - const watchers: Map = (this._watchers = new Map()); + const watchers: Map = (this.#watchers = new Map()); const addWatcher = (watchedPath: string, recursive: boolean): void => { if (watchers.has(watchedPath)) { @@ -230,10 +230,10 @@ export class ProjectWatcher { recursive: recursive && useNativeRecursiveWatch, signal: sessionAbortSignal }, - (eventType, fileName) => this._onFsEvent(fileName) + (eventType, fileName) => this.#onFsEvent(fileName) ); watchers.set(watchedPath, watcher); - this._closePromises.push( + this.#closePromises.push( once(watcher, 'close').then(() => { watchers.delete(watchedPath); watcher.removeAllListeners(); @@ -241,13 +241,13 @@ export class ProjectWatcher { }) ); } catch (e) { - this._terminal.writeDebugLine(`Failed to watch path ${watchedPath}: ${(e as Error).message}`); + this.#terminal.writeDebugLine(`Failed to watch path ${watchedPath}: ${(e as Error).message}`); } }; // Always watch repo root and common config addWatcher(repoRoot, false); - addWatcher(Path.convertToSlashes(this._rushConfiguration.commonRushConfigFolder), false); + addWatcher(Path.convertToSlashes(this.#rushConfiguration.commonRushConfigFolder), false); if (useNativeRecursiveWatch) { for (const folder of projectFolders) { addWatcher(folder, true); @@ -257,55 +257,56 @@ export class ProjectWatcher { addWatcher(folder, true); } } - this._setStatus('Waiting for changes...'); + this.#setStatus('Waiting for changes...'); } /** * Closes all active file system watchers and waits for their close events to settle. */ - private async _stopWatchingAsync(): Promise { - if (!this._isWatching) { + async #stopWatchingAsync(): Promise { + if (!this.#isWatching) { return; } - this._isWatching = false; - if (this._debounceHandle) { - clearTimeout(this._debounceHandle); - this._debounceHandle = undefined; + this.#isWatching = false; + if (this.#debounceHandle) { + clearTimeout(this.#debounceHandle); + this.#debounceHandle = undefined; } - if (this._watchers) { - for (const watcher of this._watchers.values()) { + if (this.#watchers) { + for (const watcher of this.#watchers.values()) { watcher.close(); } } - await Promise.all(this._closePromises); - this._closePromises = []; - this._watchers = undefined; - this._terminal.writeDebugLine('ProjectWatcher: watchers stopped'); + await Promise.all(this.#closePromises); + this.#closePromises = []; + this.#watchers = undefined; + this.#terminal.writeDebugLine('ProjectWatcher: watchers stopped'); } /** * Handles a raw file system event by debouncing and scheduling an iteration. * Ignores changes to `.git` and `node_modules`. */ - private _onFsEvent(fileName: string | null): void { + // eslint-disable-next-line @rushstack/no-new-null -- The decoupled ESLint plugin does not recognize native private methods yet. + #onFsEvent(fileName: string | null): void { if (fileName === '.git' || fileName === 'node_modules') { return; } - if (this._debounceHandle) { - clearTimeout(this._debounceHandle); + if (this.#debounceHandle) { + clearTimeout(this.#debounceHandle); } - this._debounceHandle = setTimeout(() => this._scheduleIteration(), this._debounceMs); + this.#debounceHandle = setTimeout(() => this.#scheduleIteration(), this.#debounceMs); } /** * Schedules a new execution iteration on the graph in response to detected file changes. */ - private _scheduleIteration(): void { - this._setStatus('File change detected. Queuing new iteration...'); - this._graph + #scheduleIteration(): void { + this.#setStatus('File change detected. Queuing new iteration...'); + this.#graph .scheduleIterationAsync({}) .catch((e: unknown) => - this._terminal.writeErrorLine(`Failed to queue iteration: ${(e as Error).message}`) + this.#terminal.writeErrorLine(`Failed to queue iteration: ${(e as Error).message}`) ); } @@ -313,14 +314,14 @@ export class ProjectWatcher { * Sets up a raw-mode stdin listener so the user can interact with the watch session * via single-key keybinds. Captures the previous raw-mode state for restoration on dispose. */ - private _ensureStdin(): void { - if (this._stdinListening || !process.stdin.isTTY) { + #ensureStdin(): void { + if (this.#stdinListening || !process.stdin.isTTY) { return; } const stdin: NodeJS.ReadStream = process.stdin as NodeJS.ReadStream; // Node's ReadStream has an undocumented isRaw property when setRawMode has been used. // Capture it in a type-safe way. - this._stdinHadRawMode = + this.#stdinHadRawMode = typeof (stdin as unknown as { isRaw?: boolean }).isRaw === 'boolean' ? (stdin as unknown as { isRaw?: boolean }).isRaw : undefined; // capture existing raw state @@ -331,39 +332,39 @@ export class ProjectWatcher { } stdin.resume(); stdin.setEncoding('utf8'); - const handler = (chunk: Buffer | string): void => this._onStdinData(chunk.toString()); + const handler = (chunk: Buffer | string): void => this.#onStdinData(chunk.toString()); stdin.on('data', handler); - this._onStdinDataBound = handler; - this._stdinListening = true; + this.#onStdinDataBound = handler; + this.#stdinListening = true; } /** * Removes the stdin listener and restores the previous raw-mode state. */ - private _disposeStdin(): void { - if (!this._stdinListening) { + #disposeStdin(): void { + if (!this.#stdinListening) { return; } const stdin: NodeJS.ReadStream = process.stdin as NodeJS.ReadStream; - if (this._onStdinDataBound) { - stdin.off('data', this._onStdinDataBound); - this._onStdinDataBound = undefined; + if (this.#onStdinDataBound) { + stdin.off('data', this.#onStdinDataBound); + this.#onStdinDataBound = undefined; } try { - stdin.setRawMode?.(!!this._stdinHadRawMode); + stdin.setRawMode?.(!!this.#stdinHadRawMode); } catch { // ignore } stdin.unref(); - this._stdinListening = false; + this.#stdinListening = false; } /** * Processes a chunk of stdin data, dispatching each character to the appropriate * keybind action on the operation graph. */ - private _onStdinData(chunk: string): void { - const graph: IOperationGraph = this._graph; + #onStdinData(chunk: string): void { + const graph: IOperationGraph = this.#graph; if (!chunk) return; for (const ch of chunk) { // Once aborted, only respond to Ctrl+C (force exit) @@ -376,49 +377,49 @@ export class ProjectWatcher { switch (ch) { case '\u0003': case KEY_QUIT: { - this._terminal.writeLine('Aborting watch session... (Ctrl+C to force exit)'); + this.#terminal.writeLine('Aborting watch session... (Ctrl+C to force exit)'); graph.abortController.abort(); break; } case KEY_ABORT: { void graph.abortCurrentIterationAsync().then(() => { - this._setStatus('Current iteration aborted'); + this.#setStatus('Current iteration aborted'); }); break; } case KEY_INVALIDATE: { graph.invalidateOperations(undefined, 'manual-invalidation'); - this._setStatus('All operations invalidated'); + this.#setStatus('All operations invalidated'); break; } case KEY_CLOSE_RUNNERS: { void graph.closeRunnersAsync().then(() => { - this._setStatus('Closed all runners'); + this.#setStatus('Closed all runners'); }); break; } case KEY_DEBUG: { graph.debugMode = !graph.debugMode; - this._setStatus(`Debug mode ${graph.debugMode ? 'enabled' : 'disabled'}`); + this.#setStatus(`Debug mode ${graph.debugMode ? 'enabled' : 'disabled'}`); break; } case KEY_VERBOSE: { graph.quietMode = !graph.quietMode; - this._setStatus(`Verbose mode ${!graph.quietMode ? 'enabled' : 'disabled'}`); + this.#setStatus(`Verbose mode ${!graph.quietMode ? 'enabled' : 'disabled'}`); break; } case KEY_PAUSE_RESUME: { graph.pauseNextIteration = !graph.pauseNextIteration; - this._setStatus(graph.pauseNextIteration ? 'Watch paused' : 'Watch resumed'); + this.#setStatus(graph.pauseNextIteration ? 'Watch paused' : 'Watch resumed'); break; } case KEY_PARALLELISM_UP: case '=': { - this._adjustParallelism(1); + this.#adjustParallelism(1); break; } case KEY_PARALLELISM_DOWN: { - this._adjustParallelism(-1); + this.#adjustParallelism(-1); break; } case KEY_BUILD: { @@ -427,9 +428,9 @@ export class ProjectWatcher { if (graph.pauseNextIteration === true) { void graph.executeScheduledIterationAsync(); } - this._setStatus('Build iteration queued'); + this.#setStatus('Build iteration queued'); } else { - this._setStatus('No work to queue'); + this.#setStatus('No work to queue'); } }); break; @@ -446,12 +447,12 @@ export class ProjectWatcher { * Adjusts the parallelism on the operation graph by the given delta * and reports the result. */ - private _adjustParallelism(delta: number): void { - const graph: IOperationGraph = this._graph; + #adjustParallelism(delta: number): void { + const graph: IOperationGraph = this.#graph; const previous: number = graph.parallelism; graph.parallelism = previous + delta; // setter will clamp/normalize const effective: number = graph.parallelism; - this._setStatus(`Parallelism ${effective !== previous ? 'set to' : 'remains'} ${effective}`); + this.#setStatus(`Parallelism ${effective !== previous ? 'set to' : 'remains'} ${effective}`); } } diff --git a/libraries/rush-lib/src/logic/PublishGit.ts b/libraries/rush-lib/src/logic/PublishGit.ts index f61e504ba22..c7bbdc6823b 100644 --- a/libraries/rush-lib/src/logic/PublishGit.ts +++ b/libraries/rush-lib/src/logic/PublishGit.ts @@ -9,14 +9,14 @@ import type { Git } from './Git'; const DUMMY_BRANCH_NAME: string = '-branch-name-'; export class PublishGit { - private readonly _targetBranch: string | undefined; - private readonly _gitPath: string; - private readonly _gitTagSeparator: string; + readonly #targetBranch: string | undefined; + readonly #gitPath: string; + readonly #gitTagSeparator: string; public constructor(git: Git, targetBranch: string | undefined) { - this._targetBranch = targetBranch; - this._gitPath = git.getGitPathOrThrow(); - this._gitTagSeparator = git.getTagSeparator(); + this.#targetBranch = targetBranch; + this.#gitPath = git.getGitPathOrThrow(); + this.#gitTagSeparator = git.getTagSeparator(); } public async checkoutAsync(branchName: string | undefined, createBranch: boolean = false): Promise { @@ -28,16 +28,16 @@ export class PublishGit { args.push(branchName || DUMMY_BRANCH_NAME); await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, args }); } public async mergeAsync(branchName: string, verify: boolean = false): Promise { await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, args: ['merge', branchName, '--no-edit', ...(verify ? [] : ['--no-verify'])] }); } @@ -52,14 +52,14 @@ export class PublishGit { } await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, args: ['branch', '-d', branchName] }); if (hasRemote) { await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, args: ['push', 'origin', '--delete', branchName, ...(verify ? [] : ['--no-verify'])] }); } @@ -67,24 +67,24 @@ export class PublishGit { public async pullAsync(verify: boolean = false): Promise { const args: string[] = ['pull', 'origin']; - if (this._targetBranch) { - args.push(this._targetBranch); + if (this.#targetBranch) { + args.push(this.#targetBranch); } if (!verify) { args.push('--no-verify'); } await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, args }); } public async fetchAsync(): Promise { await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, args: ['fetch', 'origin'] }); } @@ -92,8 +92,8 @@ export class PublishGit { public async addChangesAsync(pathspec?: string, workingDirectory?: string): Promise { const files: string = pathspec || '.'; await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, args: ['add', files], workingDirectory }); @@ -110,11 +110,11 @@ export class PublishGit { const tagName: string = PublishUtilities.createTagname( packageName, packageVersion, - this._gitTagSeparator + this.#gitTagSeparator ); await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch && shouldExecute, - command: this._gitPath, + shouldExecute: !!this.#targetBranch && shouldExecute, + command: this.#gitPath, args: [ 'tag', '-a', @@ -132,11 +132,11 @@ export class PublishGit { const tagName: string = PublishUtilities.createTagname( packageConfig.packageName, packageConfig.packageJson.version, - this._gitTagSeparator + this.#gitTagSeparator ); const tagOutput: string = ( await Utilities.executeCommandAndCaptureOutputAsync({ - command: this._gitPath, + command: this.#gitPath, args: ['tag', '-l', tagName], workingDirectory: packageConfig.projectFolder, environment: PublishUtilities.getEnvArgs(), @@ -149,8 +149,8 @@ export class PublishGit { public async commitAsync(commitMessage: string, verify: boolean = false): Promise { await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, args: ['commit', '-m', commitMessage, ...(verify ? [] : ['--no-verify'])] }); } @@ -161,8 +161,8 @@ export class PublishGit { followTags: boolean = true ): Promise { await PublishUtilities.execCommandAsync({ - shouldExecute: !!this._targetBranch, - command: this._gitPath, + shouldExecute: !!this.#targetBranch, + command: this.#gitPath, // We append "--no-verify" to prevent Git hooks from running. For example, people may // want to invoke "rush change -v" as a pre-push hook. args: [ diff --git a/libraries/rush-lib/src/logic/PurgeManager.ts b/libraries/rush-lib/src/logic/PurgeManager.ts index 58df2009851..3d1225e2202 100644 --- a/libraries/rush-lib/src/logic/PurgeManager.ts +++ b/libraries/rush-lib/src/logic/PurgeManager.ts @@ -14,27 +14,27 @@ import type { RushGlobalFolder } from '../api/RushGlobalFolder'; * This class implements the logic for "rush purge" */ export class PurgeManager { - private _rushConfiguration: RushConfiguration; - private _rushGlobalFolder: RushGlobalFolder; - private _rushUserFolderRecycler: AsyncRecycler; + #rushConfiguration: RushConfiguration; + #rushGlobalFolder: RushGlobalFolder; + #rushUserFolderRecycler: AsyncRecycler; public readonly commonTempFolderRecycler: AsyncRecycler; public constructor(rushConfiguration: RushConfiguration, rushGlobalFolder: RushGlobalFolder) { - this._rushConfiguration = rushConfiguration; - this._rushGlobalFolder = rushGlobalFolder; + this.#rushConfiguration = rushConfiguration; + this.#rushGlobalFolder = rushGlobalFolder; const commonAsyncRecyclerPath: string = path.join( - this._rushConfiguration.commonTempFolder, + this.#rushConfiguration.commonTempFolder, RushConstants.rushRecyclerFolderName ); this.commonTempFolderRecycler = new AsyncRecycler(commonAsyncRecyclerPath); const rushUserAsyncRecyclerPath: string = path.join( - this._rushGlobalFolder.path, + this.#rushGlobalFolder.path, RushConstants.rushRecyclerFolderName ); - this._rushUserFolderRecycler = new AsyncRecycler(rushUserAsyncRecyclerPath); + this.#rushUserFolderRecycler = new AsyncRecycler(rushUserAsyncRecyclerPath); } /** @@ -44,7 +44,7 @@ export class PurgeManager { public async startDeleteAllAsync(): Promise { await Promise.all([ this.commonTempFolderRecycler.startDeleteAllAsync(), - this._rushUserFolderRecycler.startDeleteAllAsync() + this.#rushUserFolderRecycler.startDeleteAllAsync() ]); } @@ -54,11 +54,11 @@ export class PurgeManager { public purgeNormal(): void { // Delete everything under common\temp except for the recycler folder itself // eslint-disable-next-line no-console - console.log('Purging ' + this._rushConfiguration.commonTempFolder); + console.log('Purging ' + this.#rushConfiguration.commonTempFolder); this.commonTempFolderRecycler.moveAllItemsInFolder( - this._rushConfiguration.commonTempFolder, - this._getMembersToExclude(this._rushConfiguration.commonTempFolder, true) + this.#rushConfiguration.commonTempFolder, + this.#getMembersToExclude(this.#rushConfiguration.commonTempFolder, true) ); } @@ -71,35 +71,35 @@ export class PurgeManager { // We will delete everything under ~/.rush/ except for the recycler folder itself // eslint-disable-next-line no-console - console.log('Purging ' + this._rushGlobalFolder.path); + console.log('Purging ' + this.#rushGlobalFolder.path); // If Rush itself is running under a folder such as ~/.rush/node-v4.5.6/rush-1.2.3, // we cannot delete that folder. // First purge the node-specific folder, e.g. ~/.rush/node-v4.5.6/* except for rush-1.2.3: - this._rushUserFolderRecycler.moveAllItemsInFolder( - this._rushGlobalFolder.nodeSpecificPath, - this._getMembersToExclude(this._rushGlobalFolder.nodeSpecificPath, true) + this.#rushUserFolderRecycler.moveAllItemsInFolder( + this.#rushGlobalFolder.nodeSpecificPath, + this.#getMembersToExclude(this.#rushGlobalFolder.nodeSpecificPath, true) ); // Then purge the the global folder, e.g. ~/.rush/* except for node-v4.5.6 - this._rushUserFolderRecycler.moveAllItemsInFolder( - this._rushGlobalFolder.path, - this._getMembersToExclude(this._rushGlobalFolder.path, false) + this.#rushUserFolderRecycler.moveAllItemsInFolder( + this.#rushGlobalFolder.path, + this.#getMembersToExclude(this.#rushGlobalFolder.path, false) ); if ( - this._rushConfiguration.isPnpm && - this._rushConfiguration.pnpmOptions.pnpmStore === 'global' && - this._rushConfiguration.pnpmOptions.pnpmStorePath + this.#rushConfiguration.isPnpm && + this.#rushConfiguration.pnpmOptions.pnpmStore === 'global' && + this.#rushConfiguration.pnpmOptions.pnpmStorePath ) { // eslint-disable-next-line no-console console.warn(Colorize.yellow(`Purging the global pnpm-store`)); - this._rushUserFolderRecycler.moveAllItemsInFolder(this._rushConfiguration.pnpmOptions.pnpmStorePath); + this.#rushUserFolderRecycler.moveAllItemsInFolder(this.#rushConfiguration.pnpmOptions.pnpmStorePath); } } - private _getMembersToExclude(folderToRecycle: string, showWarning: boolean): string[] { + #getMembersToExclude(folderToRecycle: string, showWarning: boolean): string[] { // Don't recycle the recycler const membersToExclude: string[] = [RushConstants.rushRecyclerFolderName]; diff --git a/libraries/rush-lib/src/logic/RepoStateFile.ts b/libraries/rush-lib/src/logic/RepoStateFile.ts index 499903848fa..990d8e63787 100644 --- a/libraries/rush-lib/src/logic/RepoStateFile.ts +++ b/libraries/rush-lib/src/logic/RepoStateFile.ts @@ -47,12 +47,12 @@ const _jsonSchema: JsonSchema = JsonSchema.fromLoadedObject(schemaJson); * @public */ export class RepoStateFile { - private _pnpmShrinkwrapHash: string | undefined; - private _preferredVersionsHash: string | undefined; - private _packageJsonInjectedDependenciesHash: string | undefined; - private _pnpmCatalogsHash: string | undefined; - private _isValid: boolean; - private _modified: boolean = false; + #pnpmShrinkwrapHash: string | undefined; + #preferredVersionsHash: string | undefined; + #packageJsonInjectedDependenciesHash: string | undefined; + #pnpmCatalogsHash: string | undefined; + #isValid: boolean; + #modified: boolean = false; /** * Get the absolute file path of the repo-state.json file. @@ -61,13 +61,13 @@ export class RepoStateFile { private constructor(repoStateJson: IRepoStateJson | undefined, isValid: boolean, filePath: string) { this.filePath = filePath; - this._isValid = isValid; + this.#isValid = isValid; if (repoStateJson) { - this._pnpmShrinkwrapHash = repoStateJson.pnpmShrinkwrapHash; - this._preferredVersionsHash = repoStateJson.preferredVersionsHash; - this._packageJsonInjectedDependenciesHash = repoStateJson.packageJsonInjectedDependenciesHash; - this._pnpmCatalogsHash = repoStateJson.pnpmCatalogsHash; + this.#pnpmShrinkwrapHash = repoStateJson.pnpmShrinkwrapHash; + this.#preferredVersionsHash = repoStateJson.preferredVersionsHash; + this.#packageJsonInjectedDependenciesHash = repoStateJson.packageJsonInjectedDependenciesHash; + this.#pnpmCatalogsHash = repoStateJson.pnpmCatalogsHash; } } @@ -75,35 +75,35 @@ export class RepoStateFile { * The hash of the pnpm shrinkwrap file at the end of the last update. */ public get pnpmShrinkwrapHash(): string | undefined { - return this._pnpmShrinkwrapHash; + return this.#pnpmShrinkwrapHash; } /** * The hash of all preferred versions at the end of the last update. */ public get preferredVersionsHash(): string | undefined { - return this._preferredVersionsHash; + return this.#preferredVersionsHash; } /** * The hash of all preferred versions at the end of the last update. */ public get packageJsonInjectedDependenciesHash(): string | undefined { - return this._packageJsonInjectedDependenciesHash; + return this.#packageJsonInjectedDependenciesHash; } /** * The hash of the PNPM catalog definitions at the end of the last update. */ public get pnpmCatalogsHash(): string | undefined { - return this._pnpmCatalogsHash; + return this.#pnpmCatalogsHash; } /** * If false, the repo-state.json file is not valid and its values cannot be relied upon */ public get isValid(): boolean { - return this._isValid; + return this.#isValid; } /** @@ -190,14 +190,14 @@ export class RepoStateFile { rushConfiguration.experimentsConfiguration.configuration ); - if (this._pnpmShrinkwrapHash !== shrinkwrapFileHash) { - this._pnpmShrinkwrapHash = shrinkwrapFileHash; - this._modified = true; + if (this.#pnpmShrinkwrapHash !== shrinkwrapFileHash) { + this.#pnpmShrinkwrapHash = shrinkwrapFileHash; + this.#modified = true; } } - } else if (this._pnpmShrinkwrapHash !== undefined) { - this._pnpmShrinkwrapHash = undefined; - this._modified = true; + } else if (this.#pnpmShrinkwrapHash !== undefined) { + this.#pnpmShrinkwrapHash = undefined; + this.#modified = true; } // Currently, only support saving the preferred versions hash if using workspaces @@ -206,13 +206,13 @@ export class RepoStateFile { if (useWorkspaces) { const commonVersions: CommonVersionsConfiguration = subspace.getCommonVersions(variant); const preferredVersionsHash: string = commonVersions.getPreferredVersionsHash(); - if (this._preferredVersionsHash !== preferredVersionsHash) { - this._preferredVersionsHash = preferredVersionsHash; - this._modified = true; + if (this.#preferredVersionsHash !== preferredVersionsHash) { + this.#preferredVersionsHash = preferredVersionsHash; + this.#modified = true; } - } else if (this._preferredVersionsHash !== undefined) { - this._preferredVersionsHash = undefined; - this._modified = true; + } else if (this.#preferredVersionsHash !== undefined) { + this.#preferredVersionsHash = undefined; + this.#modified = true; } if (rushConfiguration.isPnpm) { @@ -223,65 +223,65 @@ export class RepoStateFile { // so we don't need to track the hash value for that subspace if ( packageJsonInjectedDependenciesHash && - packageJsonInjectedDependenciesHash !== this._packageJsonInjectedDependenciesHash + packageJsonInjectedDependenciesHash !== this.#packageJsonInjectedDependenciesHash ) { - this._packageJsonInjectedDependenciesHash = packageJsonInjectedDependenciesHash; - this._modified = true; - } else if (!packageJsonInjectedDependenciesHash && this._packageJsonInjectedDependenciesHash) { + this.#packageJsonInjectedDependenciesHash = packageJsonInjectedDependenciesHash; + this.#modified = true; + } else if (!packageJsonInjectedDependenciesHash && this.#packageJsonInjectedDependenciesHash) { // if packageJsonInjectedDependenciesHash is undefined, but this._packageJsonInjectedDependenciesHash is not // means users may turn off the injected installation // so we will need to remove unused fields in repo-state.json as well - this._packageJsonInjectedDependenciesHash = undefined; - this._modified = true; + this.#packageJsonInjectedDependenciesHash = undefined; + this.#modified = true; } // Track catalog hash to detect when catalog definitions change const pnpmCatalogsHash: string | undefined = subspace.getPnpmCatalogsHash(); - if (pnpmCatalogsHash && pnpmCatalogsHash !== this._pnpmCatalogsHash) { - this._pnpmCatalogsHash = pnpmCatalogsHash; - this._modified = true; - } else if (!pnpmCatalogsHash && this._pnpmCatalogsHash) { - this._pnpmCatalogsHash = undefined; - this._modified = true; + if (pnpmCatalogsHash && pnpmCatalogsHash !== this.#pnpmCatalogsHash) { + this.#pnpmCatalogsHash = pnpmCatalogsHash; + this.#modified = true; + } else if (!pnpmCatalogsHash && this.#pnpmCatalogsHash) { + this.#pnpmCatalogsHash = undefined; + this.#modified = true; } } // Now that the file has been refreshed, we know its contents are valid - this._isValid = true; + this.#isValid = true; - return this._saveIfModified(); + return this.#saveIfModified(); } /** * Writes the "repo-state.json" file to disk, using the filename that was passed to loadFromFile(). */ - private _saveIfModified(): boolean { - if (this._modified) { + #saveIfModified(): boolean { + if (this.#modified) { const content: string = '// DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush.' + - `${NewlineKind.Lf}${this._serialize()}`; + `${NewlineKind.Lf}${this.#serialize()}`; FileSystem.writeFile(this.filePath, content); - this._modified = false; + this.#modified = false; return true; } return false; } - private _serialize(): string { + #serialize(): string { // We need to set these one-by-one, since JsonFile.stringify does not like undefined values const repoStateJson: IRepoStateJson = {}; - if (this._pnpmShrinkwrapHash) { - repoStateJson.pnpmShrinkwrapHash = this._pnpmShrinkwrapHash; + if (this.#pnpmShrinkwrapHash) { + repoStateJson.pnpmShrinkwrapHash = this.#pnpmShrinkwrapHash; } - if (this._preferredVersionsHash) { - repoStateJson.preferredVersionsHash = this._preferredVersionsHash; + if (this.#preferredVersionsHash) { + repoStateJson.preferredVersionsHash = this.#preferredVersionsHash; } - if (this._packageJsonInjectedDependenciesHash) { - repoStateJson.packageJsonInjectedDependenciesHash = this._packageJsonInjectedDependenciesHash; + if (this.#packageJsonInjectedDependenciesHash) { + repoStateJson.packageJsonInjectedDependenciesHash = this.#packageJsonInjectedDependenciesHash; } - if (this._pnpmCatalogsHash) { - repoStateJson.pnpmCatalogsHash = this._pnpmCatalogsHash; + if (this.#pnpmCatalogsHash) { + repoStateJson.pnpmCatalogsHash = this.#pnpmCatalogsHash; } return JsonFile.stringify(repoStateJson, { newlineConversion: NewlineKind.Lf }); diff --git a/libraries/rush-lib/src/logic/Telemetry.ts b/libraries/rush-lib/src/logic/Telemetry.ts index 8d855cd46a0..1915f266ffa 100644 --- a/libraries/rush-lib/src/logic/Telemetry.ts +++ b/libraries/rush-lib/src/logic/Telemetry.ts @@ -144,33 +144,33 @@ const MAX_FILE_COUNT: number = 100; const ONE_MEGABYTE_IN_BYTES: 1048576 = 1048576; export class Telemetry { - private _enabled: boolean; - private _store: ITelemetryData[]; - private _dataFolder: string; - private _rushConfiguration: RushConfiguration; - private _rushSession: RushSession; - private _flushAsyncTasks: Set> = new Set(); - private _telemetryStartTime: number = 0; + #enabled: boolean; + #store: ITelemetryData[]; + #dataFolder: string; + #rushConfiguration: RushConfiguration; + #rushSession: RushSession; + private readonly _flushAsyncTasks: Set> = new Set(); + #telemetryStartTime: number = 0; public constructor(rushConfiguration: RushConfiguration, rushSession: RushSession) { - this._rushConfiguration = rushConfiguration; - this._rushSession = rushSession; - this._enabled = this._rushConfiguration.telemetryEnabled; - this._store = []; + this.#rushConfiguration = rushConfiguration; + this.#rushSession = rushSession; + this.#enabled = this.#rushConfiguration.telemetryEnabled; + this.#store = []; const folderName: string = 'telemetry'; - this._dataFolder = path.join(this._rushConfiguration.commonTempFolder, folderName); + this.#dataFolder = path.join(this.#rushConfiguration.commonTempFolder, folderName); } public log(telemetryData: ITelemetryData): void { - if (!this._enabled) { + if (!this.#enabled) { return; } const cpus: os.CpuInfo[] = os.cpus(); const data: ITelemetryData = { ...telemetryData, performanceEntries: - telemetryData.performanceEntries || collectPerformanceEntries(this._telemetryStartTime), + telemetryData.performanceEntries || collectPerformanceEntries(this.#telemetryStartTime), machineInfo: telemetryData.machineInfo || { machineArchitecture: os.arch(), // The Node.js model is sometimes padded, for example: @@ -184,23 +184,23 @@ export class Telemetry { platform: telemetryData.platform || process.platform, rushVersion: telemetryData.rushVersion || Rush.version }; - this._telemetryStartTime = performance.now(); - this._store.push(data); + this.#telemetryStartTime = performance.now(); + this.#store.push(data); } public flush(): void { - if (!this._enabled || this._store.length === 0) { + if (!this.#enabled || this.#store.length === 0) { return; } - const fullPath: string = this._getFilePath(); - JsonFile.save(this._store, fullPath, { ensureFolderExists: true, ignoreUndefinedValues: true }); - if (this._rushSession.hooks.flushTelemetry.isUsed()) { + const fullPath: string = this.#getFilePath(); + JsonFile.save(this.#store, fullPath, { ensureFolderExists: true, ignoreUndefinedValues: true }); + if (this.#rushSession.hooks.flushTelemetry.isUsed()) { /** * User defined flushTelemetry should not block anything, so we don't await here, * and store the promise into a list so that we can await it later. */ - const asyncTaskPromise: Promise = this._rushSession.hooks.flushTelemetry.promise(this._store); + const asyncTaskPromise: Promise = this.#rushSession.hooks.flushTelemetry.promise(this.#store); this._flushAsyncTasks.add(asyncTaskPromise); asyncTaskPromise.then( () => { @@ -212,8 +212,8 @@ export class Telemetry { ); } - this._store = []; - this._cleanUp(); + this.#store = []; + this.#cleanUp(); } /** @@ -224,19 +224,19 @@ export class Telemetry { } public get store(): ITelemetryData[] { - return this._store; + return this.#store; } /** * When there are too many log files, delete the old ones. */ - private _cleanUp(): void { - if (FileSystem.exists(this._dataFolder)) { - const files: string[] = FileSystem.readFolderItemNames(this._dataFolder); + #cleanUp(): void { + if (FileSystem.exists(this.#dataFolder)) { + const files: string[] = FileSystem.readFolderItemNames(this.#dataFolder); if (files.length > MAX_FILE_COUNT) { const sortedFiles: string[] = files .map((fileName) => { - const filePath: string = path.join(this._dataFolder, fileName); + const filePath: string = path.join(this.#dataFolder, fileName); const stats: FileSystemStats = FileSystem.getStatistics(filePath); return { filePath: filePath, @@ -262,9 +262,9 @@ export class Telemetry { } } - private _getFilePath(): string { + #getFilePath(): string { let fileName: string = `telemetry_${new Date().toISOString()}`; fileName = fileName.replace(/[\-\:\.]/g, '_') + '.json'; - return path.join(this._dataFolder, fileName); + return path.join(this.#dataFolder, fileName); } } diff --git a/libraries/rush-lib/src/logic/TempProjectHelper.ts b/libraries/rush-lib/src/logic/TempProjectHelper.ts index 10c27d2e847..129b4b2a454 100644 --- a/libraries/rush-lib/src/logic/TempProjectHelper.ts +++ b/libraries/rush-lib/src/logic/TempProjectHelper.ts @@ -17,19 +17,19 @@ import type { Subspace } from '../api/Subspace'; /* eslint-disable no-bitwise */ export class TempProjectHelper { - private _rushConfiguration: RushConfiguration; - private _subspace: Subspace; + #rushConfiguration: RushConfiguration; + #subspace: Subspace; public constructor(rushConfiguration: RushConfiguration, subspace: Subspace) { - this._rushConfiguration = rushConfiguration; - this._subspace = subspace; + this.#rushConfiguration = rushConfiguration; + this.#subspace = subspace; } /** * Deletes the existing tarball and creates a tarball for the given rush project */ public createTempProjectTarball(rushProject: RushConfigurationProject): void { - FileSystem.ensureFolder(path.resolve(this._subspace.getSubspaceTempFolderPath(), 'projects')); + FileSystem.ensureFolder(path.resolve(this.#subspace.getSubspaceTempFolderPath(), 'projects')); const tarballFile: string = this.getTarballFilePath(rushProject); const tempProjectFolder: string = this.getTempProjectFolder(rushProject); @@ -49,7 +49,7 @@ export class TempProjectHelper { prefix: npmPackageFolder, filter: (tarPath: string, stat: Stats): boolean => { if ( - !this._rushConfiguration.experimentsConfiguration.configuration.noChmodFieldInTarHeaderNormalization + !this.#rushConfiguration.experimentsConfiguration.configuration.noChmodFieldInTarHeaderNormalization ) { stat.mode = (stat.mode & ~0x1ff) | PosixModeBits.AllRead | PosixModeBits.UserWrite | PosixModeBits.AllExecute; @@ -67,7 +67,7 @@ export class TempProjectHelper { */ public getTarballFilePath(project: RushConfigurationProject): string { return path.join( - this._subspace.getSubspaceTempFolderPath(), + this.#subspace.getSubspaceTempFolderPath(), RushConstants.rushTempProjectsFolderName, `${project.unscopedTempProjectName}.tgz` ); @@ -76,7 +76,7 @@ export class TempProjectHelper { public getTempProjectFolder(rushProject: RushConfigurationProject): string { const unscopedTempProjectName: string = rushProject.unscopedTempProjectName; return path.join( - this._subspace.getSubspaceTempFolderPath(), + this.#subspace.getSubspaceTempFolderPath(), RushConstants.rushTempProjectsFolderName, unscopedTempProjectName ); diff --git a/libraries/rush-lib/src/logic/UnlinkManager.ts b/libraries/rush-lib/src/logic/UnlinkManager.ts index d77a73b97b4..c0fb760b8c8 100644 --- a/libraries/rush-lib/src/logic/UnlinkManager.ts +++ b/libraries/rush-lib/src/logic/UnlinkManager.ts @@ -16,10 +16,10 @@ import { RushConstants } from './RushConstants'; * This class implements the logic for "rush unlink" */ export class UnlinkManager { - private _rushConfiguration: RushConfiguration; + #rushConfiguration: RushConfiguration; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; } /** @@ -30,7 +30,7 @@ export class UnlinkManager { */ public async unlinkAsync(force: boolean = false): Promise { const useWorkspaces: boolean = - this._rushConfiguration.pnpmOptions && this._rushConfiguration.pnpmOptions.useWorkspaces; + this.#rushConfiguration.pnpmOptions && this.#rushConfiguration.pnpmOptions.useWorkspaces; if (!force && useWorkspaces) { // eslint-disable-next-line no-console console.log( @@ -43,11 +43,11 @@ export class UnlinkManager { } await new FlagFile( - this._rushConfiguration.defaultSubspace.getSubspaceTempFolderPath(), + this.#rushConfiguration.defaultSubspace.getSubspaceTempFolderPath(), RushConstants.lastLinkFlagFilename, {} ).clearAsync(); - return this._deleteProjectFiles(); + return this.#deleteProjectFiles(); } /** @@ -57,10 +57,10 @@ export class UnlinkManager { * * Returns true if anything was deleted * */ - private _deleteProjectFiles(): boolean { + #deleteProjectFiles(): boolean { let didDeleteAnything: boolean = false; - for (const rushProject of this._rushConfiguration.projects) { + for (const rushProject of this.#rushConfiguration.projects) { const localModuleFolder: string = path.join(rushProject.projectFolder, 'node_modules'); if (FileSystem.exists(localModuleFolder)) { // eslint-disable-next-line no-console diff --git a/libraries/rush-lib/src/logic/VersionManager.ts b/libraries/rush-lib/src/logic/VersionManager.ts index ac41623f215..b42f689c021 100644 --- a/libraries/rush-lib/src/logic/VersionManager.ts +++ b/libraries/rush-lib/src/logic/VersionManager.ts @@ -20,9 +20,9 @@ import { DependencySpecifier } from './DependencySpecifier'; import { cloneDeep } from '../utilities/objectUtilities'; export class VersionManager { - private _rushConfiguration: RushConfiguration; - private _userEmail: string; - private _versionPolicyConfiguration: VersionPolicyConfiguration; + #rushConfiguration: RushConfiguration; + #userEmail: string; + #versionPolicyConfiguration: VersionPolicyConfiguration; public readonly updatedProjects: Map; public readonly changeFiles: Map; @@ -32,11 +32,11 @@ export class VersionManager { userEmail: string, versionPolicyConfiguration: VersionPolicyConfiguration ) { - this._rushConfiguration = rushConfiguration; - this._userEmail = userEmail; - this._versionPolicyConfiguration = versionPolicyConfiguration + this.#rushConfiguration = rushConfiguration; + this.#userEmail = userEmail; + this.#versionPolicyConfiguration = versionPolicyConfiguration ? versionPolicyConfiguration - : this._rushConfiguration.versionPolicyConfiguration; + : this.#rushConfiguration.versionPolicyConfiguration; this.updatedProjects = new Map(); this.changeFiles = new Map(); @@ -52,7 +52,7 @@ export class VersionManager { * @param force -- update even when project version is higher than policy version. */ public ensure(versionPolicyName?: string, shouldCommit?: boolean, force?: boolean): void { - this._ensure(versionPolicyName, shouldCommit, force); + this.#ensure(versionPolicyName, shouldCommit, force); } /** @@ -73,26 +73,26 @@ export class VersionManager { shouldCommit?: boolean ): Promise { // Bump all the lock step version policies. - this._versionPolicyConfiguration.bump(lockStepVersionPolicyName, bumpType, identifier, shouldCommit); + this.#versionPolicyConfiguration.bump(lockStepVersionPolicyName, bumpType, identifier, shouldCommit); // Update packages and generate change files due to lock step bump. - this._ensure(lockStepVersionPolicyName, shouldCommit); + this.#ensure(lockStepVersionPolicyName, shouldCommit); // Refresh rush configuration since we may have modified the package.json versions // when calling this._ensure(...) - this._rushConfiguration = RushConfiguration.loadFromConfigurationFile( - this._rushConfiguration.rushJsonFile + this.#rushConfiguration = RushConfiguration.loadFromConfigurationFile( + this.#rushConfiguration.rushJsonFile ); // Update projects based on individual policies const changeManager: ChangeManager = new ChangeManager( - this._rushConfiguration, - this._getManuallyVersionedProjects() + this.#rushConfiguration, + this.#getManuallyVersionedProjects() ); await changeManager.loadAsync(); if (changeManager.hasChanges()) { - changeManager.validateChanges(this._versionPolicyConfiguration); + changeManager.validateChanges(this.#versionPolicyConfiguration); changeManager.apply(!!shouldCommit)!.forEach((packageJson) => { this.updatedProjects.set(packageJson.name, packageJson); }); @@ -101,40 +101,40 @@ export class VersionManager { // Refresh rush configuration again, since we've further modified the package.json files // by calling changeManager.apply(...) - this._rushConfiguration = RushConfiguration.loadFromConfigurationFile( - this._rushConfiguration.rushJsonFile + this.#rushConfiguration = RushConfiguration.loadFromConfigurationFile( + this.#rushConfiguration.rushJsonFile ); } - private _ensure(versionPolicyName?: string, shouldCommit?: boolean, force?: boolean): void { - this._updateVersionsByPolicy(versionPolicyName, force); + #ensure(versionPolicyName?: string, shouldCommit?: boolean, force?: boolean): void { + this.#updateVersionsByPolicy(versionPolicyName, force); let changed: boolean = false; do { changed = false; // Update all dependencies if needed. - const dependenciesUpdated: boolean = this._updateDependencies(); + const dependenciesUpdated: boolean = this.#updateDependencies(); changed = changed || dependenciesUpdated; } while (changed); if (shouldCommit) { - this._updatePackageJsonFiles(); + this.#updatePackageJsonFiles(); this.changeFiles.forEach((changeFile) => { changeFile.writeSync(); }); } } - private _getManuallyVersionedProjects(): Set | undefined { + #getManuallyVersionedProjects(): Set | undefined { const lockStepVersionPolicyNames: Set = new Set(); - this._versionPolicyConfiguration.versionPolicies.forEach((versionPolicy) => { + this.#versionPolicyConfiguration.versionPolicies.forEach((versionPolicy) => { if (versionPolicy instanceof LockStepVersionPolicy && versionPolicy.nextBump !== undefined) { lockStepVersionPolicyNames.add(versionPolicy.policyName); } }); const lockStepProjectNames: Set = new Set(); - this._rushConfiguration.projects.forEach((rushProject) => { + this.#rushConfiguration.projects.forEach((rushProject) => { if (lockStepVersionPolicyNames.has(rushProject.versionPolicyName!)) { lockStepProjectNames.add(rushProject.packageName); } @@ -142,18 +142,18 @@ export class VersionManager { return lockStepProjectNames; } - private _updateVersionsByPolicy(versionPolicyName?: string, force?: boolean): boolean { + #updateVersionsByPolicy(versionPolicyName?: string, force?: boolean): boolean { let changed: boolean = false; // Update versions based on version policy - this._rushConfiguration.projects.forEach((rushProject) => { + this.#rushConfiguration.projects.forEach((rushProject) => { const projectVersionPolicyName: string | undefined = rushProject.versionPolicyName; if ( projectVersionPolicyName && (!versionPolicyName || projectVersionPolicyName === versionPolicyName) ) { const versionPolicy: VersionPolicy = - this._versionPolicyConfiguration.getVersionPolicy(projectVersionPolicyName); + this.#versionPolicyConfiguration.getVersionPolicy(projectVersionPolicyName); const oldVersion: string = this.updatedProjects.get(rushProject.packageName)?.version || rushProject.packageJson.version; @@ -163,8 +163,8 @@ export class VersionManager { if (updatedProject) { this.updatedProjects.set(updatedProject.name, updatedProject); // No need to create an entry for prerelease version bump. - if (!this._isPrerelease(updatedProject.version) && rushProject.isMainProject) { - this._addChangeInfo(updatedProject.name, [this._createChangeInfo(updatedProject, rushProject)]); + if (!this.#isPrerelease(updatedProject.version) && rushProject.isMainProject) { + this.#addChangeInfo(updatedProject.name, [this.#createChangeInfo(updatedProject, rushProject)]); } } } @@ -173,11 +173,11 @@ export class VersionManager { return changed; } - private _isPrerelease(version: string): boolean { + #isPrerelease(version: string): boolean { return !!semver.prerelease(version); } - private _addChangeInfo(packageName: string, changeInfos: IChangeInfo[]): void { + #addChangeInfo(packageName: string, changeInfos: IChangeInfo[]): void { if (!changeInfos.length) { return; } @@ -187,9 +187,9 @@ export class VersionManager { { changes: [], packageName: packageName, - email: this._userEmail + email: this.#userEmail }, - this._rushConfiguration + this.#rushConfiguration ); this.changeFiles.set(packageName, changeFile); } @@ -198,10 +198,10 @@ export class VersionManager { }); } - private _updateDependencies(): boolean { + #updateDependencies(): boolean { let updated: boolean = false; - this._rushConfiguration.projects.forEach((rushProject) => { + this.#rushConfiguration.projects.forEach((rushProject) => { let clonedProject: IPackageJson | undefined = this.updatedProjects.get(rushProject.packageName); let projectVersionChanged: boolean = true; @@ -210,7 +210,7 @@ export class VersionManager { projectVersionChanged = false; } - const dependenciesUpdated: boolean = this._updateProjectAllDependencies( + const dependenciesUpdated: boolean = this.#updateProjectAllDependencies( rushProject, clonedProject!, projectVersionChanged @@ -222,7 +222,7 @@ export class VersionManager { return updated; } - private _updateProjectAllDependencies( + #updateProjectAllDependencies( rushProject: RushConfigurationProject, clonedProject: IPackageJson, projectVersionChanged: boolean @@ -233,7 +233,7 @@ export class VersionManager { const changes: IChangeInfo[] = []; let updated: boolean = false; if ( - this._updateProjectDependencies( + this.#updateProjectDependencies( clonedProject.dependencies, changes, clonedProject, @@ -244,7 +244,7 @@ export class VersionManager { updated = true; } if ( - this._updateProjectDependencies( + this.#updateProjectDependencies( clonedProject.devDependencies, changes, clonedProject, @@ -255,7 +255,7 @@ export class VersionManager { updated = true; } if ( - this._updateProjectDependencies( + this.#updateProjectDependencies( clonedProject.peerDependencies, changes, clonedProject, @@ -268,13 +268,13 @@ export class VersionManager { if (updated) { this.updatedProjects.set(clonedProject.name, clonedProject); - this._addChangeInfo(clonedProject.name, changes); + this.#addChangeInfo(clonedProject.name, changes); } return updated; } - private _updateProjectDependencies( + #updateProjectDependencies( dependencies: { [key: string]: string } | undefined, changes: IChangeInfo[], clonedProject: IPackageJson, @@ -303,8 +303,8 @@ export class VersionManager { if (newDependencyVersion !== oldDependencyVersion) { updated = true; - if (this._shouldTrackDependencyChange(rushProject, updatedDependentProjectName)) { - this._trackDependencyChange( + if (this.#shouldTrackDependencyChange(rushProject, updatedDependentProjectName)) { + this.#trackDependencyChange( changes, clonedProject, projectVersionChanged, @@ -320,12 +320,12 @@ export class VersionManager { return updated; } - private _shouldTrackDependencyChange( + #shouldTrackDependencyChange( rushProject: RushConfigurationProject, dependencyName: string ): boolean { const dependencyRushProject: RushConfigurationProject | undefined = - this._rushConfiguration.projectsByName.get(dependencyName); + this.#rushConfiguration.projectsByName.get(dependencyName); return ( !!dependencyRushProject && @@ -337,7 +337,7 @@ export class VersionManager { ); } - private _trackDependencyChange( + #trackDependencyChange( changes: IChangeInfo[], clonedProject: IPackageJson, projectVersionChanged: boolean, @@ -353,7 +353,7 @@ export class VersionManager { !semver.satisfies(updatedDependentProject.version, oldSpecifier.versionSpecifier) && !projectVersionChanged ) { - this._addChange(changes, { + this.#addChange(changes, { changeType: ChangeType.patch, packageName: clonedProject.name }); @@ -361,8 +361,8 @@ export class VersionManager { // If current version is not a prerelease version and new dependency is also not a prerelease version, // add change entry. Otherwise, too many changes will be created for frequent releases. - if (!this._isPrerelease(updatedDependentProject.version) && !this._isPrerelease(clonedProject.version)) { - this._addChange(changes, { + if (!this.#isPrerelease(updatedDependentProject.version) && !this.#isPrerelease(clonedProject.version)) { + this.#addChange(changes, { changeType: ChangeType.dependency, comment: `Dependency ${updatedDependentProject.name} version bump from ${oldDependencyVersion}` + @@ -372,7 +372,7 @@ export class VersionManager { } } - private _addChange(changes: IChangeInfo[], newChange: IChangeInfo): void { + #addChange(changes: IChangeInfo[], newChange: IChangeInfo): void { const exists: boolean = changes.some((changeInfo) => { return ( changeInfo.author === newChange.author && @@ -388,10 +388,10 @@ export class VersionManager { } } - private _updatePackageJsonFiles(): void { + #updatePackageJsonFiles(): void { this.updatedProjects.forEach((newPackageJson, packageName) => { const rushProject: RushConfigurationProject | undefined = - this._rushConfiguration.getProjectByName(packageName); + this.#rushConfiguration.getProjectByName(packageName); // Update package.json if (rushProject) { const packagePath: string = path.join(rushProject.projectFolder, FileConstants.PackageJson); @@ -400,7 +400,7 @@ export class VersionManager { }); } - private _createChangeInfo( + #createChangeInfo( newPackageJson: IPackageJson, rushProject: RushConfigurationProject ): IChangeInfo { diff --git a/libraries/rush-lib/src/logic/base/BaseInstallManager.ts b/libraries/rush-lib/src/logic/base/BaseInstallManager.ts index fa21aed84c0..5322df003b9 100644 --- a/libraries/rush-lib/src/logic/base/BaseInstallManager.ts +++ b/libraries/rush-lib/src/logic/base/BaseInstallManager.ts @@ -75,9 +75,9 @@ const gitLfsHooks: ReadonlySet = new Set(['post-checkout', 'post-commit' * This class implements common logic between "rush install" and "rush update". */ export abstract class BaseInstallManager { - private readonly _commonTempLinkFlag: FlagFile; - private _npmSetupValidated: boolean = false; - private _syncNpmrcAlreadyCalled: boolean = false; + readonly #commonTempLinkFlag: FlagFile; + #npmSetupValidated: boolean = false; + #syncNpmrcAlreadyCalled: boolean = false; protected readonly _terminal: ITerminal; @@ -100,7 +100,7 @@ export abstract class BaseInstallManager { this.installRecycler = purgeManager.commonTempFolderRecycler; this.options = options; - this._commonTempLinkFlag = new FlagFile( + this.#commonTempLinkFlag = new FlagFile( options.subspace.getSubspaceTempFolderPath(), RushConstants.lastLinkFlagFilename, {} @@ -224,7 +224,7 @@ export abstract class BaseInstallManager { if (!this.rushConfiguration.rushConfigurationJson.suppressRushIsPublicVersionCheck) { let publishedRelease: boolean | undefined; try { - publishedRelease = await this._checkIfReleaseIsPublishedAsync(); + publishedRelease = await this.#checkIfReleaseIsPublishedAsync(); } catch { // If the user is working in an environment that can't reach the registry, // don't bother them with errors. @@ -244,7 +244,7 @@ export abstract class BaseInstallManager { // Since we're going to be tampering with common/node_modules, delete the "rush link" flag file if it exists; // this ensures that a full "rush link" is required next time - await this._commonTempLinkFlag.clearAsync(); + await this.#commonTempLinkFlag.clearAsync(); } // Give plugins an opportunity to act before invoking the installation process @@ -448,7 +448,7 @@ export abstract class BaseInstallManager { // than whatever pnpm would emit. detectAndReportWorkspaceCycles(this.rushConfiguration, terminal); - await this._installGitHooksAsync(); + await this.#installGitHooksAsync(); const approvedPackagesChecker: ApprovedPackagesChecker = new ApprovedPackagesChecker( this.rushConfiguration @@ -561,7 +561,7 @@ export abstract class BaseInstallManager { createIfMissing: this.rushConfiguration.subspacesFeatureEnabled, supportEnvVarFallbackSyntax: this.rushConfiguration.isPnpm }); - this._syncNpmrcAlreadyCalled = true; + this.#syncNpmrcAlreadyCalled = true; const npmrcHash: string | undefined = npmrcText ? crypto.createHash('sha1').update(npmrcText).digest('hex') @@ -648,7 +648,7 @@ export abstract class BaseInstallManager { ]); shrinkwrapIsUpToDate = shrinkwrapIsUpToDate && !this.options.recheckShrinkwrap; - this._syncTempShrinkwrap(subspace, variant, shrinkwrapFile); + this.#syncTempShrinkwrap(subspace, variant, shrinkwrapFile); // Write out the reported warnings if (shrinkwrapWarnings.length > 0) { @@ -698,7 +698,7 @@ export abstract class BaseInstallManager { /** * Git hooks are only installed if the repo opts in by including files in /common/git-hooks */ - private async _installGitHooksAsync(): Promise { + async #installGitHooksAsync(): Promise { const hookSource: string = path.join(this.rushConfiguration.commonFolder, 'git-hooks'); const git: Git = new Git(this.rushConfiguration); const hookDestination: string | undefined = git.getHooksFolder(); @@ -1026,7 +1026,7 @@ ${gitLfsHookHandling} } } - private async _checkIfReleaseIsPublishedAsync(): Promise { + async #checkIfReleaseIsPublishedAsync(): Promise { const lastCheckFile: string = path.join( this.rushGlobalFolder.nodeSpecificPath, 'rush-' + Rush.version, @@ -1064,7 +1064,7 @@ ${gitLfsHookHandling} try { // For this check we use the official registry, not the private registry - const publishedRelease: boolean = await this._queryIfReleaseIsPublishedAsync( + const publishedRelease: boolean = await this.#queryIfReleaseIsPublishedAsync( 'https://registry.npmjs.org:443' ); // Cache the result @@ -1077,7 +1077,7 @@ ${gitLfsHookHandling} } // Helper for checkIfReleaseIsPublished() - private async _queryIfReleaseIsPublishedAsync(registryUrl: string): Promise { + async #queryIfReleaseIsPublishedAsync(registryUrl: string): Promise { let queryUrl: string = registryUrl; if (queryUrl[-1] !== '/') { queryUrl += '/'; @@ -1129,7 +1129,7 @@ ${gitLfsHookHandling} return true; } - private _syncTempShrinkwrap( + #syncTempShrinkwrap( subspace: Subspace, variant: string | undefined, shrinkwrapFile: BaseShrinkwrapFile | undefined @@ -1160,7 +1160,7 @@ ${gitLfsHookHandling} } protected async validateNpmSetupAsync(): Promise { - if (this._npmSetupValidated) { + if (this.#npmSetupValidated) { return; } @@ -1168,7 +1168,7 @@ ${gitLfsHookHandling} const setupPackageRegistry: SetupPackageRegistry = new SetupPackageRegistry({ rushConfiguration: this.rushConfiguration, isDebug: this.options.debug, - syncNpmrcAlreadyCalled: this._syncNpmrcAlreadyCalled + syncNpmrcAlreadyCalled: this.#syncNpmrcAlreadyCalled }); const valid: boolean = await setupPackageRegistry.checkOnlyAsync(); if (!valid) { @@ -1189,6 +1189,6 @@ ${gitLfsHookHandling} } } - this._npmSetupValidated = true; + this.#npmSetupValidated = true; } } diff --git a/libraries/rush-lib/src/logic/base/BasePackage.ts b/libraries/rush-lib/src/logic/base/BasePackage.ts index 2a1fb304a0d..4491c499742 100644 --- a/libraries/rush-lib/src/logic/base/BasePackage.ts +++ b/libraries/rush-lib/src/logic/base/BasePackage.ts @@ -103,7 +103,7 @@ export class BasePackage { * The child packages are not necessarily dependencies of this package. */ public children: BasePackage[]; - private _childrenByName: Map; + #childrenByName: Map; protected constructor( name: string, @@ -128,7 +128,7 @@ export class BasePackage { } this.children = []; - this._childrenByName = new Map(); + this.#childrenByName = new Map(); } /** @@ -186,16 +186,16 @@ export class BasePackage { if (child.parent) { throw new Error('Child already has a parent'); } - if (this._childrenByName.has(child.installedName)) { + if (this.#childrenByName.has(child.installedName)) { throw new Error(`Child already exists: ${child.installedName}`); } child.parent = this; this.children.push(child); - this._childrenByName.set(child.installedName, child); + this.#childrenByName.set(child.installedName, child); } public getChildByName(childPackageName: string): BasePackage | undefined { - return this._childrenByName.get(childPackageName); + return this.#childrenByName.get(childPackageName); } public printTree(indent?: string): void { diff --git a/libraries/rush-lib/src/logic/base/BaseShrinkwrapFile.ts b/libraries/rush-lib/src/logic/base/BaseShrinkwrapFile.ts index 04d64cc8ebd..7a79dbc1ac3 100644 --- a/libraries/rush-lib/src/logic/base/BaseShrinkwrapFile.ts +++ b/libraries/rush-lib/src/logic/base/BaseShrinkwrapFile.ts @@ -66,7 +66,7 @@ export abstract class BaseShrinkwrapFile { return false; } - return this._checkDependencyVersion(dependencySpecifier, shrinkwrapDependency); + return this.#checkDependencyVersion(dependencySpecifier, shrinkwrapDependency); } /** @@ -100,7 +100,7 @@ export abstract class BaseShrinkwrapFile { return false; } - return this._checkDependencyVersion(dependencySpecifier, shrinkwrapDependency); + return this.#checkDependencyVersion(dependencySpecifier, shrinkwrapDependency); } /** @@ -180,7 +180,7 @@ export abstract class BaseShrinkwrapFile { return result; } - private _checkDependencyVersion( + #checkDependencyVersion( projectDependency: DependencySpecifier, shrinkwrapDependency: DependencySpecifier ): boolean { diff --git a/libraries/rush-lib/src/logic/buildCache/OperationBuildCache.ts b/libraries/rush-lib/src/logic/buildCache/OperationBuildCache.ts index b7f98903827..bfcd964a6f0 100644 --- a/libraries/rush-lib/src/logic/buildCache/OperationBuildCache.ts +++ b/libraries/rush-lib/src/logic/buildCache/OperationBuildCache.ts @@ -129,15 +129,15 @@ export function _setTarUtilityPromiseForTesting( * @internal */ export class OperationBuildCache { - private readonly _project: RushConfigurationProject; - private readonly _localBuildCacheProvider: FileSystemBuildCacheProvider; - private readonly _cloudBuildCacheProvider: ICloudBuildCacheProvider | undefined; - private readonly _buildCacheEnabled: boolean; - private readonly _cacheWriteEnabled: boolean; - private readonly _projectOutputFolderNames: ReadonlyArray; - private readonly _cacheId: string | undefined; - private readonly _excludeAppleDoubleFiles: boolean; - private readonly _useDirectFileTransfersForBuildCache: boolean; + readonly #project: RushConfigurationProject; + readonly #localBuildCacheProvider: FileSystemBuildCacheProvider; + readonly #cloudBuildCacheProvider: ICloudBuildCacheProvider | undefined; + readonly #buildCacheEnabled: boolean; + readonly #cacheWriteEnabled: boolean; + readonly #projectOutputFolderNames: ReadonlyArray; + readonly #cacheId: string | undefined; + readonly #excludeAppleDoubleFiles: boolean; + readonly #useDirectFileTransfersForBuildCache: boolean; private constructor(cacheId: string | undefined, options: IProjectBuildCacheOptions) { const { @@ -152,19 +152,19 @@ export class OperationBuildCache { excludeAppleDoubleFiles, useDirectFileTransfersForBuildCache } = options; - this._project = project; - this._localBuildCacheProvider = localCacheProvider; - this._cloudBuildCacheProvider = cloudCacheProvider; - this._buildCacheEnabled = buildCacheEnabled; - this._cacheWriteEnabled = cacheWriteEnabled; - this._projectOutputFolderNames = projectOutputFolderNames || []; - this._cacheId = cacheId; - this._excludeAppleDoubleFiles = excludeAppleDoubleFiles && process.platform === 'darwin'; - this._useDirectFileTransfersForBuildCache = useDirectFileTransfersForBuildCache; + this.#project = project; + this.#localBuildCacheProvider = localCacheProvider; + this.#cloudBuildCacheProvider = cloudCacheProvider; + this.#buildCacheEnabled = buildCacheEnabled; + this.#cacheWriteEnabled = cacheWriteEnabled; + this.#projectOutputFolderNames = projectOutputFolderNames || []; + this.#cacheId = cacheId; + this.#excludeAppleDoubleFiles = excludeAppleDoubleFiles && process.platform === 'darwin'; + this.#useDirectFileTransfersForBuildCache = useDirectFileTransfersForBuildCache; } public get cacheId(): string | undefined { - return this._cacheId; + return this.#cacheId; } public static getOperationBuildCache(options: IProjectBuildCacheOptions): OperationBuildCache { @@ -202,33 +202,33 @@ export class OperationBuildCache { } public async tryRestoreFromCacheAsync(terminal: ITerminal, specifiedCacheId?: string): Promise { - const cacheId: string | undefined = specifiedCacheId || this._cacheId; + const cacheId: string | undefined = specifiedCacheId || this.#cacheId; if (!cacheId) { terminal.writeWarningLine('Unable to get cache ID. Ensure Git is installed.'); return false; } - if (!this._buildCacheEnabled) { + if (!this.#buildCacheEnabled) { // Skip reading local and cloud build caches, without any noise return false; } let localCacheEntryPath: string | undefined = - await this._localBuildCacheProvider.tryGetCacheEntryPathByIdAsync(terminal, cacheId); + await this.#localBuildCacheProvider.tryGetCacheEntryPathByIdAsync(terminal, cacheId); let cloudCacheHit: boolean = false; let updateLocalCacheSuccess: boolean | undefined; - if (!localCacheEntryPath && this._cloudBuildCacheProvider) { + if (!localCacheEntryPath && this.#cloudBuildCacheProvider) { terminal.writeVerboseLine( 'This project was not found in the local build cache. Querying the cloud build cache.' ); if ( - this._useDirectFileTransfersForBuildCache && - this._cloudBuildCacheProvider.tryDownloadCacheEntryToFileAsync + this.#useDirectFileTransfersForBuildCache && + this.#cloudBuildCacheProvider.tryDownloadCacheEntryToFileAsync ) { // Use file-based path to avoid loading the entire cache entry into memory. // The provider downloads directly to a temp file that is atomically moved into place. - const targetPath: string = this._localBuildCacheProvider.getCacheEntryPath(cacheId); + const targetPath: string = this.#localBuildCacheProvider.getCacheEntryPath(cacheId); // If multiple local Rush processes race to restore the same cache entry (e.g. parallel // "rush build" invocations on the same machine or CI agent), avoid redundant downloads by @@ -264,7 +264,7 @@ export class OperationBuildCache { const tempTargetPath: string = _getTempLocalCacheEntryPath(targetPath); try { const downloadedToTempFile: boolean = - await this._cloudBuildCacheProvider.tryDownloadCacheEntryToFileAsync( + await this.#cloudBuildCacheProvider.tryDownloadCacheEntryToFileAsync( terminal, cacheId, tempTargetPath @@ -305,11 +305,11 @@ export class OperationBuildCache { } } else { const cacheEntryBuffer: Buffer | undefined = - await this._cloudBuildCacheProvider.tryGetCacheEntryBufferByIdAsync(terminal, cacheId); + await this.#cloudBuildCacheProvider.tryGetCacheEntryBufferByIdAsync(terminal, cacheId); if (cacheEntryBuffer) { cloudCacheHit = true; try { - localCacheEntryPath = await this._localBuildCacheProvider.trySetCacheEntryBufferAsync( + localCacheEntryPath = await this.#localBuildCacheProvider.trySetCacheEntryBufferAsync( terminal, cacheId, cacheEntryBuffer @@ -331,12 +331,12 @@ export class OperationBuildCache { terminal.writeLine('Build cache hit.'); terminal.writeVerboseLine(`Cache key: ${cacheId}`); - const projectFolderPath: string = this._project.projectFolder; + const projectFolderPath: string = this.#project.projectFolder; // Purge output folders - terminal.writeVerboseLine(`Clearing cached folders: ${this._projectOutputFolderNames.join(', ')}`); + terminal.writeVerboseLine(`Clearing cached folders: ${this.#projectOutputFolderNames.join(', ')}`); await Promise.all( - this._projectOutputFolderNames.map((outputFolderName: string) => + this.#projectOutputFolderNames.map((outputFolderName: string) => FileSystem.deleteFolderAsync(`${projectFolderPath}/${outputFolderName}`) ) ); @@ -344,7 +344,7 @@ export class OperationBuildCache { const tarUtility: TarExecutable | undefined = await _tryGetTarUtility(terminal); let restoreSuccess: boolean = false; if (tarUtility && localCacheEntryPath) { - const logFilePath: string = this._getTarLogFilePath(cacheId, 'untar'); + const logFilePath: string = this.#getTarLogFilePath(cacheId, 'untar'); const tarExitCode: number = await tarUtility.tryUntarAsync({ archivePath: localCacheEntryPath, outputFolderPath: projectFolderPath, @@ -369,12 +369,12 @@ export class OperationBuildCache { } public async trySetCacheEntryAsync(terminal: ITerminal, specifiedCacheId?: string): Promise { - if (!this._cacheWriteEnabled) { + if (!this.#cacheWriteEnabled) { // Skip writing local and cloud build caches, without any noise return true; } - const cacheId: string | undefined = specifiedCacheId || this._cacheId; + const cacheId: string | undefined = specifiedCacheId || this.#cacheId; if (!cacheId) { terminal.writeWarningLine('Unable to get cache ID. Ensure Git is installed.'); return false; @@ -393,14 +393,14 @@ export class OperationBuildCache { const tarUtility: TarExecutable | undefined = await _tryGetTarUtility(terminal); if (tarUtility) { - const finalLocalCacheEntryPath: string = this._localBuildCacheProvider.getCacheEntryPath(cacheId); + const finalLocalCacheEntryPath: string = this.#localBuildCacheProvider.getCacheEntryPath(cacheId); const tempLocalCacheEntryPath: string = _getTempLocalCacheEntryPath(finalLocalCacheEntryPath); - const logFilePath: string = this._getTarLogFilePath(cacheId, 'tar'); + const logFilePath: string = this.#getTarLogFilePath(cacheId, 'tar'); const tarExitCode: number = await tarUtility.tryCreateArchiveFromProjectPathsAsync({ archivePath: tempLocalCacheEntryPath, paths: filesToCache.outputFilePaths, - project: this._project, + project: this.#project, logFilePath }); @@ -447,25 +447,25 @@ export class OperationBuildCache { // the configured CLOUD cache. If the cache is enabled, rush is always allowed to read from and // write to the local build cache. - if (this._cloudBuildCacheProvider?.isCacheWriteAllowed) { + if (this.#cloudBuildCacheProvider?.isCacheWriteAllowed) { if (!localCacheEntryPath) { throw new InternalError('Expected the local cache entry path to be set.'); } if ( - this._useDirectFileTransfersForBuildCache && - this._cloudBuildCacheProvider.tryUploadCacheEntryFromFileAsync + this.#useDirectFileTransfersForBuildCache && + this.#cloudBuildCacheProvider.tryUploadCacheEntryFromFileAsync ) { // Use file-based upload to avoid loading the entire cache entry into memory. // The provider reads from the local cache file directly. - setCloudCacheEntryPromise = this._cloudBuildCacheProvider.tryUploadCacheEntryFromFileAsync( + setCloudCacheEntryPromise = this.#cloudBuildCacheProvider.tryUploadCacheEntryFromFileAsync( terminal, cacheId, localCacheEntryPath ); } else { const cacheEntryBuffer: Buffer = await FileSystem.readFileToBufferAsync(localCacheEntryPath); - setCloudCacheEntryPromise = this._cloudBuildCacheProvider.trySetCacheEntryBufferAsync( + setCloudCacheEntryPromise = this.#cloudBuildCacheProvider.trySetCacheEntryBufferAsync( terminal, cacheId, cacheEntryBuffer @@ -496,14 +496,14 @@ export class OperationBuildCache { * symbolic link was encountered. */ private async _tryCollectPathsToCacheAsync(terminal: ITerminal): Promise { - const projectFolderPath: string = this._project.projectFolder; + const projectFolderPath: string = this.#project.projectFolder; const outputFilePaths: string[] = []; const queue: [string, string][] = []; const filteredOutputFolderNames: string[] = []; let hasSymbolicLinks: boolean = false; - const excludeAppleDoubleFiles: boolean = this._excludeAppleDoubleFiles; + const excludeAppleDoubleFiles: boolean = this.#excludeAppleDoubleFiles; // Adds child directories to the queue, files to the path list, and bails on symlinks function processChildren(relativePath: string, diskPath: string, children: FolderItem[]): void { @@ -540,7 +540,7 @@ export class OperationBuildCache { } // Handle declared output folders. - for (const outputFolder of this._projectOutputFolderNames) { + for (const outputFolder of this.#projectOutputFolderNames) { const diskPath: string = `${projectFolderPath}/${outputFolder}`; try { const children: FolderItem[] = await FileSystem.readFolderItemsAsync(diskPath); @@ -575,7 +575,7 @@ export class OperationBuildCache { }; } - private _getTarLogFilePath(cacheId: string, mode: 'tar' | 'untar'): string { - return path.join(this._project.projectRushTempFolder, `${cacheId}.${mode}.log`); + #getTarLogFilePath(cacheId: string, mode: 'tar' | 'untar'): string { + return path.join(this.#project.projectRushTempFolder, `${cacheId}.${mode}.log`); } } diff --git a/libraries/rush-lib/src/logic/buildCache/test/OperationBuildCache.test.ts b/libraries/rush-lib/src/logic/buildCache/test/OperationBuildCache.test.ts index d91554100aa..3431d5eb460 100644 --- a/libraries/rush-lib/src/logic/buildCache/test/OperationBuildCache.test.ts +++ b/libraries/rush-lib/src/logic/buildCache/test/OperationBuildCache.test.ts @@ -71,7 +71,7 @@ describe(OperationBuildCache.name, () => { describe(OperationBuildCache.getOperationBuildCache.name, () => { it('returns an OperationBuildCache with a calculated cacheId value', () => { const subject: OperationBuildCache = prepareSubject({}); - expect(subject['_cacheId']).toMatchInlineSnapshot( + expect(subject.cacheId).toMatchInlineSnapshot( `"acme-wizard/1926f30e8ed24cb47be89aea39e7efd70fcda075"` ); }); diff --git a/libraries/rush-lib/src/logic/cobuild/CobuildLock.ts b/libraries/rush-lib/src/logic/cobuild/CobuildLock.ts index 9dbf7114c3d..9eddf8f6954 100644 --- a/libraries/rush-lib/src/logic/cobuild/CobuildLock.ts +++ b/libraries/rush-lib/src/logic/cobuild/CobuildLock.ts @@ -43,7 +43,7 @@ export class CobuildLock { public readonly cobuildConfiguration: CobuildConfiguration; public readonly operationBuildCache: OperationBuildCache; - private _cobuildContext: ICobuildContext; + #cobuildContext: ICobuildContext; public constructor(options: ICobuildLockOptions) { const { @@ -75,7 +75,7 @@ export class CobuildLock { // Example: cobuild:completed:: const completedStateKey: string = ['cobuild', 'completed', contextId, cacheId].join(KEY_SEPARATOR); - this._cobuildContext = { + this.#cobuildContext = { contextId, clusterId, runnerId, @@ -91,20 +91,20 @@ export class CobuildLock { public async setCompletedStateAsync(state: ICobuildCompletedState): Promise { await this.cobuildConfiguration .getCobuildLockProvider() - .setCompletedStateAsync(this._cobuildContext, state); + .setCompletedStateAsync(this.#cobuildContext, state); } public async getCompletedStateAsync(): Promise { const state: ICobuildCompletedState | undefined = await this.cobuildConfiguration .getCobuildLockProvider() - .getCompletedStateAsync(this._cobuildContext); + .getCompletedStateAsync(this.#cobuildContext); return state; } public async tryAcquireLockAsync(): Promise { const acquireLockResult: boolean = await this.cobuildConfiguration .getCobuildLockProvider() - .acquireLockAsync(this._cobuildContext); + .acquireLockAsync(this.#cobuildContext); if (acquireLockResult) { // renew the lock in a redundant way in case of losing the lock await this.renewLockAsync(); @@ -113,10 +113,10 @@ export class CobuildLock { } public async renewLockAsync(): Promise { - await this.cobuildConfiguration.getCobuildLockProvider().renewLockAsync(this._cobuildContext); + await this.cobuildConfiguration.getCobuildLockProvider().renewLockAsync(this.#cobuildContext); } public get cobuildContext(): ICobuildContext { - return this._cobuildContext; + return this.#cobuildContext; } } diff --git a/libraries/rush-lib/src/logic/cobuild/DisjointSet.ts b/libraries/rush-lib/src/logic/cobuild/DisjointSet.ts index 3a33aef59ae..6b41149b8e1 100644 --- a/libraries/rush-lib/src/logic/cobuild/DisjointSet.ts +++ b/libraries/rush-lib/src/logic/cobuild/DisjointSet.ts @@ -7,101 +7,101 @@ import { InternalError } from '@rushstack/node-core-library'; * A disjoint set data structure */ export class DisjointSet { - private _forest: Set; - private _parentMap: Map; - private _sizeMap: Map; - private _setByElement: Map> | undefined; + #forest: Set; + #parentMap: Map; + #sizeMap: Map; + #setByElement: Map> | undefined; public constructor() { - this._forest = new Set(); - this._parentMap = new Map(); - this._sizeMap = new Map(); - this._setByElement = new Map>(); + this.#forest = new Set(); + this.#parentMap = new Map(); + this.#sizeMap = new Map(); + this.#setByElement = new Map>(); } public destroy(): void { - this._forest.clear(); - this._parentMap.clear(); - this._sizeMap.clear(); - this._setByElement?.clear(); + this.#forest.clear(); + this.#parentMap.clear(); + this.#sizeMap.clear(); + this.#setByElement?.clear(); } /** * Adds a new set containing specific object */ public add(x: T): void { - if (this._forest.has(x)) { + if (this.#forest.has(x)) { return; } - this._forest.add(x); - this._parentMap.set(x, x); - this._sizeMap.set(x, 1); - this._setByElement = undefined; + this.#forest.add(x); + this.#parentMap.set(x, x); + this.#sizeMap.set(x, 1); + this.#setByElement = undefined; } /** * Unions the sets that contain two objects */ public union(a: T, b: T): void { - let x: T = this._find(a); - let y: T = this._find(b); + let x: T = this.#find(a); + let y: T = this.#find(b); if (x === y) { // x and y are already in the same set return; } - const xSize: number = this._getSize(x); - const ySize: number = this._getSize(y); + const xSize: number = this.#getSize(x); + const ySize: number = this.#getSize(y); if (xSize < ySize) { const t: T = x; x = y; y = t; } - this._parentMap.set(y, x); - this._sizeMap.set(x, xSize + ySize); - this._setByElement = undefined; + this.#parentMap.set(y, x); + this.#sizeMap.set(x, xSize + ySize); + this.#setByElement = undefined; } public getAllSets(): Iterable> { - if (this._setByElement === undefined) { - this._setByElement = new Map>(); + if (this.#setByElement === undefined) { + this.#setByElement = new Map>(); - for (const element of this._forest) { - const root: T = this._find(element); - let set: Set | undefined = this._setByElement.get(root); + for (const element of this.#forest) { + const root: T = this.#find(element); + let set: Set | undefined = this.#setByElement.get(root); if (set === undefined) { set = new Set(); - this._setByElement.set(root, set); + this.#setByElement.set(root, set); } set.add(element); } } - return this._setByElement.values(); + return this.#setByElement.values(); } /** * Returns true if x and y are in the same set */ public isConnected(x: T, y: T): boolean { - return this._find(x) === this._find(y); + return this.#find(x) === this.#find(y); } - private _find(a: T): T { + #find(a: T): T { let x: T = a; - let parent: T = this._getParent(x); + let parent: T = this.#getParent(x); while (parent !== x) { - parent = this._getParent(parent); - this._parentMap.set(x, parent); + parent = this.#getParent(parent); + this.#parentMap.set(x, parent); x = parent; - parent = this._getParent(x); + parent = this.#getParent(x); } return x; } - private _getParent(x: T): T { - const parent: T | undefined = this._parentMap.get(x); + #getParent(x: T): T { + const parent: T | undefined = this.#parentMap.get(x); if (parent === undefined) { // This should not happen throw new InternalError(`Can not find parent`); @@ -109,8 +109,8 @@ export class DisjointSet { return parent; } - private _getSize(x: T): number { - const size: number | undefined = this._sizeMap.get(x); + #getSize(x: T): number { + const size: number | undefined = this.#sizeMap.get(x); if (size === undefined) { // This should not happen throw new InternalError(`Can not get size`); diff --git a/libraries/rush-lib/src/logic/incremental/InputsSnapshot.ts b/libraries/rush-lib/src/logic/incremental/InputsSnapshot.ts index c0c61334f33..4fa4d1b0ac2 100644 --- a/libraries/rush-lib/src/logic/incremental/InputsSnapshot.ts +++ b/libraries/rush-lib/src/logic/incremental/InputsSnapshot.ts @@ -198,26 +198,26 @@ export class InputsSnapshot implements IInputsSnapshot { /** * The metadata for each project. This is a superset of the information in `projectMap` and includes caching of queries. */ - private readonly _projectMetadataMap: Map< + readonly #projectMetadataMap: Map< IRushConfigurationProjectForSnapshot, IInternalInputsSnapshotProjectMetadata >; /** * Hashes of files to be included in all result sets. */ - private readonly _globalAdditionalHashes: ReadonlyMap | undefined; + readonly #globalAdditionalHashes: ReadonlyMap | undefined; /** * Hashes for files selected by `dependsOnAdditionalFiles`. */ - private readonly _additionalHashes: ReadonlyMap | undefined; + readonly #additionalHashes: ReadonlyMap | undefined; /** * The environment to use for `dependsOnEnvVars`. */ - private readonly _environment: Record; + readonly #environment: Record; /** * Pre-computed Node.js version strings at each granularity level for `dependsOnNodeVersion`. */ - private readonly _nodeVersionByGranularity: Readonly>; + readonly #nodeVersionByGranularity: Readonly>; /** * @@ -283,13 +283,13 @@ export class InputsSnapshot implements IInputsSnapshot { Sort.sortMapKeys(record.hashes); } - this._projectMetadataMap = projectMetadataMap; - this._additionalHashes = additionalHashes; - this._globalAdditionalHashes = globalAdditionalHashes; + this.#projectMetadataMap = projectMetadataMap; + this.#additionalHashes = additionalHashes; + this.#globalAdditionalHashes = globalAdditionalHashes; // Snapshot the environment so that queries are not impacted by when they happen - this._environment = environment; + this.#environment = environment; // Parse Node.js version once so it doesn't need to be re-parsed per operation - this._nodeVersionByGranularity = _parseNodeVersion(nodeVersion); + this.#nodeVersionByGranularity = _parseNodeVersion(nodeVersion); this.hashes = hashes; this.hasUncommittedChanges = hasUncommittedChanges; this.rootDirectory = rootDir; @@ -302,7 +302,7 @@ export class InputsSnapshot implements IInputsSnapshot { project: IRushConfigurationProjectForSnapshot, operationName?: string ): ReadonlyMap { - const record: IInternalInputsSnapshotProjectMetadata | undefined = this._projectMetadataMap.get(project); + const record: IInternalInputsSnapshotProjectMetadata | undefined = this.#projectMetadataMap.get(project); if (!record) { throw new InternalError(`No information available for project at ${project.projectFolder}`); } @@ -336,13 +336,13 @@ export class InputsSnapshot implements IInputsSnapshot { if (additionalFilesForOperation) { // Sort the additional files to ensure deterministic hash computation const sortedAdditionalFiles: string[] = Array.from(additionalFilesForOperation).sort(); - for (const [filePath, hash] of this._resolveHashes(sortedAdditionalFiles)) { + for (const [filePath, hash] of this.#resolveHashes(sortedAdditionalFiles)) { hashes.set(filePath, hash); } } } - const { _globalAdditionalHashes: globalAdditionalHashes } = this; + const globalAdditionalHashes: ReadonlyMap | undefined = this.#globalAdditionalHashes; if (globalAdditionalHashes) { for (const [file, hash] of globalAdditionalHashes) { record.hashes.set(file, hash); @@ -379,7 +379,7 @@ export class InputsSnapshot implements IInputsSnapshot { project: IRushConfigurationProjectForSnapshot, operationName?: string ): string { - const record: IInternalInputsSnapshotProjectMetadata | undefined = this._projectMetadataMap.get(project); + const record: IInternalInputsSnapshotProjectMetadata | undefined = this.#projectMetadataMap.get(project); if (!record) { throw new Error(`No information available for project at ${project.projectFolder}`); } @@ -403,14 +403,14 @@ export class InputsSnapshot implements IInputsSnapshot { // As long as we enumerate environment variables in a consistent order, we will get a stable hash. // Changing the order in rush-project.json will change the hash anyway since the file contents are part of the hash. for (const envVar of dependsOnEnvVars) { - hasher.update(`${hashDelimiter}$${envVar}=${this._environment[envVar] || ''}`); + hasher.update(`${hashDelimiter}$${envVar}=${this.#environment[envVar] || ''}`); } } if (dependsOnNodeVersion) { const granularity: NodeVersionGranularity = dependsOnNodeVersion === true ? 'patch' : dependsOnNodeVersion; - hasher.update(`${hashDelimiter}nodeVersion=${this._nodeVersionByGranularity[granularity]}`); + hasher.update(`${hashDelimiter}nodeVersion=${this.#nodeVersionByGranularity[granularity]}`); } if (outputFolderNames) { @@ -432,11 +432,12 @@ export class InputsSnapshot implements IInputsSnapshot { return hash; } - private *_resolveHashes(filePaths: Iterable): Generator<[string, string]> { - const { hashes, _additionalHashes } = this; + *#resolveHashes(filePaths: Iterable): Generator<[string, string]> { + const { hashes } = this; + const additionalHashes: ReadonlyMap | undefined = this.#additionalHashes; for (const filePath of filePaths) { - const hash: string | undefined = hashes.get(filePath) ?? _additionalHashes?.get(filePath); + const hash: string | undefined = hashes.get(filePath) ?? additionalHashes?.get(filePath); if (!hash) { throw new Error(`Could not find hash for file path "${filePath}"`); } diff --git a/libraries/rush-lib/src/logic/installManager/RushInstallManager.ts b/libraries/rush-lib/src/logic/installManager/RushInstallManager.ts index ff64f638de6..5114cb91057 100644 --- a/libraries/rush-lib/src/logic/installManager/RushInstallManager.ts +++ b/libraries/rush-lib/src/logic/installManager/RushInstallManager.ts @@ -61,7 +61,7 @@ declare module 'tar' { * This class implements common logic between "rush install" and "rush update". */ export class RushInstallManager extends BaseInstallManager { - private _tempProjectHelper: TempProjectHelper; + #tempProjectHelper: TempProjectHelper; public constructor( rushConfiguration: RushConfiguration, @@ -70,7 +70,7 @@ export class RushInstallManager extends BaseInstallManager { options: IInstallManagerOptions ) { super(rushConfiguration, rushGlobalFolder, purgeManager, options); - this._tempProjectHelper = new TempProjectHelper( + this.#tempProjectHelper = new TempProjectHelper( this.rushConfiguration, rushConfiguration.defaultSubspace ); @@ -144,7 +144,7 @@ export class RushInstallManager extends BaseInstallManager { } }); - if (this._findMissingTempProjects(shrinkwrapFile)) { + if (this.#findMissingTempProjects(shrinkwrapFile)) { // If any Rush project's tarball is missing from the shrinkwrap file, then we need to update // the shrinkwrap file. shrinkwrapIsUpToDate = false; @@ -182,7 +182,7 @@ export class RushInstallManager extends BaseInstallManager { const packageJson: PackageJsonEditor = rushProject.packageJsonEditor; // Example: "C:\MyRepo\common\temp\projects\my-project-2.tgz" - const tarballFile: string = this._tempProjectHelper.getTarballFilePath(rushProject); + const tarballFile: string = this.#tempProjectHelper.getTarballFilePath(rushProject); // Example: dependencies["@rush-temp/my-project-2"] = "file:./projects/my-project-2.tgz" commonDependencies.set( @@ -203,7 +203,7 @@ export class RushInstallManager extends BaseInstallManager { // These can be regular, optional, or peer dependencies (but NOT dev dependencies). // (A given packageName will never appear more than once in this list.) for (const dependency of packageJson.dependencyList) { - if (this.options.fullUpgrade && this._revertWorkspaceNotation(dependency)) { + if (this.options.fullUpgrade && this.#revertWorkspaceNotation(dependency)) { shrinkwrapIsUpToDate = false; } @@ -219,7 +219,7 @@ export class RushInstallManager extends BaseInstallManager { } for (const dependency of packageJson.devDependencyList) { - if (this.options.fullUpgrade && this._revertWorkspaceNotation(dependency)) { + if (this.options.fullUpgrade && this.#revertWorkspaceNotation(dependency)) { shrinkwrapIsUpToDate = false; } @@ -282,7 +282,7 @@ export class RushInstallManager extends BaseInstallManager { } // Example: "C:\MyRepo\common\temp\projects\my-project-2" - const tempProjectFolder: string = this._tempProjectHelper.getTempProjectFolder(rushProject); + const tempProjectFolder: string = this.#tempProjectHelper.getTempProjectFolder(rushProject); // Example: "C:\MyRepo\common\temp\projects\my-project-2\package.json" const tempPackageJsonFilename: string = path.join(tempProjectFolder, FileConstants.PackageJson); @@ -319,7 +319,7 @@ export class RushInstallManager extends BaseInstallManager { JsonFile.save(tempPackageJson, tempPackageJsonFilename); // Delete the existing tarball and create a new one - this._tempProjectHelper.createTempProjectTarball(rushProject); + this.#tempProjectHelper.createTempProjectTarball(rushProject); // eslint-disable-next-line no-console console.log(`Updating ${tarballFile}`); @@ -340,7 +340,7 @@ export class RushInstallManager extends BaseInstallManager { this.rushConfiguration.experimentsConfiguration.configuration.usePnpmFrozenLockfileForRushInstall ) { const pnpmShrinkwrapFile: PnpmShrinkwrapFile = shrinkwrapFile as PnpmShrinkwrapFile; - const tarballIntegrityValid: boolean = await this._validateRushProjectTarballIntegrityAsync( + const tarballIntegrityValid: boolean = await this.#validateRushProjectTarballIntegrityAsync( pnpmShrinkwrapFile, rushProject ); @@ -396,7 +396,7 @@ export class RushInstallManager extends BaseInstallManager { return { shrinkwrapIsUpToDate, shrinkwrapWarnings }; } - private _revertWorkspaceNotation(dependency: PackageJsonDependency): boolean { + #revertWorkspaceNotation(dependency: PackageJsonDependency): boolean { const specifier: DependencySpecifier = DependencySpecifier.parseWithCache( dependency.name, dependency.version @@ -420,7 +420,7 @@ export class RushInstallManager extends BaseInstallManager { return true; } - private async _validateRushProjectTarballIntegrityAsync( + async #validateRushProjectTarballIntegrityAsync( shrinkwrapFile: PnpmShrinkwrapFile | undefined, rushProject: RushConfigurationProject ): Promise { @@ -435,7 +435,7 @@ export class RushInstallManager extends BaseInstallManager { const parentShrinkwrapEntry: IPnpmShrinkwrapDependencyYaml = shrinkwrapFile.getShrinkwrapEntryFromTempProjectDependencyKey(tempProjectDependencyKey)!; const newIntegrity: string = ( - await ssri.fromStream(fs.createReadStream(this._tempProjectHelper.getTarballFilePath(rushProject))) + await ssri.fromStream(fs.createReadStream(this.#tempProjectHelper.getTarballFilePath(rushProject))) ).toString(); if (!parentShrinkwrapEntry.resolution || parentShrinkwrapEntry.resolution.integrity !== newIntegrity) { @@ -464,7 +464,7 @@ export class RushInstallManager extends BaseInstallManager { // Example: "C:\MyRepo\common\temp\projects\my-project-2.tgz" potentiallyChangedFiles.push( ...this.rushConfiguration.projects.map((x) => { - return this._tempProjectHelper.getTarballFilePath(x); + return this.#tempProjectHelper.getTarballFilePath(x); }) ); @@ -479,7 +479,7 @@ export class RushInstallManager extends BaseInstallManager { // This ensures that any existing tarballs with older header bits will be regenerated. // It is safe to assume that temp project pacakge.jsons already exist. for (const rushProject of this.rushConfiguration.projects) { - this._tempProjectHelper.createTempProjectTarball(rushProject); + this.#tempProjectHelper.createTempProjectTarball(rushProject); } // NOTE: The PNPM store is supposed to be transactionally safe, so we don't delete it automatically. @@ -653,7 +653,7 @@ export class RushInstallManager extends BaseInstallManager { // eslint-disable-next-line no-console console.log('"npm shrinkwrap" completed\n'); - await this._fixupNpm5RegressionAsync(); + await this.#fixupNpm5RegressionAsync(); } } @@ -683,7 +683,7 @@ export class RushInstallManager extends BaseInstallManager { * Our workaround is to rewrite the package.json files for each of the @rush-temp projects * in the node_modules folder, after "npm install" completes. */ - private async _fixupNpm5RegressionAsync(): Promise { + async #fixupNpm5RegressionAsync(): Promise { const pathToDeleteWithoutStar: string = path.join( this.rushConfiguration.commonTempFolder, 'node_modules', @@ -725,7 +725,7 @@ export class RushInstallManager extends BaseInstallManager { * * @returns true if orphans were found, or false if everything is okay */ - private _findMissingTempProjects(shrinkwrapFile: BaseShrinkwrapFile): boolean { + #findMissingTempProjects(shrinkwrapFile: BaseShrinkwrapFile): boolean { const tempProjectNames: Set = new Set(shrinkwrapFile.getTempProjectNames()); for (const rushProject of this.rushConfiguration.projects) { diff --git a/libraries/rush-lib/src/logic/npm/NpmLinkManager.ts b/libraries/rush-lib/src/logic/npm/NpmLinkManager.ts index 97e4098d7ef..a3bf7f8a4c0 100644 --- a/libraries/rush-lib/src/logic/npm/NpmLinkManager.ts +++ b/libraries/rush-lib/src/logic/npm/NpmLinkManager.ts @@ -45,7 +45,7 @@ export class NpmLinkManager extends BaseLinkManager { for (const rushProject of this._rushConfiguration.projects) { // eslint-disable-next-line no-console console.log(`\nLINKING: ${rushProject.packageName}`); - await this._linkProjectAsync(rushProject, commonRootPackage, commonPackageLookup); + await this.#linkProjectAsync(rushProject, commonRootPackage, commonPackageLookup); } } @@ -55,7 +55,7 @@ export class NpmLinkManager extends BaseLinkManager { * @param commonRootPackage The common/temp/package.json package * @param commonPackageLookup A dictionary for finding packages under common/temp/node_modules */ - private async _linkProjectAsync( + async #linkProjectAsync( project: RushConfigurationProject, commonRootPackage: NpmPackage, commonPackageLookup: PackageLookup diff --git a/libraries/rush-lib/src/logic/npm/NpmShrinkwrapFile.ts b/libraries/rush-lib/src/logic/npm/NpmShrinkwrapFile.ts index b0880d98b7b..6555e361389 100644 --- a/libraries/rush-lib/src/logic/npm/NpmShrinkwrapFile.ts +++ b/libraries/rush-lib/src/logic/npm/NpmShrinkwrapFile.ts @@ -24,21 +24,21 @@ interface INpmShrinkwrapJson { export class NpmShrinkwrapFile extends BaseShrinkwrapFile { public readonly isWorkspaceCompatible: boolean; - private _shrinkwrapJson: INpmShrinkwrapJson; + #shrinkwrapJson: INpmShrinkwrapJson; private constructor(shrinkwrapJson: INpmShrinkwrapJson) { super(); - this._shrinkwrapJson = shrinkwrapJson; + this.#shrinkwrapJson = shrinkwrapJson; // Normalize the data - if (!this._shrinkwrapJson.version) { - this._shrinkwrapJson.version = ''; + if (!this.#shrinkwrapJson.version) { + this.#shrinkwrapJson.version = ''; } - if (!this._shrinkwrapJson.name) { - this._shrinkwrapJson.name = ''; + if (!this.#shrinkwrapJson.name) { + this.#shrinkwrapJson.name = ''; } - if (!this._shrinkwrapJson.dependencies) { - this._shrinkwrapJson.dependencies = {}; + if (!this.#shrinkwrapJson.dependencies) { + this.#shrinkwrapJson.dependencies = {}; } // Workspaces not supported in NPM @@ -68,17 +68,17 @@ export class NpmShrinkwrapFile extends BaseShrinkwrapFile { } public override getTempProjectNames(): ReadonlyArray { - return this._getTempProjectNames(this._shrinkwrapJson.dependencies); + return this._getTempProjectNames(this.#shrinkwrapJson.dependencies); } protected override serialize(): string { - return JsonFile.stringify(this._shrinkwrapJson); + return JsonFile.stringify(this.#shrinkwrapJson); } protected override getTopLevelDependencyVersion(dependencyName: string): DependencySpecifier | undefined { // First, check under tempProjectName, as this is the first place we look during linking. const dependencyJson: INpmShrinkwrapDependencyJson | undefined = NpmShrinkwrapFile.tryGetValue( - this._shrinkwrapJson.dependencies, + this.#shrinkwrapJson.dependencies, dependencyName ); @@ -102,7 +102,7 @@ export class NpmShrinkwrapFile extends BaseShrinkwrapFile { let dependencyJson: INpmShrinkwrapDependencyJson | undefined = undefined; const tempDependency: INpmShrinkwrapDependencyJson | undefined = NpmShrinkwrapFile.tryGetValue( - this._shrinkwrapJson.dependencies, + this.#shrinkwrapJson.dependencies, tempProjectName ); if (tempDependency && tempDependency.dependencies) { diff --git a/libraries/rush-lib/src/logic/operations/AsyncOperationQueue.ts b/libraries/rush-lib/src/logic/operations/AsyncOperationQueue.ts index 6602ca74485..035eb53395a 100644 --- a/libraries/rush-lib/src/logic/operations/AsyncOperationQueue.ts +++ b/libraries/rush-lib/src/logic/operations/AsyncOperationQueue.ts @@ -17,19 +17,19 @@ import { RushConstants } from '../RushConstants'; export class AsyncOperationQueue implements AsyncIterable, AsyncIterator { - private readonly _queue: OperationExecutionRecord[]; - private readonly _pendingIterators: ((result: IteratorResult) => void)[]; - private readonly _totalOperations: number; - private readonly _completedOperations: Set; + readonly #queue: OperationExecutionRecord[]; + readonly #pendingIterators: ((result: IteratorResult) => void)[]; + readonly #totalOperations: number; + readonly #completedOperations: Set; /** * Tracks how many times each operation has been assigned to an execution slot. * Operations that have been assigned more times (e.g. cobuild retries) are sorted * after operations with fewer attempts, so untried work is preferred. */ - private readonly _numberOfTimesQueuedByOperation: Map; + readonly #numberOfTimesQueuedByOperation: Map; - private _isDone: boolean; + #isDone: boolean; /** * @param operations - The set of operations to be executed @@ -39,12 +39,12 @@ export class AsyncOperationQueue * - Returning 0 indicates no preference. */ public constructor(operations: Iterable, sortFn: IOperationSortFunction) { - this._queue = computeTopologyAndSort(operations, sortFn); - this._pendingIterators = []; - this._totalOperations = this._queue.length; - this._isDone = false; - this._completedOperations = new Set(); - this._numberOfTimesQueuedByOperation = new Map(); + this.#queue = computeTopologyAndSort(operations, sortFn); + this.#pendingIterators = []; + this.#totalOperations = this.#queue.length; + this.#isDone = false; + this.#completedOperations = new Set(); + this.#numberOfTimesQueuedByOperation = new Map(); } /** @@ -52,7 +52,8 @@ export class AsyncOperationQueue * @see {AsyncIterator} */ public next(): Promise> { - const { _pendingIterators: waitingIterators } = this; + const waitingIterators: Array<(result: IteratorResult) => void> = + this.#pendingIterators; const promise: Promise> = new Promise( (resolve: (result: IteratorResult) => void) => { @@ -70,8 +71,8 @@ export class AsyncOperationQueue * If all operations are completed, set the queue to done, resolve all pending iterators in next cycle. */ public complete(record: OperationExecutionRecord): void { - this._completedOperations.add(record); - this._numberOfTimesQueuedByOperation.delete(record); + this.#completedOperations.add(record); + this.#numberOfTimesQueuedByOperation.delete(record); // Apply status changes to direct dependents if (record.status !== OperationStatus.Failure && record.status !== OperationStatus.Blocked) { @@ -90,8 +91,8 @@ export class AsyncOperationQueue this.assignOperations(); - if (this._completedOperations.size === this._totalOperations) { - this._isDone = true; + if (this.#completedOperations.size === this.#totalOperations) { + this.#isDone = true; } } @@ -100,11 +101,10 @@ export class AsyncOperationQueue * if the caller does not update operation dependencies prior to calling `next()`, may need to be invoked manually. */ public assignOperations(): void { - const { - _queue: queue, - _pendingIterators: waitingIterators, - _numberOfTimesQueuedByOperation: timesQueued - } = this; + const queue: OperationExecutionRecord[] = this.#queue; + const waitingIterators: Array<(result: IteratorResult) => void> = + this.#pendingIterators; + const timesQueued: Map = this.#numberOfTimesQueuedByOperation; const readyOperations: OperationExecutionRecord[] = []; @@ -164,10 +164,10 @@ export class AsyncOperationQueue // Since items only get removed from the queue when they have a final status, this should be safe. if (queue.length === 0) { - this._isDone = true; + this.#isDone = true; } - if (this._isDone) { + if (this.#isDone) { for (const resolveAsyncIterator of waitingIterators.splice(0)) { resolveAsyncIterator({ value: undefined, diff --git a/libraries/rush-lib/src/logic/operations/BuildPlanPlugin.ts b/libraries/rush-lib/src/logic/operations/BuildPlanPlugin.ts index dce4ed3785a..cc17d508895 100644 --- a/libraries/rush-lib/src/logic/operations/BuildPlanPlugin.ts +++ b/libraries/rush-lib/src/logic/operations/BuildPlanPlugin.ts @@ -34,14 +34,14 @@ interface ICobuildPlan { } export class BuildPlanPlugin implements IPhasedCommandPlugin { - private readonly _terminal: ITerminal; + readonly #terminal: ITerminal; public constructor(terminal: ITerminal) { - this._terminal = terminal; + this.#terminal = terminal; } public apply(hooks: PhasedCommandHooks): void { - const terminal: ITerminal = this._terminal; + const terminal: ITerminal = this.#terminal; hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, (graph: IOperationGraph, context: IOperationGraphContext) => { graph.hooks.configureIteration.tap(PLUGIN_NAME, (currentStates, lastStates, iterationOptions) => { diff --git a/libraries/rush-lib/src/logic/operations/CacheableOperationPlugin.ts b/libraries/rush-lib/src/logic/operations/CacheableOperationPlugin.ts index 6f254f52fc6..6980355c88f 100644 --- a/libraries/rush-lib/src/logic/operations/CacheableOperationPlugin.ts +++ b/libraries/rush-lib/src/logic/operations/CacheableOperationPlugin.ts @@ -98,12 +98,12 @@ interface ITryGetLogOnlyOperationBuildCacheOptions } export class CacheableOperationPlugin implements IPhasedCommandPlugin { - private _buildCacheContextByOperation: Map = new Map(); + #buildCacheContextByOperation: Map = new Map(); - private readonly _options: ICacheableOperationPluginOptions; + readonly #options: ICacheableOperationPluginOptions; public constructor(options: ICacheableOperationPluginOptions) { - this._options = options; + this.#options = options; } public apply(hooks: PhasedCommandHooks): void { @@ -113,7 +113,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { cobuildConfiguration, excludeAppleDoubleFiles, useDirectFileTransfersForBuildCache - } = this._options; + } = this.#options; hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, (graph: IOperationGraph, context: IOperationGraphContext) => { graph.hooks.beforeExecuteIterationAsync.tap( @@ -187,11 +187,11 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { isCacheReadAttempted: false }; // Upstream runners may mutate the property of build cache context for downstream runners - this._buildCacheContextByOperation.set(operation, buildCacheContext); + this.#buildCacheContextByOperation.set(operation, buildCacheContext); } if (disjointSet) { - clusterOperations(disjointSet, this._buildCacheContextByOperation); + clusterOperations(disjointSet, this.#buildCacheContextByOperation); for (const operationSet of disjointSet.getAllSets()) { if (cobuildConfiguration?.cobuildFeatureEnabled && cobuildConfiguration.cobuildContextId) { // Get a deterministic ordered array of operations, which is important to get a deterministic cluster id. @@ -214,7 +214,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { // Assign same cluster id to all operations in the same cluster. for (const record of groupedOperations) { const buildCacheContext: IOperationBuildCacheContext = - this._getBuildCacheContextByOperationOrThrow(record); + this.#getBuildCacheContextByOperationOrThrow(record); buildCacheContext.cobuildClusterId = cobuildClusterId; } } @@ -228,12 +228,12 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { async ( runnerContext: IOperationRunnerContext & IOperationExecutionResult ): Promise => { - if (this._buildCacheContextByOperation.size === 0) { + if (this.#buildCacheContextByOperation.size === 0) { return; } const buildCacheContext: IOperationBuildCacheContext | undefined = - this._getBuildCacheContextByOperation(runnerContext.operation); + this.#getBuildCacheContextByOperation(runnerContext.operation); if (!buildCacheContext) { return; @@ -260,7 +260,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { ) { // The writable does not exist or has been closed, re-create one // eslint-disable-next-line require-atomic-updates - buildCacheContext.buildCacheTerminal = await this._createBuildCacheTerminalAsync({ + buildCacheContext.buildCacheTerminal = await this.#createBuildCacheTerminalAsync({ record, buildCacheContext, buildCacheEnabled: buildCacheConfiguration?.buildCacheEnabled, @@ -273,7 +273,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { const buildCacheTerminal: ITerminal = buildCacheContext.buildCacheTerminal; - let operationBuildCache: OperationBuildCache | undefined = this._tryGetOperationBuildCache({ + let operationBuildCache: OperationBuildCache | undefined = this.#tryGetOperationBuildCache({ buildCacheContext, buildCacheConfiguration, terminal: buildCacheTerminal, @@ -292,7 +292,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { ) { // When the leaf project log only is allowed and the leaf project is build cache "disabled", try to get // a log files only project build cache - operationBuildCache = await this._tryGetLogOnlyOperationBuildCacheAsync({ + operationBuildCache = await this.#tryGetLogOnlyOperationBuildCacheAsync({ buildCacheConfiguration, cobuildConfiguration, buildCacheContext, @@ -312,7 +312,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { } } - cobuildLock = await this._tryGetCobuildLockAsync({ + cobuildLock = await this.#tryGetCobuildLockAsync({ buildCacheContext, operationBuildCache, cobuildConfiguration, @@ -448,7 +448,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { } const buildCacheContext: IOperationBuildCacheContext | undefined = - this._getBuildCacheContextByOperation(operation); + this.#getBuildCacheContextByOperation(operation); if (!buildCacheContext) { return; @@ -549,7 +549,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { (record: IOperationRunnerContext & IOperationExecutionResult): void => { const { operation } = record; const buildCacheContext: IOperationBuildCacheContext | undefined = - this._buildCacheContextByOperation.get(operation); + this.#buildCacheContextByOperation.get(operation); // Status changes to direct dependents let blockCacheWrite: boolean = !buildCacheContext?.isCacheWriteAllowed; @@ -565,7 +565,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { if (blockCacheWrite) { for (const consumer of operation.consumers) { const consumerBuildCacheContext: IOperationBuildCacheContext | undefined = - this._getBuildCacheContextByOperation(consumer); + this.#getBuildCacheContextByOperation(consumer); if (consumerBuildCacheContext) { consumerBuildCacheContext.isCacheWriteAllowed = false; } @@ -575,21 +575,21 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { ); graph.hooks.afterExecuteIterationAsync.tap(PLUGIN_NAME, (status: OperationStatus) => { - this._buildCacheContextByOperation.clear(); + this.#buildCacheContextByOperation.clear(); return status; }); }); } - private _getBuildCacheContextByOperation(operation: Operation): IOperationBuildCacheContext | undefined { + #getBuildCacheContextByOperation(operation: Operation): IOperationBuildCacheContext | undefined { const buildCacheContext: IOperationBuildCacheContext | undefined = - this._buildCacheContextByOperation.get(operation); + this.#buildCacheContextByOperation.get(operation); return buildCacheContext; } - private _getBuildCacheContextByOperationOrThrow(operation: Operation): IOperationBuildCacheContext { + #getBuildCacheContextByOperationOrThrow(operation: Operation): IOperationBuildCacheContext { const buildCacheContext: IOperationBuildCacheContext | undefined = - this._getBuildCacheContextByOperation(operation); + this.#getBuildCacheContextByOperation(operation); if (!buildCacheContext) { // This should not happen throw new InternalError(`Build cache context for operation ${operation.name} should be defined`); @@ -597,7 +597,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { return buildCacheContext; } - private _tryGetOperationBuildCache( + #tryGetOperationBuildCache( options: ITryGetOperationBuildCacheOptions ): OperationBuildCache | undefined { const { @@ -632,7 +632,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { } // Get an OperationBuildCache only cache/restore log files - private async _tryGetLogOnlyOperationBuildCacheAsync( + async #tryGetLogOnlyOperationBuildCacheAsync( options: ITryGetLogOnlyOperationBuildCacheOptions ): Promise { const { @@ -682,7 +682,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { return operationBuildCache; } - private async _tryGetCobuildLockAsync({ + async #tryGetCobuildLockAsync({ cobuildConfiguration, buildCacheContext, operationBuildCache, @@ -714,7 +714,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { return buildCacheContext.cobuildLock; } - private async _createBuildCacheTerminalAsync({ + async #createBuildCacheTerminalAsync({ record, buildCacheContext, buildCacheEnabled, @@ -741,7 +741,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { // This creates the writer, only do this if necessary. const collatedWriter: CollatedWriter = record.collatedWriter; const cacheProjectLogWritable: TerminalWritable | undefined = - await this._tryGetBuildCacheTerminalWritableAsync({ + await this.#tryGetBuildCacheTerminalWritableAsync({ buildCacheContext, buildCacheEnabled, rushProject, @@ -781,7 +781,7 @@ export class CacheableOperationPlugin implements IPhasedCommandPlugin { return new Terminal(buildCacheTerminalProvider); } - private async _tryGetBuildCacheTerminalWritableAsync({ + async #tryGetBuildCacheTerminalWritableAsync({ buildCacheEnabled, rushProject, buildCacheContext, diff --git a/libraries/rush-lib/src/logic/operations/ConsoleTimelinePlugin.ts b/libraries/rush-lib/src/logic/operations/ConsoleTimelinePlugin.ts index 770480762ce..09fd0efad5d 100644 --- a/libraries/rush-lib/src/logic/operations/ConsoleTimelinePlugin.ts +++ b/libraries/rush-lib/src/logic/operations/ConsoleTimelinePlugin.ts @@ -44,10 +44,10 @@ BY PHASE: * Phased command plugin that emits a timeline to the console. */ export class ConsoleTimelinePlugin implements IPhasedCommandPlugin { - private readonly _terminal: ITerminal; + readonly #terminal: ITerminal; public constructor(terminal: ITerminal) { - this._terminal = terminal; + this.#terminal = terminal; } public apply(hooks: PhasedCommandHooks): void { @@ -59,7 +59,7 @@ export class ConsoleTimelinePlugin implements IPhasedCommandPlugin { operationResults: ReadonlyMap ): OperationStatus => { _printTimeline({ - terminal: this._terminal, + terminal: this.#terminal, result: { status, operationResults }, cobuildConfiguration: context.cobuildConfiguration }); diff --git a/libraries/rush-lib/src/logic/operations/DebugHashesPlugin.ts b/libraries/rush-lib/src/logic/operations/DebugHashesPlugin.ts index 343f9b906ad..5c1391e65ed 100644 --- a/libraries/rush-lib/src/logic/operations/DebugHashesPlugin.ts +++ b/libraries/rush-lib/src/logic/operations/DebugHashesPlugin.ts @@ -10,10 +10,10 @@ import type { IConfigurableOperation, IOperationStateHashComponents } from './IO const PLUGIN_NAME: 'DebugHashesPlugin' = 'DebugHashesPlugin'; export class DebugHashesPlugin implements IPhasedCommandPlugin { - private readonly _terminal: ITerminal; + readonly #terminal: ITerminal; public constructor(terminal: ITerminal) { - this._terminal = terminal; + this.#terminal = terminal; } public apply(hooks: PhasedCommandHooks): void { @@ -21,7 +21,7 @@ export class DebugHashesPlugin implements IPhasedCommandPlugin { graph.hooks.configureIteration.tap( PLUGIN_NAME, (operations: ReadonlyMap) => { - const terminal: ITerminal = this._terminal; + const terminal: ITerminal = this.#terminal; terminal.writeLine(Colorize.blue(`===== Begin Hash Computation =====`)); for (const [operation, record] of operations) { terminal.writeLine(Colorize.cyan(`--- ${operation.name} ---`)); diff --git a/libraries/rush-lib/src/logic/operations/IPCOperationRunner.ts b/libraries/rush-lib/src/logic/operations/IPCOperationRunner.ts index f6545fee095..27249b26bfe 100644 --- a/libraries/rush-lib/src/logic/operations/IPCOperationRunner.ts +++ b/libraries/rush-lib/src/logic/operations/IPCOperationRunner.ts @@ -53,14 +53,14 @@ export class IPCOperationRunner implements IOperationRunner { public readonly silent: boolean = false; public readonly warningsAreAllowed: boolean; - private readonly _rushProject: RushConfigurationProject; - private readonly _initialCommand: string; - private readonly _incrementalCommand: string | undefined; - private readonly _commandForHash: string; - private readonly _ignoredParameterValues: ReadonlyArray; + readonly #rushProject: RushConfigurationProject; + readonly #initialCommand: string; + readonly #incrementalCommand: string | undefined; + readonly #commandForHash: string; + readonly #ignoredParameterValues: ReadonlyArray; - private _ipcProcess: ChildProcess | undefined; - private _processReadyPromise: Promise | undefined; + #ipcProcess: ChildProcess | undefined; + #processReadyPromise: Promise | undefined; public constructor(options: IIPCOperationRunnerOptions) { const { @@ -75,16 +75,16 @@ export class IPCOperationRunner implements IOperationRunner { this.name = name; this.warningsAreAllowed = EnvironmentConfiguration.allowWarningsInSuccessfulBuild || allowWarningsOnSuccess; - this._rushProject = project; - this._initialCommand = initialCommand; - this._incrementalCommand = incrementalCommand; - this._commandForHash = commandForHash; + this.#rushProject = project; + this.#initialCommand = initialCommand; + this.#incrementalCommand = incrementalCommand; + this.#commandForHash = commandForHash; - this._ignoredParameterValues = ignoredParameterValues; + this.#ignoredParameterValues = ignoredParameterValues; } public get isActive(): boolean { - return !!(this._ipcProcess && !this._ipcProcess.killed && typeof this._ipcProcess.exitCode !== 'number'); + return !!(this.#ipcProcess && !this.#ipcProcess.killed && typeof this.#ipcProcess.exitCode !== 'number'); } public async executeAsync( @@ -92,27 +92,27 @@ export class IPCOperationRunner implements IOperationRunner { lastState?: IOperationLastState ): Promise { const commandToRun: string = - lastState && this._incrementalCommand ? this._incrementalCommand : this._initialCommand; + lastState && this.#incrementalCommand ? this.#incrementalCommand : this.#initialCommand; const invalidate: (reason: string) => void = context.getInvalidateCallback(); return await context.runWithTerminalAsync( async (terminal: ITerminal, terminalProvider: ITerminalProvider): Promise => { let isConnected: boolean = false; - if (!this._ipcProcess || typeof this._ipcProcess.exitCode === 'number') { + if (!this.#ipcProcess || typeof this.#ipcProcess.exitCode === 'number') { // Log any ignored parameters - if (this._ignoredParameterValues.length > 0) { + if (this.#ignoredParameterValues.length > 0) { terminal.writeLine( - `These parameters were ignored for this operation by project-level configuration: ${this._ignoredParameterValues.join(' ')}` + `These parameters were ignored for this operation by project-level configuration: ${this.#ignoredParameterValues.join(' ')}` ); } // Run the operation terminal.writeLine('Invoking: ' + commandToRun); - const { rushConfiguration, projectFolder } = this._rushProject; + const { rushConfiguration, projectFolder } = this.#rushProject; const { environment: initialEnvironment } = context; - this._ipcProcess = Utilities.executeLifecycleCommandAsync(commandToRun, { + this.#ipcProcess = Utilities.executeLifecycleCommandAsync(commandToRun, { rushConfiguration, workingDirectory: projectFolder, initCwd: rushConfiguration.commonTempFolder, @@ -127,11 +127,11 @@ export class IPCOperationRunner implements IOperationRunner { let resolveReadyPromise!: () => void; - this._processReadyPromise = new Promise((resolve) => { + this.#processReadyPromise = new Promise((resolve) => { resolveReadyPromise = resolve; }); - this._ipcProcess.on('message', (message: unknown) => { + this.#ipcProcess.on('message', (message: unknown) => { if (isRequestRunEventMessage(message)) { const reason: string = message.detail ? `${message.requestor}: ${message.detail}` @@ -144,7 +144,7 @@ export class IPCOperationRunner implements IOperationRunner { } else { terminal.writeLine(`Connecting to existing IPC process...`); } - const subProcess: ChildProcess = this._ipcProcess; + const subProcess: ChildProcess = this.#ipcProcess; let hasWarningOrError: boolean = false; function onStdout(data: Buffer): void { @@ -198,7 +198,7 @@ export class IPCOperationRunner implements IOperationRunner { subProcess.on('message', finishHandler); subProcess.on('error', reject); subProcess.on('exit', onExit); - this._processReadyPromise!.then(() => { + this.#processReadyPromise!.then(() => { isConnected = true; terminal.writeLine('Child supports IPC protocol. Sending "run" command...'); const runCommand: IRunCommandMessage = { @@ -225,11 +225,11 @@ export class IPCOperationRunner implements IOperationRunner { } public getConfigHash(): string { - return this._commandForHash; + return this.#commandForHash; } public async closeAsync(): Promise { - const { _ipcProcess: subProcess } = this; + const subProcess: ChildProcess | undefined = this.#ipcProcess; if (!subProcess) { return; } diff --git a/libraries/rush-lib/src/logic/operations/LegacySkipPlugin.ts b/libraries/rush-lib/src/logic/operations/LegacySkipPlugin.ts index 846362409c5..03ebc73fbcc 100644 --- a/libraries/rush-lib/src/logic/operations/LegacySkipPlugin.ts +++ b/libraries/rush-lib/src/logic/operations/LegacySkipPlugin.ts @@ -51,17 +51,17 @@ export interface ILegacySkipPluginOptions { * Core phased command plugin that implements the legacy skip detection logic, used when build cache is disabled. */ export class LegacySkipPlugin implements IPhasedCommandPlugin { - private readonly _options: ILegacySkipPluginOptions; + readonly #options: ILegacySkipPluginOptions; public constructor(options: ILegacySkipPluginOptions) { - this._options = options; + this.#options = options; } public apply(hooks: PhasedCommandHooks): void { const stateMap: WeakMap = new WeakMap(); const { terminal, changedProjectsOnly, isIncrementalBuildAllowed, allowWarningsInSuccessfulBuild } = - this._options; + this.#options; hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, (graph) => { graph.hooks.beforeExecuteIterationAsync.tap( diff --git a/libraries/rush-lib/src/logic/operations/NodeDiagnosticDirPlugin.ts b/libraries/rush-lib/src/logic/operations/NodeDiagnosticDirPlugin.ts index 70e1d88c69f..ee3ae0b8c76 100644 --- a/libraries/rush-lib/src/logic/operations/NodeDiagnosticDirPlugin.ts +++ b/libraries/rush-lib/src/logic/operations/NodeDiagnosticDirPlugin.ts @@ -20,10 +20,10 @@ export interface INodeDiagnosticDirPluginOptions { * Phased command plugin that configures the NodeJS --diagnostic-dir option to contain the project and phase name. */ export class NodeDiagnosticDirPlugin implements IPhasedCommandPlugin { - private readonly _diagnosticsDir: string; + readonly #diagnosticsDir: string; public constructor(options: INodeDiagnosticDirPluginOptions) { - this._diagnosticsDir = options.diagnosticDir; + this.#diagnosticsDir = options.diagnosticDir; } public apply(hooks: PhasedCommandHooks): void { @@ -31,7 +31,7 @@ export class NodeDiagnosticDirPlugin implements IPhasedCommandPlugin { const { associatedProject } = operation; const diagnosticDir: string = path.resolve( - this._diagnosticsDir, + this.#diagnosticsDir, associatedProject.packageName, operation.logFilenameIdentifier ); diff --git a/libraries/rush-lib/src/logic/operations/OperationChunkTap.ts b/libraries/rush-lib/src/logic/operations/OperationChunkTap.ts index 89d434df150..ac26c035f1d 100644 --- a/libraries/rush-lib/src/logic/operations/OperationChunkTap.ts +++ b/libraries/rush-lib/src/logic/operations/OperationChunkTap.ts @@ -12,20 +12,20 @@ import { TerminalWritable, type ITerminalChunk } from '@rushstack/terminal'; * @internal */ export class OperationChunkTap extends TerminalWritable { - private readonly _operationId: string; - private readonly _onChunk: (operationId: string, chunk: ITerminalChunk) => void; + readonly #operationId: string; + readonly #onChunk: (operationId: string, chunk: ITerminalChunk) => void; public constructor( operationId: string, onChunk: (operationId: string, chunk: ITerminalChunk) => void ) { super({ preventAutoclose: true }); - this._operationId = operationId; - this._onChunk = onChunk; + this.#operationId = operationId; + this.#onChunk = onChunk; } /** {@inheritDoc @rushstack/terminal#TerminalWritable.onWriteChunk} */ public onWriteChunk(chunk: ITerminalChunk): void { - this._onChunk(this._operationId, chunk); + this.#onChunk(this.#operationId, chunk); } } diff --git a/libraries/rush-lib/src/logic/operations/OperationExecutionRecord.ts b/libraries/rush-lib/src/logic/operations/OperationExecutionRecord.ts index 47317ecfac8..7ce773d0165 100644 --- a/libraries/rush-lib/src/logic/operations/OperationExecutionRecord.ts +++ b/libraries/rush-lib/src/logic/operations/OperationExecutionRecord.ts @@ -167,12 +167,12 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera public logFilePaths: ILogFilePaths | undefined; - private readonly _context: IOperationExecutionRecordContext; + readonly #context: IOperationExecutionRecordContext; - private _collatedWriter: CollatedWriter | undefined = undefined; - private _status: OperationStatus; - private _stateHash: string | undefined; - private _stateHashComponents: IOperationStateHashComponents | undefined; + #collatedWriter: CollatedWriter | undefined = undefined; + #status: OperationStatus; + #stateHash: string | undefined; + #stateHashComponents: IOperationStateHashComponents | undefined; public constructor(operation: Operation, context: IOperationExecutionRecordContext) { const { runner, associatedPhase, associatedProject, enabled } = operation; @@ -195,10 +195,10 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera operation }); - this._context = context; - this._status = operation.dependencies.size > 0 ? OperationStatus.Waiting : OperationStatus.Ready; - this._stateHash = undefined; - this._stateHashComponents = undefined; + this.#context = context; + this.#status = operation.dependencies.size > 0 ? OperationStatus.Waiting : OperationStatus.Ready; + this.#stateHash = undefined; + this.#stateHashComponents = undefined; } public get name(): string { @@ -206,19 +206,19 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera } public get debugMode(): boolean { - return this._context.debugMode; + return this.#context.debugMode; } public get quietMode(): boolean { - return this._context.quietMode; + return this.#context.quietMode; } public get collatedWriter(): CollatedWriter { // Lazy instantiate because the registerTask() call affects display ordering - if (!this._collatedWriter) { - this._collatedWriter = this._context.streamCollator.registerTask(this.name); + if (!this.#collatedWriter) { + this.#collatedWriter = this.#context.streamCollator.registerTask(this.name); } - return this._collatedWriter; + return this.#collatedWriter; } public get nonCachedDurationMs(): number | undefined { @@ -232,12 +232,12 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera } public get environment(): IEnvironment | undefined { - return this._context.createEnvironment?.(this); + return this.#context.createEnvironment?.(this); } public getInvalidateCallback(): (reason: string) => void { const invalidateFn: ((operations: Iterable, reason: string) => void) | undefined = - this._context.invalidate; + this.#context.invalidate; const operations: [Operation] = [this.operation]; return (reason: string) => { invalidateFn?.(operations, reason); @@ -259,16 +259,16 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera * 'failure'. */ public get status(): OperationStatus { - return this._status; + return this.#status; } public set status(newStatus: OperationStatus) { - if (newStatus === this._status) { + if (newStatus === this.#status) { return; } - const previousStatus: OperationStatus = this._status; - this._status = newStatus; - this._context.eventSink?.onOperationStatusChanged?.(this, previousStatus); - this._context.onOperationStateChanged?.(this); + const previousStatus: OperationStatus = this.#status; + this.#status = newStatus; + this.#context.eventSink?.onOperationStatusChanged?.(this, previousStatus); + this.#context.onOperationStateChanged?.(this); } /** @@ -276,7 +276,7 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera * @internal */ public get eventSink(): IOperationGraphEventSink | undefined { - return this._context.eventSink; + return this.#context.eventSink; } public get silent(): boolean { @@ -284,7 +284,7 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera } public getStateHash(): string { - if (this._stateHash === undefined) { + if (this.#stateHash === undefined) { const { dependencies, local, config } = this.getStateHashComponents(); const hasher: crypto.Hash = crypto.createHash('sha1'); @@ -295,14 +295,14 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera hasher.update(`${RushConstants.hashDelimiter}config=${config}`); const hash: string = hasher.digest('hex'); - this._stateHash = hash; + this.#stateHash = hash; } - return this._stateHash; + return this.#stateHash; } public getStateHashComponents(): IOperationStateHashComponents { - if (!this._stateHashComponents) { - const { inputsSnapshot } = this._context; + if (!this.#stateHashComponents) { + const { inputsSnapshot } = this.#context; if (!inputsSnapshot) { throw new Error(`Cannot calculate state hash without git.`); @@ -332,9 +332,9 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera // - CLI parameters (ShellOperationRunner) const config: string = this.runner.getConfigHash(); - this._stateHashComponents = { dependencies, local, config }; + this.#stateHashComponents = { dependencies, local, config }; } - return this._stateHashComponents; + return this.#stateHashComponents; } /** @@ -366,7 +366,7 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera if (logFilePaths) { // Only assign if it won't clear an existing value; stopgap until we support multiple sets of log files per operation. this.logFilePaths = logFilePaths; - this._context.onOperationStateChanged?.(this); + this.#context.onOperationStateChanged?.(this); } try { @@ -397,7 +397,7 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera }); const chunkTapDestinations: TerminalWritable[] = []; - const eventSink: IOperationGraphEventSink | undefined = this._context.eventSink; + const eventSink: IOperationGraphEventSink | undefined = this.#context.eventSink; if (eventSink?.onOperationChunk) { // Tap the stream upstream of the quiet-mode discard so the sink observes // the exact bytes the collated writer would receive, regardless of verbosity. @@ -485,9 +485,9 @@ export class OperationExecutionRecord implements IOperationRunnerContext, IOpera await executeContext.onResultAsync(this); } finally { if (this.isTerminal) { - this._collatedWriter?.close(); - if (this._collatedWriter) { - this._context.eventSink?.onOperationStreamClosed?.(this.name); + this.#collatedWriter?.close(); + if (this.#collatedWriter) { + this.#context.eventSink?.onOperationStreamClosed?.(this.name); } this.stdioSummarizer.close(); this.problemCollector.close(); diff --git a/libraries/rush-lib/src/logic/operations/OperationGraph.ts b/libraries/rush-lib/src/logic/operations/OperationGraph.ts index 58e6c692aad..7cd67d15d37 100644 --- a/libraries/rush-lib/src/logic/operations/OperationGraph.ts +++ b/libraries/rush-lib/src/logic/operations/OperationGraph.ts @@ -160,22 +160,22 @@ export class OperationGraph implements IOperationGraph { public readonly hooks: OperationGraphHooks = new OperationGraphHooks(); public readonly operations: Set; public readonly abortController: AbortController; - private readonly _sortedOperations: readonly Operation[]; + readonly #sortedOperations: readonly Operation[]; public resultByOperation: Map; // Mutable properties extracted from options - private _parallelism: number; - private _maxParallelism: number; - private _debugMode: boolean; - private _quietMode: boolean; - private _allowOversubscription: boolean; - private _pauseNextIteration: boolean; + #parallelism: number; + #maxParallelism: number; + #debugMode: boolean; + #quietMode: boolean; + #allowOversubscription: boolean; + #pauseNextIteration: boolean; // Immutable properties from options - private readonly _isWatch: boolean; - private readonly _telemetry: IOperationGraphTelemetry | undefined; - private readonly _getInputsSnapshotAsync: (() => Promise) | undefined; + readonly #isWatch: boolean; + readonly #telemetry: IOperationGraphTelemetry | undefined; + readonly #getInputsSnapshotAsync: (() => Promise) | undefined; /** * Records invalidated during the current iteration that could not be marked `Ready` immediately @@ -183,12 +183,12 @@ export class OperationGraph implements IOperationGraph { * `records` map (mutating it mid-iteration would corrupt the summarizer's view of results). * Maps each record to the invalidation reason; applied once the iteration completes. */ - private readonly _deferredInvalidations: Map = new Map(); + readonly #deferredInvalidations: Map = new Map(); - private _currentIteration: IExecutionIterationContext | undefined = undefined; - private _scheduledIteration: IExecutionIterationContext | undefined = undefined; + #currentIteration: IExecutionIterationContext | undefined = undefined; + #scheduledIteration: IExecutionIterationContext | undefined = undefined; - private _terminalSplitter: SplitterTransform; + #terminalSplitter: SplitterTransform; /** * Optional structured event sink enabling "dual-emit": every operation state @@ -201,10 +201,10 @@ export class OperationGraph implements IOperationGraph { */ public eventSink: IOperationGraphEventSink | undefined = undefined; - private _idleTimeout: NodeJS.Timeout | undefined = undefined; + #idleTimeout: NodeJS.Timeout | undefined = undefined; /** Tracks if a graph state change notification has been scheduled for next tick. */ - private _graphStateChangeScheduled: boolean = false; - private _status: OperationStatus = OperationStatus.Ready; + #graphStateChangeScheduled: boolean = false; + #status: OperationStatus = OperationStatus.Ready; public constructor(operations: Set, options: IOperationGraphOptions) { const { @@ -223,26 +223,26 @@ export class OperationGraph implements IOperationGraph { this.operations = operations; - this._maxParallelism = maxParallelism; - this._parallelism = coerceParallelism(parallelism, maxParallelism, 1); - this._debugMode = debugMode; - this._quietMode = quietMode; - this._allowOversubscription = allowOversubscription; - this._pauseNextIteration = pauseNextIteration; - this._isWatch = isWatch; - this._telemetry = telemetry; - this._getInputsSnapshotAsync = getInputsSnapshotAsync; - - this._sortedOperations = Array.from(operations).sort(sortOperationsByName); - this._terminalSplitter = new SplitterTransform({ destinations }); + this.#maxParallelism = maxParallelism; + this.#parallelism = coerceParallelism(parallelism, maxParallelism, 1); + this.#debugMode = debugMode; + this.#quietMode = quietMode; + this.#allowOversubscription = allowOversubscription; + this.#pauseNextIteration = pauseNextIteration; + this.#isWatch = isWatch; + this.#telemetry = telemetry; + this.#getInputsSnapshotAsync = getInputsSnapshotAsync; + + this.#sortedOperations = Array.from(operations).sort(sortOperationsByName); + this.#terminalSplitter = new SplitterTransform({ destinations }); this.resultByOperation = new Map(); this.abortController = abortController; this.abortController.signal.addEventListener( 'abort', () => { - if (this._idleTimeout) { - clearTimeout(this._idleTimeout); + if (this.#idleTimeout) { + clearTimeout(this.#idleTimeout); } void this.closeRunnersAsync(); }, @@ -341,89 +341,89 @@ export class OperationGraph implements IOperationGraph { } public get parallelism(): number { - return this._parallelism; + return this.#parallelism; } public set parallelism(value: Parallelism) { - const coerced: number = coerceParallelism(value, this._maxParallelism, 1); - if (coerced !== this._parallelism) { - this._parallelism = coerced; - this._scheduleManagerStateChanged(); + const coerced: number = coerceParallelism(value, this.#maxParallelism, 1); + if (coerced !== this.#parallelism) { + this.#parallelism = coerced; + this.#scheduleManagerStateChanged(); } } public get debugMode(): boolean { - return this._debugMode; + return this.#debugMode; } public set debugMode(value: boolean) { - if (value !== this._debugMode) { - this._debugMode = value; - this._scheduleManagerStateChanged(); + if (value !== this.#debugMode) { + this.#debugMode = value; + this.#scheduleManagerStateChanged(); } } public get quietMode(): boolean { - return this._quietMode; + return this.#quietMode; } public set quietMode(value: boolean) { - if (value !== this._quietMode) { - this._quietMode = value; - this._scheduleManagerStateChanged(); + if (value !== this.#quietMode) { + this.#quietMode = value; + this.#scheduleManagerStateChanged(); } } public get allowOversubscription(): boolean { - return this._allowOversubscription; + return this.#allowOversubscription; } public set allowOversubscription(value: boolean) { - if (value !== this._allowOversubscription) { - this._allowOversubscription = value; - this._scheduleManagerStateChanged(); + if (value !== this.#allowOversubscription) { + this.#allowOversubscription = value; + this.#scheduleManagerStateChanged(); } } public get pauseNextIteration(): boolean { - return this._pauseNextIteration; + return this.#pauseNextIteration; } public set pauseNextIteration(value: boolean) { - if (value !== this._pauseNextIteration) { - this._pauseNextIteration = value; - this._scheduleManagerStateChanged(); + if (value !== this.#pauseNextIteration) { + this.#pauseNextIteration = value; + this.#scheduleManagerStateChanged(); - this._setIdleTimeout(); + this.#setIdleTimeout(); } } public get hasScheduledIteration(): boolean { - return !!this._scheduledIteration; + return !!this.#scheduledIteration; } public get status(): OperationStatus { - return this._status; + return this.#status; } public get terminalDestinations(): ReadonlySet { - return this._terminalSplitter.destinations; + return this.#terminalSplitter.destinations; } - private _setStatus(newStatus: OperationStatus): void { - if (this._status !== newStatus) { - this._status = newStatus; - this._scheduleManagerStateChanged(); + #setStatus(newStatus: OperationStatus): void { + if (this.#status !== newStatus) { + this.#status = newStatus; + this.#scheduleManagerStateChanged(); } } - private _setScheduledIteration(iteration: IExecutionIterationContext | undefined): void { - const hadScheduled: boolean = !!this._scheduledIteration; - this._scheduledIteration = iteration; - if (hadScheduled !== !!this._scheduledIteration) { - this._scheduleManagerStateChanged(); + #setScheduledIteration(iteration: IExecutionIterationContext | undefined): void { + const hadScheduled: boolean = !!this.#scheduledIteration; + this.#scheduledIteration = iteration; + if (hadScheduled !== !!this.#scheduledIteration) { + this.#scheduleManagerStateChanged(); } } public async closeRunnersAsync(operations?: Iterable): Promise { const runnersToClose: IOperationRunnerCloseEntry[] = []; const recordMap: ReadonlyMap = - this._currentIteration?.records ?? this.resultByOperation; + this.#currentIteration?.records ?? this.resultByOperation; const closedRecords: Set = new Set(); for (const operation of operations ?? this.operations) { const closeAsync: (() => Promise) | undefined = operation.runner?.closeAsync; @@ -459,7 +459,7 @@ export class OperationGraph implements IOperationGraph { public invalidateOperations(operations?: Iterable, reason?: string): void { const invalidated: Set = new Set(); - const currentIteration: IExecutionIterationContext | undefined = this._currentIteration; + const currentIteration: IExecutionIterationContext | undefined = this.#currentIteration; const currentIterationRecords: Map | undefined = currentIteration?.records; for (const operation of operations ?? this.operations) { @@ -470,7 +470,7 @@ export class OperationGraph implements IOperationGraph { // resultByOperation. Mutating its status now would corrupt the iteration's result // snapshot (used by the summarizer). Defer the reset until the iteration ends, and // abort so the operation can be re-run in the next iteration. - this._deferredInvalidations.set(existing, reason); + this.#deferredInvalidations.set(existing, reason); currentIteration?.abortController.abort(); } else { existing.status = OperationStatus.Ready; @@ -482,7 +482,7 @@ export class OperationGraph implements IOperationGraph { this.hooks.onInvalidateOperations.call(invalidated, reason); } if (!currentIteration) { - this._setStatus(OperationStatus.Ready); + this.#setStatus(OperationStatus.Ready); } } @@ -495,7 +495,7 @@ export class OperationGraph implements IOperationGraph { public async executeAsync(iterationOptions: IOperationGraphIterationOptions): Promise { await this.abortCurrentIterationAsync(); const scheduled: IExecutionIterationContext | undefined = - await this._scheduleIterationAsync(iterationOptions); + await this.#scheduleIterationAsync(iterationOptions); if (!scheduled) { return { operationResults: this.resultByOperation, @@ -515,7 +515,7 @@ export class OperationGraph implements IOperationGraph { * @returns A promise that resolves to true if the iteration was successfully queued, or false if it was not. */ public async scheduleIterationAsync(iterationOptions: IOperationGraphIterationOptions): Promise { - return !!(await this._scheduleIterationAsync(iterationOptions)); + return !!(await this.#scheduleIterationAsync(iterationOptions)); } /** @@ -525,23 +525,23 @@ export class OperationGraph implements IOperationGraph { public async executeScheduledIterationAsync(): Promise { await this.abortCurrentIterationAsync(); - const iteration: IExecutionIterationContext | undefined = this._scheduledIteration; + const iteration: IExecutionIterationContext | undefined = this.#scheduledIteration; if (!iteration) { return false; } - this._currentIteration = iteration; - this._setScheduledIteration(undefined); + this.#currentIteration = iteration; + this.#setScheduledIteration(undefined); - iteration.promise = this._executeInnerAsync(this._currentIteration).finally(() => { - this._currentIteration = undefined; + iteration.promise = this.#executeInnerAsync(this.#currentIteration).finally(() => { + this.#currentIteration = undefined; // Apply any status resets that were deferred because the records were part of the // now-completed iteration and could not be mutated mid-iteration. // Coalesce by reason so consumers receive one notification per reason group. const byReason: Map = new Map(); - for (const [record, deferredReason] of this._deferredInvalidations) { + for (const [record, deferredReason] of this.#deferredInvalidations) { record.status = OperationStatus.Ready; let group: Operation[] | undefined = byReason.get(deferredReason); if (!group) { @@ -550,12 +550,12 @@ export class OperationGraph implements IOperationGraph { } group.push(record.operation); } - this._deferredInvalidations.clear(); + this.#deferredInvalidations.clear(); for (const [deferredReason, ops] of byReason) { this.hooks.onInvalidateOperations.call(ops, deferredReason); } - this._setIdleTimeout(); + this.#setIdleTimeout(); }); await iteration.promise; @@ -563,7 +563,7 @@ export class OperationGraph implements IOperationGraph { } public async abortCurrentIterationAsync(): Promise { - const iteration: IExecutionIterationContext | undefined = this._currentIteration; + const iteration: IExecutionIterationContext | undefined = this.#currentIteration; if (iteration) { iteration.abortController.abort(); try { @@ -573,44 +573,45 @@ export class OperationGraph implements IOperationGraph { } } - this._setIdleTimeout(); + this.#setIdleTimeout(); } public addTerminalDestination(destination: TerminalWritable): void { - this._terminalSplitter.addDestination(destination); + this.#terminalSplitter.addDestination(destination); } public removeTerminalDestination(destination: TerminalWritable, close: boolean = true): boolean { - return this._terminalSplitter.removeDestination(destination, close); + return this.#terminalSplitter.removeDestination(destination, close); } - private _setIdleTimeout(): void { - if (this._currentIteration || this.abortController.signal.aborted) { + #setIdleTimeout(): void { + if (this.#currentIteration || this.abortController.signal.aborted) { return; } - if (!this._idleTimeout) { - this._idleTimeout = setTimeout(this._onIdle, 0); + if (!this.#idleTimeout) { + this.#idleTimeout = setTimeout(this.#onIdle, 0); } } - private _onIdle = (): void => { - this._idleTimeout = undefined; - if (this._currentIteration || this.abortController.signal.aborted) { + #onIdle = (): void => { + this.#idleTimeout = undefined; + if (this.#currentIteration || this.abortController.signal.aborted) { return; } - if (!this.pauseNextIteration && this._scheduledIteration) { + if (!this.pauseNextIteration && this.#scheduledIteration) { void this.executeScheduledIterationAsync(); } else { this.hooks.onIdle.call(); } }; - private async _scheduleIterationAsync( + async #scheduleIterationAsync( iterationOptions: IOperationGraphIterationOptions ): Promise { - const { _getInputsSnapshotAsync: getInputsSnapshotAsync } = this; + const getInputsSnapshotAsync: (() => Promise) | undefined = + this.#getInputsSnapshotAsync; const { startTime = performance.now(), inputsSnapshot = await getInputsSnapshotAsync?.() } = iterationOptions; @@ -625,7 +626,7 @@ export class OperationGraph implements IOperationGraph { // streamCollator --> colorsNewlinesTransform --> StdioWritable // const colorsNewlinesTransform: TextRewriterTransform = new TextRewriterTransform({ - destination: this._terminalSplitter, + destination: this.#terminalSplitter, normalizeNewlines: NewlineKind.OsDefault, removeColors: !ConsoleTerminalProvider.supportsColor }); @@ -635,7 +636,7 @@ export class OperationGraph implements IOperationGraph { onWriterActive }); - const sortedOperations: readonly Operation[] = this._sortedOperations; + const sortedOperations: readonly Operation[] = this.#sortedOperations; const graph: OperationGraph = this; @@ -650,7 +651,7 @@ export class OperationGraph implements IOperationGraph { streamCollator, terminal, inputsSnapshot, - maxParallelism: this._maxParallelism, + maxParallelism: this.#maxParallelism, onOperationStateChanged: undefined, createEnvironment: createEnvironmentForOperation, invalidate: (operations: Iterable, reason: string) => { @@ -717,7 +718,7 @@ export class OperationGraph implements IOperationGraph { return; } - this._setScheduledIteration(iterationContext); + this.#setScheduledIteration(iterationContext); // Notify listeners that an iteration has been scheduled with the planned operation records try { this.hooks.onIterationScheduled.call(iterationContext.records); @@ -728,8 +729,8 @@ export class OperationGraph implements IOperationGraph { terminal.writeStderrLine(Colorize.red(errorMessage)); throw e; } - if (!this._currentIteration) { - this._setIdleTimeout(); + if (!this.#currentIteration) { + this.#setIdleTimeout(); } else if (!this.pauseNextIteration) { void this.abortCurrentIterationAsync(); } @@ -779,13 +780,13 @@ export class OperationGraph implements IOperationGraph { * only trigger the hook once. This avoids redundant re-computation in listeners (e.g. UI refresh) while preserving * ordering guarantees that the notification occurs after the initiating state changes are fully applied. */ - private _scheduleManagerStateChanged(): void { - if (this._graphStateChangeScheduled || this.abortController.signal.aborted) { + #scheduleManagerStateChanged(): void { + if (this.#graphStateChangeScheduled || this.abortController.signal.aborted) { return; } - this._graphStateChangeScheduled = true; + this.#graphStateChangeScheduled = true; process.nextTick(() => { - this._graphStateChangeScheduled = false; + this.#graphStateChangeScheduled = false; this.hooks.onGraphStateChanged.call(this); }); } @@ -794,8 +795,8 @@ export class OperationGraph implements IOperationGraph { * Executes all operations which have been registered, returning a promise which is resolved when all operations have been processed to a final state. * The abortController can be used to cancel the execution of any operations that have not yet begun execution. */ - private async _executeInnerAsync(iterationContext: IExecutionIterationContext): Promise { - this._setStatus(OperationStatus.Executing); + async #executeInnerAsync(iterationContext: IExecutionIterationContext): Promise { + this.#setStatus(OperationStatus.Executing); const { hooks } = this; @@ -974,16 +975,16 @@ export class OperationGraph implements IOperationGraph { return OperationStatus.Success; })(); - this._setStatus( + this.#setStatus( (await measureAsyncFn(`${PERF_PREFIX}:afterExecuteIterationAsync`, async () => { return await hooks.afterExecuteIterationAsync.promise(status, executionRecords, iterationOptions); })) ?? status ); - const { _telemetry: telemetry } = this; + const telemetry: IOperationGraphTelemetry | undefined = this.#telemetry; if (telemetry) { const logEntry: ITelemetryData = measureFn(`${PERF_PREFIX}:prepareTelemetry`, () => { - const isWatch: boolean = this._isWatch; + const isWatch: boolean = this.#isWatch; const jsonOperationResults: Record = {}; const durationInSeconds: number = (performance.now() - (iterationContext.startTime ?? 0)) / 1000; diff --git a/libraries/rush-lib/src/logic/operations/OperationMetadataManager.ts b/libraries/rush-lib/src/logic/operations/OperationMetadataManager.ts index e3f1f2f0dc5..51007b65a60 100644 --- a/libraries/rush-lib/src/logic/operations/OperationMetadataManager.ts +++ b/libraries/rush-lib/src/logic/operations/OperationMetadataManager.ts @@ -49,10 +49,10 @@ export interface ILogChunkStorage { export class OperationMetadataManager { public readonly stateFile: OperationStateFile; public readonly logFilenameIdentifier: string; - private readonly _metadataFolderPath: string; - private readonly _logPath: string; - private readonly _errorLogPath: string; - private readonly _logChunksPath: string; + readonly #metadataFolderPath: string; + readonly #logPath: string; + readonly #errorLogPath: string; + readonly #logChunksPath: string; public wasCobuilt: boolean = false; public constructor(options: IOperationMetadataManagerOptions) { @@ -70,10 +70,10 @@ export class OperationMetadataManager { metadataFolder: metadataFolderPath }); - this._metadataFolderPath = metadataFolderPath; - this._logPath = `${projectFolder}/${metadataFolderPath}/all.log`; - this._errorLogPath = `${projectFolder}/${metadataFolderPath}/error.log`; - this._logChunksPath = `${projectFolder}/${metadataFolderPath}/log-chunks.jsonl`; + this.#metadataFolderPath = metadataFolderPath; + this.#logPath = `${projectFolder}/${metadataFolderPath}/all.log`; + this.#errorLogPath = `${projectFolder}/${metadataFolderPath}/error.log`; + this.#logChunksPath = `${projectFolder}/${metadataFolderPath}/log-chunks.jsonl`; } /** @@ -84,7 +84,7 @@ export class OperationMetadataManager { * Example: `.rush/temp/operation/_phase_build/error.log` */ public get metadataFolderPath(): string { - return this._metadataFolderPath; + return this.#metadataFolderPath; } public async saveAsync({ @@ -105,15 +105,15 @@ export class OperationMetadataManager { const copyFileOptions: IFileSystemCopyFileOptions[] = [ { sourcePath: logPath, - destinationPath: this._logPath + destinationPath: this.#logPath }, { sourcePath: errorLogPath, - destinationPath: this._errorLogPath + destinationPath: this.#errorLogPath }, { sourcePath: logChunksPath, - destinationPath: this._logChunksPath + destinationPath: this.#logChunksPath } ]; @@ -150,7 +150,7 @@ export class OperationMetadataManager { this.stateFile.state?.cobuildRunnerId !== cobuildRunnerId; try { - const rawLogChunks: string = await FileSystem.readFileAsync(this._logChunksPath); + const rawLogChunks: string = await FileSystem.readFileAsync(this.#logChunksPath); const chunks: ITerminalChunk[] = []; for (const chunk of rawLogChunks.split('\n')) { if (chunk) { @@ -167,7 +167,7 @@ export class OperationMetadataManager { } catch (e) { if (FileSystem.isNotExistError(e)) { // Log chunks file doesn't exist, try to restore log file - await restoreFromLogFile(terminal, this._logPath); + await restoreFromLogFile(terminal, this.#logPath); } else { throw e; } @@ -176,7 +176,7 @@ export class OperationMetadataManager { // Try to restore cached error log as error log file try { await FileSystem.copyFileAsync({ - sourcePath: this._errorLogPath, + sourcePath: this.#errorLogPath, destinationPath: errorLogPath }); } catch (e) { diff --git a/libraries/rush-lib/src/logic/operations/OperationResultSummarizerPlugin.ts b/libraries/rush-lib/src/logic/operations/OperationResultSummarizerPlugin.ts index 1ff82c3baf6..7f9c171a119 100644 --- a/libraries/rush-lib/src/logic/operations/OperationResultSummarizerPlugin.ts +++ b/libraries/rush-lib/src/logic/operations/OperationResultSummarizerPlugin.ts @@ -25,10 +25,10 @@ type IOperationsByStatus = Map; * Phased command plugin that emits a summary of build results to the console. */ export class OperationResultSummarizerPlugin implements IPhasedCommandPlugin { - private readonly _terminal: ITerminal; + readonly #terminal: ITerminal; public constructor(terminal: ITerminal) { - this._terminal = terminal; + this.#terminal = terminal; } public apply(hooks: PhasedCommandHooks): void { @@ -40,7 +40,7 @@ export class OperationResultSummarizerPlugin implements IPhasedCommandPlugin { status: OperationStatus, results: ReadonlyMap ): OperationStatus => { - _printOperationStatus(this._terminal, { status, operationResults: results }); + _printOperationStatus(this.#terminal, { status, operationResults: results }); return status; } ); diff --git a/libraries/rush-lib/src/logic/operations/OperationStateFile.ts b/libraries/rush-lib/src/logic/operations/OperationStateFile.ts index b05cf70b57f..c0773f066ed 100644 --- a/libraries/rush-lib/src/logic/operations/OperationStateFile.ts +++ b/libraries/rush-lib/src/logic/operations/OperationStateFile.ts @@ -26,7 +26,7 @@ export interface IOperationStateJson { * @internal */ export class OperationStateFile { - private _state: IOperationStateJson | undefined; + #state: IOperationStateJson | undefined; /** * The path of the state json file. @@ -51,25 +51,25 @@ export class OperationStateFile { } public get state(): IOperationStateJson | undefined { - return this._state; + return this.#state; } public async writeAsync(json: IOperationStateJson): Promise { await JsonFile.saveAsync(json, this.filepath, { ensureFolderExists: true, ignoreUndefinedValues: true }); - this._state = json; + this.#state = json; } public async tryRestoreAsync(): Promise { try { - this._state = await JsonFile.loadAsync(this.filepath); + this.#state = await JsonFile.loadAsync(this.filepath); } catch (error) { if (FileSystem.isNotExistError(error as Error)) { - this._state = undefined; + this.#state = undefined; } else { // This should not happen throw new InternalError(error); } } - return this._state; + return this.#state; } } diff --git a/libraries/rush-lib/src/logic/operations/PeriodicCallback.ts b/libraries/rush-lib/src/logic/operations/PeriodicCallback.ts index 26aa1814f55..8c645ef373b 100644 --- a/libraries/rush-lib/src/logic/operations/PeriodicCallback.ts +++ b/libraries/rush-lib/src/logic/operations/PeriodicCallback.ts @@ -13,42 +13,42 @@ export interface IPeriodicCallbackOptions { * @beta */ export class PeriodicCallback { - private _callbacks: ICallbackFn[]; - private _interval: number; - private _intervalId: NodeJS.Timeout | undefined; - private _isRunning: boolean; + #callbacks: ICallbackFn[]; + #interval: number; + #intervalId: NodeJS.Timeout | undefined; + #isRunning: boolean; public constructor(options: IPeriodicCallbackOptions) { - this._callbacks = []; - this._interval = options.interval; - this._isRunning = false; + this.#callbacks = []; + this.#interval = options.interval; + this.#isRunning = false; } public addCallback(callback: ICallbackFn): void { - if (this._isRunning) { + if (this.#isRunning) { throw new Error('Can not add callback while watcher is running'); } - this._callbacks.push(callback); + this.#callbacks.push(callback); } public start(): void { - if (this._intervalId) { + if (this.#intervalId) { throw new Error('Watcher already started'); } - if (this._callbacks.length === 0) { + if (this.#callbacks.length === 0) { return; } - this._isRunning = true; - this._intervalId = setInterval(() => { - this._callbacks.forEach((callback) => callback()); - }, this._interval); + this.#isRunning = true; + this.#intervalId = setInterval(() => { + this.#callbacks.forEach((callback) => callback()); + }, this.#interval); } public stop(): void { - if (this._intervalId) { - clearInterval(this._intervalId); - this._intervalId = undefined; - this._isRunning = false; + if (this.#intervalId) { + clearInterval(this.#intervalId); + this.#intervalId = undefined; + this.#isRunning = false; } } } diff --git a/libraries/rush-lib/src/logic/operations/PnpmSyncCopyOperationPlugin.ts b/libraries/rush-lib/src/logic/operations/PnpmSyncCopyOperationPlugin.ts index 6857acf1ec0..ba47d2e4a6f 100644 --- a/libraries/rush-lib/src/logic/operations/PnpmSyncCopyOperationPlugin.ts +++ b/libraries/rush-lib/src/logic/operations/PnpmSyncCopyOperationPlugin.ts @@ -16,10 +16,10 @@ import { RushConstants } from '../RushConstants'; const PLUGIN_NAME: 'PnpmSyncCopyOperationPlugin' = 'PnpmSyncCopyOperationPlugin'; export class PnpmSyncCopyOperationPlugin implements IPhasedCommandPlugin { - private readonly _terminal: ITerminal; + readonly #terminal: ITerminal; public constructor(terminal: ITerminal) { - this._terminal = terminal; + this.#terminal = terminal; } public apply(hooks: PhasedCommandHooks): void { hooks.onGraphCreatedAsync.tap(PLUGIN_NAME, (graph) => { @@ -53,7 +53,7 @@ export class PnpmSyncCopyOperationPlugin implements IPhasedCommandPlugin { forEachAsyncWithConcurrency: Async.forEachAsync, getPackageIncludedFiles: PackageExtractor.getPackageIncludedFilesAsync, logMessageCallback: (logMessageOptions: ILogMessageCallbackOptions) => - PnpmSyncUtilities.processLogMessage(logMessageOptions, this._terminal) + PnpmSyncUtilities.processLogMessage(logMessageOptions, this.#terminal) }); } } diff --git a/libraries/rush-lib/src/logic/operations/ProjectLogWritable.ts b/libraries/rush-lib/src/logic/operations/ProjectLogWritable.ts index c11888a6b0d..7a9d4e4e6b7 100644 --- a/libraries/rush-lib/src/logic/operations/ProjectLogWritable.ts +++ b/libraries/rush-lib/src/logic/operations/ProjectLogWritable.ts @@ -93,19 +93,19 @@ const LOG_CHUNKS_FOLDER_RELATIVE_PATH: string = `${RushConstants.projectRushFold export class JsonLFileWritable extends TerminalWritable { public readonly logPath: string; - private _writer: FileWriter | undefined; + #writer: FileWriter | undefined; public constructor(logPath: string) { super(); this.logPath = logPath; - this._writer = FileWriter.open(logPath); + this.#writer = FileWriter.open(logPath); } // Override writeChunk function to throw custom error public override writeChunk(chunk: ITerminalChunk): void { - if (!this._writer) { + if (!this.#writer) { throw new InternalError(`Log writer was closed for ${this.logPath}`); } // Stderr can always get written to a error log writer @@ -113,20 +113,20 @@ export class JsonLFileWritable extends TerminalWritable { } protected onWriteChunk(chunk: ITerminalChunk): void { - if (!this._writer) { + if (!this.#writer) { throw new InternalError(`Log writer was closed for ${this.logPath}`); } - this._writer.write(JSON.stringify(chunk) + '\n'); + this.#writer.write(JSON.stringify(chunk) + '\n'); } protected override onClose(): void { - if (this._writer) { + if (this.#writer) { try { - this._writer.close(); + this.#writer.close(); } catch (error) { - throw new InternalError('Failed to close file handle for ' + this._writer.filePath); + throw new InternalError('Failed to close file handle for ' + this.#writer.filePath); } - this._writer = undefined; + this.#writer = undefined; } } } @@ -138,8 +138,8 @@ export class SplitLogFileWritable extends TerminalWritable { public readonly logPath: string; public readonly errorLogPath: string; - private _logWriter: FileWriter | undefined = undefined; - private _errorLogWriter: FileWriter | undefined = undefined; + #logWriter: FileWriter | undefined = undefined; + #errorLogWriter: FileWriter | undefined = undefined; public constructor(logPath: string, errorLogPath: string) { super(); @@ -147,13 +147,13 @@ export class SplitLogFileWritable extends TerminalWritable { this.logPath = logPath; this.errorLogPath = errorLogPath; - this._logWriter = FileWriter.open(logPath); - this._errorLogWriter = undefined; + this.#logWriter = FileWriter.open(logPath); + this.#errorLogWriter = undefined; } // Override writeChunk function to throw custom error public override writeChunk(chunk: ITerminalChunk): void { - if (!this._logWriter) { + if (!this.#logWriter) { throw new InternalError(`Log writer was closed for ${this.logPath}`); } // Stderr can always get written to a error log writer @@ -161,38 +161,38 @@ export class SplitLogFileWritable extends TerminalWritable { } protected onWriteChunk(chunk: ITerminalChunk): void { - if (!this._logWriter) { + if (!this.#logWriter) { throw new InternalError('Output file was closed'); } // Both stderr and stdout get written to *..log - this._logWriter.write(chunk.text); + this.#logWriter.write(chunk.text); if (chunk.kind === TerminalChunkKind.Stderr) { // Only stderr gets written to *..error.log - if (!this._errorLogWriter) { - this._errorLogWriter = FileWriter.open(this.errorLogPath); + if (!this.#errorLogWriter) { + this.#errorLogWriter = FileWriter.open(this.errorLogPath); } - this._errorLogWriter.write(chunk.text); + this.#errorLogWriter.write(chunk.text); } } protected override onClose(): void { - if (this._logWriter) { + if (this.#logWriter) { try { - this._logWriter.close(); + this.#logWriter.close(); } catch (error) { - throw new InternalError('Failed to close file handle for ' + this._logWriter.filePath); + throw new InternalError('Failed to close file handle for ' + this.#logWriter.filePath); } - this._logWriter = undefined; + this.#logWriter = undefined; } - if (this._errorLogWriter) { + if (this.#errorLogWriter) { try { - this._errorLogWriter.close(); + this.#errorLogWriter.close(); } catch (error) { - throw new InternalError('Failed to close file handle for ' + this._errorLogWriter.filePath); + throw new InternalError('Failed to close file handle for ' + this.#errorLogWriter.filePath); } - this._errorLogWriter = undefined; + this.#errorLogWriter = undefined; } } } diff --git a/libraries/rush-lib/src/logic/operations/ShellOperationRunner.ts b/libraries/rush-lib/src/logic/operations/ShellOperationRunner.ts index a9de80dde28..ee511fd7d5d 100644 --- a/libraries/rush-lib/src/logic/operations/ShellOperationRunner.ts +++ b/libraries/rush-lib/src/logic/operations/ShellOperationRunner.ts @@ -41,13 +41,13 @@ export class ShellOperationRunner implements IOperationRunner { */ public readonly isNoOp: boolean = false; - private readonly _commandForHash: string; - private readonly _initialCommand: string; - private readonly _incrementalCommand: string | undefined; + readonly #commandForHash: string; + readonly #initialCommand: string; + readonly #incrementalCommand: string | undefined; - private readonly _rushProject: RushConfigurationProject; + readonly #rushProject: RushConfigurationProject; - private readonly _ignoredParameterValues: ReadonlyArray; + readonly #ignoredParameterValues: ReadonlyArray; public constructor(options: IShellOperationRunnerOptions) { const { @@ -63,11 +63,11 @@ export class ShellOperationRunner implements IOperationRunner { this.name = displayName; this.warningsAreAllowed = EnvironmentConfiguration.allowWarningsInSuccessfulBuild || phase.allowWarningsOnSuccess || false; - this._rushProject = rushProject; - this._initialCommand = initialCommand; - this._incrementalCommand = incrementalCommand; - this._commandForHash = commandForHash; - this._ignoredParameterValues = ignoredParameterValues; + this.#rushProject = rushProject; + this.#initialCommand = initialCommand; + this.#incrementalCommand = incrementalCommand; + this.#commandForHash = commandForHash; + this.#ignoredParameterValues = ignoredParameterValues; } public async executeAsync( @@ -79,21 +79,21 @@ export class ShellOperationRunner implements IOperationRunner { let hasWarningOrError: boolean = false; // Log any ignored parameters - if (this._ignoredParameterValues.length > 0) { + if (this.#ignoredParameterValues.length > 0) { terminal.writeLine( - `These parameters were ignored for this operation by project-level configuration: ${this._ignoredParameterValues.join(' ')}` + `These parameters were ignored for this operation by project-level configuration: ${this.#ignoredParameterValues.join(' ')}` ); } const incrementalCommand: string | undefined = - lastState && this._incrementalCommand ? this._incrementalCommand : undefined; - const commandToRun: string = incrementalCommand ?? this._initialCommand; + lastState && this.#incrementalCommand ? this.#incrementalCommand : undefined; + const commandToRun: string = incrementalCommand ?? this.#initialCommand; // Run the operation terminal.writeLine( `Invoking (${incrementalCommand !== undefined ? 'incremental' : 'initial'}): ${commandToRun}` ); - const { rushConfiguration, projectFolder } = this._rushProject; + const { rushConfiguration, projectFolder } = this.#rushProject; const { environment: initialEnvironment } = context; @@ -152,7 +152,7 @@ export class ShellOperationRunner implements IOperationRunner { } public getConfigHash(): string { - return this._commandForHash; + return this.#commandForHash; } } diff --git a/libraries/rush-lib/src/logic/operations/ValidateOperationsPlugin.ts b/libraries/rush-lib/src/logic/operations/ValidateOperationsPlugin.ts index 0f256c4789b..fcca1674973 100644 --- a/libraries/rush-lib/src/logic/operations/ValidateOperationsPlugin.ts +++ b/libraries/rush-lib/src/logic/operations/ValidateOperationsPlugin.ts @@ -14,10 +14,10 @@ const PLUGIN_NAME: 'ValidateOperationsPlugin' = 'ValidateOperationsPlugin'; * Core phased command plugin that verifies correctness of the entries in rush-project.json */ export class ValidateOperationsPlugin implements IPhasedCommandPlugin { - private readonly _terminal: ITerminal; + readonly #terminal: ITerminal; public constructor(terminal: ITerminal) { - this._terminal = terminal; + this.#terminal = terminal; } public apply(hooks: PhasedCommandHooks): void { @@ -41,7 +41,7 @@ export class ValidateOperationsPlugin implements IPhasedCommandPlugin { const projectConfiguration: RushProjectConfiguration | undefined = context.projectConfigurations.get(project); if (projectConfiguration) { - projectConfiguration.validatePhaseConfiguration(phases, this._terminal); + projectConfiguration.validatePhaseConfiguration(phases, this.#terminal); } } }); diff --git a/libraries/rush-lib/src/logic/operations/test/MockOperationRunner.ts b/libraries/rush-lib/src/logic/operations/test/MockOperationRunner.ts index 3e620634580..dc8444abeb0 100644 --- a/libraries/rush-lib/src/logic/operations/test/MockOperationRunner.ts +++ b/libraries/rush-lib/src/logic/operations/test/MockOperationRunner.ts @@ -7,7 +7,7 @@ import { OperationStatus } from '../OperationStatus'; import type { IOperationRunner, IOperationRunnerContext } from '../IOperationRunner'; export class MockOperationRunner implements IOperationRunner { - private readonly _action: ((terminal: CollatedTerminal) => Promise) | undefined; + readonly #action: ((terminal: CollatedTerminal) => Promise) | undefined; public readonly name: string; public readonly reportTiming: boolean = true; public readonly silent: boolean = false; @@ -23,14 +23,14 @@ export class MockOperationRunner implements IOperationRunner { ) { this.isNoOp = isNoOp; this.name = name; - this._action = action; + this.#action = action; this.warningsAreAllowed = warningsAreAllowed; } public async executeAsync(context: IOperationRunnerContext): Promise { let result: OperationStatus | undefined; - if (this._action) { - result = await this._action(context.collatedWriter.terminal); + if (this.#action) { + result = await this.#action(context.collatedWriter.terminal); } return result || OperationStatus.Success; } diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmLinkManager.ts b/libraries/rush-lib/src/logic/pnpm/PnpmLinkManager.ts index b020bea25af..d5b1d7bea20 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmLinkManager.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmLinkManager.ts @@ -35,7 +35,7 @@ import { IS_WINDOWS } from '../../utilities/executionUtilities'; const DEBUG: boolean = false; export class PnpmLinkManager extends BaseLinkManager { - private readonly _pnpmVersion: semver.SemVer = new semver.SemVer( + readonly #pnpmVersion: semver.SemVer = new semver.SemVer( this._rushConfiguration.packageManagerToolVersion ); @@ -73,7 +73,7 @@ export class PnpmLinkManager extends BaseLinkManager { } for (const rushProject of this._rushConfiguration.projects) { - await this._linkProjectAsync(rushProject, pnpmShrinkwrapFile); + await this.#linkProjectAsync(rushProject, pnpmShrinkwrapFile); } } else { // eslint-disable-next-line no-console @@ -91,7 +91,7 @@ export class PnpmLinkManager extends BaseLinkManager { * @param project The local project that we will create symlinks for * @param rushLinkJson The common/temp/rush-link.json output file */ - private async _linkProjectAsync( + async #linkProjectAsync( project: RushConfigurationProject, pnpmShrinkwrapFile: PnpmShrinkwrapFile ): Promise { @@ -228,7 +228,7 @@ export class PnpmLinkManager extends BaseLinkManager { : ''; // e.g.: C:\wbt\common\temp\node_modules\.local\C%3A%2Fwbt%2Fcommon%2Ftemp%2Fprojects%2Fapi-documenter.tgz\node_modules - const pathToLocalInstallation: string = await this._getPathToLocalInstallationAsync( + const pathToLocalInstallation: string = await this.#getPathToLocalInstallationAsync( tarballEntry, absolutePathToTgzFile, folderNameSuffix, @@ -244,7 +244,7 @@ export class PnpmLinkManager extends BaseLinkManager { } for (const dependencyName of Object.keys(commonPackage.packageJson!.dependencies || {})) { - const newLocalPackage: BasePackage = this._createLocalPackageForDependency( + const newLocalPackage: BasePackage = this.#createLocalPackageForDependency( project, parentShrinkwrapEntry, localPackage, @@ -289,13 +289,13 @@ export class PnpmLinkManager extends BaseLinkManager { }); } - private async _getPathToLocalInstallationAsync( + async #getPathToLocalInstallationAsync( tarballEntry: string, absolutePathToTgzFile: string, folderSuffix: string, tempProjectDependencyKey: string ): Promise { - if (this._pnpmVersion.major === 6) { + if (this.#pnpmVersion.major === 6) { // PNPM 6 changed formatting to replace all ':' and '/' chars with '+'. Additionally, folder names > 120 // are trimmed and hashed. NOTE: PNPM internally uses fs.realpath.native, which will cause additional // issues in environments that do not support long paths. @@ -323,7 +323,7 @@ export class PnpmLinkManager extends BaseLinkManager { folderName, RushConstants.nodeModulesFolderName ); - } else if (this._pnpmVersion.major >= 10) { + } else if (this.#pnpmVersion.major >= 10) { const pnpmKitV10: typeof import('@rushstack/rush-pnpm-kit-v10') = await import( '@rushstack/rush-pnpm-kit-v10' ); @@ -343,7 +343,7 @@ export class PnpmLinkManager extends BaseLinkManager { folderName, RushConstants.nodeModulesFolderName ); - } else if (this._pnpmVersion.major >= 9) { + } else if (this.#pnpmVersion.major >= 9) { const pnpmKitV9: typeof import('@rushstack/rush-pnpm-kit-v9') = await import( '@rushstack/rush-pnpm-kit-v9' ); @@ -359,7 +359,7 @@ export class PnpmLinkManager extends BaseLinkManager { folderName, RushConstants.nodeModulesFolderName ); - } else if (this._pnpmVersion.major >= 8) { + } else if (this.#pnpmVersion.major >= 8) { const pnpmKitV8: typeof import('@rushstack/rush-pnpm-kit-v8') = await import( '@rushstack/rush-pnpm-kit-v8' ); @@ -376,7 +376,7 @@ export class PnpmLinkManager extends BaseLinkManager { folderName, RushConstants.nodeModulesFolderName ); - } else if (this._pnpmVersion.major >= 7) { + } else if (this.#pnpmVersion.major >= 7) { const { depPathToFilename } = await import('dependency-path'); // PNPM 7 changed the local path format again and the hashing algorithm // See https://github.com/pnpm/pnpm/releases/tag/v7.0.0 @@ -410,7 +410,7 @@ export class PnpmLinkManager extends BaseLinkManager { ); } } - private _createLocalPackageForDependency( + #createLocalPackageForDependency( project: RushConfigurationProject, parentShrinkwrapEntry: IPnpmShrinkwrapDependencyYaml, localPackage: BasePackage, diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts b/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts index f5c3b0481d5..79d38da2b7c 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmOptionsConfiguration.ts @@ -212,9 +212,9 @@ export interface IPnpmOptionsJson extends IPackageManagerOptionsJsonBase { * @public */ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfigurationBase { - private readonly _json: JsonObject; - private readonly _commonTempFolder: string; - private _globalPatchedDependencies: Record | undefined; + readonly #json: JsonObject; + readonly #commonTempFolder: string; + #globalPatchedDependencies: Record | undefined; /** * The method used to resolve the store used by PNPM. @@ -553,13 +553,13 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration * PNPM documentation: https://pnpm.io/package_json#pnpmpatcheddependencies */ public get globalPatchedDependencies(): Record | undefined { - return this._globalPatchedDependencies; + return this.#globalPatchedDependencies; } private constructor(json: IPnpmOptionsJson, commonTempFolder: string, jsonFilename?: string) { super(json); - this._json = json; - this._commonTempFolder = commonTempFolder; + this.#json = json; + this.#commonTempFolder = commonTempFolder; this.jsonFilename = jsonFilename; this.pnpmStore = json.pnpmStore || 'local'; if (EnvironmentConfiguration.pnpmStorePathOverride) { @@ -588,7 +588,7 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration this.globalIgnoredOptionalDependencies = json.globalIgnoredOptionalDependencies; this.globalAllowedDeprecatedVersions = json.globalAllowedDeprecatedVersions; this.unsupportedPackageJsonSettings = json.unsupportedPackageJsonSettings; - this._globalPatchedDependencies = json.globalPatchedDependencies; + this.#globalPatchedDependencies = json.globalPatchedDependencies; this.resolutionMode = json.resolutionMode; this.autoInstallPeers = json.autoInstallPeers; @@ -638,7 +638,7 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration return new PnpmOptionsConfiguration(json, commonTempFolder); } - private _getJsonFilenameOrThrow(): string { + #getJsonFilenameOrThrow(): string { if (!this.jsonFilename) { throw new Error('Cannot save pnpm-config.json because no jsonFilename was provided.'); } @@ -660,16 +660,16 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration const normalized: Record = {}; for (const [dependency, patchPath] of Object.entries(patchedDependencies)) { normalized[dependency] = - path.isAbsolute(patchPath) && Path.isUnder(patchPath, this._commonTempFolder) - ? Path.convertToSlashes(path.relative(this._commonTempFolder, patchPath)) + path.isAbsolute(patchPath) && Path.isUnder(patchPath, this.#commonTempFolder) + ? Path.convertToSlashes(path.relative(this.#commonTempFolder, patchPath)) : patchPath; } patchedDependencies = normalized; } - this._globalPatchedDependencies = patchedDependencies; - this._json.globalPatchedDependencies = patchedDependencies; - JsonFile.save(this._json, this._getJsonFilenameOrThrow(), { + this.#globalPatchedDependencies = patchedDependencies; + this.#json.globalPatchedDependencies = patchedDependencies; + JsonFile.save(this.#json, this.#getJsonFilenameOrThrow(), { updateExistingFile: true, ignoreUndefinedValues: true }); @@ -681,9 +681,9 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration * @deprecated Use {@link PnpmOptionsConfiguration.updateGlobalOnlyBuiltDependenciesAsync} instead. */ public updateGlobalOnlyBuiltDependencies(onlyBuiltDependencies: string[] | undefined): void { - this._json.globalOnlyBuiltDependencies = onlyBuiltDependencies; + this.#json.globalOnlyBuiltDependencies = onlyBuiltDependencies; if (this.jsonFilename) { - JsonFile.save(this._json, this.jsonFilename, { + JsonFile.save(this.#json, this.jsonFilename, { updateExistingFile: true, ignoreUndefinedValues: true }); @@ -696,8 +696,8 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration public async updateGlobalOnlyBuiltDependenciesAsync( onlyBuiltDependencies: string[] | undefined ): Promise { - this._json.globalOnlyBuiltDependencies = onlyBuiltDependencies; - await JsonFile.saveAsync(this._json, this._getJsonFilenameOrThrow(), { + this.#json.globalOnlyBuiltDependencies = onlyBuiltDependencies; + await JsonFile.saveAsync(this.#json, this.#getJsonFilenameOrThrow(), { updateExistingFile: true, ignoreUndefinedValues: true }); @@ -709,8 +709,8 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration public async updateGlobalCatalogsAsync( catalogs: Record> | undefined ): Promise { - this._json.globalCatalogs = catalogs; - await JsonFile.saveAsync(this._json, this._getJsonFilenameOrThrow(), { + this.#json.globalCatalogs = catalogs; + await JsonFile.saveAsync(this.#json, this.#getJsonFilenameOrThrow(), { updateExistingFile: true, ignoreUndefinedValues: true }); @@ -720,9 +720,9 @@ export class PnpmOptionsConfiguration extends PackageManagerOptionsConfiguration * Updates globalAllowBuilds field of the PNPM options in the common/config/rush/pnpm-config.json file. */ public updateGlobalAllowBuilds(allowBuilds: Record | undefined): void { - this._json.globalAllowBuilds = allowBuilds; + this.#json.globalAllowBuilds = allowBuilds; if (this.jsonFilename) { - JsonFile.save(this._json, this.jsonFilename, { updateExistingFile: true }); + JsonFile.save(this.#json, this.jsonFilename, { updateExistingFile: true }); } } } diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmProjectShrinkwrapFile.ts b/libraries/rush-lib/src/logic/pnpm/PnpmProjectShrinkwrapFile.ts index 19e3899804c..07c54476590 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmProjectShrinkwrapFile.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmProjectShrinkwrapFile.ts @@ -107,18 +107,18 @@ export class PnpmProjectShrinkwrapFile extends BaseProjectShrinkwrapFile, name: string, version: IPnpmVersionSpecifier, @@ -159,14 +159,14 @@ export class PnpmProjectShrinkwrapFile extends BaseProjectShrinkwrapFile, shrinkwrapEntry: IPnpmShrinkwrapDependencyYaml, parentShrinkwrapEntry?: IPnpmShrinkwrapDependencyYaml @@ -215,7 +215,7 @@ export class PnpmProjectShrinkwrapFile extends BaseProjectShrinkwrapFile>; - private _pnpmfileConfiguration: PnpmfileConfiguration | undefined; + readonly #shrinkwrapJson: IPnpmShrinkwrapYaml; + readonly #integrities: Map>; + #pnpmfileConfiguration: PnpmfileConfiguration | undefined; private constructor(shrinkwrapJson: IPnpmShrinkwrapYaml, hash: string, subspaceHasNoProjects: boolean) { super(); this.hash = hash; - this._shrinkwrapJson = shrinkwrapJson; + this.#shrinkwrapJson = shrinkwrapJson; cacheByLockfileHash.set(hash, this); // Normalize the data @@ -371,7 +371,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { this.isWorkspaceCompatible = isWorkspaceCompatible; - this._integrities = new Map(); + this.#integrities = new Map(); } public static getLockfileV9PackageId(name: string, version: string): string { @@ -466,7 +466,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { // when computing the hash, since the main concern is changes to the overall external dependency footprint const { omitImportersFromPreventManualShrinkwrapChanges } = experimentsConfig || {}; - const shrinkwrapContent: string = this._serializeInternal( + const shrinkwrapContent: string = this.#serializeInternal( omitImportersFromPreventManualShrinkwrapChanges ); return crypto.createHash('sha1').update(shrinkwrapContent).digest('hex'); @@ -476,7 +476,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { * Determine whether `pnpm-lock.yaml` contains insecure sha1 hashes. * @internal */ - private _disallowInsecureSha1( + #disallowInsecureSha1( customTipsConfiguration: CustomTipsConfiguration, exemptPackageVersions: Record, terminal: ITerminal, @@ -485,14 +485,14 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { const exemptPackageList: Map = new Map(); for (const [pkgName, versions] of Object.entries(exemptPackageVersions)) { for (const version of versions) { - exemptPackageList.set(this._getPackageId(pkgName, version), true); + exemptPackageList.set(this.#getPackageId(pkgName, version), true); } } for (const [pkgName, { resolution }] of this.packages) { if ( resolution?.integrity?.startsWith('sha1') && - !exemptPackageList.has(this._parseDependencyPath(pkgName)) + !exemptPackageList.has(this.#parseDependencyPath(pkgName)) ) { terminal.writeErrorLine( 'Error: An integrity field with "sha1" was detected in the pnpm-lock.yaml file located in subspace ' + @@ -518,7 +518,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { let invalidPoliciesCount: number = 0; if (pnpmLockfilePolicies?.disallowInsecureSha1?.enabled) { - const isError: boolean = this._disallowInsecureSha1( + const isError: boolean = this.#disallowInsecureSha1( rushConfiguration.customTipsConfiguration, pnpmLockfilePolicies.disallowInsecureSha1.exemptPackageVersions, terminal, @@ -589,7 +589,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { * This operation exactly mirrors the behavior of PNPM's own implementation: * https://github.com/pnpm/pnpm/blob/73ebfc94e06d783449579cda0c30a40694d210e4/lockfile/lockfile-file/src/experiments/inlineSpecifiersLockfileConverters.ts#L162 */ - private _convertLockfileV6DepPathToV5DepPath(newDepPath: string): string { + #convertLockfileV6DepPathToV5DepPath(newDepPath: string): string { if (!newDepPath.includes('@', 2) || newDepPath.startsWith('file:')) return newDepPath; const index: number = newDepPath.indexOf('@', newDepPath.indexOf('/@') + 2); if (newDepPath.includes('(') && index > pnpmKitV8.dependencyPath.indexOfPeersSuffix(newDepPath)) @@ -602,7 +602,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { * Example: "/eslint-utils@3.0.0(eslint@8.23.1)" --> "/eslint-utils@3.0.0" * Example: "/@typescript-eslint/experimental-utils/5.9.1_eslint@8.6.0+typescript@4.4.4" --> "/@typescript-eslint/experimental-utils/5.9.1" */ - private _parseDependencyPath(packagePath: string): string { + #parseDependencyPath(packagePath: string): string { let name: string | undefined; let version: string | undefined; @@ -616,7 +616,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { ({ name, version } = pnpmKitV9.dependencyPath.parse(packagePath)); } else { if (this.shrinkwrapFileMajorVersion >= ShrinkwrapFileMajorVersion.V6) { - packagePath = this._convertLockfileV6DepPathToV5DepPath(packagePath); + packagePath = this.#convertLockfileV6DepPathToV5DepPath(packagePath); } ({ name, version } = pnpmKitV8.dependencyPath.parse(packagePath)); @@ -626,11 +626,11 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { throw new InternalError(`Unable to parse package path: ${packagePath}`); } - return this._getPackageId(name, version); + return this.#getPackageId(name, version); } public override getTempProjectNames(): ReadonlyArray { - return this._getTempProjectNames(this._shrinkwrapJson.dependencies || {}); + return this._getTempProjectNames(this.#shrinkwrapJson.dependencies || {}); } /** @@ -798,7 +798,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { name: string, version: IPnpmVersionSpecifier ): IPnpmShrinkwrapDependencyYaml | undefined { - const packageId: string = this._getPackageId(name, version); + const packageId: string = this.#getPackageId(name, version); return this.packages.get(packageId); } @@ -806,7 +806,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { * Serializes the PNPM Shrinkwrap file */ protected override serialize(): string { - return this._serializeInternal(false); + return this.#serializeInternal(false); } /** @@ -834,7 +834,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { } const packageDescription: IPnpmShrinkwrapDependencyYaml | undefined = - this._getPackageDescription(tempProjectDependencyKey); + this.#getPackageDescription(tempProjectDependencyKey); if ( !packageDescription || !packageDescription.dependencies || @@ -844,7 +844,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { } const dependencyKey: IPnpmVersionSpecifier = packageDescription.dependencies[packageName]; - return this._parsePnpmDependencyKey(packageName, dependencyKey); + return this.#parsePnpmDependencyKey(packageName, dependencyKey); } public override findOrphanedProjects( @@ -896,13 +896,13 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { public getIntegrityForImporter(importerKey: string): Map | undefined { // This logic formerly lived in PnpmProjectShrinkwrapFile. Moving it here allows caching of the external // dependency integrity relationships across projects - let integrityMap: Map | undefined = this._integrities.get(importerKey); + let integrityMap: Map | undefined = this.#integrities.get(importerKey); if (!integrityMap) { const importer: IPnpmShrinkwrapImporterYaml | undefined = this.getImporter(importerKey); if (importer) { const resolvedIntegrityMap: Map = new Map(); integrityMap = resolvedIntegrityMap; - this._integrities.set(importerKey, resolvedIntegrityMap); + this.#integrities.set(importerKey, resolvedIntegrityMap); const sha256Digest: string = crypto .createHash('sha256') @@ -938,7 +938,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { externalDeps[name] = versionSpecifier; } } - this._addIntegrities(resolvedIntegrityMap, externalDeps, optional); + this.#addIntegrities(resolvedIntegrityMap, externalDeps, optional); }; if (dependencies) { @@ -977,8 +977,8 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { const packageJson: IPackageJson = project.packageJsonEditor.saveToObject(); // Initialize the pnpmfile if it doesn't exist - if (!this._pnpmfileConfiguration) { - this._pnpmfileConfiguration = await PnpmfileConfiguration.initializeAsync( + if (!this.#pnpmfileConfiguration) { + this.#pnpmfileConfiguration = await PnpmfileConfiguration.initializeAsync( project.rushConfiguration, subspace, variant @@ -1044,7 +1044,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { // Use a new PackageJsonEditor since it will classify each dependency type, making tracking the // found versions much simpler. const { dependencyList, devDependencyList, dependencyMetaList } = PackageJsonEditor.fromObject( - this._pnpmfileConfiguration.transform(transformedPackageJson), + this.#pnpmfileConfiguration.transform(transformedPackageJson), project.packageJsonEditor.filePath ); @@ -1233,8 +1233,8 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { return false; } - private _getIntegrityForPackage(specifier: string, optional: boolean): Map { - const integrities: Map> = this._integrities; + #getIntegrityForPackage(specifier: string, optional: boolean): Map { + const integrities: Map> = this.#integrities; let integrityMap: Map | undefined = integrities.get(specifier); if (integrityMap) { @@ -1271,17 +1271,17 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { const { dependencies, optionalDependencies } = shrinkwrapEntry; if (dependencies) { - this._addIntegrities(integrityMap, dependencies, false); + this.#addIntegrities(integrityMap, dependencies, false); } if (optionalDependencies) { - this._addIntegrities(integrityMap, optionalDependencies, true); + this.#addIntegrities(integrityMap, optionalDependencies, true); } return integrityMap; } - private _addIntegrities( + #addIntegrities( integrityMap: Map, collection: Record, optional: boolean @@ -1300,13 +1300,13 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { } } } else { - const packageId: string = this._getPackageId(name, version); + const packageId: string = this.#getPackageId(name, version); if (integrityMap.has(packageId)) { // The entry could already have been added as a nested dependency continue; } - const contribution: Map = this._getIntegrityForPackage(packageId, optional); + const contribution: Map = this.#getIntegrityForPackage(packageId, optional); for (const [dep, integrity] of contribution) { integrityMap.set(dep, integrity); } @@ -1317,7 +1317,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { /** * Gets the package description for a tempProject from the shrinkwrap file. */ - private _getPackageDescription( + #getPackageDescription( tempProjectDependencyKey: string ): IPnpmShrinkwrapDependencyYaml | undefined { const packageDescription: IPnpmShrinkwrapDependencyYaml | undefined = @@ -1326,7 +1326,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { return packageDescription && packageDescription.dependencies ? packageDescription : undefined; } - private _getPackageId(name: string, versionSpecifier: IPnpmVersionSpecifier): string { + #getPackageId(name: string, versionSpecifier: IPnpmVersionSpecifier): string { const version: string = normalizePnpmVersionSpecifier(versionSpecifier); if (this.shrinkwrapFileMajorVersion >= ShrinkwrapFileMajorVersion.V9) { return PnpmShrinkwrapFile.getLockfileV9PackageId(name, version); @@ -1343,7 +1343,7 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { } } - private _parsePnpmDependencyKey( + #parsePnpmDependencyKey( dependencyName: string, pnpmDependencyKey: IPnpmVersionSpecifier ): DependencySpecifier | undefined { @@ -1366,11 +1366,11 @@ export class PnpmShrinkwrapFile extends BaseShrinkwrapFile { } } - private _serializeInternal(omitImporters: boolean = false): string { + #serializeInternal(omitImporters: boolean = false): string { // Ensure that if any of the top-level properties are provided but empty are removed. We populate the object // properties when we read the shrinkwrap but PNPM does not set these top-level properties unless they are present. const shrinkwrapToSerialize: { [key: string]: unknown } = {}; - for (const [key, value] of Object.entries(this._shrinkwrapJson)) { + for (const [key, value] of Object.entries(this.#shrinkwrapJson)) { if (omitImporters && key === 'importers') { continue; } diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts b/libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts index 7734ee575e1..433ac3d699c 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmWorkspaceFile.ts @@ -128,7 +128,7 @@ export class PnpmWorkspaceFile extends BaseWorkspaceFile { */ public readonly workspaceFilename: string; - private readonly _workspacePackages: Set; + readonly #workspacePackages: Set; public catalogs: IPnpmWorkspaceYaml['catalogs']; public allowBuilds: IPnpmWorkspaceYaml['allowBuilds']; public overrides: IPnpmWorkspaceYaml['overrides']; @@ -154,7 +154,7 @@ export class PnpmWorkspaceFile extends BaseWorkspaceFile { this.workspaceFilename = workspaceYamlFilename; // Ignore any existing file since this file is generated and we need to handle deleting packages // If we need to support manual customization, that should be an additional parameter for "base file" - this._workspacePackages = new Set(); + this.#workspacePackages = new Set(); } /** @@ -230,12 +230,12 @@ export class PnpmWorkspaceFile extends BaseWorkspaceFile { // Glob can't handle Windows paths const globPath: string = Path.convertToSlashes(packagePath); - this._workspacePackages.add(globEscape(globPath)); + this.#workspacePackages.add(globEscape(globPath)); } protected override async serializeAsync(): Promise { + const workspacePackages: Set = this.#workspacePackages; const { - _workspacePackages: workspacePackages, catalogs, allowBuilds, overrides, diff --git a/libraries/rush-lib/src/logic/pnpm/PnpmfileConfiguration.ts b/libraries/rush-lib/src/logic/pnpm/PnpmfileConfiguration.ts index 0db2eb38807..8f2c4cebebf 100644 --- a/libraries/rush-lib/src/logic/pnpm/PnpmfileConfiguration.ts +++ b/libraries/rush-lib/src/logic/pnpm/PnpmfileConfiguration.ts @@ -21,11 +21,11 @@ import type { Subspace } from '../../api/Subspace'; * optionally utilizing a pnpmfile shim to inject preferred versions. */ export class PnpmfileConfiguration { - private _context: IPnpmfileContext | undefined; + #context: IPnpmfileContext | undefined; private constructor(context: IPnpmfileContext) { pnpmfile.reset(); - this._context = context; + this.#context = context; } public static async initializeAsync( @@ -88,10 +88,10 @@ export class PnpmfileConfiguration { * @returns the transformed object, or the original input if pnpmfile.js was not found. */ public transform(packageJson: IPackageJson): IPackageJson { - if (!pnpmfile.hooks?.readPackage || !this._context) { + if (!pnpmfile.hooks?.readPackage || !this.#context) { return packageJson; } else { - return pnpmfile.hooks.readPackage(packageJson, this._context); + return pnpmfile.hooks.readPackage(packageJson, this.#context); } } } diff --git a/libraries/rush-lib/src/logic/selectors/GitChangedProjectSelectorParser.ts b/libraries/rush-lib/src/logic/selectors/GitChangedProjectSelectorParser.ts index 65d7b40fae5..ee5095fd241 100644 --- a/libraries/rush-lib/src/logic/selectors/GitChangedProjectSelectorParser.ts +++ b/libraries/rush-lib/src/logic/selectors/GitChangedProjectSelectorParser.ts @@ -21,30 +21,30 @@ export interface IGitSelectorParserOptions { } export class GitChangedProjectSelectorParser implements ISelectorParser { - private readonly _rushConfiguration: RushConfiguration; - private readonly _options: IGitSelectorParserOptions; + readonly #rushConfiguration: RushConfiguration; + readonly #options: IGitSelectorParserOptions; public constructor(rushConfiguration: RushConfiguration, options: IGitSelectorParserOptions) { - this._rushConfiguration = rushConfiguration; - this._options = options; + this.#rushConfiguration = rushConfiguration; + this.#options = options; } public async evaluateSelectorAsync({ unscopedSelector, terminal }: IEvaluateSelectorOptions): Promise> { - const projectChangeAnalyzer: ProjectChangeAnalyzer = new ProjectChangeAnalyzer(this._rushConfiguration); + const projectChangeAnalyzer: ProjectChangeAnalyzer = new ProjectChangeAnalyzer(this.#rushConfiguration); const options: IGetChangedProjectsOptions = { terminal, targetBranchName: unscopedSelector, - ...this._options + ...this.#options }; return await projectChangeAnalyzer.getChangedProjectsAsync(options); } public getCompletions(): Iterable { - return [this._rushConfiguration.repositoryDefaultBranch, 'HEAD~1', 'HEAD']; + return [this.#rushConfiguration.repositoryDefaultBranch, 'HEAD~1', 'HEAD']; } } diff --git a/libraries/rush-lib/src/logic/selectors/NamedProjectSelectorParser.ts b/libraries/rush-lib/src/logic/selectors/NamedProjectSelectorParser.ts index b39ab7ffe96..536c07648ff 100644 --- a/libraries/rush-lib/src/logic/selectors/NamedProjectSelectorParser.ts +++ b/libraries/rush-lib/src/logic/selectors/NamedProjectSelectorParser.ts @@ -9,10 +9,10 @@ import type { IEvaluateSelectorOptions, ISelectorParser } from './ISelectorParse import { RushConstants } from '../RushConstants'; export class NamedProjectSelectorParser implements ISelectorParser { - private readonly _rushConfiguration: RushConfiguration; + readonly #rushConfiguration: RushConfiguration; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; } public async evaluateSelectorAsync({ @@ -21,7 +21,7 @@ export class NamedProjectSelectorParser implements ISelectorParser> { const project: RushConfigurationProject | undefined = - this._rushConfiguration.findProjectByShorthandName(unscopedSelector); + this.#rushConfiguration.findProjectByShorthandName(unscopedSelector); if (!project) { terminal.writeErrorLine( `The project name "${unscopedSelector}" passed to "${parameterName}" does not exist in ` + @@ -37,7 +37,7 @@ export class NamedProjectSelectorParser implements ISelectorParser = new Map(); const scopedNames: Set = new Set(); - for (const project of this._rushConfiguration.rushConfigurationJson.projects) { + for (const project of this.#rushConfiguration.rushConfigurationJson.projects) { scopedNames.add(project.packageName); const unscopedName: string = PackageName.getUnscopedName(project.packageName); const count: number = unscopedNamesMap.get(unscopedName) || 0; diff --git a/libraries/rush-lib/src/logic/selectors/PathProjectSelectorParser.ts b/libraries/rush-lib/src/logic/selectors/PathProjectSelectorParser.ts index eb91e176b2d..97c2136bc72 100644 --- a/libraries/rush-lib/src/logic/selectors/PathProjectSelectorParser.ts +++ b/libraries/rush-lib/src/logic/selectors/PathProjectSelectorParser.ts @@ -12,12 +12,12 @@ import type { IEvaluateSelectorOptions, ISelectorParser } from './ISelectorParse import { RushConstants } from '../RushConstants'; export class PathProjectSelectorParser implements ISelectorParser { - private readonly _rushConfiguration: RushConfiguration; - private readonly _workingDirectory: string; + readonly #rushConfiguration: RushConfiguration; + readonly #workingDirectory: string; public constructor(rushConfiguration: RushConfiguration, workingDirectory: string) { - this._rushConfiguration = rushConfiguration; - this._workingDirectory = workingDirectory; + this.#rushConfiguration = rushConfiguration; + this.#workingDirectory = workingDirectory; } public async evaluateSelectorAsync({ @@ -26,17 +26,17 @@ export class PathProjectSelectorParser implements ISelectorParser> { // Resolve the input path against the working directory - const absolutePath: string = nodePath.resolve(this._workingDirectory, unscopedSelector); + const absolutePath: string = nodePath.resolve(this.#workingDirectory, unscopedSelector); // Relativize it to the rushJsonFolder - const relativePath: string = nodePath.relative(this._rushConfiguration.rushJsonFolder, absolutePath); + const relativePath: string = nodePath.relative(this.#rushConfiguration.rushJsonFolder, absolutePath); // Normalize path separators to forward slashes for LookupByPath const normalizedPath: string = Path.convertToSlashes(relativePath); // Get the LookupByPath instance for the Rush root const lookupByPath: LookupByPath = - this._rushConfiguration.getProjectLookupForRoot(this._rushConfiguration.rushJsonFolder); + this.#rushConfiguration.getProjectLookupForRoot(this.#rushConfiguration.rushJsonFolder); // Check if this path is within a project or matches a project exactly const containingProject: RushConfigurationProject | undefined = diff --git a/libraries/rush-lib/src/logic/selectors/SubspaceSelectorParser.ts b/libraries/rush-lib/src/logic/selectors/SubspaceSelectorParser.ts index f4b3a2bfd06..7abc26db991 100644 --- a/libraries/rush-lib/src/logic/selectors/SubspaceSelectorParser.ts +++ b/libraries/rush-lib/src/logic/selectors/SubspaceSelectorParser.ts @@ -8,16 +8,16 @@ import { RushConstants } from '../RushConstants'; import type { IEvaluateSelectorOptions, ISelectorParser } from './ISelectorParser'; export class SubspaceSelectorParser implements ISelectorParser { - private readonly _rushConfiguration: RushConfiguration; + readonly #rushConfiguration: RushConfiguration; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; } public async evaluateSelectorAsync({ unscopedSelector }: IEvaluateSelectorOptions): Promise> { - const subspace: Subspace = this._rushConfiguration.getSubspace(unscopedSelector); + const subspace: Subspace = this.#rushConfiguration.getSubspace(unscopedSelector); return subspace.getProjects(); } @@ -25,8 +25,8 @@ export class SubspaceSelectorParser implements ISelectorParser { // Tab completion is a performance sensitive operation, so avoid loading all the projects const subspaceNames: string[] = []; - if (this._rushConfiguration.subspacesConfiguration) { - subspaceNames.push(...this._rushConfiguration.subspacesConfiguration.subspaceNames); + if (this.#rushConfiguration.subspacesConfiguration) { + subspaceNames.push(...this.#rushConfiguration.subspacesConfiguration.subspaceNames); } if (!subspaceNames.indexOf(RushConstants.defaultSubspaceName)) { subspaceNames.push(RushConstants.defaultSubspaceName); diff --git a/libraries/rush-lib/src/logic/selectors/TagProjectSelectorParser.ts b/libraries/rush-lib/src/logic/selectors/TagProjectSelectorParser.ts index f704bb81edc..708803947a0 100644 --- a/libraries/rush-lib/src/logic/selectors/TagProjectSelectorParser.ts +++ b/libraries/rush-lib/src/logic/selectors/TagProjectSelectorParser.ts @@ -9,10 +9,10 @@ import type { IEvaluateSelectorOptions, ISelectorParser } from './ISelectorParse import { RushConstants } from '../RushConstants'; export class TagProjectSelectorParser implements ISelectorParser { - private readonly _rushConfiguration: RushConfiguration; + readonly #rushConfiguration: RushConfiguration; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; } public async evaluateSelectorAsync({ @@ -21,7 +21,7 @@ export class TagProjectSelectorParser implements ISelectorParser> { const selection: ReadonlySet | undefined = - this._rushConfiguration.projectsByTag.get(unscopedSelector); + this.#rushConfiguration.projectsByTag.get(unscopedSelector); if (!selection) { terminal.writeErrorLine( `The tag "${unscopedSelector}" passed to "${parameterName}" is not specified for any projects in ` + @@ -33,6 +33,6 @@ export class TagProjectSelectorParser implements ISelectorParser { - return this._rushConfiguration.projectsByTag.keys(); + return this.#rushConfiguration.projectsByTag.keys(); } } diff --git a/libraries/rush-lib/src/logic/selectors/VersionPolicyProjectSelectorParser.ts b/libraries/rush-lib/src/logic/selectors/VersionPolicyProjectSelectorParser.ts index c12c993afec..32c2e4c1a9f 100644 --- a/libraries/rush-lib/src/logic/selectors/VersionPolicyProjectSelectorParser.ts +++ b/libraries/rush-lib/src/logic/selectors/VersionPolicyProjectSelectorParser.ts @@ -8,10 +8,10 @@ import type { RushConfigurationProject } from '../../api/RushConfigurationProjec import type { IEvaluateSelectorOptions, ISelectorParser } from './ISelectorParser'; export class VersionPolicyProjectSelectorParser implements ISelectorParser { - private readonly _rushConfiguration: RushConfiguration; + readonly #rushConfiguration: RushConfiguration; public constructor(rushConfiguration: RushConfiguration) { - this._rushConfiguration = rushConfiguration; + this.#rushConfiguration = rushConfiguration; } public async evaluateSelectorAsync({ @@ -21,14 +21,14 @@ export class VersionPolicyProjectSelectorParser implements ISelectorParser> { const selection: Set = new Set(); - if (!this._rushConfiguration.versionPolicyConfiguration.versionPolicies.has(unscopedSelector)) { + if (!this.#rushConfiguration.versionPolicyConfiguration.versionPolicies.has(unscopedSelector)) { terminal.writeErrorLine( `The version policy "${unscopedSelector}" passed to "${parameterName}" does not exist in version-policies.json.` ); throw new AlreadyReportedError(); } - for (const project of this._rushConfiguration.projects) { + for (const project of this.#rushConfiguration.projects) { if (project.versionPolicyName === unscopedSelector) { selection.add(project); } @@ -38,6 +38,6 @@ export class VersionPolicyProjectSelectorParser implements ISelectorParser { - return this._rushConfiguration.versionPolicyConfiguration.versionPolicies.keys(); + return this.#rushConfiguration.versionPolicyConfiguration.versionPolicies.keys(); } } diff --git a/libraries/rush-lib/src/logic/setup/ArtifactoryConfiguration.ts b/libraries/rush-lib/src/logic/setup/ArtifactoryConfiguration.ts index effb502a5c9..3779c73ce90 100644 --- a/libraries/rush-lib/src/logic/setup/ArtifactoryConfiguration.ts +++ b/libraries/rush-lib/src/logic/setup/ArtifactoryConfiguration.ts @@ -38,7 +38,7 @@ const _jsonSchema: JsonSchema = JsonSchema.fromLoadedObject(schemaJson); * It configures the "rush setup" command. */ export class ArtifactoryConfiguration { - private readonly _jsonFileName: string; + readonly #jsonFileName: string; /** * Get the artifactory configuration. @@ -49,7 +49,7 @@ export class ArtifactoryConfiguration { * @internal */ public constructor(jsonFileName: string) { - this._jsonFileName = jsonFileName; + this.#jsonFileName = jsonFileName; this.configuration = { packageRegistry: { @@ -59,8 +59,8 @@ export class ArtifactoryConfiguration { } }; - if (FileSystem.exists(this._jsonFileName)) { - this.configuration = JsonFile.loadAndValidate(this._jsonFileName, _jsonSchema); + if (FileSystem.exists(this.#jsonFileName)) { + this.configuration = JsonFile.loadAndValidate(this.#jsonFileName, _jsonSchema); if (!this.configuration.packageRegistry.credentialType) { this.configuration.packageRegistry.credentialType = 'password'; } diff --git a/libraries/rush-lib/src/logic/setup/KeyboardLoop.ts b/libraries/rush-lib/src/logic/setup/KeyboardLoop.ts index 962dd2d5e68..ce795308f47 100644 --- a/libraries/rush-lib/src/logic/setup/KeyboardLoop.ts +++ b/libraries/rush-lib/src/logic/setup/KeyboardLoop.ts @@ -18,10 +18,10 @@ const ANSI_ESCAPE_HIDE_CURSOR: string = '\u001B[?25h'; export class KeyboardLoop { protected stdin: NodeJS.ReadStream; protected stderr: NodeJS.WriteStream; - private _readlineInterface: readline.Interface | undefined; - private _resolvePromise: (() => void) | undefined; - private _rejectPromise: ((error: Error) => void) | undefined; - private _cursorHidden: boolean = false; + #readlineInterface: readline.Interface | undefined; + #resolvePromise: (() => void) | undefined; + #rejectPromise: ((error: Error) => void) | undefined; + #cursorHidden: boolean = false; public constructor() { this.stdin = process.stdin; @@ -29,24 +29,24 @@ export class KeyboardLoop { } public get capturedInput(): boolean { - return this._readlineInterface !== undefined; + return this.#readlineInterface !== undefined; } - private _captureInput(): void { - if (this._readlineInterface) { + #captureInput(): void { + if (this.#readlineInterface) { return; } - this._checkForTTY(); + this.#checkForTTY(); - this._readlineInterface = readline.createInterface({ input: this.stdin }); + this.#readlineInterface = readline.createInterface({ input: this.stdin }); readline.emitKeypressEvents(process.stdin); this.stdin.setRawMode(true); - this.stdin.addListener('keypress', this._onKeypress); + this.stdin.addListener('keypress', this.#onKeypress); } - private _checkForTTY(): void { + #checkForTTY(): void { // Typescript thinks setRawMode always extists, but we're testing that assumption here. if (this.stdin.isTTY && (this.stdin as Partial).setRawMode) { return; @@ -83,63 +83,63 @@ export class KeyboardLoop { throw new AlreadyReportedError(); } - private _uncaptureInput(): void { - if (!this._readlineInterface) { + #uncaptureInput(): void { + if (!this.#readlineInterface) { return; } - this.stdin.removeListener('keypress', this._onKeypress); + this.stdin.removeListener('keypress', this.#onKeypress); this.stdin.setRawMode(false); - this._readlineInterface.close(); - this._readlineInterface = undefined; + this.#readlineInterface.close(); + this.#readlineInterface = undefined; } protected hideCursor(): void { - if (this._cursorHidden) { + if (this.#cursorHidden) { return; } - this._cursorHidden = true; + this.#cursorHidden = true; this.stderr.write(ANSI_ESCAPE_SHOW_CURSOR); } protected unhideCursor(): void { - if (!this._cursorHidden) { + if (!this.#cursorHidden) { return; } - this._cursorHidden = false; + this.#cursorHidden = false; this.stderr.write(ANSI_ESCAPE_HIDE_CURSOR); } public async startAsync(): Promise { try { - this._captureInput(); + this.#captureInput(); this.onStart(); await new Promise((resolve: () => void, reject: (error: Error) => void) => { - this._resolvePromise = resolve; - this._rejectPromise = reject; + this.#resolvePromise = resolve; + this.#rejectPromise = reject; }); } finally { - this._uncaptureInput(); + this.#uncaptureInput(); this.unhideCursor(); } } protected resolveAsync(): void { - if (!this._resolvePromise) { + if (!this.#resolvePromise) { return; } - this._resolvePromise(); - this._resolvePromise = undefined; - this._rejectPromise = undefined; + this.#resolvePromise(); + this.#resolvePromise = undefined; + this.#rejectPromise = undefined; } protected rejectAsync(error: Error): void { - if (!this._rejectPromise) { + if (!this.#rejectPromise) { return; } - this._rejectPromise(error); - this._resolvePromise = undefined; - this._rejectPromise = undefined; + this.#rejectPromise(error); + this.#resolvePromise = undefined; + this.#rejectPromise = undefined; } /** @virtual */ @@ -148,7 +148,7 @@ export class KeyboardLoop { /** @virtual */ protected onKeypress(character: string, key: readline.Key): void {} - private _onKeypress = (character: string, key: readline.Key): void => { + #onKeypress = (character: string, key: readline.Key): void => { if (key.name === 'c' && key.ctrl && !key.meta && !key.shift) { // Intercept CTRL+C process.kill(process.pid, 'SIGINT'); diff --git a/libraries/rush-lib/src/logic/setup/SetupPackageRegistry.ts b/libraries/rush-lib/src/logic/setup/SetupPackageRegistry.ts index 6ffa3504e6a..0ee3232f0c9 100644 --- a/libraries/rush-lib/src/logic/setup/SetupPackageRegistry.ts +++ b/libraries/rush-lib/src/logic/setup/SetupPackageRegistry.ts @@ -56,39 +56,39 @@ export interface ISetupPackageRegistryOptions { } export class SetupPackageRegistry { - private readonly _options: ISetupPackageRegistryOptions; + readonly #options: ISetupPackageRegistryOptions; public readonly rushConfiguration: RushConfiguration; - private readonly _terminal: Terminal; - private readonly _artifactoryConfiguration: ArtifactoryConfiguration; - private readonly _messages: IArtifactoryCustomizableMessages; + readonly #terminal: Terminal; + readonly #artifactoryConfiguration: ArtifactoryConfiguration; + readonly #messages: IArtifactoryCustomizableMessages; public constructor(options: ISetupPackageRegistryOptions) { - this._options = options; + this.#options = options; this.rushConfiguration = options.rushConfiguration; - this._terminal = new Terminal( + this.#terminal = new Terminal( new ConsoleTerminalProvider({ verboseEnabled: options.isDebug }) ); - this._artifactoryConfiguration = new ArtifactoryConfiguration( + this.#artifactoryConfiguration = new ArtifactoryConfiguration( path.join(this.rushConfiguration.commonRushConfigFolder, 'artifactory.json') ); - this._messages = { + this.#messages = { ...defaultMessages, - ...this._artifactoryConfiguration.configuration.packageRegistry.messageOverrides + ...this.#artifactoryConfiguration.configuration.packageRegistry.messageOverrides }; } - private _writeInstructionBlock(message: string): void { + #writeInstructionBlock(message: string): void { if (message === '') { return; } - this._terminal.writeLine(PrintUtilities.wrapWords(message)); - this._terminal.writeLine(); + this.#terminal.writeLine(PrintUtilities.wrapWords(message)); + this.#terminal.writeLine(); } /** @@ -98,9 +98,9 @@ export class SetupPackageRegistry { */ public async checkOnlyAsync(): Promise { const packageRegistry: IArtifactoryPackageRegistryJson = - this._artifactoryConfiguration.configuration.packageRegistry; + this.#artifactoryConfiguration.configuration.packageRegistry; if (!packageRegistry.enabled) { - this._terminal.writeVerbose('Skipping package registry setup because packageRegistry.enabled=false'); + this.#terminal.writeVerbose('Skipping package registry setup because packageRegistry.enabled=false'); return true; } @@ -109,7 +109,7 @@ export class SetupPackageRegistry { throw new Error('The "registryUrl" setting in artifactory.json is missing or empty'); } - if (!this._options.syncNpmrcAlreadyCalled) { + if (!this.#options.syncNpmrcAlreadyCalled) { Utilities.syncNpmrc({ sourceNpmrcFolder: this.rushConfiguration.commonRushConfigFolder, targetNpmrcFolder: this.rushConfiguration.commonTempFolder, @@ -128,7 +128,7 @@ export class SetupPackageRegistry { '--registry=' + packageRegistry.registryUrl ]; - this._terminal.writeLine('Testing access to private NPM registry: ' + packageRegistry.registryUrl); + this.#terminal.writeLine('Testing access to private NPM registry: ' + packageRegistry.registryUrl); const result: child_process.SpawnSyncReturns = Executable.spawnSync('npm', npmArgs, { currentWorkingDirectory: this.rushConfiguration.commonTempFolder, @@ -136,7 +136,7 @@ export class SetupPackageRegistry { // Wait at most 10 seconds for "npm view" to succeed timeoutMs: 10 * 1000 }); - this._terminal.writeLine(); + this.#terminal.writeLine(); // (This is not exactly correct, for example Node.js puts a string in error.errno instead of a string.) const error: (Error & Partial) | undefined = result.error; @@ -168,30 +168,30 @@ export class SetupPackageRegistry { try { jsonOutput = JSON.parse(jsonContent); } catch (e) { - this._terminal.writeVerboseLine('NPM response:\n\n--------\n' + jsonContent + '\n--------\n\n'); + this.#terminal.writeVerboseLine('NPM response:\n\n--------\n' + jsonContent + '\n--------\n\n'); throw new InternalError('The "npm view" command returned an invalid JSON structure'); } const errorCode: JsonObject = jsonOutput?.error?.code; if (typeof errorCode !== 'string') { - this._terminal.writeVerboseLine('NPM response:\n' + JSON.stringify(jsonOutput, undefined, 2) + '\n\n'); + this.#terminal.writeVerboseLine('NPM response:\n' + JSON.stringify(jsonOutput, undefined, 2) + '\n\n'); throw new InternalError('The "npm view" command returned unexpected output'); } switch (errorCode) { case 'E404': - this._terminal.writeLine('NPM credentials are working'); - this._terminal.writeLine(); + this.#terminal.writeLine('NPM credentials are working'); + this.#terminal.writeLine(); return true; case 'E401': case 'E403': - this._terminal.writeVerboseLine( + this.#terminal.writeVerboseLine( 'NPM response:\n' + JSON.stringify(jsonOutput, undefined, 2) + '\n\n' ); // Credentials are missing or expired return false; default: - this._terminal.writeVerboseLine( + this.#terminal.writeVerboseLine( 'NPM response:\n' + JSON.stringify(jsonOutput, undefined, 2) + '\n\n' ); throw new Error(`The "npm view" command returned an unexpected error code "${errorCode}"`); @@ -206,86 +206,86 @@ export class SetupPackageRegistry { return; } - this._terminal.writeWarningLine('NPM credentials are missing or expired'); - this._terminal.writeLine(); + this.#terminal.writeWarningLine('NPM credentials are missing or expired'); + this.#terminal.writeLine(); const packageRegistry: IArtifactoryPackageRegistryJson = - this._artifactoryConfiguration.configuration.packageRegistry; + this.#artifactoryConfiguration.configuration.packageRegistry; const fixThisProblem: boolean = await TerminalInput.promptYesNoAsync({ message: 'Fix this problem now?', defaultValue: false }); - this._terminal.writeLine(); + this.#terminal.writeLine(); if (!fixThisProblem) { return; } - this._writeInstructionBlock(this._messages.introduction); + this.#writeInstructionBlock(this.#messages.introduction); const hasArtifactoryAccount: boolean = await TerminalInput.promptYesNoAsync({ message: 'Do you already have an Artifactory user account?' }); - this._terminal.writeLine(); + this.#terminal.writeLine(); if (!hasArtifactoryAccount) { - this._writeInstructionBlock(this._messages.obtainAnAccount); + this.#writeInstructionBlock(this.#messages.obtainAnAccount); throw new AlreadyReportedError(); } - if (this._messages.visitWebsite) { - this._writeInstructionBlock(this._messages.visitWebsite); + if (this.#messages.visitWebsite) { + this.#writeInstructionBlock(this.#messages.visitWebsite); const artifactoryWebsiteUrl: string = - this._artifactoryConfiguration.configuration.packageRegistry.artifactoryWebsiteUrl; + this.#artifactoryConfiguration.configuration.packageRegistry.artifactoryWebsiteUrl; if (artifactoryWebsiteUrl) { - this._terminal.writeLine(' ', Colorize.cyan(artifactoryWebsiteUrl)); - this._terminal.writeLine(); + this.#terminal.writeLine(' ', Colorize.cyan(artifactoryWebsiteUrl)); + this.#terminal.writeLine(); } } - this._writeInstructionBlock(this._messages.locateUserName); + this.#writeInstructionBlock(this.#messages.locateUserName); let artifactoryUser: string = await TerminalInput.promptLineAsync({ - message: this._messages.userNamePrompt + message: this.#messages.userNamePrompt }); - this._terminal.writeLine(); + this.#terminal.writeLine(); artifactoryUser = artifactoryUser.trim(); if (artifactoryUser.length === 0) { - this._terminal.writeLine(Colorize.red('Operation aborted because the input was empty')); - this._terminal.writeLine(); + this.#terminal.writeLine(Colorize.red('Operation aborted because the input was empty')); + this.#terminal.writeLine(); throw new AlreadyReportedError(); } - this._writeInstructionBlock(this._messages.locateApiKey); + this.#writeInstructionBlock(this.#messages.locateApiKey); let artifactoryKey: string = await TerminalInput.promptPasswordLineAsync({ - message: this._messages.apiKeyPrompt + message: this.#messages.apiKeyPrompt }); - this._terminal.writeLine(); + this.#terminal.writeLine(); artifactoryKey = artifactoryKey.trim(); if (artifactoryKey.length === 0) { - this._terminal.writeLine(Colorize.red('Operation aborted because the input was empty')); - this._terminal.writeLine(); + this.#terminal.writeLine(Colorize.red('Operation aborted because the input was empty')); + this.#terminal.writeLine(); throw new AlreadyReportedError(); } - await this._fetchTokenAndUpdateNpmrcAsync(artifactoryUser, artifactoryKey, packageRegistry); + await this.#fetchTokenAndUpdateNpmrcAsync(artifactoryUser, artifactoryKey, packageRegistry); } /** * Fetch a valid NPM token from the Artifactory service and add it to the `~/.npmrc` file, * preserving other settings in that file. */ - private async _fetchTokenAndUpdateNpmrcAsync( + async #fetchTokenAndUpdateNpmrcAsync( artifactoryUser: string, artifactoryKey: string, packageRegistry: IArtifactoryPackageRegistryJson ): Promise { - this._terminal.writeLine('\nFetching an NPM token from the Artifactory service...'); + this.#terminal.writeLine('\nFetching an NPM token from the Artifactory service...'); // Defer this import since it is conditionally needed. const { WebClient } = await import('../../utilities/WebClient'); @@ -356,7 +356,7 @@ export class SetupPackageRegistry { const npmrcPath: string = path.join(User.getHomeFolder(), '.npmrc'); - this._mergeLinesIntoNpmrc(npmrcPath, linesToAdd); + this.#mergeLinesIntoNpmrc(npmrcPath, linesToAdd); } /** @@ -373,7 +373,7 @@ export class SetupPackageRegistry { * - Under no circumstances is a duplicate key/value added to the file; in the case of * duplicates, the earliest line in `linesToAdd` takes precedence */ - private _mergeLinesIntoNpmrc(npmrcPath: string, linesToAdd: readonly string[]): void { + #mergeLinesIntoNpmrc(npmrcPath: string, linesToAdd: readonly string[]): void { // We'll replace entries with "undefined" if they get discarded const workingLinesToAdd: (string | undefined)[] = [...linesToAdd]; @@ -398,8 +398,8 @@ export class SetupPackageRegistry { } } - this._terminal.writeLine(); - this._terminal.writeLine(Colorize.green('Adding Artifactory token to: '), npmrcPath); + this.#terminal.writeLine(); + this.#terminal.writeLine(Colorize.green('Adding Artifactory token to: '), npmrcPath); const npmrcLines: string[] = []; diff --git a/libraries/rush-lib/src/logic/setup/TerminalInput.ts b/libraries/rush-lib/src/logic/setup/TerminalInput.ts index a73b4eda1f6..627dd7b9af9 100644 --- a/libraries/rush-lib/src/logic/setup/TerminalInput.ts +++ b/libraries/rush-lib/src/logic/setup/TerminalInput.ts @@ -82,23 +82,23 @@ class YesNoKeyboardLoop extends KeyboardLoop { } class PasswordKeyboardLoop extends KeyboardLoop { - private readonly _options: IPromptPasswordOptions; - private _passwordCharacter: string; - private _startX: number = 0; - private _printedY: number = 0; - private _lastPrintedLength: number = 0; + readonly #options: IPromptPasswordOptions; + #passwordCharacter: string; + #startX: number = 0; + #printedY: number = 0; + #lastPrintedLength: number = 0; public result: string = ''; public constructor(options: IPromptPasswordOptions) { super(); - this._options = options; + this.#options = options; - this._passwordCharacter = - this._options.passwordCharacter === undefined ? '*' : this._options.passwordCharacter.substr(0, 1); + this.#passwordCharacter = + this.#options.passwordCharacter === undefined ? '*' : this.#options.passwordCharacter.substr(0, 1); } - private _getLineWrapWidth(): number { + #getLineWrapWidth(): number { return this.stderr.columns ? this.stderr.columns : 80; } @@ -107,7 +107,7 @@ class PasswordKeyboardLoop extends KeyboardLoop { readline.cursorTo(this.stderr, 0); readline.clearLine(this.stderr, 1); - const prefix: string = Colorize.green('==>') + ' ' + Colorize.bold(this._options.message) + ' '; + const prefix: string = Colorize.green('==>') + ' ' + Colorize.bold(this.#options.message) + ' '; this.stderr.write(prefix); let lineStartIndex: number = prefix.lastIndexOf('\n'); @@ -115,24 +115,24 @@ class PasswordKeyboardLoop extends KeyboardLoop { lineStartIndex = 0; } const line: string = prefix.substring(lineStartIndex); - this._startX = AnsiEscape.removeCodes(line).length % this._getLineWrapWidth(); + this.#startX = AnsiEscape.removeCodes(line).length % this.#getLineWrapWidth(); } protected override onKeypress(character: string, key: readline.Key): void { switch (key.name) { case 'enter': case 'return': - if (this._passwordCharacter !== '') { + if (this.#passwordCharacter !== '') { // To avoid disclosing the length of the password, after the user presses ENTER, // replace the "*********" sequence with exactly three stars ("***"). - this._render(this._passwordCharacter.repeat(3)); + this.#render(this.#passwordCharacter.repeat(3)); } this.stderr.write('\n'); this.resolveAsync(); return; case 'backspace': this.result = this.result.substring(0, this.result.length - 1); - this._render(this.result); + this.#render(this.result); break; default: let printable: boolean = true; @@ -146,50 +146,50 @@ class PasswordKeyboardLoop extends KeyboardLoop { if (printable) { this.result += character; - this._render(this.result); + this.#render(this.result); } } } - private _render(text: string): void { + #render(text: string): void { // Optimize rendering when we don't need to erase anything - const needsClear: boolean = text.length < this._lastPrintedLength; - this._lastPrintedLength = text.length; + const needsClear: boolean = text.length < this.#lastPrintedLength; + this.#lastPrintedLength = text.length; this.hideCursor(); // Restore Y - while (this._printedY > 0) { + while (this.#printedY > 0) { readline.cursorTo(this.stderr, 0); if (needsClear) { readline.clearLine(this.stderr, 1); } readline.moveCursor(this.stderr, 0, -1); - --this._printedY; + --this.#printedY; } // Restore X - readline.cursorTo(this.stderr, this._startX); + readline.cursorTo(this.stderr, this.#startX); let i: number = 0; - let column: number = this._startX; - this._printedY = 0; + let column: number = this.#startX; + this.#printedY = 0; let buffer: string = ''; while (i < text.length) { - if (this._passwordCharacter === '') { + if (this.#passwordCharacter === '') { buffer += text.substr(i, 1); } else { - buffer += this._passwordCharacter; + buffer += this.#passwordCharacter; } ++i; ++column; // -1 to avoid weird TTY behavior in final column - if (column >= this._getLineWrapWidth() - 1) { + if (column >= this.#getLineWrapWidth() - 1) { column = 0; - ++this._printedY; + ++this.#printedY; buffer += '\n'; } } diff --git a/libraries/rush-lib/src/logic/test/Telemetry.test.ts b/libraries/rush-lib/src/logic/test/Telemetry.test.ts index aebc60ef4a9..a1e4511b0e2 100644 --- a/libraries/rush-lib/src/logic/test/Telemetry.test.ts +++ b/libraries/rush-lib/src/logic/test/Telemetry.test.ts @@ -10,7 +10,7 @@ import { Telemetry, type ITelemetryData, type ITelemetryMachineInfo } from '../T import { RushSession } from '../../pluginFramework/RushSession'; interface ITelemetryPrivateMembers extends Omit { - _flushAsyncTasks: Map>; + _flushAsyncTasks: Set>; } describe(Telemetry.name, () => { diff --git a/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinder.ts b/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinder.ts index f456dd81d99..719924aae70 100644 --- a/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinder.ts +++ b/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinder.ts @@ -52,18 +52,18 @@ export class VersionMismatchFinder { * } * } */ - private _allowedAlternativeVersion: Map>; - private _mismatches: Map>; - private _projects: VersionMismatchFinderEntity[]; + #allowedAlternativeVersion: Map>; + #mismatches: Map>; + #projects: VersionMismatchFinderEntity[]; public constructor( projects: VersionMismatchFinderEntity[], allowedAlternativeVersions?: Map> ) { - this._projects = projects; - this._mismatches = new Map>(); - this._allowedAlternativeVersion = allowedAlternativeVersions || new Map>(); - this._analyze(); + this.#projects = projects; + this.#mismatches = new Map>(); + this.#allowedAlternativeVersion = allowedAlternativeVersions || new Map>(); + this.#analyze(); } public static rushCheck( @@ -130,19 +130,19 @@ export class VersionMismatchFinder { } public get mismatches(): ReadonlyMap> { - return this._mismatches; + return this.#mismatches; } public get numberOfMismatches(): number { - return this._mismatches.size; + return this.#mismatches.size; } public getMismatches(): string[] { - return this._getKeys(this._mismatches); + return this.#getKeys(this.#mismatches); } public getVersionsOfMismatch(mismatch: string): string[] | undefined { - return this._mismatches.has(mismatch) ? this._getKeys(this._mismatches.get(mismatch)) : undefined; + return this.#mismatches.has(mismatch) ? this.#getKeys(this.#mismatches.get(mismatch)) : undefined; } public getConsumersOfMismatch( @@ -150,7 +150,7 @@ export class VersionMismatchFinder { version: string ): VersionMismatchFinderEntity[] | undefined { const mismatchedPackage: Map | undefined = - this._mismatches.get(mismatch); + this.#mismatches.get(mismatch); if (!mismatchedPackage) { return undefined; } @@ -228,8 +228,8 @@ export class VersionMismatchFinder { }); } - private _analyze(): void { - this._projects.forEach((project: VersionMismatchFinderEntity) => { + #analyze(): void { + this.#projects.forEach((project: VersionMismatchFinderEntity) => { if (!project.skipRushCheck) { // NOTE: We do not consider peer dependencies here. The purpose of "rush check" is // mainly to avoid side-by-side duplicates in the node_modules folder, whereas @@ -244,16 +244,16 @@ export class VersionMismatchFinder { const isCyclic: boolean = project.decoupledLocalDependencies.has(dependency.name); - if (this._isVersionAllowedAlternative(dependency.name, version)) { + if (this.#isVersionAllowedAlternative(dependency.name, version)) { return; } const name: string = dependency.name + (isCyclic ? ' (cyclic)' : ''); let dependencyVersions: Map | undefined = - this._mismatches.get(name); + this.#mismatches.get(name); if (!dependencyVersions) { - this._mismatches.set( + this.#mismatches.set( name, (dependencyVersions = new Map()) ); @@ -270,21 +270,21 @@ export class VersionMismatchFinder { } }); - this._mismatches.forEach((mismatches: Map, project: string) => { + this.#mismatches.forEach((mismatches: Map, project: string) => { if (mismatches.size <= 1) { - this._mismatches.delete(project); + this.#mismatches.delete(project); } }); } - private _isVersionAllowedAlternative(dependency: string, version: string): boolean { + #isVersionAllowedAlternative(dependency: string, version: string): boolean { const allowedAlternatives: ReadonlyArray | undefined = - this._allowedAlternativeVersion.get(dependency); + this.#allowedAlternativeVersion.get(dependency); return Boolean(allowedAlternatives && allowedAlternatives.indexOf(version) > -1); } // eslint-disable-next-line @typescript-eslint/no-explicit-any - private _getKeys(iterable: Map | undefined): string[] { + #getKeys(iterable: Map | undefined): string[] { const keys: string[] = []; if (iterable) { // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinderCommonVersions.ts b/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinderCommonVersions.ts index 1e2c11b17bf..a571a140bc3 100644 --- a/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinderCommonVersions.ts +++ b/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinderCommonVersions.ts @@ -7,7 +7,7 @@ import type { CommonVersionsConfiguration } from '../../api/CommonVersionsConfig import { VersionMismatchFinderEntity } from './VersionMismatchFinderEntity'; export class VersionMismatchFinderCommonVersions extends VersionMismatchFinderEntity { - private _fileManager: CommonVersionsConfiguration; + #fileManager: CommonVersionsConfiguration; public constructor(commonVersionsConfiguration: CommonVersionsConfiguration) { super({ @@ -15,29 +15,29 @@ export class VersionMismatchFinderCommonVersions extends VersionMismatchFinderEn decoupledLocalDependencies: new Set() }); - this._fileManager = commonVersionsConfiguration; + this.#fileManager = commonVersionsConfiguration; } public get filePath(): string { - return this._fileManager.filePath; + return this.#fileManager.filePath; } public get allDependencies(): ReadonlyArray { const dependencies: PackageJsonDependency[] = []; - this._fileManager.getAllPreferredVersions().forEach((version, dependencyName) => { - dependencies.push(this._getPackageJsonDependency(dependencyName, version)); + this.#fileManager.getAllPreferredVersions().forEach((version, dependencyName) => { + dependencies.push(this.#getPackageJsonDependency(dependencyName, version)); }); return dependencies; } public tryGetDependency(packageName: string): PackageJsonDependency | undefined { - const version: string | undefined = this._fileManager.getAllPreferredVersions().get(packageName); + const version: string | undefined = this.#fileManager.getAllPreferredVersions().get(packageName); if (!version) { return undefined; } else { - return this._getPackageJsonDependency(packageName, version); + return this.#getPackageJsonDependency(packageName, version); } } @@ -56,7 +56,7 @@ export class VersionMismatchFinderCommonVersions extends VersionMismatchFinderEn ); } - this._fileManager.preferredVersions.set(packageName, newVersion); + this.#fileManager.preferredVersions.set(packageName, newVersion); } public removeDependency(packageName: string): void { @@ -64,10 +64,10 @@ export class VersionMismatchFinderCommonVersions extends VersionMismatchFinderEn } public async saveIfModifiedAsync(): Promise { - return await this._fileManager.saveAsync(); + return await this.#fileManager.saveAsync(); } - private _getPackageJsonDependency(dependencyName: string, version: string): PackageJsonDependency { + #getPackageJsonDependency(dependencyName: string, version: string): PackageJsonDependency { return new PackageJsonDependency(dependencyName, version, DependencyType.Regular, () => this.addOrUpdateDependency(dependencyName, version, DependencyType.Regular) ); diff --git a/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinderProject.ts b/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinderProject.ts index cc63370b687..78effefc747 100644 --- a/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinderProject.ts +++ b/libraries/rush-lib/src/logic/versionMismatch/VersionMismatchFinderProject.ts @@ -7,7 +7,7 @@ import type { RushConfigurationProject } from '../../api/RushConfigurationProjec export class VersionMismatchFinderProject extends VersionMismatchFinderEntity { public packageName: string; - private _fileManager: PackageJsonEditor; + #fileManager: PackageJsonEditor; public constructor(project: RushConfigurationProject) { super({ @@ -16,24 +16,24 @@ export class VersionMismatchFinderProject extends VersionMismatchFinderEntity { skipRushCheck: project.skipRushCheck }); - this._fileManager = project.packageJsonEditor; + this.#fileManager = project.packageJsonEditor; this.packageName = project.packageName; } public get filePath(): string { - return this._fileManager.filePath; + return this.#fileManager.filePath; } public get allDependencies(): ReadonlyArray { - return [...this._fileManager.dependencyList, ...this._fileManager.devDependencyList]; + return [...this.#fileManager.dependencyList, ...this.#fileManager.devDependencyList]; } public tryGetDependency(packageName: string): PackageJsonDependency | undefined { - return this._fileManager.tryGetDependency(packageName); + return this.#fileManager.tryGetDependency(packageName); } public tryGetDevDependency(packageName: string): PackageJsonDependency | undefined { - return this._fileManager.tryGetDevDependency(packageName); + return this.#fileManager.tryGetDevDependency(packageName); } public addOrUpdateDependency( @@ -41,14 +41,14 @@ export class VersionMismatchFinderProject extends VersionMismatchFinderEntity { newVersion: string, dependencyType: DependencyType ): void { - return this._fileManager.addOrUpdateDependency(packageName, newVersion, dependencyType); + return this.#fileManager.addOrUpdateDependency(packageName, newVersion, dependencyType); } public removeDependency(packageName: string, dependencyType: DependencyType): void { - return this._fileManager.removeDependency(packageName, dependencyType); + return this.#fileManager.removeDependency(packageName, dependencyType); } public async saveIfModifiedAsync(): Promise { - return await this._fileManager.saveIfModifiedAsync(); + return await this.#fileManager.saveIfModifiedAsync(); } } diff --git a/libraries/rush-lib/src/logic/yarn/YarnShrinkwrapFile.ts b/libraries/rush-lib/src/logic/yarn/YarnShrinkwrapFile.ts index 920c72df3d4..5534ee6c1b4 100644 --- a/libraries/rush-lib/src/logic/yarn/YarnShrinkwrapFile.ts +++ b/libraries/rush-lib/src/logic/yarn/YarnShrinkwrapFile.ts @@ -107,17 +107,17 @@ const _packageNameAndSemVerRegExp: RegExp = /^(@?[^@\s]+)(?:@(.*))?$/; export class YarnShrinkwrapFile extends BaseShrinkwrapFile { public readonly isWorkspaceCompatible: boolean; - private _shrinkwrapJson: IYarnShrinkwrapJson; - private _tempProjectNames: string[]; + #shrinkwrapJson: IYarnShrinkwrapJson; + #tempProjectNames: string[]; private constructor(shrinkwrapJson: IYarnShrinkwrapJson) { super(); - this._shrinkwrapJson = shrinkwrapJson; - this._tempProjectNames = []; + this.#shrinkwrapJson = shrinkwrapJson; + this.#tempProjectNames = []; const seenEntries: Set = new Set(); - for (const key of Object.keys(this._shrinkwrapJson)) { + for (const key of Object.keys(this.#shrinkwrapJson)) { // Example key: const packageNameAndSemVer: IPackageNameAndSemVer = _decodePackageNameAndSemVer(key); @@ -143,9 +143,9 @@ export class YarnShrinkwrapFile extends BaseShrinkwrapFile { ); } - this._tempProjectNames.push(packageNameAndSemVer.packageName); + this.#tempProjectNames.push(packageNameAndSemVer.packageName); - const entry: IYarnShrinkwrapEntry = this._shrinkwrapJson[key]; + const entry: IYarnShrinkwrapEntry = this.#shrinkwrapJson[key]; // Yarn fails installation if the integrity hash does not match a "file://" reference to a tarball. // This is incorrect: Normally a mismatched integrity hash does indicate a corrupted download, @@ -165,7 +165,7 @@ export class YarnShrinkwrapFile extends BaseShrinkwrapFile { } } - this._tempProjectNames.sort(); // make the result deterministic + this.#tempProjectNames.sort(); // make the result deterministic // We don't support Yarn workspaces yet this.isWorkspaceCompatible = false; @@ -189,7 +189,7 @@ export class YarnShrinkwrapFile extends BaseShrinkwrapFile { } public override getTempProjectNames(): ReadonlyArray { - return this._tempProjectNames; + return this.#tempProjectNames; } public override hasCompatibleTopLevelDependency(dependencySpecifier: DependencySpecifier): boolean { @@ -201,7 +201,7 @@ export class YarnShrinkwrapFile extends BaseShrinkwrapFile { }); // Check whether this exact key appears in the shrinkwrap file - return Object.hasOwnProperty.call(this._shrinkwrapJson, key); + return Object.hasOwnProperty.call(this.#shrinkwrapJson, key); } public override tryEnsureCompatibleDependency( @@ -212,7 +212,7 @@ export class YarnShrinkwrapFile extends BaseShrinkwrapFile { } protected override serialize(): string { - return lockfileModule.stringify(this._shrinkwrapJson); + return lockfileModule.stringify(this.#shrinkwrapJson); } protected override getTopLevelDependencyVersion(dependencyName: string): DependencySpecifier | undefined { diff --git a/libraries/rush-lib/src/pluginFramework/PluginLoader/PluginLoaderBase.ts b/libraries/rush-lib/src/pluginFramework/PluginLoader/PluginLoaderBase.ts index 1c56731bdbe..a437a107e15 100644 --- a/libraries/rush-lib/src/pluginFramework/PluginLoader/PluginLoaderBase.ts +++ b/libraries/rush-lib/src/pluginFramework/PluginLoader/PluginLoaderBase.ts @@ -68,7 +68,7 @@ export abstract class PluginLoaderBase< } public load(): IRushPlugin | undefined { - const resolvedPluginPath: string | undefined = this._resolvePlugin(); + const resolvedPluginPath: string | undefined = this.#resolvePlugin(); if (!resolvedPluginPath) { return undefined; } @@ -76,11 +76,11 @@ export abstract class PluginLoaderBase< RushSdk.ensureInitialized(); - return this._loadAndValidatePluginPackage(resolvedPluginPath, pluginOptions); + return this.#loadAndValidatePluginPackage(resolvedPluginPath, pluginOptions); } public get pluginManifest(): IRushPluginManifest { - return this._getRushPluginManifest(); + return this.#getRushPluginManifest(); } public getCommandLineConfiguration(): CommandLineConfiguration | undefined { @@ -113,14 +113,14 @@ export abstract class PluginLoaderBase< } protected _getCommandLineJsonFilePath(): string | undefined { - const { commandLineJsonFilePath } = this._getRushPluginManifest(); + const { commandLineJsonFilePath } = this.#getRushPluginManifest(); if (!commandLineJsonFilePath) { return undefined; } return path.join(this.packageFolder, commandLineJsonFilePath); } - private _loadAndValidatePluginPackage(resolvedPluginPath: string, options?: JsonObject): IRushPlugin { + #loadAndValidatePluginPackage(resolvedPluginPath: string, options?: JsonObject): IRushPlugin { type IRushPluginCtor = new (opts: T) => IRushPlugin; let pluginPackage: IRushPluginCtor; try { @@ -148,8 +148,8 @@ export abstract class PluginLoaderBase< return plugin; } - private _resolvePlugin(): string | undefined { - const entryPoint: string | undefined = this._getRushPluginManifest().entryPoint; + #resolvePlugin(): string | undefined { + const entryPoint: string | undefined = this.#getRushPluginManifest().entryPoint; if (!entryPoint) { return undefined; } @@ -189,7 +189,7 @@ export abstract class PluginLoaderBase< } protected _getRushPluginOptionsSchema(): JsonSchema | undefined { - const optionsSchema: string | undefined = this._getRushPluginManifest().optionsSchema; + const optionsSchema: string | undefined = this.#getRushPluginManifest().optionsSchema; if (!optionsSchema) { return undefined; } @@ -197,7 +197,7 @@ export abstract class PluginLoaderBase< return JsonSchema.fromFile(optionsSchemaFilePath); } - private _getRushPluginManifest(): IRushPluginManifest { + #getRushPluginManifest(): IRushPluginManifest { if (!this._manifestCache) { const packageName: string = this.packageName; const pluginName: string = this.pluginName; diff --git a/libraries/rush-lib/src/pluginFramework/PluginManager.ts b/libraries/rush-lib/src/pluginFramework/PluginManager.ts index 9a5181e078c..926aac1a5e8 100644 --- a/libraries/rush-lib/src/pluginFramework/PluginManager.ts +++ b/libraries/rush-lib/src/pluginFramework/PluginManager.ts @@ -29,26 +29,26 @@ export interface ICustomCommandLineConfigurationInfo { } export class PluginManager { - private readonly _terminal: ITerminal; - private readonly _rushConfiguration: RushConfiguration; - private readonly _rushSession: RushSession; - private readonly _restrictConsoleOutput: boolean; - private readonly _builtInPluginLoaders: BuiltInPluginLoader[]; - private readonly _autoinstallerPluginLoaders: AutoinstallerPluginLoader[]; - private readonly _installedAutoinstallerNames: Set; - private readonly _loadedPluginNames: Set = new Set(); - private readonly _rushGlobalFolder: RushGlobalFolder; - - private _error: Error | undefined; + readonly #terminal: ITerminal; + readonly #rushConfiguration: RushConfiguration; + readonly #rushSession: RushSession; + readonly #restrictConsoleOutput: boolean; + readonly #builtInPluginLoaders: BuiltInPluginLoader[]; + readonly #autoinstallerPluginLoaders: AutoinstallerPluginLoader[]; + readonly #installedAutoinstallerNames: Set; + readonly #loadedPluginNames: Set = new Set(); + readonly #rushGlobalFolder: RushGlobalFolder; + + #error: Error | undefined; public constructor(options: IPluginManagerOptions) { - this._terminal = options.terminal; - this._rushConfiguration = options.rushConfiguration; - this._rushSession = options.rushSession; - this._restrictConsoleOutput = options.restrictConsoleOutput; - this._rushGlobalFolder = options.rushGlobalFolder; + this.#terminal = options.terminal; + this.#rushConfiguration = options.rushConfiguration; + this.#rushSession = options.rushSession; + this.#restrictConsoleOutput = options.restrictConsoleOutput; + this.#rushGlobalFolder = options.rushGlobalFolder; - this._installedAutoinstallerNames = new Set(); + this.#installedAutoinstallerNames = new Set(); // Eventually we will require end users to explicitly configure all Rush plugins in use, regardless of // whether they are first party or third party plugins. However, we're postponing that requirement @@ -89,23 +89,23 @@ export class PluginManager { '@rushstack/rush-azure-storage-build-cache-plugin' ); - this._builtInPluginLoaders = builtInPluginConfigurations.map((pluginConfiguration) => { + this.#builtInPluginLoaders = builtInPluginConfigurations.map((pluginConfiguration) => { return new BuiltInPluginLoader({ pluginConfiguration, - rushConfiguration: this._rushConfiguration, - terminal: this._terminal + rushConfiguration: this.#rushConfiguration, + terminal: this.#terminal }); }); - this._autoinstallerPluginLoaders = ( - this._rushConfiguration?._rushPluginsConfiguration.configuration.plugins ?? [] + this.#autoinstallerPluginLoaders = ( + this.#rushConfiguration?._rushPluginsConfiguration.configuration.plugins ?? [] ).map((pluginConfiguration) => { return new AutoinstallerPluginLoader({ pluginConfiguration, - rushConfiguration: this._rushConfiguration, - terminal: this._terminal, - restrictConsoleOutput: this._restrictConsoleOutput, - rushGlobalFolder: this._rushGlobalFolder + rushConfiguration: this.#rushConfiguration, + terminal: this.#terminal, + restrictConsoleOutput: this.#restrictConsoleOutput, + rushGlobalFolder: this.#rushGlobalFolder }); }); } @@ -116,74 +116,74 @@ export class PluginManager { * (unless we are invoking a command that is used to fix plugin problems). */ public get error(): Error | undefined { - return this._error; + return this.#error; } public async updateAsync(): Promise { - await this._preparePluginAutoinstallersAsync(this._autoinstallerPluginLoaders); + await this._preparePluginAutoinstallersAsync(this.#autoinstallerPluginLoaders); const preparedAutoinstallerNames: Set = new Set(); - for (const { autoinstaller } of this._autoinstallerPluginLoaders) { + for (const { autoinstaller } of this.#autoinstallerPluginLoaders) { const storePath: string = AutoinstallerPluginLoader.getPluginAutoinstallerStorePath(autoinstaller); if (!preparedAutoinstallerNames.has(autoinstaller.name)) { FileSystem.ensureEmptyFolder(storePath); preparedAutoinstallerNames.add(autoinstaller.name); } } - for (const pluginLoader of this._autoinstallerPluginLoaders) { + for (const pluginLoader of this.#autoinstallerPluginLoaders) { pluginLoader.update(); } } public async reinitializeAllPluginsForCommandAsync(commandName: string): Promise { - this._error = undefined; + this.#error = undefined; await this.tryInitializeUnassociatedPluginsAsync(); await this.tryInitializeAssociatedCommandPluginsAsync(commandName); } public async _preparePluginAutoinstallersAsync(pluginLoaders: AutoinstallerPluginLoader[]): Promise { for (const { autoinstaller } of pluginLoaders) { - if (!this._installedAutoinstallerNames.has(autoinstaller.name)) { + if (!this.#installedAutoinstallerNames.has(autoinstaller.name)) { await autoinstaller.prepareAsync(); - this._installedAutoinstallerNames.add(autoinstaller.name); + this.#installedAutoinstallerNames.add(autoinstaller.name); } } } public async tryInitializeUnassociatedPluginsAsync(): Promise { try { - const autoinstallerPluginLoaders: AutoinstallerPluginLoader[] = this._getUnassociatedPluginLoaders( - this._autoinstallerPluginLoaders + const autoinstallerPluginLoaders: AutoinstallerPluginLoader[] = this.#getUnassociatedPluginLoaders( + this.#autoinstallerPluginLoaders ); await this._preparePluginAutoinstallersAsync(autoinstallerPluginLoaders); - const builtInPluginLoaders: BuiltInPluginLoader[] = this._getUnassociatedPluginLoaders( - this._builtInPluginLoaders + const builtInPluginLoaders: BuiltInPluginLoader[] = this.#getUnassociatedPluginLoaders( + this.#builtInPluginLoaders ); - this._initializePlugins([...builtInPluginLoaders, ...autoinstallerPluginLoaders]); + this.#initializePlugins([...builtInPluginLoaders, ...autoinstallerPluginLoaders]); } catch (e) { - this._error = e as Error; + this.#error = e as Error; } } public async tryInitializeAssociatedCommandPluginsAsync(commandName: string): Promise { try { - const autoinstallerPluginLoaders: AutoinstallerPluginLoader[] = this._getPluginLoadersForCommand( + const autoinstallerPluginLoaders: AutoinstallerPluginLoader[] = this.#getPluginLoadersForCommand( commandName, - this._autoinstallerPluginLoaders + this.#autoinstallerPluginLoaders ); await this._preparePluginAutoinstallersAsync(autoinstallerPluginLoaders); - const builtInPluginLoaders: BuiltInPluginLoader[] = this._getPluginLoadersForCommand( + const builtInPluginLoaders: BuiltInPluginLoader[] = this.#getPluginLoadersForCommand( commandName, - this._builtInPluginLoaders + this.#builtInPluginLoaders ); - this._initializePlugins([...builtInPluginLoaders, ...autoinstallerPluginLoaders]); + this.#initializePlugins([...builtInPluginLoaders, ...autoinstallerPluginLoaders]); } catch (e) { - this._error = e as Error; + this.#error = e as Error; } } public tryGetCustomCommandLineConfigurationInfos(): ICustomCommandLineConfigurationInfo[] { const commandLineConfigurationInfos: ICustomCommandLineConfigurationInfo[] = []; - for (const pluginLoader of this._autoinstallerPluginLoaders) { + for (const pluginLoader of this.#autoinstallerPluginLoaders) { const commandLineConfiguration: CommandLineConfiguration | undefined = pluginLoader.getCommandLineConfiguration(); if (commandLineConfiguration) { @@ -196,21 +196,21 @@ export class PluginManager { return commandLineConfigurationInfos; } - private _initializePlugins(pluginLoaders: PluginLoaderBase[]): void { + #initializePlugins(pluginLoaders: PluginLoaderBase[]): void { for (const pluginLoader of pluginLoaders) { const pluginName: string = pluginLoader.pluginName; - if (this._loadedPluginNames.has(pluginName)) { + if (this.#loadedPluginNames.has(pluginName)) { throw new Error(`Error applying plugin: A plugin with name "${pluginName}" has already been applied`); } const plugin: IRushPlugin | undefined = pluginLoader.load(); - this._loadedPluginNames.add(pluginName); + this.#loadedPluginNames.add(pluginName); if (plugin) { - this._applyPlugin(plugin, pluginName); + this.#applyPlugin(plugin, pluginName); } } } - private _getUnassociatedPluginLoaders( + #getUnassociatedPluginLoaders( pluginLoaders: T[] ): T[] { return pluginLoaders.filter((pluginLoader) => { @@ -218,7 +218,7 @@ export class PluginManager { }); } - private _getPluginLoadersForCommand( + #getPluginLoadersForCommand( commandName: string, pluginLoaders: T[] ): T[] { @@ -227,9 +227,9 @@ export class PluginManager { }); } - private _applyPlugin(plugin: IRushPlugin, pluginName: string): void { + #applyPlugin(plugin: IRushPlugin, pluginName: string): void { try { - plugin.apply(this._rushSession, this._rushConfiguration); + plugin.apply(this.#rushSession, this.#rushConfiguration); } catch (e) { throw new InternalError(`Error applying "${pluginName}": ${e}`); } diff --git a/libraries/rush-lib/src/pluginFramework/RushSession.ts b/libraries/rush-lib/src/pluginFramework/RushSession.ts index 0e512764438..2d0e5585b35 100644 --- a/libraries/rush-lib/src/pluginFramework/RushSession.ts +++ b/libraries/rush-lib/src/pluginFramework/RushSession.ts @@ -37,14 +37,14 @@ export type CobuildLockProviderFactory = ( * @beta */ export class RushSession { - private readonly _options: IRushSessionOptions; - private readonly _cloudBuildCacheProviderFactories: Map = new Map(); - private readonly _cobuildLockProviderFactories: Map = new Map(); + readonly #options: IRushSessionOptions; + readonly #cloudBuildCacheProviderFactories: Map = new Map(); + readonly #cobuildLockProviderFactories: Map = new Map(); public readonly hooks: RushLifecycleHooks; public constructor(options: IRushSessionOptions) { - this._options = options; + this.#options = options; this.hooks = new RushLifecycleHooks(); } @@ -54,51 +54,51 @@ export class RushSession { throw new InternalError('RushSession.getLogger(name) called without a name'); } - const terminalProvider: ITerminalProvider = this._options.terminalProvider; + const terminalProvider: ITerminalProvider = this.#options.terminalProvider; const loggerOptions: ILoggerOptions = { loggerName: name, - getShouldPrintStacks: () => this._options.getIsDebugMode(), + getShouldPrintStacks: () => this.#options.getIsDebugMode(), terminalProvider }; return new Logger(loggerOptions); } public get terminalProvider(): ITerminalProvider { - return this._options.terminalProvider; + return this.#options.terminalProvider; } public registerCloudBuildCacheProviderFactory( cacheProviderName: string, factory: CloudBuildCacheProviderFactory ): void { - if (this._cloudBuildCacheProviderFactories.has(cacheProviderName)) { + if (this.#cloudBuildCacheProviderFactories.has(cacheProviderName)) { throw new Error(`A build cache provider factory for ${cacheProviderName} has already been registered`); } - this._cloudBuildCacheProviderFactories.set(cacheProviderName, factory); + this.#cloudBuildCacheProviderFactories.set(cacheProviderName, factory); } public getCloudBuildCacheProviderFactory( cacheProviderName: string ): CloudBuildCacheProviderFactory | undefined { - return this._cloudBuildCacheProviderFactories.get(cacheProviderName); + return this.#cloudBuildCacheProviderFactories.get(cacheProviderName); } public registerCobuildLockProviderFactory( cobuildLockProviderName: string, factory: CobuildLockProviderFactory ): void { - if (this._cobuildLockProviderFactories.has(cobuildLockProviderName)) { + if (this.#cobuildLockProviderFactories.has(cobuildLockProviderName)) { throw new Error( `A cobuild lock provider factory for ${cobuildLockProviderName} has already been registered` ); } - this._cobuildLockProviderFactories.set(cobuildLockProviderName, factory); + this.#cobuildLockProviderFactories.set(cobuildLockProviderName, factory); } public getCobuildLockProviderFactory( cobuildLockProviderName: string ): CobuildLockProviderFactory | undefined { - return this._cobuildLockProviderFactories.get(cobuildLockProviderName); + return this.#cobuildLockProviderFactories.get(cobuildLockProviderName); } } diff --git a/libraries/rush-lib/src/pluginFramework/logging/Logger.ts b/libraries/rush-lib/src/pluginFramework/logging/Logger.ts index 46b01be524f..389453d6a42 100644 --- a/libraries/rush-lib/src/pluginFramework/logging/Logger.ts +++ b/libraries/rush-lib/src/pluginFramework/logging/Logger.ts @@ -27,14 +27,14 @@ export interface ILoggerOptions { } export class Logger implements ILogger { - private readonly _options: ILoggerOptions; - private readonly _errors: Error[] = []; - private readonly _warnings: Error[] = []; + readonly #options: ILoggerOptions; + readonly #errors: Error[] = []; + readonly #warnings: Error[] = []; public readonly terminal: Terminal; public constructor(options: ILoggerOptions) { - this._options = options; + this.#options = options; this.terminal = new Terminal(options.terminalProvider); } @@ -54,9 +54,9 @@ export class Logger implements ILogger { * {@inheritdoc ILogger.emitError} */ public emitError(error: Error): void { - this._errors.push(error); + this.#errors.push(error); this.terminal.writeErrorLine(`Error: ${Logger.getErrorMessage(error)}`); - if (this._shouldPrintStacks && error.stack) { + if (this.#shouldPrintStacks && error.stack) { this.terminal.writeErrorLine(error.stack); } } @@ -65,14 +65,14 @@ export class Logger implements ILogger { * {@inheritdoc ILogger.emitWarning} */ public emitWarning(warning: Error): void { - this._warnings.push(warning); + this.#warnings.push(warning); this.terminal.writeWarningLine(`Warning: ${Logger.getErrorMessage(warning)}`); - if (this._shouldPrintStacks && warning.stack) { + if (this.#shouldPrintStacks && warning.stack) { this.terminal.writeWarningLine(warning.stack); } } - private get _shouldPrintStacks(): boolean { - return this._options.getShouldPrintStacks(); + get #shouldPrintStacks(): boolean { + return this.#options.getShouldPrintStacks(); } } diff --git a/libraries/rush-lib/src/utilities/AsyncRecycler.ts b/libraries/rush-lib/src/utilities/AsyncRecycler.ts index eb63ca734b1..ccf89277358 100644 --- a/libraries/rush-lib/src/utilities/AsyncRecycler.ts +++ b/libraries/rush-lib/src/utilities/AsyncRecycler.ts @@ -16,9 +16,9 @@ import { IS_WINDOWS } from './executionUtilities'; * background process to recursively delete that folder. */ export class AsyncRecycler { - private _movedFolderCount: number; - private _deleting: boolean; - private _prefix: string; + #movedFolderCount: number; + #deleting: boolean; + #prefix: string; /** * The full path of the recycler folder. @@ -28,9 +28,9 @@ export class AsyncRecycler { public constructor(recyclerFolder: string) { this.recyclerFolder = path.resolve(recyclerFolder); - this._movedFolderCount = 0; - this._deleting = false; - this._prefix = `${Date.now()}`; + this.#movedFolderCount = 0; + this.#deleting = false; + this.#prefix = `${Date.now()}`; } /** @@ -39,7 +39,7 @@ export class AsyncRecycler { * deleteAll() must be called to actually delete the contents of the recycler folder. */ public moveFolder(folderPath: string): void { - if (this._deleting) { + if (this.#deleting) { throw new Error('AsyncRecycler.moveFolder() must not be called after deleteAll() has started'); } @@ -51,7 +51,7 @@ export class AsyncRecycler { return; } - ++this._movedFolderCount; + ++this.#movedFolderCount; // We need to do a simple "fs.renameSync" here, however if the folder we're trying to rename // has a lock, or if its destination container doesn't exist yet, @@ -63,7 +63,7 @@ export class AsyncRecycler { Utilities.createFolderWithRetry(this.recyclerFolder); Utilities.retryUntilTimeout( - () => this._renameOrRecurseInFolder(folderPath), + () => this.#renameOrRecurseInFolder(folderPath), maxWaitTimeMs, (e) => new Error(`Error: ${e}\nOften this is caused by a file lock from a process like the virus scanner.`), @@ -86,7 +86,7 @@ export class AsyncRecycler { if (!excludeSet.has(normalizedMemberName)) { const absolutePath: string = path.resolve(folderPath, dirent.name); if (dirent.isDirectory()) { - this._renameOrRecurseInFolder(absolutePath); + this.#renameOrRecurseInFolder(absolutePath); } else { FileSystem.deleteFile(absolutePath); } @@ -102,15 +102,15 @@ export class AsyncRecycler { * MUST NOT be called again after deleteAll() has started. */ public async startDeleteAllAsync(): Promise { - if (this._deleting) { + if (this.#deleting) { throw new Error( `${AsyncRecycler.name}.${this.startDeleteAllAsync.name}() must not be called more than once` ); } - this._deleting = true; + this.#deleting = true; - if (this._movedFolderCount === 0) { + if (this.#movedFolderCount === 0) { // Nothing to do return; } @@ -183,9 +183,9 @@ export class AsyncRecycler { process.unref(); } - private _renameOrRecurseInFolder(folderPath: string): void { - const ordinal: number = this._movedFolderCount++; - const targetDir: string = `${this.recyclerFolder}/${this._prefix}_${ordinal}`; + #renameOrRecurseInFolder(folderPath: string): void { + const ordinal: number = this.#movedFolderCount++; + const targetDir: string = `${this.recyclerFolder}/${this.#prefix}_${ordinal}`; try { fs.renameSync(folderPath, targetDir); return; @@ -203,7 +203,7 @@ export class AsyncRecycler { for (const child of children) { const absoluteChild: string = `${folderPath}/${child.name}`; if (child.isDirectory()) { - this._renameOrRecurseInFolder(absoluteChild); + this.#renameOrRecurseInFolder(absoluteChild); } else { FileSystem.deleteFile(absoluteChild); } diff --git a/libraries/rush-lib/src/utilities/CollatedTerminalProvider.ts b/libraries/rush-lib/src/utilities/CollatedTerminalProvider.ts index d83701011c3..b5c93d3f0ff 100644 --- a/libraries/rush-lib/src/utilities/CollatedTerminalProvider.ts +++ b/libraries/rush-lib/src/utilities/CollatedTerminalProvider.ts @@ -9,28 +9,28 @@ export interface ICollatedTerminalProviderOptions { } export class CollatedTerminalProvider implements ITerminalProvider { - private readonly _collatedTerminal: CollatedTerminal; - private _hasErrors: boolean = false; - private _hasWarnings: boolean = false; - private _debugEnabled: boolean = false; + readonly #collatedTerminal: CollatedTerminal; + #hasErrors: boolean = false; + #hasWarnings: boolean = false; + #debugEnabled: boolean = false; public readonly supportsColor: boolean = true; public readonly eolCharacter: string = '\n'; public get hasErrors(): boolean { - return this._hasErrors; + return this.#hasErrors; } public get hasWarnings(): boolean { - return this._hasWarnings; + return this.#hasWarnings; } public constructor( collatedTerminal: CollatedTerminal, options?: Partial ) { - this._collatedTerminal = collatedTerminal; - this._debugEnabled = !!options?.debugEnabled; + this.#collatedTerminal = collatedTerminal; + this.#debugEnabled = !!options?.debugEnabled; } public write(data: string, severity: TerminalProviderSeverity): void { @@ -40,28 +40,28 @@ export class CollatedTerminalProvider implements ITerminalProvider { // Unlike the basic ConsoleTerminalProvider, verbose messages are always passed // to stdout -- by convention the user-controlled build script output is sent // to verbose, and will be routed to a variety of other providers in the ProjectBuilder. - this._collatedTerminal.writeChunk({ text: data, kind: TerminalChunkKind.Stdout }); + this.#collatedTerminal.writeChunk({ text: data, kind: TerminalChunkKind.Stdout }); break; } case TerminalProviderSeverity.debug: { // Similar to the basic ConsoleTerminalProvider, debug messages are discarded // unless they are explicitly enabled. - if (this._debugEnabled) { - this._collatedTerminal.writeChunk({ text: data, kind: TerminalChunkKind.Stdout }); + if (this.#debugEnabled) { + this.#collatedTerminal.writeChunk({ text: data, kind: TerminalChunkKind.Stdout }); } break; } case TerminalProviderSeverity.error: { - this._collatedTerminal.writeChunk({ text: data, kind: TerminalChunkKind.Stderr }); - this._hasErrors = true; + this.#collatedTerminal.writeChunk({ text: data, kind: TerminalChunkKind.Stderr }); + this.#hasErrors = true; break; } case TerminalProviderSeverity.warning: { - this._collatedTerminal.writeChunk({ text: data, kind: TerminalChunkKind.Stderr }); - this._hasWarnings = true; + this.#collatedTerminal.writeChunk({ text: data, kind: TerminalChunkKind.Stderr }); + this.#hasWarnings = true; break; } diff --git a/libraries/rush-lib/src/utilities/HotlinkManager.ts b/libraries/rush-lib/src/utilities/HotlinkManager.ts index 24d0ad027c6..3257255996c 100644 --- a/libraries/rush-lib/src/utilities/HotlinkManager.ts +++ b/libraries/rush-lib/src/utilities/HotlinkManager.ts @@ -59,20 +59,20 @@ interface IRushLinkOptions { const PROJECT_LINKS_STATE_JSON_SCHEMA: JsonSchema = JsonSchema.fromLoadedObject(schema); export class HotlinkManager { - private _linksBySubspaceName: LinksBySubspaceNameMap; - private readonly _rushLinkStateFilePath: string; + #linksBySubspaceName: LinksBySubspaceNameMap; + readonly #rushLinkStateFilePath: string; private constructor(options: IRushLinkOptions) { const { rushLinkStateFilePath, linksBySubspaceName } = options; - this._rushLinkStateFilePath = rushLinkStateFilePath; - this._linksBySubspaceName = linksBySubspaceName; + this.#rushLinkStateFilePath = rushLinkStateFilePath; + this.#linksBySubspaceName = linksBySubspaceName; } public hasAnyHotlinksInSubspace(subspaceName: string): boolean { - return !!this._linksBySubspaceName.get(subspaceName)?.length; + return !!this.#linksBySubspaceName.get(subspaceName)?.length; } - private async _hardLinkToLinkedPackageAsync( + async #hardLinkToLinkedPackageAsync( terminal: ITerminal, sourcePath: string, targetFolder: Set, @@ -98,16 +98,16 @@ export class HotlinkManager { }); } - private async _modifyAndSaveLinkStateAsync( + async #modifyAndSaveLinkStateAsync( cb: (linkState: LinksBySubspaceNameMap) => Promise | LinksBySubspaceNameMap ): Promise { - const newLinksBySubspaceName: LinksBySubspaceNameMap = await cb(this._linksBySubspaceName); - this._linksBySubspaceName = newLinksBySubspaceName; + const newLinksBySubspaceName: LinksBySubspaceNameMap = await cb(this.#linksBySubspaceName); + this.#linksBySubspaceName = newLinksBySubspaceName; const linkStateJson: IProjectLinksStateJson = { fileVersion: 0, linksBySubspace: Object.fromEntries(newLinksBySubspaceName) }; - await JsonFile.saveAsync(linkStateJson, this._rushLinkStateFilePath); + await JsonFile.saveAsync(linkStateJson, this.#rushLinkStateFilePath); } public async purgeLinksAsync(terminal: ITerminal, subspaceName: string): Promise { @@ -119,7 +119,7 @@ export class HotlinkManager { PnpmSyncUtilities.processLogMessage(logMessageOptions, terminal); }; - await this._modifyAndSaveLinkStateAsync(async (linksBySubspaceName) => { + await this.#modifyAndSaveLinkStateAsync(async (linksBySubspaceName) => { const rushLinkFileState: IProjectLinkInSubspaceJson[] = linksBySubspaceName.get(subspaceName) ?? []; await Async.forEachAsync( rushLinkFileState, @@ -150,7 +150,7 @@ export class HotlinkManager { return true; } - private async _getLinkedPackageInfoAsync(linkedPackagePath: string): Promise { + async #getLinkedPackageInfoAsync(linkedPackagePath: string): Promise { const linkedPackageJsonPath: string = `${linkedPackagePath}/${FileConstants.PackageJson}`; const linkedPackageJsonExists: boolean = await FileSystem.existsAsync(linkedPackageJsonPath); @@ -185,7 +185,7 @@ export class HotlinkManager { }; } - private async _getPackagePathsMatchingNameAndVersionAsync( + async #getPackagePathsMatchingNameAndVersionAsync( consumerPackagePnpmDependenciesFolderPath: string, packageName: string, versionRange: string @@ -214,11 +214,11 @@ export class HotlinkManager { ): Promise { const subspaceName: string = subspace.subspaceName; try { - const { packageName } = await this._getLinkedPackageInfoAsync(linkedPackagePath); + const { packageName } = await this.#getLinkedPackageInfoAsync(linkedPackagePath); const consumerPackagePnpmDependenciesFolderPath: string = `${subspace.getSubspaceTempFolderPath()}/${ RushConstants.nodeModulesFolderName }/${RushConstants.pnpmVirtualStoreFolderName}`; - const sourcePathSet: Set = await this._getPackagePathsMatchingNameAndVersionAsync( + const sourcePathSet: Set = await this.#getPackagePathsMatchingNameAndVersionAsync( consumerPackagePnpmDependenciesFolderPath, packageName, version @@ -228,8 +228,8 @@ export class HotlinkManager { `Cannot find package ${packageName} ${version} in ${consumerPackagePnpmDependenciesFolderPath}` ); } - await this._hardLinkToLinkedPackageAsync(terminal, linkedPackagePath, sourcePathSet, subspaceName); - await this._modifyAndSaveLinkStateAsync((linksBySubspaceName) => { + await this.#hardLinkToLinkedPackageAsync(terminal, linkedPackagePath, sourcePathSet, subspaceName); + await this.#modifyAndSaveLinkStateAsync((linksBySubspaceName) => { const newConsumerPackageLinks: IProjectLinkInSubspaceJson[] = [ ...(linksBySubspaceName.get(subspaceName) ?? []) ]; @@ -275,7 +275,7 @@ export class HotlinkManager { ): Promise { const consumerPackageName: string = consumerPackage.packageName; try { - const { packageName: linkedPackageName } = await this._getLinkedPackageInfoAsync(linkedPackagePath); + const { packageName: linkedPackageName } = await this.#getLinkedPackageInfoAsync(linkedPackagePath); const slashIndex: number = linkedPackageName.indexOf('/'); const [scope, packageBaseName] = @@ -301,7 +301,7 @@ export class HotlinkManager { }); // Record the link information between the consumer package and the linked package - await this._modifyAndSaveLinkStateAsync((linksBySubspaceName) => { + await this.#modifyAndSaveLinkStateAsync((linksBySubspaceName) => { const subspaceName: string = consumerPackage.subspace.subspaceName; const newConsumerPackageLinks: IProjectLinkInSubspaceJson[] = [ ...(linksBySubspaceName.get(subspaceName) ?? []) diff --git a/libraries/rush-lib/src/utilities/OverlappingPathAnalyzer.ts b/libraries/rush-lib/src/utilities/OverlappingPathAnalyzer.ts index 826a5e7255a..084e5e33c15 100644 --- a/libraries/rush-lib/src/utilities/OverlappingPathAnalyzer.ts +++ b/libraries/rush-lib/src/utilities/OverlappingPathAnalyzer.ts @@ -12,14 +12,14 @@ interface IPathTreeNode { * 'lib/x' and 'lib/y' do not. */ export class OverlappingPathAnalyzer { - private readonly _root: IPathTreeNode = { + readonly #root: IPathTreeNode = { encounteredLabels: new Set(), paths: {} }; public addPathAndGetFirstEncounteredLabels(path: string, label: TLabel): TLabel[] | undefined { const pathParts: string[] = path.split('/'); - let currentNode: IPathTreeNode = this._root; + let currentNode: IPathTreeNode = this.#root; let currentNodeIsNew: boolean = false; let labelWasAlreadyPresentInCurrentNode: boolean = false; for (const pathPart of pathParts) { diff --git a/libraries/rush-lib/src/utilities/RushAlerts.ts b/libraries/rush-lib/src/utilities/RushAlerts.ts index abca0c70577..1cbe2dd64ad 100644 --- a/libraries/rush-lib/src/utilities/RushAlerts.ts +++ b/libraries/rush-lib/src/utilities/RushAlerts.ts @@ -58,12 +58,12 @@ const enum AlertPriority { } export class RushAlerts { - private readonly _terminal: ITerminal; + readonly #terminal: ITerminal; - private readonly _rushAlertsConfig: IRushAlertsConfig | undefined; - private readonly _rushAlertsState: IRushAlertsState; + readonly #rushAlertsConfig: IRushAlertsConfig | undefined; + readonly #rushAlertsState: IRushAlertsState; - private readonly _rushJsonFolder: string; + readonly #rushJsonFolder: string; public readonly rushAlertsStateFilePath: string; public readonly rushAlertsConfigFilePath: string; @@ -105,12 +105,12 @@ export class RushAlerts { rushAlertsConfig, rushAlertsState = {} } = options; - this._terminal = terminal; - this._rushJsonFolder = rushJsonFolder; + this.#terminal = terminal; + this.#rushJsonFolder = rushJsonFolder; this.rushAlertsStateFilePath = rushAlertsStateFilePath; this.rushAlertsConfigFilePath = rushAlertsConfigFilePath; - this._rushAlertsConfig = rushAlertsConfig; - this._rushAlertsState = rushAlertsState; + this.#rushAlertsConfig = rushAlertsConfig; + this.#rushAlertsState = rushAlertsState; } public static async loadFromConfigurationAsync( @@ -148,12 +148,12 @@ export class RushAlerts { }); } - private _ensureAlertStateIsUpToDate(): void { + #ensureAlertStateIsUpToDate(): void { // ensure `temp/rush-alerts.json` is up to date - if (this._rushAlertsConfig) { - for (const alert of this._rushAlertsConfig.alerts) { - if (!(alert.alertId in this._rushAlertsState)) { - this._rushAlertsState[alert.alertId] = { + if (this.#rushAlertsConfig) { + for (const alert of this.#rushAlertsConfig.alerts) { + if (!(alert.alertId in this.#rushAlertsState)) { + this.#rushAlertsState[alert.alertId] = { snooze: false }; } @@ -162,23 +162,23 @@ export class RushAlerts { } public async printAlertsAsync(): Promise { - if (!this._rushAlertsConfig || this._rushAlertsConfig.alerts.length === 0) return; + if (!this.#rushAlertsConfig || this.#rushAlertsConfig.alerts.length === 0) return; - this._ensureAlertStateIsUpToDate(); + this.#ensureAlertStateIsUpToDate(); - this._terminal.writeLine(); + this.#terminal.writeLine(); - const alert: IRushAlertsConfigEntry | undefined = await this._selectAlertByPriorityAsync(); + const alert: IRushAlertsConfigEntry | undefined = await this.#selectAlertByPriorityAsync(); if (alert) { - this._printMessageInBoxStyle(alert); - this._rushAlertsState[alert.alertId].lastDisplayTime = new Date().toISOString(); + this.#printMessageInBoxStyle(alert); + this.#rushAlertsState[alert.alertId].lastDisplayTime = new Date().toISOString(); } - await this._writeRushAlertStateAsync(); + await this.#writeRushAlertStateAsync(); } public async printAllAlertsAsync(): Promise { - const allAlerts: IRushAlertsConfigEntry[] = this._rushAlertsConfig?.alerts ?? []; + const allAlerts: IRushAlertsConfigEntry[] = this.#rushAlertsConfig?.alerts ?? []; const activeAlerts: IRushAlertsConfigEntry[] = []; const snoozedAlerts: IRushAlertsConfigEntry[] = []; @@ -186,15 +186,15 @@ export class RushAlerts { await Promise.all( allAlerts.map(async (alert) => { - const isAlertValid: boolean = await this._isAlertValidAsync(alert); - const alertState: IRushAlertStateEntry = this._rushAlertsState[alert.alertId]; + const isAlertValid: boolean = await this.#isAlertValidAsync(alert); + const alertState: IRushAlertStateEntry = this.#rushAlertsState[alert.alertId]; if (!isAlertValid) { inactiveAlerts.push(alert); return; } - if (this._isSnoozing(alertState)) { + if (this.#isSnoozing(alertState)) { snoozedAlerts.push(alert); return; } @@ -203,53 +203,53 @@ export class RushAlerts { }) ); - this._printAlerts(activeAlerts, 'active'); - this._printAlerts(snoozedAlerts, 'snoozed'); - this._printAlerts(inactiveAlerts, 'inactive'); + this.#printAlerts(activeAlerts, 'active'); + this.#printAlerts(snoozedAlerts, 'snoozed'); + this.#printAlerts(inactiveAlerts, 'inactive'); } - private _printAlerts(alerts: IRushAlertsConfigEntry[], status: AlertStatus): void { + #printAlerts(alerts: IRushAlertsConfigEntry[], status: AlertStatus): void { if (alerts.length === 0) return; switch (status) { case 'active': case 'inactive': - this._terminal.writeLine(Colorize.yellow(`The following alerts are currently ${status}:`)); + this.#terminal.writeLine(Colorize.yellow(`The following alerts are currently ${status}:`)); break; case 'snoozed': - this._terminal.writeLine(Colorize.yellow('The following alerts are currently active but snoozed:')); + this.#terminal.writeLine(Colorize.yellow('The following alerts are currently active but snoozed:')); break; } alerts.forEach(({ title }) => { - this._terminal.writeLine(Colorize.green(`"${title}"`)); + this.#terminal.writeLine(Colorize.green(`"${title}"`)); }); - this._terminal.writeLine(); + this.#terminal.writeLine(); } public async snoozeAlertsByAlertIdAsync(alertId: string, forever: boolean = false): Promise { - this._ensureAlertStateIsUpToDate(); + this.#ensureAlertStateIsUpToDate(); if (forever) { - this._rushAlertsState[alertId].snooze = true; + this.#rushAlertsState[alertId].snooze = true; } else { - this._rushAlertsState[alertId].snooze = true; + this.#rushAlertsState[alertId].snooze = true; const snoozeEndTime: Date = new Date(); snoozeEndTime.setDate(snoozeEndTime.getDate() + 7); - this._rushAlertsState[alertId].snoozeEndTime = snoozeEndTime.toISOString(); + this.#rushAlertsState[alertId].snoozeEndTime = snoozeEndTime.toISOString(); } - await this._writeRushAlertStateAsync(); + await this.#writeRushAlertStateAsync(); } - private async _selectAlertByPriorityAsync(): Promise { - const alerts: Array = this._rushAlertsConfig!.alerts; - const alertsState: IRushAlertsState = this._rushAlertsState; + async #selectAlertByPriorityAsync(): Promise { + const alerts: Array = this.#rushAlertsConfig!.alerts; + const alertsState: IRushAlertsState = this.#rushAlertsState; const needDisplayAlerts: Array = ( await Promise.all( alerts.map(async (alert) => { - const isAlertValid: boolean = await this._isAlertValidAsync(alert); + const isAlertValid: boolean = await this.#isAlertValidAsync(alert); const alertState: IRushAlertStateEntry = alertsState[alert.alertId]; if ( isAlertValid && - !this._isSnoozing(alertState) && + !this.#isSnoozing(alertState) && (!alertState.lastDisplayTime || Number(new Date()) - Number(new Date(alertState.lastDisplayTime)) > RushAlerts.alertDisplayIntervalDurations.get( @@ -271,14 +271,14 @@ export class RushAlerts { return alertsSortedByPriority[0]; } - private _isSnoozing(alertState: IRushAlertStateEntry): boolean { + #isSnoozing(alertState: IRushAlertStateEntry): boolean { return ( Boolean(alertState.snooze) && (!alertState.snoozeEndTime || Number(new Date()) < Number(new Date(alertState.snoozeEndTime))) ); } - private async _isAlertValidAsync(alert: IRushAlertsConfigEntry): Promise { + async #isAlertValidAsync(alert: IRushAlertsConfigEntry): Promise { const timeNow: Date = new Date(); if (alert.startTime) { @@ -308,7 +308,7 @@ export class RushAlerts { JSON.stringify(conditionScript) ); } - const conditionScriptPath: string = `${this._rushJsonFolder}/common/config/rush/alert-scripts/${conditionScript}`; + const conditionScriptPath: string = `${this.#rushJsonFolder}/common/config/rush/alert-scripts/${conditionScript}`; if (!(await FileSystem.existsAsync(conditionScriptPath))) { throw new Error( 'The "conditionScript" field in rush-alerts.json refers to a nonexistent file:\n' + @@ -316,7 +316,7 @@ export class RushAlerts { ); } - this._terminal.writeDebugLine(`Invoking condition script "${conditionScript}" from rush-alerts.json`); + this.#terminal.writeDebugLine(`Invoking condition script "${conditionScript}" from rush-alerts.json`); const startTimemark: number = performance.now(); interface IAlertsConditionScriptModule { @@ -342,7 +342,7 @@ export class RushAlerts { try { // "Rush will invoke this script with the working directory set to the monorepo root folder, // with no guarantee that `rush install` has been run." - process.chdir(this._rushJsonFolder); + process.chdir(this.#rushJsonFolder); conditionResult = conditionScriptModule.canShowAlert(); if (typeof conditionResult !== 'boolean') { @@ -357,7 +357,7 @@ export class RushAlerts { } const totalMs: number = performance.now() - startTimemark; - this._terminal.writeDebugLine( + this.#terminal.writeDebugLine( `Invoked conditionScript "${conditionScript}"` + ` in ${Math.round(totalMs)} ms with result "${conditionResult}"` ); @@ -369,7 +369,7 @@ export class RushAlerts { return true; } - private _printMessageInBoxStyle(alert: IRushAlertsConfigEntry): void { + #printMessageInBoxStyle(alert: IRushAlertsConfigEntry): void { const boxTitle: string = alert.title.toUpperCase(); const boxMessage: string = typeof alert.message === 'string' ? alert.message : alert.message.join(''); @@ -405,16 +405,16 @@ export class RushAlerts { } // Print the box - this._terminal.writeLine('╔═' + '═'.repeat(lineLength) + '═╗'); + this.#terminal.writeLine('╔═' + '═'.repeat(lineLength) + '═╗'); for (const line of lines) { - this._terminal.writeLine(`║ ${line.padEnd(lineLength)} ║`); + this.#terminal.writeLine(`║ ${line.padEnd(lineLength)} ║`); } - this._terminal.writeLine('╚═' + '═'.repeat(lineLength) + '═╝'); - this._terminal.writeLine(`To stop seeing this alert, run "rush alert --snooze ${alert.alertId}"`); + this.#terminal.writeLine('╚═' + '═'.repeat(lineLength) + '═╝'); + this.#terminal.writeLine(`To stop seeing this alert, run "rush alert --snooze ${alert.alertId}"`); } - private async _writeRushAlertStateAsync(): Promise { - await JsonFile.saveAsync(this._rushAlertsState, this.rushAlertsStateFilePath, { + async #writeRushAlertStateAsync(): Promise { + await JsonFile.saveAsync(this.#rushAlertsState, this.rushAlertsStateFilePath, { ignoreUndefinedValues: true, headerComment: '// THIS FILE IS MACHINE-GENERATED -- DO NOT MODIFY', jsonSyntax: JsonSyntax.JsonWithComments diff --git a/libraries/rush-lib/src/utilities/Stopwatch.ts b/libraries/rush-lib/src/utilities/Stopwatch.ts index e137f27e140..d4eac852ad0 100644 --- a/libraries/rush-lib/src/utilities/Stopwatch.ts +++ b/libraries/rush-lib/src/utilities/Stopwatch.ts @@ -39,24 +39,24 @@ export interface IStopwatchResult { * of elapsed time in between two events. */ export class Stopwatch implements IStopwatchResult { - private _startTime: number | undefined; - private _endTime: number | undefined; - private _state: StopwatchState; + #startTime: number | undefined; + #endTime: number | undefined; + #state: StopwatchState; - private _getTime: () => number; + #getTime: () => number; public constructor(getTime: () => number = Utilities.getTimeInMs) { - this._startTime = undefined; - this._endTime = undefined; - this._getTime = getTime; - this._state = StopwatchState.Stopped; + this.#startTime = undefined; + this.#endTime = undefined; + this.#getTime = getTime; + this.#state = StopwatchState.Stopped; } public static fromState({ startTime, endTime }: { startTime: number; endTime: number }): Stopwatch { const stopwatch: Stopwatch = new Stopwatch(); - stopwatch._startTime = startTime; - stopwatch._endTime = endTime; - stopwatch._state = StopwatchState.Stopped; + stopwatch.#startTime = startTime; + stopwatch.#endTime = endTime; + stopwatch.#state = StopwatchState.Stopped; return stopwatch; } @@ -68,7 +68,7 @@ export class Stopwatch implements IStopwatchResult { } public get state(): StopwatchState { - return this._state; + return this.#state; } /** @@ -76,12 +76,12 @@ export class Stopwatch implements IStopwatchResult { * reset() should be called before calling start() again. */ public start(startTimeOverride?: number): Stopwatch { - if (this._startTime !== undefined) { + if (this.#startTime !== undefined) { throw new Error('Call reset() before starting the Stopwatch'); } - this._startTime = startTimeOverride ?? this._getTime(); - this._endTime = undefined; - this._state = StopwatchState.Started; + this.#startTime = startTimeOverride ?? this.#getTime(); + this.#endTime = undefined; + this.#state = StopwatchState.Started; return this; } @@ -89,8 +89,8 @@ export class Stopwatch implements IStopwatchResult { * Stops executing the stopwatch and saves the current timestamp */ public stop(): Stopwatch { - this._endTime = this._startTime !== undefined ? this._getTime() : undefined; - this._state = StopwatchState.Stopped; + this.#endTime = this.#startTime !== undefined ? this.#getTime() : undefined; + this.#state = StopwatchState.Stopped; return this; } @@ -98,8 +98,8 @@ export class Stopwatch implements IStopwatchResult { * Resets all values of the stopwatch back to the original */ public reset(): Stopwatch { - this._endTime = this._startTime = undefined; - this._state = StopwatchState.Stopped; + this.#endTime = this.#startTime = undefined; + this.#state = StopwatchState.Stopped; return this; } @@ -107,7 +107,7 @@ export class Stopwatch implements IStopwatchResult { * Displays how long the stopwatch has been executing in a human readable format. */ public toString(): string { - if (this._state === StopwatchState.Stopped && this._startTime === undefined) { + if (this.#state === StopwatchState.Stopped && this.#startTime === undefined) { return '0.00 seconds (stopped)'; } const totalSeconds: number = this.duration; @@ -126,25 +126,25 @@ export class Stopwatch implements IStopwatchResult { * Get the duration in seconds. */ public get duration(): number { - if (this._startTime === undefined) { + if (this.#startTime === undefined) { return 0; } - const curTime: number = this._endTime !== undefined ? this._endTime : this._getTime(); + const curTime: number = this.#endTime !== undefined ? this.#endTime : this.#getTime(); - return (curTime - this._startTime) / 1000.0; + return (curTime - this.#startTime) / 1000.0; } /** * Return the start time of the most recent stopwatch run. */ public get startTime(): number | undefined { - return this._startTime; + return this.#startTime; } /** * Return the end time of the most recent stopwatch run. */ public get endTime(): number | undefined { - return this._endTime; + return this.#endTime; } } diff --git a/libraries/rush-lib/src/utilities/TarExecutable.ts b/libraries/rush-lib/src/utilities/TarExecutable.ts index 6ea2e0f4d61..db58cc902de 100644 --- a/libraries/rush-lib/src/utilities/TarExecutable.ts +++ b/libraries/rush-lib/src/utilities/TarExecutable.ts @@ -28,10 +28,10 @@ export interface ICreateArchiveOptions extends ITarOptionsBase { } export class TarExecutable { - private _tarExecutablePath: string; + #tarExecutablePath: string; private constructor(tarExecutablePath: string) { - this._tarExecutablePath = tarExecutablePath; + this.#tarExecutablePath = tarExecutablePath; } public static async tryInitializeAsync(terminal: ITerminal): Promise { @@ -52,7 +52,7 @@ export class TarExecutable { * The "tar" exit code */ public async tryUntarAsync(options: IUntarOptions): Promise { - return await this._spawnTarWithLoggingAsync( + return await this.#spawnTarWithLoggingAsync( // These parameters are chosen for compatibility with the very primitive bsdtar 3.3.2 shipped with Windows 10. [ // [Windows bsdtar 3.3.2] Extract: tar -x [options] [] @@ -82,7 +82,7 @@ export class TarExecutable { await FileSystem.ensureFolderAsync(path.dirname(archivePath)); const projectFolderPath: string = project.projectFolder; - const tarExitCode: number = await this._spawnTarWithLoggingAsync( + const tarExitCode: number = await this.#spawnTarWithLoggingAsync( // These parameters are chosen for compatibility with the very primitive bsdtar 3.3.2 shipped with Windows 10. [ // [Windows bsdtar 3.3.2] -c Create @@ -105,7 +105,7 @@ export class TarExecutable { return tarExitCode; } - private async _spawnTarWithLoggingAsync( + async #spawnTarWithLoggingAsync( args: string[], currentWorkingDirectory: string, logFilePath: string, @@ -141,7 +141,7 @@ export class TarExecutable { fileWriter.write( [ `Start time: ${new Date().toString()}`, - `Invoking "${this._tarExecutablePath} ${args.join(' ')}"`, + `Invoking "${this.#tarExecutablePath} ${args.join(' ')}"`, '', `======= BEGIN PROCESS INPUT ======`, input || '', @@ -151,7 +151,7 @@ export class TarExecutable { ].join('\n') ); - const childProcess: ChildProcess = Executable.spawn(this._tarExecutablePath, args, { + const childProcess: ChildProcess = Executable.spawn(this.#tarExecutablePath, args, { currentWorkingDirectory: currentWorkingDirectory });