From dd7d86e17c6f996890b437851de266c888589bcb Mon Sep 17 00:00:00 2001 From: Bharat Middha <5100938+bmiddha@users.noreply.github.com> Date: Wed, 19 Aug 2026 14:20:00 -0700 Subject: [PATCH 1/3] refactor(heft): convert private fields to #private Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ebd5bf2-c44b-42d5-be25-e7936d4b0a14 --- apps/heft/src/cli/HeftActionRunner.ts | 92 +++++----- apps/heft/src/cli/HeftCommandLineParser.ts | 70 ++++---- apps/heft/src/cli/actions/AliasAction.ts | 12 +- apps/heft/src/cli/actions/CleanAction.ts | 74 ++++---- apps/heft/src/cli/actions/PhaseAction.ts | 22 +-- apps/heft/src/cli/actions/RunAction.ts | 46 ++--- .../src/configuration/HeftConfiguration.ts | 50 +++--- .../configuration/HeftPluginConfiguration.ts | 44 ++--- .../src/configuration/HeftPluginDefinition.ts | 30 ++-- .../src/configuration/RigPackageResolver.ts | 38 ++-- apps/heft/src/metrics/MetricsCollector.ts | 19 +- .../runners/PhaseOperationRunner.ts | 14 +- .../operations/runners/TaskOperationRunner.ts | 32 ++-- .../heft/src/pluginFramework/HeftLifecycle.ts | 70 ++++---- .../pluginFramework/HeftLifecycleSession.ts | 14 +- .../pluginFramework/HeftParameterManager.ts | 60 +++---- apps/heft/src/pluginFramework/HeftPhase.ts | 66 +++---- .../src/pluginFramework/HeftPhaseSession.ts | 14 +- .../src/pluginFramework/HeftPluginHost.ts | 18 +- apps/heft/src/pluginFramework/HeftTask.ts | 70 ++++---- .../src/pluginFramework/HeftTaskSession.ts | 24 +-- .../pluginFramework/InternalHeftSession.ts | 54 +++--- .../StaticFileSystemAdapter.ts | 22 +-- .../pluginFramework/logging/LoggingManager.ts | 40 ++--- .../pluginFramework/logging/ScopedLogger.ts | 28 +-- apps/heft/src/plugins/NodeServicePlugin.ts | 168 +++++++++--------- apps/heft/src/utilities/GitUtilities.ts | 48 ++--- .../src/utilities/WatchFileSystemAdapter.ts | 94 +++++----- 28 files changed, 667 insertions(+), 666 deletions(-) diff --git a/apps/heft/src/cli/HeftActionRunner.ts b/apps/heft/src/cli/HeftActionRunner.ts index b9d5c7f7f26..9b51129a7b5 100644 --- a/apps/heft/src/cli/HeftActionRunner.ts +++ b/apps/heft/src/cli/HeftActionRunner.ts @@ -197,24 +197,24 @@ export async function runWithLoggingAsync( } export class HeftActionRunner { - private readonly _action: IHeftAction; - private readonly _terminal: ITerminal; - private readonly _internalHeftSession: InternalHeftSession; - private readonly _metricsCollector: MetricsCollector; - private readonly _loggingManager: LoggingManager; - private readonly _heftConfiguration: HeftConfiguration; - private _parameterManager: HeftParameterManager | undefined; - private readonly _parallelism: number; + readonly #action: IHeftAction; + readonly #terminal: ITerminal; + readonly #internalHeftSession: InternalHeftSession; + readonly #metricsCollector: MetricsCollector; + readonly #loggingManager: LoggingManager; + readonly #heftConfiguration: HeftConfiguration; + #parameterManager: HeftParameterManager | undefined; + readonly #parallelism: number; public constructor(options: IHeftActionRunnerOptions) { const { action, internalHeftSession, heftConfiguration, loggingManager, terminal, metricsCollector } = options; - this._action = action; - this._internalHeftSession = internalHeftSession; - this._heftConfiguration = heftConfiguration; - this._loggingManager = loggingManager; - this._terminal = terminal; - this._metricsCollector = metricsCollector; + this.#action = action; + this.#internalHeftSession = internalHeftSession; + this.#heftConfiguration = heftConfiguration; + this.#loggingManager = loggingManager; + this.#terminal = terminal; + this.#metricsCollector = metricsCollector; const numberOfCores: number = heftConfiguration.numberOfCores; @@ -224,26 +224,26 @@ export class HeftActionRunner { // On desktop Windows, some people have complained that their system becomes // sluggish if Node is using all the CPU cores. Leave one thread for // other operations. For CI environments, you can use the "max" argument to use all available cores. - this._parallelism = Math.max(numberOfCores - 1, 1); + this.#parallelism = Math.max(numberOfCores - 1, 1); } else { // Unix-like operating systems have more balanced scheduling, so default // to the number of CPU cores - this._parallelism = numberOfCores; + this.#parallelism = numberOfCores; } } protected get parameterManager(): HeftParameterManager { - if (!this._parameterManager) { + if (!this.#parameterManager) { throw new InternalError(`HeftActionRunner.defineParameters() has not been called.`); } - return this._parameterManager; + return this.#parameterManager; } public defineParameters(parameterProvider?: CommandLineParameterProvider | undefined): void { - if (!this._parameterManager) { + if (!this.#parameterManager) { // Use the provided parameter provider if one was provided. This is used by the RunAction // to allow for the Heft plugin parameters to be applied as scoped parameters. - parameterProvider = parameterProvider || this._action; + parameterProvider = parameterProvider || this.#action; } else { throw new InternalError(`HeftActionParameters.defineParameters() has already been called.`); } @@ -265,7 +265,7 @@ export class HeftActionRunner { let cleanFlagDescription: string = 'If specified, clean the outputs at the beginning of the lifecycle and before running each phase.'; - if (this._action.watch) { + if (this.#action.watch) { cleanFlagDescription = `${cleanFlagDescription} Cleaning will only be performed once for the lifecycle and each phase, ` + `and further incremental runs will not be cleaned for the duration of execution.`; @@ -276,21 +276,21 @@ export class HeftActionRunner { }); const parameterManager: HeftParameterManager = new HeftParameterManager({ - getIsDebug: () => this._internalHeftSession.debug, + getIsDebug: () => this.#internalHeftSession.debug, getIsVerbose: () => verboseFlag.value, getIsProduction: () => productionFlag.value, - getIsWatch: () => this._action.watch, + getIsWatch: () => this.#action.watch, getLocales: () => localesParameter.values, getIsClean: () => !!cleanFlag?.value }); // Add all the lifecycle parameters for the action - for (const lifecyclePluginDefinition of this._internalHeftSession.lifecycle.pluginDefinitions) { + for (const lifecyclePluginDefinition of this.#internalHeftSession.lifecycle.pluginDefinitions) { parameterManager.addPluginParameters(lifecyclePluginDefinition); } // Add all the task parameters for the action - for (const phase of this._action.selectedPhases) { + for (const phase of this.#action.selectedPhases) { for (const task of phase.tasks) { parameterManager.addPluginParameters(task.pluginDefinition); } @@ -298,17 +298,17 @@ export class HeftActionRunner { // Finalize and apply to the CommandLineParameterProvider parameterManager.finalizeParameters(parameterProvider); - this._parameterManager = parameterManager; + this.#parameterManager = parameterManager; } public async executeAsync(): Promise { - const terminal: ITerminal = this._terminal; + const terminal: ITerminal = this.#terminal; // Set the parameter manager on the internal session, which is used to provide the selected // parameters to plugins. Set this in onExecute() since we now know that this action is being // executed, and the session should be populated with the executing parameters. - this._internalHeftSession.parameterManager = this.parameterManager; + this.#internalHeftSession.parameterManager = this.parameterManager; - initializeHeft(this._heftConfiguration, terminal, this.parameterManager.defaultParameters.verbose); + initializeHeft(this.#heftConfiguration, terminal, this.parameterManager.defaultParameters.verbose); const operations: ReadonlySet> = this._generateOperations(); @@ -318,12 +318,12 @@ export class HeftActionRunner { IHeftPhaseOperationMetadata > = new OperationExecutionManager(operations); - const cliAbortSignal: AbortSignal = ensureCliAbortSignal(this._terminal); + const cliAbortSignal: AbortSignal = ensureCliAbortSignal(this.#terminal); try { - await _startLifecycleAsync(this._internalHeftSession); + await _startLifecycleAsync(this.#internalHeftSession); - if (this._action.watch) { + if (this.#action.watch) { const watchLoop: WatchLoop = this._createWatchLoop(executionManager); if (process.send) { @@ -342,12 +342,12 @@ export class HeftActionRunner { // This is treated as a finalizer for any assets created in lifecycle plugins. // It is the responsibility of the lifecycle plugin to ensure that finish gracefully handles // aborted runs. - await _finishLifecycleAsync(this._internalHeftSession); + await _finishLifecycleAsync(this.#internalHeftSession); } } private _createWatchLoop(executionManager: OperationExecutionManager): WatchLoop { - const { _terminal: terminal } = this; + const terminal: ITerminal = this.#terminal; const watchLoop: WatchLoop = new WatchLoop({ onBeforeExecute: () => { // Write an empty line to the terminal for separation between iterations. We've already iterated @@ -373,9 +373,9 @@ export class HeftActionRunner { abortSignal: AbortSignal, requestRun?: OperationRequestRunCallback ): Promise { - const { taskStart, taskFinish, phaseStart, phaseFinish } = this._internalHeftSession.lifecycle.hooks; + const { taskStart, taskFinish, phaseStart, phaseFinish } = this.#internalHeftSession.lifecycle.hooks; // Record this as the start of task execution. - this._metricsCollector.setStartTime(); + this.#metricsCollector.setStartTime(); // Execute the action operations return await runWithLoggingAsync( () => { @@ -383,8 +383,8 @@ export class HeftActionRunner { IHeftTaskOperationMetadata, IHeftPhaseOperationMetadata > = { - terminal: this._terminal, - parallelism: this._parallelism, + terminal: this.#terminal, + parallelism: this.#parallelism, abortSignal, requestRun, beforeExecuteOperation( @@ -419,24 +419,24 @@ export class HeftActionRunner { return executionManager.executeAsync(operationExecutionManagerOptions); }, - this._action, - this._loggingManager, - this._terminal, - this._metricsCollector, + this.#action, + this.#loggingManager, + this.#terminal, + this.#metricsCollector, abortSignal, !requestRun ); } private _generateOperations(): Set> { - const { selectedPhases } = this._action; + const { selectedPhases } = this.#action; const operations: Map< string, Operation > = new Map(); const operationGroups: Map> = new Map(); - const internalHeftSession: InternalHeftSession = this._internalHeftSession; + const internalHeftSession: InternalHeftSession = this.#internalHeftSession; let hasWarnedAboutSkippedPhases: boolean = false; for (const phase of selectedPhases) { @@ -446,7 +446,7 @@ export class HeftActionRunner { if (!selectedPhases.has(dependencyPhase)) { // Only write once, and write with yellow to make it stand out without writing a warning to stderr hasWarnedAboutSkippedPhases = true; - this._terminal.writeLine( + this.#terminal.writeLine( Colorize.bold( 'The provided list of phases does not contain all phase dependencies. You may need to run the ' + 'excluded phases manually.' @@ -485,7 +485,7 @@ export class HeftActionRunner { // Set all tasks in a in a phase as dependencies of the consuming phase for (const consumingPhase of phase.consumingPhases) { - if (this._action.selectedPhases.has(consumingPhase)) { + if (this.#action.selectedPhases.has(consumingPhase)) { // Set all tasks in a dependency phase as dependencies of the consuming phase to ensure the dependency // tasks run first const consumingPhaseOperation: Operation = _getOrCreatePhaseOperation( diff --git a/apps/heft/src/cli/HeftCommandLineParser.ts b/apps/heft/src/cli/HeftCommandLineParser.ts index 67389a7d053..272b09c3d7b 100644 --- a/apps/heft/src/cli/HeftCommandLineParser.ts +++ b/apps/heft/src/cli/HeftCommandLineParser.ts @@ -38,14 +38,14 @@ const HEFT_TOOL_FILENAME: 'heft' = 'heft'; export class HeftCommandLineParser extends CommandLineParser { public readonly globalTerminal: ITerminal; - private readonly _debugFlag: CommandLineFlagParameter; - private readonly _unmanagedFlag: CommandLineFlagParameter; - private readonly _debug: boolean; - private readonly _terminalProvider: ConsoleTerminalProvider; - private readonly _loggingManager: LoggingManager; - private readonly _metricsCollector: MetricsCollector; - private readonly _heftConfiguration: HeftConfiguration; - private _internalHeftSession: InternalHeftSession | undefined; + readonly #debugFlag: CommandLineFlagParameter; + readonly #unmanagedFlag: CommandLineFlagParameter; + readonly #debug: boolean; + readonly #terminalProvider: ConsoleTerminalProvider; + readonly #loggingManager: LoggingManager; + readonly #metricsCollector: MetricsCollector; + readonly #heftConfiguration: HeftConfiguration; + #internalHeftSession: InternalHeftSession | undefined; public constructor() { super({ @@ -54,7 +54,7 @@ export class HeftCommandLineParser extends CommandLineParser { }); // Initialize the debug flag as a parameter on the tool itself - this._debugFlag = this.defineFlagParameter({ + this.#debugFlag = this.defineFlagParameter({ parameterLongName: Constants.debugParameterLongName, description: 'Show the full call stack if an error occurs while executing the tool' }); @@ -62,7 +62,7 @@ export class HeftCommandLineParser extends CommandLineParser { // Initialize the unmanaged flag as a parameter on the tool itself. While this parameter // is only used during version selection, we need to support parsing it here so that we // don't throw due to an unrecognized parameter. - this._unmanagedFlag = this.defineFlagParameter({ + this.#unmanagedFlag = this.defineFlagParameter({ parameterLongName: Constants.unmanagedParameterLongName, description: 'Disables the Heft version selector: When Heft is invoked via the shell path, normally it' + @@ -74,29 +74,29 @@ export class HeftCommandLineParser extends CommandLineParser { // Pre-initialize with known argument values to determine state of "--debug" const preInitializationArgumentValues: IPreInitializationArgumentValues = this._getPreInitializationArgumentValues(); - this._debug = !!preInitializationArgumentValues.debug; + this.#debug = !!preInitializationArgumentValues.debug; // Enable debug and verbose logging if the "--debug" flag is set - this._terminalProvider = new ConsoleTerminalProvider({ - debugEnabled: this._debug, - verboseEnabled: this._debug + this.#terminalProvider = new ConsoleTerminalProvider({ + debugEnabled: this.#debug, + verboseEnabled: this.#debug }); - this.globalTerminal = new Terminal(this._terminalProvider); - this._loggingManager = new LoggingManager({ terminalProvider: this._terminalProvider }); - if (this._debug) { + this.globalTerminal = new Terminal(this.#terminalProvider); + this.#loggingManager = new LoggingManager({ terminalProvider: this.#terminalProvider }); + if (this.#debug) { // Enable printing stacktraces if the "--debug" flag is set - this._loggingManager.enablePrintStacks(); + this.#loggingManager.enablePrintStacks(); InternalError.breakInDebugger = true; } const numberOfCores: number = os.availableParallelism?.() ?? os.cpus().length; - this._heftConfiguration = HeftConfiguration.initialize({ + this.#heftConfiguration = HeftConfiguration.initialize({ cwd: process.cwd(), - terminalProvider: this._terminalProvider, + terminalProvider: this.#terminalProvider, numberOfCores }); - this._metricsCollector = new MetricsCollector(); + this.#metricsCollector = new MetricsCollector(); } public async executeAsync(args?: string[]): Promise { @@ -108,19 +108,19 @@ export class HeftCommandLineParser extends CommandLineParser { this._normalizeCwd(); const internalHeftSession: InternalHeftSession = await InternalHeftSession.initializeAsync({ - debug: this._debug, - heftConfiguration: this._heftConfiguration, - loggingManager: this._loggingManager, - metricsCollector: this._metricsCollector + debug: this.#debug, + heftConfiguration: this.#heftConfiguration, + loggingManager: this.#loggingManager, + metricsCollector: this.#metricsCollector }); - this._internalHeftSession = internalHeftSession; + this.#internalHeftSession = internalHeftSession; const actionOptions: IHeftActionOptions = { internalHeftSession: internalHeftSession, terminal: this.globalTerminal, - loggingManager: this._loggingManager, - metricsCollector: this._metricsCollector, - heftConfiguration: this._heftConfiguration + loggingManager: this.#loggingManager, + metricsCollector: this.#metricsCollector, + heftConfiguration: this.#heftConfiguration }; // Add the clean action, the run action, and the individual phase actions @@ -193,7 +193,7 @@ export class HeftCommandLineParser extends CommandLineParser { } } - this._internalHeftSession!.parsedCommandLine = { + this.#internalHeftSession!.parsedCommandLine = { commandName, unaliasedCommandName }; @@ -207,7 +207,7 @@ export class HeftCommandLineParser extends CommandLineParser { } private _normalizeCwd(): void { - const buildFolder: string = this._heftConfiguration.buildFolderPath; + const buildFolder: string = this.#heftConfiguration.buildFolderPath; const currentCwd: string = process.cwd(); if (currentCwd !== buildFolder) { // Update the CWD to the project's build root. Some tools, like Jest, use process.cwd() @@ -223,7 +223,7 @@ export class HeftCommandLineParser extends CommandLineParser { private _getPreInitializationArgumentValues( args: string[] = process.argv ): IPreInitializationArgumentValues { - if (!this._debugFlag) { + if (!this.#debugFlag) { // The `this._debugFlag` parameter (the parameter itself, not its value) // has not yet been defined. Parameters need to be defined before we // try to evaluate any parameters. This is to ensure that the @@ -234,8 +234,8 @@ export class HeftCommandLineParser extends CommandLineParser { const toolParameters: Set = getToolParameterNamesFromArgs(args); return { - debug: toolParameters.has(this._debugFlag.longName), - unmanaged: toolParameters.has(this._unmanagedFlag.longName) + debug: toolParameters.has(this.#debugFlag.longName), + unmanaged: toolParameters.has(this.#unmanagedFlag.longName) }; } @@ -244,7 +244,7 @@ export class HeftCommandLineParser extends CommandLineParser { this.globalTerminal.writeErrorLine(error.toString()); } - if (this._debug) { + if (this.#debug) { this.globalTerminal.writeLine(); this.globalTerminal.writeErrorLine(error.stack!); } diff --git a/apps/heft/src/cli/actions/AliasAction.ts b/apps/heft/src/cli/actions/AliasAction.ts index 71fd1e52af3..7bf3311bf9d 100644 --- a/apps/heft/src/cli/actions/AliasAction.ts +++ b/apps/heft/src/cli/actions/AliasAction.ts @@ -13,23 +13,23 @@ export interface IAliasActionOptions extends IAliasCommandLineActionOptions { } export class AliasAction extends AliasCommandLineAction { - private readonly _toolFilename: string; - private readonly _terminal: ITerminal; + readonly #toolFilename: string; + readonly #terminal: ITerminal; public constructor(options: IAliasActionOptions) { super(options); - this._toolFilename = options.toolFilename; - this._terminal = options.terminal; + this.#toolFilename = options.toolFilename; + this.#terminal = options.terminal; } protected override async onExecuteAsync(): Promise { - const toolFilename: string = this._toolFilename; + const toolFilename: string = this.#toolFilename; const actionName: string = this.actionName; const targetAction: CommandLineAction = this.targetAction; const defaultParameters: ReadonlyArray = this.defaultParameters; const defaultParametersString: string = defaultParameters.join(' '); - this._terminal.writeLine( + this.#terminal.writeLine( `The "${toolFilename} ${actionName}" alias was expanded to "${toolFilename} ${targetAction.actionName}` + `${defaultParametersString ? ` ${defaultParametersString}` : ''}".` ); diff --git a/apps/heft/src/cli/actions/CleanAction.ts b/apps/heft/src/cli/actions/CleanAction.ts index 11d1c8e4c2b..1d91b5f0522 100644 --- a/apps/heft/src/cli/actions/CleanAction.ts +++ b/apps/heft/src/cli/actions/CleanAction.ts @@ -22,14 +22,14 @@ import { ensureCliAbortSignal, initializeHeft, runWithLoggingAsync } from '../He export class CleanAction extends CommandLineAction implements IHeftAction { public readonly watch: boolean = false; - private readonly _internalHeftSession: InternalHeftSession; - private readonly _terminal: ITerminal; - private readonly _metricsCollector: MetricsCollector; - private readonly _verboseFlag: CommandLineFlagParameter; - private readonly _toParameter: CommandLineStringListParameter; - private readonly _toExceptParameter: CommandLineStringListParameter; - private readonly _onlyParameter: CommandLineStringListParameter; - private _selectedPhases: ReadonlySet | undefined; + readonly #internalHeftSession: InternalHeftSession; + readonly #terminal: ITerminal; + readonly #metricsCollector: MetricsCollector; + readonly #verboseFlag: CommandLineFlagParameter; + readonly #toParameter: CommandLineStringListParameter; + readonly #toExceptParameter: CommandLineStringListParameter; + readonly #onlyParameter: CommandLineStringListParameter; + #selectedPhases: ReadonlySet | undefined; public constructor(options: IHeftActionOptions) { super({ @@ -38,16 +38,16 @@ export class CleanAction extends CommandLineAction implements IHeftAction { summary: 'Clean the project, removing temporary task folders and specified clean paths.' }); - this._terminal = options.terminal; - this._metricsCollector = options.metricsCollector; - this._internalHeftSession = options.internalHeftSession; + this.#terminal = options.terminal; + this.#metricsCollector = options.metricsCollector; + this.#internalHeftSession = options.internalHeftSession; const { toParameter, toExceptParameter, onlyParameter } = definePhaseScopingParameters(this); - this._toParameter = toParameter; - this._toExceptParameter = toExceptParameter; - this._onlyParameter = onlyParameter; + this.#toParameter = toParameter; + this.#toExceptParameter = toExceptParameter; + this.#onlyParameter = onlyParameter; - this._verboseFlag = this.defineFlagParameter({ + this.#verboseFlag = this.defineFlagParameter({ parameterLongName: Constants.verboseParameterLongName, parameterShortName: Constants.verboseParameterShortName, description: 'If specified, log information useful for debugging.' @@ -55,40 +55,40 @@ export class CleanAction extends CommandLineAction implements IHeftAction { } public get selectedPhases(): ReadonlySet { - if (!this._selectedPhases) { + if (!this.#selectedPhases) { if ( - this._onlyParameter.values.length || - this._toParameter.values.length || - this._toExceptParameter.values.length + this.#onlyParameter.values.length || + this.#toParameter.values.length || + this.#toExceptParameter.values.length ) { - this._selectedPhases = expandPhases( - this._onlyParameter, - this._toParameter, - this._toExceptParameter, - this._internalHeftSession, - this._terminal + this.#selectedPhases = expandPhases( + this.#onlyParameter, + this.#toParameter, + this.#toExceptParameter, + this.#internalHeftSession, + this.#terminal ); } else { // No selected phases, clean everything - this._selectedPhases = this._internalHeftSession.phases; + this.#selectedPhases = this.#internalHeftSession.phases; } } - return this._selectedPhases; + return this.#selectedPhases; } protected override async onExecuteAsync(): Promise { - const { heftConfiguration } = this._internalHeftSession; - const abortSignal: AbortSignal = ensureCliAbortSignal(this._terminal); + const { heftConfiguration } = this.#internalHeftSession; + const abortSignal: AbortSignal = ensureCliAbortSignal(this.#terminal); // Record this as the start of task execution. - this._metricsCollector.setStartTime(); - initializeHeft(heftConfiguration, this._terminal, this._verboseFlag.value); + this.#metricsCollector.setStartTime(); + initializeHeft(heftConfiguration, this.#terminal, this.#verboseFlag.value); await runWithLoggingAsync( this._cleanFilesAsync.bind(this), this, - this._internalHeftSession.loggingManager, - this._terminal, - this._metricsCollector, + this.#internalHeftSession.loggingManager, + this.#terminal, + this.#metricsCollector, abortSignal ); } @@ -97,7 +97,7 @@ export class CleanAction extends CommandLineAction implements IHeftAction { const deleteOperations: IDeleteOperation[] = []; for (const phase of this.selectedPhases) { // Add the temp folder and cache folder (if requested) for each task - const phaseSession: HeftPhaseSession = this._internalHeftSession.getSessionForPhase(phase); + const phaseSession: HeftPhaseSession = this.#internalHeftSession.getSessionForPhase(phase); for (const task of phase.tasks) { const taskSession: HeftTaskSession = phaseSession.getSessionForTask(task); deleteOperations.push({ sourcePath: taskSession.tempFolderPath }); @@ -108,8 +108,8 @@ export class CleanAction extends CommandLineAction implements IHeftAction { // Delete the files if (deleteOperations.length) { - const rootFolderPath: string = this._internalHeftSession.heftConfiguration.buildFolderPath; - await deleteFilesAsync(rootFolderPath, deleteOperations, this._terminal); + const rootFolderPath: string = this.#internalHeftSession.heftConfiguration.buildFolderPath; + await deleteFilesAsync(rootFolderPath, deleteOperations, this.#terminal); } return deleteOperations.length === 0 ? OperationStatus.NoOp : OperationStatus.Success; diff --git a/apps/heft/src/cli/actions/PhaseAction.ts b/apps/heft/src/cli/actions/PhaseAction.ts index f1f4643af3a..5a0abc3b696 100644 --- a/apps/heft/src/cli/actions/PhaseAction.ts +++ b/apps/heft/src/cli/actions/PhaseAction.ts @@ -15,9 +15,9 @@ export interface IPhaseActionOptions extends IHeftActionOptions { export class PhaseAction extends CommandLineAction implements IHeftAction { public readonly watch: boolean; - private readonly _actionRunner: HeftActionRunner; - private readonly _phase: HeftPhase; - private _selectedPhases: Set | undefined; + readonly #actionRunner: HeftActionRunner; + readonly #phase: HeftPhase; + #selectedPhases: Set | undefined; public constructor(options: IPhaseActionOptions) { const { phase, watch = false } = options; @@ -34,22 +34,22 @@ export class PhaseAction extends CommandLineAction implements IHeftAction { }); this.watch = watch; - this._phase = phase; - this._actionRunner = new HeftActionRunner({ action: this, ...options }); - this._actionRunner.defineParameters(); + this.#phase = phase; + this.#actionRunner = new HeftActionRunner({ action: this, ...options }); + this.#actionRunner.defineParameters(); } public get selectedPhases(): ReadonlySet { - if (!this._selectedPhases) { - this._selectedPhases = Selection.recursiveExpand( - [this._phase], + if (!this.#selectedPhases) { + this.#selectedPhases = Selection.recursiveExpand( + [this.#phase], (phase: HeftPhase) => phase.dependencyPhases ); } - return this._selectedPhases; + return this.#selectedPhases; } protected override async onExecuteAsync(): Promise { - await this._actionRunner.executeAsync(); + await this.#actionRunner.executeAsync(); } } diff --git a/apps/heft/src/cli/actions/RunAction.ts b/apps/heft/src/cli/actions/RunAction.ts index 6454ea5b901..d69390dbbf1 100644 --- a/apps/heft/src/cli/actions/RunAction.ts +++ b/apps/heft/src/cli/actions/RunAction.ts @@ -101,13 +101,13 @@ export function definePhaseScopingParameters(action: IHeftAction): IScopingParam export class RunAction extends ScopedCommandLineAction implements IHeftAction { public readonly watch: boolean; - private readonly _internalHeftSession: InternalHeftSession; - private readonly _terminal: ITerminal; - private readonly _actionRunner: HeftActionRunner; - private readonly _toParameter: CommandLineStringListParameter; - private readonly _toExceptParameter: CommandLineStringListParameter; - private readonly _onlyParameter: CommandLineStringListParameter; - private _selectedPhases: Set | undefined; + readonly #internalHeftSession: InternalHeftSession; + readonly #terminal: ITerminal; + readonly #actionRunner: HeftActionRunner; + readonly #toParameter: CommandLineStringListParameter; + readonly #toExceptParameter: CommandLineStringListParameter; + readonly #onlyParameter: CommandLineStringListParameter; + #selectedPhases: Set | undefined; public constructor(options: IHeftActionOptions) { super({ @@ -117,35 +117,35 @@ export class RunAction extends ScopedCommandLineAction implements IHeftAction { }); this.watch = options.watch ?? false; - this._terminal = options.terminal; - this._internalHeftSession = options.internalHeftSession; + this.#terminal = options.terminal; + this.#internalHeftSession = options.internalHeftSession; const { toParameter, toExceptParameter, onlyParameter } = definePhaseScopingParameters(this); - this._toParameter = toParameter; - this._toExceptParameter = toExceptParameter; - this._onlyParameter = onlyParameter; + this.#toParameter = toParameter; + this.#toExceptParameter = toExceptParameter; + this.#onlyParameter = onlyParameter; - this._actionRunner = new HeftActionRunner({ action: this, ...options }); + this.#actionRunner = new HeftActionRunner({ action: this, ...options }); } public get selectedPhases(): ReadonlySet { - if (!this._selectedPhases) { - this._selectedPhases = expandPhases( - this._onlyParameter, - this._toParameter, - this._toExceptParameter, - this._internalHeftSession, - this._terminal + if (!this.#selectedPhases) { + this.#selectedPhases = expandPhases( + this.#onlyParameter, + this.#toParameter, + this.#toExceptParameter, + this.#internalHeftSession, + this.#terminal ); } - return this._selectedPhases; + return this.#selectedPhases; } protected onDefineScopedParameters(scopedParameterProvider: CommandLineParameterProvider): void { - this._actionRunner.defineParameters(scopedParameterProvider); + this.#actionRunner.defineParameters(scopedParameterProvider); } protected override async onExecuteAsync(): Promise { - await this._actionRunner.executeAsync(); + await this.#actionRunner.executeAsync(); } } diff --git a/apps/heft/src/configuration/HeftConfiguration.ts b/apps/heft/src/configuration/HeftConfiguration.ts index e6079a8a3f6..44f68f64d50 100644 --- a/apps/heft/src/configuration/HeftConfiguration.ts +++ b/apps/heft/src/configuration/HeftConfiguration.ts @@ -47,13 +47,13 @@ interface IProjectConfigurationFileEntry { * @public */ export class HeftConfiguration { - private _slashNormalizedBuildFolderPath: string | undefined; - private _projectConfigFolderPath: string | undefined; - private _tempFolderPath: string | undefined; - private _rigConfig: IRigConfig | undefined; - private _rigPackageResolver: RigPackageResolver | undefined; + #slashNormalizedBuildFolderPath: string | undefined; + #projectConfigFolderPath: string | undefined; + #tempFolderPath: string | undefined; + #rigConfig: IRigConfig | undefined; + #rigPackageResolver: RigPackageResolver | undefined; - private readonly _knownConfigurationFiles: Map> = new Map(); + readonly #knownConfigurationFiles: Map> = new Map(); /** * Project build folder path. This is the folder containing the project's package.json file. @@ -64,22 +64,22 @@ export class HeftConfiguration { * {@link HeftConfiguration.buildFolderPath} with all path separators converted to forward slashes. */ public get slashNormalizedBuildFolderPath(): string { - if (!this._slashNormalizedBuildFolderPath) { - this._slashNormalizedBuildFolderPath = Path.convertToSlashes(this.buildFolderPath); + if (!this.#slashNormalizedBuildFolderPath) { + this.#slashNormalizedBuildFolderPath = Path.convertToSlashes(this.buildFolderPath); } - return this._slashNormalizedBuildFolderPath; + return this.#slashNormalizedBuildFolderPath; } /** * The path to the project's "config" folder. */ public get projectConfigFolderPath(): string { - if (!this._projectConfigFolderPath) { - this._projectConfigFolderPath = path.join(this.buildFolderPath, Constants.projectConfigFolderName); + if (!this.#projectConfigFolderPath) { + this.#projectConfigFolderPath = path.join(this.buildFolderPath, Constants.projectConfigFolderName); } - return this._projectConfigFolderPath; + return this.#projectConfigFolderPath; } /** @@ -90,38 +90,38 @@ export class HeftConfiguration { * Instead, plugins should write to the directory provided by HeftTaskSession.taskTempFolderPath */ public get tempFolderPath(): string { - if (!this._tempFolderPath) { - this._tempFolderPath = path.join(this.buildFolderPath, Constants.tempFolderName); + if (!this.#tempFolderPath) { + this.#tempFolderPath = path.join(this.buildFolderPath, Constants.tempFolderName); } - return this._tempFolderPath; + return this.#tempFolderPath; } /** * The rig.json configuration for this project, if present. */ public get rigConfig(): IRigConfig { - if (!this._rigConfig) { + if (!this.#rigConfig) { throw new InternalError( 'The rigConfig cannot be accessed until HeftConfiguration.checkForRigAsync() has been called' ); } - return this._rigConfig; + return this.#rigConfig; } /** * The rig package resolver, which can be used to rig-resolve a requested package. */ public get rigPackageResolver(): IRigPackageResolver { - if (!this._rigPackageResolver) { - this._rigPackageResolver = new RigPackageResolver({ + if (!this.#rigPackageResolver) { + this.#rigPackageResolver = new RigPackageResolver({ buildFolder: this.buildFolderPath, projectPackageJson: this.projectPackageJson, rigConfig: this.rigConfig }); } - return this._rigPackageResolver; + return this.#rigPackageResolver; } /** @@ -166,8 +166,8 @@ export class HeftConfiguration { * @internal */ public async _checkForRigAsync(): Promise { - if (!this._rigConfig) { - this._rigConfig = await RigConfig.loadForProjectFolderAsync({ + if (!this.#rigConfig) { + this.#rigConfig = await RigConfig.loadForProjectFolderAsync({ projectFolderPath: this.buildFolderPath }); } @@ -184,7 +184,7 @@ export class HeftConfiguration { terminal: ITerminal ): TConfigFile | undefined { const loader: ProjectConfigurationFile = this._getConfigFileLoader(options); - return loader.tryLoadConfigurationFileForProject(terminal, this.buildFolderPath, this._rigConfig); + return loader.tryLoadConfigurationFileForProject(terminal, this.buildFolderPath, this.#rigConfig); } /** @@ -198,7 +198,7 @@ export class HeftConfiguration { terminal: ITerminal ): Promise { const loader: ProjectConfigurationFile = this._getConfigFileLoader(options); - return loader.tryLoadConfigurationFileForProjectAsync(terminal, this.buildFolderPath, this._rigConfig); + return loader.tryLoadConfigurationFileForProjectAsync(terminal, this.buildFolderPath, this.#rigConfig); } /** @@ -231,7 +231,7 @@ export class HeftConfiguration { private _getConfigFileLoader( options: IProjectConfigurationFileSpecification ): ProjectConfigurationFile { - let entry: IProjectConfigurationFileEntry | undefined = this._knownConfigurationFiles.get( + let entry: IProjectConfigurationFileEntry | undefined = this.#knownConfigurationFiles.get( options.projectRelativeFilePath ) as IProjectConfigurationFileEntry | undefined; diff --git a/apps/heft/src/configuration/HeftPluginConfiguration.ts b/apps/heft/src/configuration/HeftPluginConfiguration.ts index 1842c68d778..5e117b4b40b 100644 --- a/apps/heft/src/configuration/HeftPluginConfiguration.ts +++ b/apps/heft/src/configuration/HeftPluginConfiguration.ts @@ -27,11 +27,11 @@ const _pluginConfigurationPromises: Map * Loads and validates the heft-plugin.json file. */ export class HeftPluginConfiguration { - private readonly _heftPluginConfigurationJson: IHeftPluginConfigurationJson; - private _lifecyclePluginDefinitions: Set | undefined; - private _lifecyclePluginDefinitionsMap: Map | undefined; - private _taskPluginDefinitions: Set | undefined; - private _taskPluginDefinitionsMap: Map | undefined; + readonly #heftPluginConfigurationJson: IHeftPluginConfigurationJson; + #lifecyclePluginDefinitions: Set | undefined; + #lifecyclePluginDefinitionsMap: Map | undefined; + #taskPluginDefinitions: Set | undefined; + #taskPluginDefinitionsMap: Map | undefined; /** * The path to the root of the package that contains the heft-plugin.json file. @@ -48,7 +48,7 @@ export class HeftPluginConfiguration { packageRoot: string, packageName: string ) { - this._heftPluginConfigurationJson = heftPluginConfigurationJson; + this.#heftPluginConfigurationJson = heftPluginConfigurationJson; this.packageRoot = packageRoot; this.packageName = packageName; this._validate(heftPluginConfigurationJson, packageName); @@ -138,15 +138,15 @@ export class HeftPluginConfiguration { public tryGetLifecyclePluginDefinitionByName( lifecyclePluginName: string ): HeftLifecyclePluginDefinition | undefined { - if (!this._lifecyclePluginDefinitionsMap) { - this._lifecyclePluginDefinitionsMap = new Map( + if (!this.#lifecyclePluginDefinitionsMap) { + this.#lifecyclePluginDefinitionsMap = new Map( Array.from(this._getLifecyclePluginDefinitions()).map((d: HeftLifecyclePluginDefinition) => [ d.pluginName, d ]) ); } - return this._lifecyclePluginDefinitionsMap.get(lifecyclePluginName); + return this.#lifecyclePluginDefinitionsMap.get(lifecyclePluginName); } /** @@ -154,19 +154,19 @@ export class HeftPluginConfiguration { * returns undefined. */ public tryGetTaskPluginDefinitionByName(taskPluginName: string): HeftTaskPluginDefinition | undefined { - if (!this._taskPluginDefinitionsMap) { - this._taskPluginDefinitionsMap = new Map( + if (!this.#taskPluginDefinitionsMap) { + this.#taskPluginDefinitionsMap = new Map( Array.from(this._getTaskPluginDefinitions()).map((d: HeftTaskPluginDefinition) => [d.pluginName, d]) ); } - return this._taskPluginDefinitionsMap.get(taskPluginName); + return this.#taskPluginDefinitionsMap.get(taskPluginName); } private _getLifecyclePluginDefinitions(): ReadonlySet { - if (!this._lifecyclePluginDefinitions) { - this._lifecyclePluginDefinitions = new Set(); - for (const lifecyclePluginDefinitionJson of this._heftPluginConfigurationJson.lifecyclePlugins || []) { - this._lifecyclePluginDefinitions.add( + if (!this.#lifecyclePluginDefinitions) { + this.#lifecyclePluginDefinitions = new Set(); + for (const lifecyclePluginDefinitionJson of this.#heftPluginConfigurationJson.lifecyclePlugins || []) { + this.#lifecyclePluginDefinitions.add( HeftLifecyclePluginDefinition.loadFromObject({ heftPluginDefinitionJson: lifecyclePluginDefinitionJson, packageRoot: this.packageRoot, @@ -175,17 +175,17 @@ export class HeftPluginConfiguration { ); } } - return this._lifecyclePluginDefinitions; + return this.#lifecyclePluginDefinitions; } /** * Task plugin definitions sourced from the heft-plugin.json file. */ private _getTaskPluginDefinitions(): ReadonlySet { - if (!this._taskPluginDefinitions) { - this._taskPluginDefinitions = new Set(); - for (const taskPluginDefinitionJson of this._heftPluginConfigurationJson.taskPlugins || []) { - this._taskPluginDefinitions.add( + if (!this.#taskPluginDefinitions) { + this.#taskPluginDefinitions = new Set(); + for (const taskPluginDefinitionJson of this.#heftPluginConfigurationJson.taskPlugins || []) { + this.#taskPluginDefinitions.add( HeftTaskPluginDefinition.loadFromObject({ heftPluginDefinitionJson: taskPluginDefinitionJson, packageRoot: this.packageRoot, @@ -194,7 +194,7 @@ export class HeftPluginConfiguration { ); } } - return this._taskPluginDefinitions; + return this.#taskPluginDefinitions; } private _validate(heftPluginConfigurationJson: IHeftPluginConfigurationJson, packageName: string): void { diff --git a/apps/heft/src/configuration/HeftPluginDefinition.ts b/apps/heft/src/configuration/HeftPluginDefinition.ts index 9c4a0114054..822ef3453e3 100644 --- a/apps/heft/src/configuration/HeftPluginDefinition.ts +++ b/apps/heft/src/configuration/HeftPluginDefinition.ts @@ -193,15 +193,15 @@ export interface IHeftPluginDefinitionOptions { } export abstract class HeftPluginDefinitionBase { - private _heftPluginDefinitionJson: IHeftPluginDefinitionJson; - private _pluginPackageName: string; - private _resolvedEntryPoint: string; - private _optionsSchema: JsonSchema | undefined; + #heftPluginDefinitionJson: IHeftPluginDefinitionJson; + #pluginPackageName: string; + #resolvedEntryPoint: string; + #optionsSchema: JsonSchema | undefined; protected constructor(options: IHeftPluginDefinitionOptions) { - this._heftPluginDefinitionJson = options.heftPluginDefinitionJson; - this._pluginPackageName = options.packageName; - this._resolvedEntryPoint = path.resolve(options.packageRoot, this._heftPluginDefinitionJson.entryPoint); + this.#heftPluginDefinitionJson = options.heftPluginDefinitionJson; + this.#pluginPackageName = options.packageName; + this.#resolvedEntryPoint = path.resolve(options.packageRoot, this.#heftPluginDefinitionJson.entryPoint); // Ensure that the plugin parameters are unique const seenParameters: Set = new Set(); @@ -222,7 +222,7 @@ export abstract class HeftPluginDefinitionBase { options.packageRoot, options.heftPluginDefinitionJson.optionsSchema ); - this._optionsSchema = JsonSchema.fromFile(resolvedSchemaPath); + this.#optionsSchema = JsonSchema.fromFile(resolvedSchemaPath); } } @@ -230,21 +230,21 @@ export abstract class HeftPluginDefinitionBase { * The package name containing the target plugin. */ public get pluginPackageName(): string { - return this._pluginPackageName; + return this.#pluginPackageName; } /** * The name of the target plugin. */ public get pluginName(): string { - return this._heftPluginDefinitionJson.pluginName; + return this.#heftPluginDefinitionJson.pluginName; } /** * The resolved entry point to the plugin. */ public get entryPoint(): string { - return this._resolvedEntryPoint; + return this.#resolvedEntryPoint; } /** @@ -254,14 +254,14 @@ export abstract class HeftPluginDefinitionBase { // Default to the plugin name for the parameter scope. Plugin names should be unique within any run // of Heft. Additionally, plugin names have the same naming restrictions as parameter scopes so can // be used without modification. - return this._heftPluginDefinitionJson.parameterScope || this.pluginName; + return this.#heftPluginDefinitionJson.parameterScope || this.pluginName; } /** * The parameters that are defined for this plugin. */ public get pluginParameters(): ReadonlyArray { - return this._heftPluginDefinitionJson.parameters || []; + return this.#heftPluginDefinitionJson.parameters || []; } /** @@ -314,9 +314,9 @@ export abstract class HeftPluginDefinitionBase { * Validate the provided plugin options against the plugin's options schema, if one is provided. */ public validateOptions(options: unknown): void { - if (this._optionsSchema) { + if (this.#optionsSchema) { try { - this._optionsSchema.validateObject(options || {}, ''); + this.#optionsSchema.validateObject(options || {}, ''); } catch (error) { throw new Error( `Provided options for plugin ${JSON.stringify(this.pluginName)} did not match the provided ` + diff --git a/apps/heft/src/configuration/RigPackageResolver.ts b/apps/heft/src/configuration/RigPackageResolver.ts index 03a70db6dc4..5f91418a73f 100644 --- a/apps/heft/src/configuration/RigPackageResolver.ts +++ b/apps/heft/src/configuration/RigPackageResolver.ts @@ -37,16 +37,16 @@ export interface IRigPackageResolverOptions { * Rig resolves requested tools from the project's Heft rig. */ export class RigPackageResolver implements IRigPackageResolver { - private readonly _buildFolder: string; - private readonly _projectPackageJson: IPackageJson; - private readonly _rigConfig: IRigConfig; - private readonly _packageJsonLookup: PackageJsonLookup = new PackageJsonLookup(); - private readonly _resolverCache: Map> = new Map(); + readonly #buildFolder: string; + readonly #projectPackageJson: IPackageJson; + readonly #rigConfig: IRigConfig; + readonly #packageJsonLookup: PackageJsonLookup = new PackageJsonLookup(); + readonly #resolverCache: Map> = new Map(); public constructor(options: IRigPackageResolverOptions) { - this._buildFolder = options.buildFolder; - this._projectPackageJson = options.projectPackageJson; - this._rigConfig = options.rigConfig; + this.#buildFolder = options.buildFolder; + this.#projectPackageJson = options.projectPackageJson; + this.#rigConfig = options.rigConfig; } /** @@ -61,17 +61,17 @@ export class RigPackageResolver implements IRigPackageResolver { * - OTHERWISE try to resolve it from the current project. */ public async resolvePackageAsync(packageName: string, terminal: ITerminal): Promise { - const buildFolder: string = this._buildFolder; - const projectFolder: string | undefined = this._packageJsonLookup.tryGetPackageFolderFor(buildFolder); + const buildFolder: string = this.#buildFolder; + const projectFolder: string | undefined = this.#packageJsonLookup.tryGetPackageFolderFor(buildFolder); if (!projectFolder) { throw new Error(`Unable to find a package.json file for "${buildFolder}".`); } const cacheKey: string = `${projectFolder};${packageName}`; - let resolutionPromise: Promise | undefined = this._resolverCache.get(cacheKey); + let resolutionPromise: Promise | undefined = this.#resolverCache.get(cacheKey); if (!resolutionPromise) { resolutionPromise = this._resolvePackageInnerAsync(packageName, terminal); - this._resolverCache.set(cacheKey, resolutionPromise); + this.#resolverCache.set(cacheKey, resolutionPromise); } return await resolutionPromise; @@ -80,13 +80,13 @@ export class RigPackageResolver implements IRigPackageResolver { private async _resolvePackageInnerAsync(toolPackageName: string, terminal: ITerminal): Promise { // See if the project has a devDependency on the package if ( - this._projectPackageJson.devDependencies && - this._projectPackageJson.devDependencies[toolPackageName] + this.#projectPackageJson.devDependencies && + this.#projectPackageJson.devDependencies[toolPackageName] ) { try { const resolvedPackageFolder: string = Import.resolvePackage({ packageName: toolPackageName, - baseFolderPath: this._buildFolder + baseFolderPath: this.#buildFolder }); terminal.writeVerboseLine( `Resolved ${JSON.stringify(toolPackageName)} as a direct devDependency of the project.` @@ -101,11 +101,11 @@ export class RigPackageResolver implements IRigPackageResolver { } // See if the project rig has a regular dependency on the package - const rigConfiguration: IRigConfig = this._rigConfig; + const rigConfiguration: IRigConfig = this.#rigConfig; if (rigConfiguration.rigFound) { const rigFolder: string = rigConfiguration.getResolvedProfileFolder(); const rigPackageJsonPath: string | undefined = - this._packageJsonLookup.tryGetPackageJsonFilePathFor(rigFolder); + this.#packageJsonLookup.tryGetPackageJsonFilePathFor(rigFolder); if (!rigPackageJsonPath) { throw new Error( 'Unable to resolve the package.json file for the ' + @@ -113,7 +113,7 @@ export class RigPackageResolver implements IRigPackageResolver { ); } const rigPackageJson: INodePackageJson = - this._packageJsonLookup.loadNodePackageJson(rigPackageJsonPath); + this.#packageJsonLookup.loadNodePackageJson(rigPackageJsonPath); if (rigPackageJson.dependencies && rigPackageJson.dependencies[toolPackageName]) { try { const resolvedPackageFolder: string = Import.resolvePackage({ @@ -139,7 +139,7 @@ export class RigPackageResolver implements IRigPackageResolver { try { const resolvedPackageFolder: string = Import.resolvePackage({ packageName: toolPackageName, - baseFolderPath: this._buildFolder + baseFolderPath: this.#buildFolder }); terminal.writeVerboseLine( `Resolved ${JSON.stringify(toolPackageName)} from "${resolvedPackageFolder}".` diff --git a/apps/heft/src/metrics/MetricsCollector.ts b/apps/heft/src/metrics/MetricsCollector.ts index b7f6352387d..d1e03b27352 100644 --- a/apps/heft/src/metrics/MetricsCollector.ts +++ b/apps/heft/src/metrics/MetricsCollector.ts @@ -103,18 +103,18 @@ export class MetricsCollector { public readonly recordMetricsHook: AsyncParallelHook = new AsyncParallelHook(['recordMetricsHookOptions']); - private _bootDurationMs: number | undefined; - private _startTimeMs: number | undefined; + #bootDurationMs: number | undefined; + #startTimeMs: number | undefined; /** * Start metrics log timer. */ public setStartTime(): void { - if (this._bootDurationMs === undefined) { + if (this.#bootDurationMs === undefined) { // Only set this once. This is for tracking boot overhead. - this._bootDurationMs = process.uptime() * 1000; + this.#bootDurationMs = process.uptime() * 1000; } - this._startTimeMs = performance.now(); + this.#startTimeMs = performance.now(); } /** @@ -129,8 +129,9 @@ export class MetricsCollector { performanceData?: Partial, parameters?: Record ): Promise { - const { _bootDurationMs, _startTimeMs } = this; - if (_bootDurationMs === undefined || _startTimeMs === undefined) { + const bootDurationMs: number | undefined = this.#bootDurationMs; + const startTimeMs: number | undefined = this.#startTimeMs; + if (bootDurationMs === undefined || startTimeMs === undefined) { throw new InternalError('MetricsCollector has not been initialized with setStartTime() yet'); } @@ -139,7 +140,7 @@ export class MetricsCollector { } const filledPerformanceData: IPerformanceData = { - taskTotalExecutionMs: performance.now() - _startTimeMs, + taskTotalExecutionMs: performance.now() - startTimeMs, ...(performanceData || {}) }; @@ -150,7 +151,7 @@ export class MetricsCollector { const metricData: IMetricsData = { command: command, encounteredError: filledPerformanceData.encounteredError, - bootDurationMs: _bootDurationMs, + bootDurationMs: bootDurationMs, taskTotalExecutionMs: taskTotalExecutionMs, totalUptimeMs: process.uptime() * 1000, machineOs: process.platform, diff --git a/apps/heft/src/operations/runners/PhaseOperationRunner.ts b/apps/heft/src/operations/runners/PhaseOperationRunner.ts index f6f1ba3ed0d..fd9f46488e8 100644 --- a/apps/heft/src/operations/runners/PhaseOperationRunner.ts +++ b/apps/heft/src/operations/runners/PhaseOperationRunner.ts @@ -20,19 +20,19 @@ export interface IPhaseOperationRunnerOptions { export class PhaseOperationRunner implements IOperationRunner { public readonly silent: boolean = true; - private readonly _options: IPhaseOperationRunnerOptions; - private _isClean: boolean = false; + readonly #options: IPhaseOperationRunnerOptions; + #isClean: boolean = false; public get name(): string { - return `Phase ${JSON.stringify(this._options.phase.phaseName)}`; + return `Phase ${JSON.stringify(this.#options.phase.phaseName)}`; } public constructor(options: IPhaseOperationRunnerOptions) { - this._options = options; + this.#options = options; } public async executeAsync(context: IOperationRunnerContext): Promise { - const { internalHeftSession, phase } = this._options; + const { internalHeftSession, phase } = this.#options; const { clean } = internalHeftSession.parameterManager.defaultParameters; // Load and apply the plugins for this phase only @@ -40,7 +40,7 @@ export class PhaseOperationRunner implements IOperationRunner { const { phaseLogger, cleanLogger } = phaseSession; await phaseSession.applyPluginsAsync(phaseLogger.terminal); - if (this._isClean || !clean) { + if (this.#isClean || !clean) { return OperationStatus.NoOp; } @@ -68,7 +68,7 @@ export class PhaseOperationRunner implements IOperationRunner { } // Ensure we only run the clean operation once - this._isClean = true; + this.#isClean = true; cleanLogger.terminal.writeVerboseLine(`Finished clean (${performance.now() - startTime}ms)`); diff --git a/apps/heft/src/operations/runners/TaskOperationRunner.ts b/apps/heft/src/operations/runners/TaskOperationRunner.ts index 5cdd397d9b4..30bf1ab1f8d 100644 --- a/apps/heft/src/operations/runners/TaskOperationRunner.ts +++ b/apps/heft/src/operations/runners/TaskOperationRunner.ts @@ -60,25 +60,25 @@ export async function runAndMeasureAsync( } export class TaskOperationRunner implements IOperationRunner { - private readonly _options: ITaskOperationRunnerOptions; + readonly #options: ITaskOperationRunnerOptions; - private _fileOperations: IHeftTaskFileOperations | undefined = undefined; - private _copyConfigHash: string | undefined; - private _watchFileSystemAdapter: WatchFileSystemAdapter | undefined = undefined; + #fileOperations: IHeftTaskFileOperations | undefined = undefined; + #copyConfigHash: string | undefined; + #watchFileSystemAdapter: WatchFileSystemAdapter | undefined = undefined; public readonly silent: boolean = false; public get name(): string { - const { taskName, parentPhase } = this._options.task; + const { taskName, parentPhase } = this.#options.task; return `Task ${JSON.stringify(taskName)} of phase ${JSON.stringify(parentPhase.phaseName)}`; } public constructor(options: ITaskOperationRunnerOptions) { - this._options = options; + this.#options = options; } public async executeAsync(context: IOperationRunnerContext): Promise { - const { internalHeftSession, task } = this._options; + const { internalHeftSession, task } = this.#options; const { parentPhase } = task; const phaseSession: HeftPhaseSession = internalHeftSession.getSessionForPhase(parentPhase); const taskSession: HeftTaskSession = phaseSession.getSessionForTask(task); @@ -96,7 +96,7 @@ export class TaskOperationRunner implements IOperationRunner { // if this is an immediate rerun logger.resetErrorsAndWarnings(); - const rootFolderPath: string = this._options.internalHeftSession.heftConfiguration.buildFolderPath; + const rootFolderPath: string = this.#options.internalHeftSession.heftConfiguration.buildFolderPath; const isWatchMode: boolean = taskSession.parameters.watch && !!requestRun; const { terminal } = logger; @@ -106,7 +106,7 @@ export class TaskOperationRunner implements IOperationRunner { return OperationStatus.Aborted; } - if (!this._fileOperations && hooks.registerFileOperations.isUsed()) { + if (!this.#fileOperations && hooks.registerFileOperations.isUsed()) { const fileOperations: IHeftTaskFileOperations = await hooks.registerFileOperations.promise({ copyOperations: new Set(), deleteOperations: new Set() @@ -135,22 +135,22 @@ export class TaskOperationRunner implements IOperationRunner { copyConfigHash = hasher.digest('base64'); } - this._fileOperations = fileOperations; - this._copyConfigHash = copyConfigHash; + this.#fileOperations = fileOperations; + this.#copyConfigHash = copyConfigHash; } const shouldRunIncremental: boolean = isWatchMode && hooks.runIncremental.isUsed(); let watchFileSystemAdapter: WatchFileSystemAdapter | undefined; const getWatchFileSystemAdapter = (): WatchFileSystemAdapter => { if (!watchFileSystemAdapter) { - watchFileSystemAdapter = this._watchFileSystemAdapter ||= new WatchFileSystemAdapter(); + watchFileSystemAdapter = this.#watchFileSystemAdapter ||= new WatchFileSystemAdapter(); watchFileSystemAdapter.setBaseline(); } return watchFileSystemAdapter; }; const shouldRun: boolean = hooks.run.isUsed() || shouldRunIncremental; - if (!shouldRun && !this._fileOperations) { + if (!shouldRun && !this.#fileOperations) { terminal.writeVerboseLine('Task execution skipped, no implementation provided'); return OperationStatus.NoOp; } @@ -211,9 +211,9 @@ export class TaskOperationRunner implements IOperationRunner { : // This branch only occurs if only file operations are defined. OperationStatus.Success; - if (this._fileOperations) { - const { copyOperations, deleteOperations } = this._fileOperations; - const copyConfigHash: string | undefined = this._copyConfigHash; + if (this.#fileOperations) { + const { copyOperations, deleteOperations } = this.#fileOperations; + const copyConfigHash: string | undefined = this.#copyConfigHash; await Promise.all([ copyConfigHash diff --git a/apps/heft/src/pluginFramework/HeftLifecycle.ts b/apps/heft/src/pluginFramework/HeftLifecycle.ts index b762e23f238..fa9682904db 100644 --- a/apps/heft/src/pluginFramework/HeftLifecycle.ts +++ b/apps/heft/src/pluginFramework/HeftLifecycle.ts @@ -34,30 +34,30 @@ export interface IHeftLifecycleContext { } export class HeftLifecycle extends HeftPluginHost { - private readonly _internalHeftSession: InternalHeftSession; - private readonly _lifecyclePluginSpecifiers: IHeftConfigurationJsonPluginSpecifier[]; - private readonly _lifecycleHooks: IHeftLifecycleHooks; - private readonly _lifecycleContextByDefinition: Map = + readonly #internalHeftSession: InternalHeftSession; + readonly #lifecyclePluginSpecifiers: IHeftConfigurationJsonPluginSpecifier[]; + readonly #lifecycleHooks: IHeftLifecycleHooks; + readonly #lifecycleContextByDefinition: Map = new Map(); - private readonly _lifecyclePluginsByDefinition: Map< + readonly #lifecyclePluginsByDefinition: Map< HeftLifecyclePluginDefinition, IHeftLifecyclePlugin > = new Map(); - private _lifecycleLogger: ScopedLogger | undefined; + #lifecycleLogger: ScopedLogger | undefined; - private _isInitialized: boolean = false; + #isInitialized: boolean = false; public get hooks(): IHeftLifecycleHooks { - return this._lifecycleHooks; + return this.#lifecycleHooks; } public get pluginDefinitions(): Iterable { - if (!this._isInitialized) { + if (!this.#isInitialized) { throw new InternalError( 'HeftLifecycle.ensureInitializedAsync() must be called before accessing HeftLifecycle.pluginDefinitions.' ); } - return this._lifecycleContextByDefinition.keys(); + return this.#lifecycleContextByDefinition.keys(); } public constructor( @@ -65,10 +65,10 @@ export class HeftLifecycle extends HeftPluginHost { lifecyclePluginSpecifiers: IHeftConfigurationJsonPluginSpecifier[] ) { super(); - this._internalHeftSession = internalHeftSession; - this._lifecyclePluginSpecifiers = lifecyclePluginSpecifiers; + this.#internalHeftSession = internalHeftSession; + this.#lifecyclePluginSpecifiers = lifecyclePluginSpecifiers; - this._lifecycleHooks = { + this.#lifecycleHooks = { clean: new AsyncParallelHook(), toolStart: new AsyncParallelHook(), toolFinish: new AsyncParallelHook(), @@ -85,20 +85,20 @@ export class HeftLifecycle extends HeftPluginHost { // Load up all plugins concurrently const loadPluginPromises: Promise>[] = []; - for (const [pluginDefinition, lifecycleContext] of this._lifecycleContextByDefinition) { + for (const [pluginDefinition, lifecycleContext] of this.#lifecycleContextByDefinition) { if (!lifecycleContext.lifecycleSession) { // Generate the plugin-specific session lifecycleContext.lifecycleSession = new HeftLifecycleSession({ - debug: this._internalHeftSession.debug, - heftConfiguration: this._internalHeftSession.heftConfiguration, - loggingManager: this._internalHeftSession.loggingManager, - metricsCollector: this._internalHeftSession.metricsCollector, - logger: this._internalHeftSession.loggingManager.requestScopedLogger( + debug: this.#internalHeftSession.debug, + heftConfiguration: this.#internalHeftSession.heftConfiguration, + loggingManager: this.#internalHeftSession.loggingManager, + metricsCollector: this.#internalHeftSession.metricsCollector, + logger: this.#internalHeftSession.loggingManager.requestScopedLogger( `lifecycle:${pluginDefinition.pluginName}` ), lifecycleHooks: this.hooks, lifecycleParameters: - this._internalHeftSession.parameterManager.getParametersForPlugin(pluginDefinition), + this.#internalHeftSession.parameterManager.getParametersForPlugin(pluginDefinition), pluginDefinition: pluginDefinition, pluginHost: this }); @@ -113,13 +113,13 @@ export class HeftLifecycle extends HeftPluginHost { // Iterate through and apply the plugins let pluginIndex: number = 0; - for (const [pluginDefinition, lifecycleContext] of this._lifecycleContextByDefinition) { + for (const [pluginDefinition, lifecycleContext] of this.#lifecycleContextByDefinition) { const lifecyclePlugin: IHeftLifecyclePlugin = plugins[pluginIndex++]; try { // Apply the plugin. We know the session should exist because we generated it above. lifecyclePlugin.apply( lifecycleContext.lifecycleSession!, - this._internalHeftSession.heftConfiguration, + this.#internalHeftSession.heftConfiguration, lifecycleContext.pluginOptions ); } catch (error) { @@ -132,19 +132,19 @@ export class HeftLifecycle extends HeftPluginHost { // Do a second pass to apply the plugin access requests for each plugin pluginIndex = 0; - for (const [pluginDefinition] of this._lifecycleContextByDefinition) { + for (const [pluginDefinition] of this.#lifecycleContextByDefinition) { const lifecyclePlugin: IHeftLifecyclePlugin = plugins[pluginIndex++]; this.resolvePluginAccessRequests(lifecyclePlugin, pluginDefinition); } } public async ensureInitializedAsync(): Promise { - if (!this._isInitialized) { - this._isInitialized = true; + if (!this.#isInitialized) { + this.#isInitialized = true; // Load up all plugin configurations concurrently const pluginConfigurationPromises: Promise[] = []; - for (const pluginSpecifier of this._lifecyclePluginSpecifiers) { + for (const pluginSpecifier of this.#lifecyclePluginSpecifiers) { const { pluginPackageRoot, pluginPackage } = pluginSpecifier; pluginConfigurationPromises.push( HeftPluginConfiguration.loadFromPackageAsync(pluginPackageRoot, pluginPackage) @@ -156,7 +156,7 @@ export class HeftLifecycle extends HeftPluginHost { // Iterate through and generate the lifecycle context for each plugin let pluginConfigurationIndex: number = 0; - for (const pluginSpecifier of this._lifecyclePluginSpecifiers) { + for (const pluginSpecifier of this.#lifecyclePluginSpecifiers) { const pluginConfiguration: HeftPluginConfiguration = pluginConfigurations[pluginConfigurationIndex++]; const pluginDefinition: HeftPluginDefinitionBase = pluginConfiguration.getPluginDefinitionBySpecifier(pluginSpecifier); @@ -171,7 +171,7 @@ export class HeftLifecycle extends HeftPluginHost { } // Ensure there are no duplicate plugin names within the same package - if (this._lifecycleContextByDefinition.has(pluginDefinition)) { + if (this.#lifecycleContextByDefinition.has(pluginDefinition)) { throw new Error( `Lifecycle plugin ${JSON.stringify(pluginDefinition.pluginName)} from package ` + `${JSON.stringify(pluginSpecifier.pluginPackage)} cannot be specified more than once.` @@ -184,16 +184,16 @@ export class HeftLifecycle extends HeftPluginHost { // Partially populate the context. The session will be populated while applying the plugins. const lifecycleContext: IHeftLifecycleContext = { pluginOptions }; - this._lifecycleContextByDefinition.set(pluginDefinition, lifecycleContext); + this.#lifecycleContextByDefinition.set(pluginDefinition, lifecycleContext); } } } public get lifecycleLogger(): ScopedLogger { - let logger: ScopedLogger | undefined = this._lifecycleLogger; + let logger: ScopedLogger | undefined = this.#lifecycleLogger; if (!logger) { - logger = this._internalHeftSession.loggingManager.requestScopedLogger(`lifecycle`); - this._lifecycleLogger = logger; + logger = this.#internalHeftSession.loggingManager.requestScopedLogger(`lifecycle`); + this.#lifecycleLogger = logger; } return logger; } @@ -203,7 +203,7 @@ export class HeftLifecycle extends HeftPluginHost { ): Promise { await this.ensureInitializedAsync(); const lifecycleContext: IHeftLifecycleContext | undefined = - this._lifecycleContextByDefinition.get(pluginDefinition); + this.#lifecycleContextByDefinition.get(pluginDefinition); if (!lifecycleContext) { throw new InternalError( `Could not find lifecycle context for plugin ${JSON.stringify(pluginDefinition.pluginName)}.` @@ -224,10 +224,10 @@ export class HeftLifecycle extends HeftPluginHost { lifecycleSession: IHeftLifecycleSession ): Promise> { let lifecyclePlugin: IHeftPlugin | undefined = - this._lifecyclePluginsByDefinition.get(pluginDefinition); + this.#lifecyclePluginsByDefinition.get(pluginDefinition); if (!lifecyclePlugin) { lifecyclePlugin = await pluginDefinition.loadPluginAsync(lifecycleSession.logger); - this._lifecyclePluginsByDefinition.set(pluginDefinition, lifecyclePlugin); + this.#lifecyclePluginsByDefinition.set(pluginDefinition, lifecyclePlugin); } return lifecyclePlugin; } diff --git a/apps/heft/src/pluginFramework/HeftLifecycleSession.ts b/apps/heft/src/pluginFramework/HeftLifecycleSession.ts index 92d30a13fac..96c26a875b1 100644 --- a/apps/heft/src/pluginFramework/HeftLifecycleSession.ts +++ b/apps/heft/src/pluginFramework/HeftLifecycleSession.ts @@ -214,8 +214,8 @@ export interface IHeftLifecycleSessionOptions extends IInternalHeftSessionOption } export class HeftLifecycleSession implements IHeftLifecycleSession { - private _options: IHeftLifecycleSessionOptions; - private _pluginHost: HeftPluginHost; + #options: IHeftLifecycleSessionOptions; + #pluginHost: HeftPluginHost; public readonly hooks: IHeftLifecycleHooks; public readonly parameters: IHeftParameters; @@ -229,7 +229,7 @@ export class HeftLifecycleSession implements IHeftLifecycleSession { public readonly metricsCollector: MetricsCollector; public constructor(options: IHeftLifecycleSessionOptions) { - this._options = options; + this.#options = options; const { logger, metricsCollector, lifecycleHooks, lifecycleParameters, debug, pluginDefinition, heftConfiguration, pluginHost } = options; this.logger = logger; @@ -245,7 +245,7 @@ export class HeftLifecycleSession implements IHeftLifecycleSession { // /temp/. this.tempFolderPath = path.join(heftConfiguration.tempFolderPath, uniquePluginFolderName); - this._pluginHost = pluginHost; + this.#pluginHost = pluginHost; } public requestAccessToPluginByName( @@ -253,9 +253,9 @@ export class HeftLifecycleSession implements IHeftLifecycleSession { pluginToAccessName: string, pluginApply: (pluginAccessor: T) => void ): void { - const { pluginPackageName, pluginName } = this._options.pluginDefinition; - const pluginHookName: string = this._pluginHost.getPluginHookName(pluginPackageName, pluginName); - this._pluginHost.requestAccessToPluginByName( + const { pluginPackageName, pluginName } = this.#options.pluginDefinition; + const pluginHookName: string = this.#pluginHost.getPluginHookName(pluginPackageName, pluginName); + this.#pluginHost.requestAccessToPluginByName( pluginHookName, pluginToAccessPackage, pluginToAccessName, diff --git a/apps/heft/src/pluginFramework/HeftParameterManager.ts b/apps/heft/src/pluginFramework/HeftParameterManager.ts index edf79c00fd4..8a0cd4defee 100644 --- a/apps/heft/src/pluginFramework/HeftParameterManager.ts +++ b/apps/heft/src/pluginFramework/HeftParameterManager.ts @@ -134,38 +134,38 @@ export interface IHeftParameterManagerOptions { } export class HeftParameterManager { - private readonly _options: IHeftParameterManagerOptions; + readonly #options: IHeftParameterManagerOptions; // plugin definition => parameter accessors and defaults - private readonly _heftParametersByDefinition: Map = new Map(); + readonly #heftParametersByDefinition: Map = new Map(); // plugin definition => Map< parameter long name => applied parameter > - private readonly _parametersByDefinition: Map> = + readonly #parametersByDefinition: Map> = new Map(); // parameter scope => plugin definition - private readonly _pluginDefinitionsByScope: Map = new Map(); + readonly #pluginDefinitionsByScope: Map = new Map(); - private _isFinalized: boolean = false; + #isFinalized: boolean = false; - private _defaultParameters: IHeftDefaultParameters | undefined; + #defaultParameters: IHeftDefaultParameters | undefined; public get defaultParameters(): IHeftDefaultParameters { - if (!this._isFinalized) { + if (!this.#isFinalized) { throw new InternalError('Parameters have not yet been finalized.'); } - if (!this._defaultParameters) { - this._defaultParameters = { - clean: this._options.getIsClean(), - debug: this._options.getIsDebug(), - verbose: this._options.getIsVerbose(), - production: this._options.getIsProduction(), - locales: this._options.getLocales(), - watch: this._options.getIsWatch() + if (!this.#defaultParameters) { + this.#defaultParameters = { + clean: this.#options.getIsClean(), + debug: this.#options.getIsDebug(), + verbose: this.#options.getIsVerbose(), + production: this.#options.getIsProduction(), + locales: this.#options.getLocales(), + watch: this.#options.getIsWatch() }; } - return this._defaultParameters; + return this.#defaultParameters; } public constructor(options: IHeftParameterManagerOptions) { - this._options = options; + this.#options = options; } /** @@ -173,11 +173,11 @@ export class HeftParameterManager { * command line parameter provider after finalization. */ public addPluginParameters(pluginDefinition: HeftPluginDefinitionBase): void { - if (this._isFinalized) { + if (this.#isFinalized) { throw new InternalError('Parameters have already been finalized.'); } - if (!this._parametersByDefinition.has(pluginDefinition)) { - this._parametersByDefinition.set(pluginDefinition, new Map()); + if (!this.#parametersByDefinition.has(pluginDefinition)) { + this.#parametersByDefinition.set(pluginDefinition, new Map()); } } @@ -186,11 +186,11 @@ export class HeftParameterManager { * can only be finalized once. */ public finalizeParameters(commandLineParameterProvider: CommandLineParameterProvider): void { - if (this._isFinalized) { + if (this.#isFinalized) { throw new InternalError('Parameters have already been finalized.'); } - this._isFinalized = true; - for (const pluginDefinition of this._parametersByDefinition.keys()) { + this.#isFinalized = true; + for (const pluginDefinition of this.#parametersByDefinition.keys()) { this._addParametersToProvider(pluginDefinition, commandLineParameterProvider); } } @@ -199,14 +199,14 @@ export class HeftParameterManager { * Get the finalized parameters for the specified plugin definition. */ public getParametersForPlugin(pluginDefinition: HeftPluginDefinitionBase): IHeftParameters { - if (!this._isFinalized) { + if (!this.#isFinalized) { throw new InternalError('Parameters have not yet been finalized.'); } - let heftParameters: IHeftParameters | undefined = this._heftParametersByDefinition.get(pluginDefinition); + let heftParameters: IHeftParameters | undefined = this.#heftParametersByDefinition.get(pluginDefinition); if (!heftParameters) { const parameters: Map | undefined = - this._parametersByDefinition.get(pluginDefinition); + this.#parametersByDefinition.get(pluginDefinition); if (!parameters) { throw new InternalError( `Parameters from plugin ${JSON.stringify(pluginDefinition.pluginName)} in package ` + @@ -232,7 +232,7 @@ export class HeftParameterManager { getStringListParameter: (parameterLongName: string) => this._getParameter(parameters, parameterLongName, CommandLineParameterKind.StringList) }; - this._heftParametersByDefinition.set(pluginDefinition, heftParameters); + this.#heftParametersByDefinition.set(pluginDefinition, heftParameters); } return heftParameters; } @@ -255,7 +255,7 @@ export class HeftParameterManager { pluginParameters } = pluginDefinition; const existingDefinitionWithScope: HeftPluginDefinitionBase | undefined = - this._pluginDefinitionsByScope.get(parameterScope); + this.#pluginDefinitionsByScope.get(parameterScope); if (existingDefinitionWithScope && existingDefinitionWithScope !== pluginDefinition) { const { pluginName: existingScopePluginName, pluginPackageName: existingScopePluginPackageName } = existingDefinitionWithScope; @@ -267,11 +267,11 @@ export class HeftParameterManager { `${JSON.stringify(existingScopePluginPackageName)}.` ); } else { - this._pluginDefinitionsByScope.set(parameterScope, pluginDefinition); + this.#pluginDefinitionsByScope.set(parameterScope, pluginDefinition); } const definedPluginParametersByName: Map = - this._parametersByDefinition.get(pluginDefinition)!; + this.#parametersByDefinition.get(pluginDefinition)!; for (const parameter of pluginParameters) { let definedParameter: CommandLineParameter; diff --git a/apps/heft/src/pluginFramework/HeftPhase.ts b/apps/heft/src/pluginFramework/HeftPhase.ts index e7ac8e65ca6..541a2237870 100644 --- a/apps/heft/src/pluginFramework/HeftPhase.ts +++ b/apps/heft/src/pluginFramework/HeftPhase.ts @@ -25,23 +25,23 @@ export interface IHeftPhase { * @internal */ export class HeftPhase implements IHeftPhase { - private _internalHeftSession: InternalHeftSession; - private _phaseName: string; - private _phaseSpecifier: IHeftConfigurationJsonPhaseSpecifier; - private _consumingPhases: Set | undefined; - private _dependencyPhases: Set | undefined; - private _cleanFiles: Set | undefined; - private _tasks: Set | undefined; - private _tasksByName: Map | undefined; + #internalHeftSession: InternalHeftSession; + #phaseName: string; + #phaseSpecifier: IHeftConfigurationJsonPhaseSpecifier; + #consumingPhases: Set | undefined; + #dependencyPhases: Set | undefined; + #cleanFiles: Set | undefined; + #tasks: Set | undefined; + #tasksByName: Map | undefined; public constructor( internalHeftSession: InternalHeftSession, phaseName: string, phaseSpecifier: IHeftConfigurationJsonPhaseSpecifier ) { - this._internalHeftSession = internalHeftSession; - this._phaseName = phaseName; - this._phaseSpecifier = phaseSpecifier; + this.#internalHeftSession = internalHeftSession; + this.#phaseName = phaseName; + this.#phaseSpecifier = phaseSpecifier; this._validate(); } @@ -50,61 +50,61 @@ export class HeftPhase implements IHeftPhase { * The name of the phase. */ public get phaseName(): string { - return this._phaseName; + return this.#phaseName; } /** * The description of the phase. */ public get phaseDescription(): string | undefined { - return this._phaseSpecifier.phaseDescription; + return this.#phaseSpecifier.phaseDescription; } /** * Returns delete operations that are specified on the phase. */ public get cleanFiles(): ReadonlySet { - if (!this._cleanFiles) { - this._cleanFiles = new Set(this._phaseSpecifier.cleanFiles || []); + if (!this.#cleanFiles) { + this.#cleanFiles = new Set(this.#phaseSpecifier.cleanFiles || []); } - return this._cleanFiles; + return this.#cleanFiles; } /** * Returns the set of phases that depend on this phase. */ public get consumingPhases(): ReadonlySet { - if (!this._consumingPhases) { + if (!this.#consumingPhases) { // Force initialize all dependency relationships // This needs to operate on every phase in the set because the relationships are only specified // in the consuming phase. - const { phases } = this._internalHeftSession; + const { phases } = this.#internalHeftSession; for (const phase of phases) { - phase._consumingPhases = new Set(); + phase.#consumingPhases = new Set(); } for (const phase of phases) { for (const dependency of phase.dependencyPhases) { - dependency._consumingPhases!.add(phase); + dependency.#consumingPhases!.add(phase); } } } - return this._consumingPhases!; + return this.#consumingPhases!; } /** * Returns the set of phases that this phase depends on. */ public get dependencyPhases(): ReadonlySet { - let dependencyPhases: Set | undefined = this._dependencyPhases; + let dependencyPhases: Set | undefined = this.#dependencyPhases; if (!dependencyPhases) { - this._dependencyPhases = dependencyPhases = new Set(); - const dependencyNamesSet: Set = new Set(this._phaseSpecifier.phaseDependencies || []); + this.#dependencyPhases = dependencyPhases = new Set(); + const dependencyNamesSet: Set = new Set(this.#phaseSpecifier.phaseDependencies || []); for (const dependencyName of dependencyNamesSet) { // Skip if we can't find the dependency const dependencyPhase: HeftPhase | undefined = - this._internalHeftSession.phasesByName.get(dependencyName); + this.#internalHeftSession.phasesByName.get(dependencyName); if (!dependencyPhase) { throw new Error(`Could not find dependency phase ${JSON.stringify(dependencyName)}.`); } @@ -119,7 +119,7 @@ export class HeftPhase implements IHeftPhase { */ public get tasks(): ReadonlySet { this._ensureTasks(); - return this._tasks!; + return this.#tasks!; } /** @@ -127,17 +127,17 @@ export class HeftPhase implements IHeftPhase { */ public get tasksByName(): ReadonlyMap { this._ensureTasks(); - return this._tasksByName!; + return this.#tasksByName!; } private _ensureTasks(): void { - if (!this._tasks || !this._tasksByName) { - this._tasks = new Set(); - this._tasksByName = new Map(); - for (const [taskName, taskSpecifier] of Object.entries(this._phaseSpecifier.tasksByName || {})) { + if (!this.#tasks || !this.#tasksByName) { + this.#tasks = new Set(); + this.#tasksByName = new Map(); + for (const [taskName, taskSpecifier] of Object.entries(this.#phaseSpecifier.tasksByName || {})) { const task: HeftTask = new HeftTask(this, taskName, taskSpecifier); - this._tasks.add(task); - this._tasksByName.set(taskName, task); + this.#tasks.add(task); + this.#tasksByName.set(taskName, task); } } } diff --git a/apps/heft/src/pluginFramework/HeftPhaseSession.ts b/apps/heft/src/pluginFramework/HeftPhaseSession.ts index 4482827883a..13f8b96fab7 100644 --- a/apps/heft/src/pluginFramework/HeftPhaseSession.ts +++ b/apps/heft/src/pluginFramework/HeftPhaseSession.ts @@ -19,12 +19,12 @@ export class HeftPhaseSession extends HeftPluginHost { public readonly phaseLogger: ScopedLogger; public readonly cleanLogger: ScopedLogger; - private readonly _options: IHeftPhaseSessionOptions; - private readonly _taskSessionsByTask: Map = new Map(); + readonly #options: IHeftPhaseSessionOptions; + readonly #taskSessionsByTask: Map = new Map(); public constructor(options: IHeftPhaseSessionOptions) { super(); - this._options = options; + this.#options = options; const loggingManager: LoggingManager = options.internalHeftSession.loggingManager; this.phaseLogger = loggingManager.requestScopedLogger(options.phase.phaseName); @@ -35,14 +35,14 @@ export class HeftPhaseSession extends HeftPluginHost { * Get a task session for the given task. */ public getSessionForTask(task: HeftTask): HeftTaskSession { - let taskSession: HeftTaskSession | undefined = this._taskSessionsByTask.get(task); + let taskSession: HeftTaskSession | undefined = this.#taskSessionsByTask.get(task); if (!taskSession) { taskSession = new HeftTaskSession({ - ...this._options, + ...this.#options, task, pluginHost: this }); - this._taskSessionsByTask.set(task, taskSession); + this.#taskSessionsByTask.set(task, taskSession); } return taskSession; } @@ -54,7 +54,7 @@ export class HeftPhaseSession extends HeftPluginHost { const { internalHeftSession: { heftConfiguration }, phase: { tasks } - } = this._options; + } = this.#options; // Load up all plugins concurrently const loadPluginPromises: Promise>[] = []; diff --git a/apps/heft/src/pluginFramework/HeftPluginHost.ts b/apps/heft/src/pluginFramework/HeftPluginHost.ts index 9f3dad8edcc..df957c3f613 100644 --- a/apps/heft/src/pluginFramework/HeftPluginHost.ts +++ b/apps/heft/src/pluginFramework/HeftPluginHost.ts @@ -11,17 +11,17 @@ import type { IHeftPlugin } from './IHeftPlugin'; export abstract class HeftPluginHost { // eslint-disable-next-line @typescript-eslint/no-explicit-any - private readonly _pluginAccessRequestHooks: Map> = new Map(); - private _pluginsApplied: boolean = false; + readonly #pluginAccessRequestHooks: Map> = new Map(); + #pluginsApplied: boolean = false; public async applyPluginsAsync(terminal: ITerminal): Promise { - if (this._pluginsApplied) { + if (this.#pluginsApplied) { // No need to apply them a second time. return; } terminal.writeVerboseLine('Applying plugins'); await this.applyPluginsInternalAsync(); - this._pluginsApplied = true; + this.#pluginsApplied = true; } protected abstract applyPluginsInternalAsync(): Promise; @@ -35,7 +35,7 @@ export abstract class HeftPluginHost { pluginToAccessName: string, accessorCallback: (pluginAccessor: T) => void ): void { - if (this._pluginsApplied) { + if (this.#pluginsApplied) { throw new Error( `Requestor ${JSON.stringify(requestorName)} cannot request access to plugin ` + `${JSON.stringify(pluginToAccessName)} from package ${JSON.stringify(pluginToAccessPackage)} ` + @@ -44,10 +44,10 @@ export abstract class HeftPluginHost { } const pluginHookName: string = this.getPluginHookName(pluginToAccessPackage, pluginToAccessName); - let pluginAccessRequestHook: SyncHook | undefined = this._pluginAccessRequestHooks.get(pluginHookName); + let pluginAccessRequestHook: SyncHook | undefined = this.#pluginAccessRequestHooks.get(pluginHookName); if (!pluginAccessRequestHook) { pluginAccessRequestHook = new SyncHook(['pluginAccessor']); - this._pluginAccessRequestHooks.set(pluginHookName, pluginAccessRequestHook); + this.#pluginAccessRequestHooks.set(pluginHookName, pluginAccessRequestHook); } if (pluginAccessRequestHook.taps.some((t) => t.name === requestorName)) { throw new Error( @@ -74,7 +74,7 @@ export abstract class HeftPluginHost { plugin: IHeftPlugin, pluginDefinition: HeftPluginDefinitionBase ): void { - if (this._pluginsApplied) { + if (this.#pluginsApplied) { throw new InternalError('Cannot resolve plugin access requests after plugins have been applied.'); } const pluginHookName: string = this.getPluginHookName( @@ -82,7 +82,7 @@ export abstract class HeftPluginHost { pluginDefinition.pluginName ); const pluginAccessRequestHook: SyncHook | undefined = - this._pluginAccessRequestHooks.get(pluginHookName); + this.#pluginAccessRequestHooks.get(pluginHookName); if (pluginAccessRequestHook?.isUsed()) { const accessor: object | undefined = plugin.accessor; if (accessor) { diff --git a/apps/heft/src/pluginFramework/HeftTask.ts b/apps/heft/src/pluginFramework/HeftTask.ts index d5f098bd1d8..a1813197f9c 100644 --- a/apps/heft/src/pluginFramework/HeftTask.ts +++ b/apps/heft/src/pluginFramework/HeftTask.ts @@ -32,75 +32,75 @@ export interface IHeftTask { * @internal */ export class HeftTask implements IHeftTask { - private _parentPhase: HeftPhase; - private _taskName: string; - private _taskSpecifier: IHeftConfigurationJsonTaskSpecifier; - private _consumingTasks: Set | undefined; - private _dependencyTasks: Set | undefined; + #parentPhase: HeftPhase; + #taskName: string; + #taskSpecifier: IHeftConfigurationJsonTaskSpecifier; + #consumingTasks: Set | undefined; + #dependencyTasks: Set | undefined; - private _taskPluginDefinition: HeftTaskPluginDefinition | undefined; - private _taskPlugin: IHeftTaskPlugin | undefined; + #taskPluginDefinition: HeftTaskPluginDefinition | undefined; + #taskPlugin: IHeftTaskPlugin | undefined; public get parentPhase(): HeftPhase { - return this._parentPhase; + return this.#parentPhase; } public get taskName(): string { - return this._taskName; + return this.#taskName; } public get consumingTasks(): ReadonlySet { - if (!this._consumingTasks) { + if (!this.#consumingTasks) { // Force initialize all dependency relationships // This needs to operate on every phase in the set because the relationships are only specified // in the consuming phase. - const { tasks } = this._parentPhase; + const { tasks } = this.#parentPhase; for (const task of tasks) { - task._consumingTasks = new Set(); + task.#consumingTasks = new Set(); } for (const task of tasks) { for (const dependency of task.dependencyTasks) { - dependency._consumingTasks!.add(task); + dependency.#consumingTasks!.add(task); } } } - return this._consumingTasks!; + return this.#consumingTasks!; } public get pluginDefinition(): HeftTaskPluginDefinition { - if (!this._taskPluginDefinition) { + if (!this.#taskPluginDefinition) { throw new InternalError( 'HeftTask.ensureInitializedAsync() must be called before accessing HeftTask.pluginDefinition.' ); } - return this._taskPluginDefinition; + return this.#taskPluginDefinition; } public get pluginOptions(): object | undefined { - return this._taskSpecifier.taskPlugin.options; + return this.#taskSpecifier.taskPlugin.options; } public get dependencyTasks(): Set { - if (!this._dependencyTasks) { - this._dependencyTasks = new Set(); - const dependencyNamesSet: Set = new Set(this._taskSpecifier.taskDependencies || []); + if (!this.#dependencyTasks) { + this.#dependencyTasks = new Set(); + const dependencyNamesSet: Set = new Set(this.#taskSpecifier.taskDependencies || []); for (const dependencyName of dependencyNamesSet) { // Skip if we can't find the dependency - const dependencyTask: HeftTask | undefined = this._parentPhase.tasksByName.get(dependencyName); + const dependencyTask: HeftTask | undefined = this.#parentPhase.tasksByName.get(dependencyName); if (!dependencyTask) { throw new Error( `Could not find dependency task ${JSON.stringify(dependencyName)} within phase ` + - `${JSON.stringify(this._parentPhase.phaseName)}.` + `${JSON.stringify(this.#parentPhase.phaseName)}.` ); } - this._dependencyTasks.add(dependencyTask); + this.#dependencyTasks.add(dependencyTask); } } - return this._dependencyTasks!; + return this.#dependencyTasks!; } public constructor( @@ -108,32 +108,32 @@ export class HeftTask implements IHeftTask { taskName: string, taskSpecifier: IHeftConfigurationJsonTaskSpecifier ) { - this._parentPhase = parentPhase; - this._taskName = taskName; - this._taskSpecifier = taskSpecifier; + this.#parentPhase = parentPhase; + this.#taskName = taskName; + this.#taskSpecifier = taskSpecifier; this._validate(); } public async ensureInitializedAsync(): Promise { - if (!this._taskPluginDefinition) { - this._taskPluginDefinition = await this._loadTaskPluginDefinitionAsync(); + if (!this.#taskPluginDefinition) { + this.#taskPluginDefinition = await this._loadTaskPluginDefinitionAsync(); this.pluginDefinition.validateOptions(this.pluginOptions); } } public async getPluginAsync(logger: IScopedLogger): Promise> { await this.ensureInitializedAsync(); - if (!this._taskPlugin) { - this._taskPlugin = await this._taskPluginDefinition!.loadPluginAsync(logger); + if (!this.#taskPlugin) { + this.#taskPlugin = await this.#taskPluginDefinition!.loadPluginAsync(logger); } - return this._taskPlugin; + return this.#taskPlugin; } private async _loadTaskPluginDefinitionAsync(): Promise { // taskPlugin.pluginPackage should already be resolved to the package root. // See CoreConfigFiles.heftConfigFileLoader - const pluginSpecifier: IHeftConfigurationJsonPluginSpecifier = this._taskSpecifier.taskPlugin; + const pluginSpecifier: IHeftConfigurationJsonPluginSpecifier = this.#taskSpecifier.taskPlugin; const pluginConfiguration: HeftPluginConfiguration = await HeftPluginConfiguration.loadFromPackageAsync( pluginSpecifier.pluginPackageRoot, pluginSpecifier.pluginPackage @@ -145,7 +145,7 @@ export class HeftTask implements IHeftTask { if (!isTaskPluginDefinition) { throw new Error( `Plugin ${JSON.stringify(pluginSpecifier.pluginName)} specified by task ` + - `${JSON.stringify(this._taskName)} is not a task plugin.` + `${JSON.stringify(this.#taskName)} is not a task plugin.` ); } return pluginDefinition; @@ -157,7 +157,7 @@ export class HeftTask implements IHeftTask { `Task name ${JSON.stringify(this.taskName)} is reserved and cannot be used as a task name.` ); } - if (!this._taskSpecifier.taskPlugin) { + if (!this.#taskSpecifier.taskPlugin) { throw new Error(`Task ${JSON.stringify(this.taskName)} has no specified task plugin.`); } } diff --git a/apps/heft/src/pluginFramework/HeftTaskSession.ts b/apps/heft/src/pluginFramework/HeftTaskSession.ts index 9898b11a492..aa06e38fcc1 100644 --- a/apps/heft/src/pluginFramework/HeftTaskSession.ts +++ b/apps/heft/src/pluginFramework/HeftTaskSession.ts @@ -238,9 +238,9 @@ export class HeftTaskSession implements IHeftTaskSession { public readonly tempFolderPath: string; public readonly logger: IScopedLogger; - private readonly _options: IHeftTaskSessionOptions; - private _parameters: IHeftParameters | undefined; - private _parsedCommandLine: IHeftParsedCommandLine; + readonly #options: IHeftTaskSessionOptions; + #parameters: IHeftParameters | undefined; + #parsedCommandLine: IHeftParsedCommandLine; /** * @internal @@ -249,16 +249,16 @@ export class HeftTaskSession implements IHeftTaskSession { public get parameters(): IHeftParameters { // Delay loading the parameters for the task until they're actually needed - if (!this._parameters) { - const parameterManager: HeftParameterManager = this._options.internalHeftSession.parameterManager; - const task: HeftTask = this._options.task; - this._parameters = parameterManager.getParametersForPlugin(task.pluginDefinition); + if (!this.#parameters) { + const parameterManager: HeftParameterManager = this.#options.internalHeftSession.parameterManager; + const task: HeftTask = this.#options.task; + this.#parameters = parameterManager.getParametersForPlugin(task.pluginDefinition); } - return this._parameters; + return this.#parameters; } public get parsedCommandLine(): IHeftParsedCommandLine { - return this._parsedCommandLine; + return this.#parsedCommandLine; } public constructor(options: IHeftTaskSessionOptions) { @@ -276,7 +276,7 @@ export class HeftTaskSession implements IHeftTaskSession { // This should not happen throw new InternalError('Attempt to construct HeftTaskSession before command line has been parsed'); } - this._parsedCommandLine = options.internalHeftSession.parsedCommandLine; + this.#parsedCommandLine = options.internalHeftSession.parsedCommandLine; this.logger = loggingManager.requestScopedLogger(`${phase.phaseName}:${task.taskName}`); this.metricsCollector = metricsCollector; @@ -298,7 +298,7 @@ export class HeftTaskSession implements IHeftTaskSession { // /temp// this.tempFolderPath = `${tempFolder}/${uniqueTaskFolderName}`; - this._options = options; + this.#options = options; } public requestAccessToPluginByName( @@ -306,7 +306,7 @@ export class HeftTaskSession implements IHeftTaskSession { pluginToAccessName: string, pluginApply: (pluginAccessor: T) => void ): void { - this._options.pluginHost.requestAccessToPluginByName( + this.#options.pluginHost.requestAccessToPluginByName( this.taskName, pluginToAccessPackage, pluginToAccessName, diff --git a/apps/heft/src/pluginFramework/InternalHeftSession.ts b/apps/heft/src/pluginFramework/InternalHeftSession.ts index 93905e3e94f..2296b1add7c 100644 --- a/apps/heft/src/pluginFramework/InternalHeftSession.ts +++ b/apps/heft/src/pluginFramework/InternalHeftSession.ts @@ -35,13 +35,13 @@ function* getAllTasks(phases: Iterable): IterableIterator { } export class InternalHeftSession { - private readonly _phaseSessionsByPhase: Map = new Map(); - private readonly _heftConfigurationJson: IHeftConfigurationJson; - private _actionReferencesByAlias: ReadonlyMap | undefined; - private _lifecycle: HeftLifecycle | undefined; - private _phases: Set | undefined; - private _phasesByName: Map | undefined; - private _parameterManager: HeftParameterManager | undefined; + readonly #phaseSessionsByPhase: Map = new Map(); + readonly #heftConfigurationJson: IHeftConfigurationJson; + #actionReferencesByAlias: ReadonlyMap | undefined; + #lifecycle: HeftLifecycle | undefined; + #phases: Set | undefined; + #phasesByName: Map | undefined; + #parameterManager: HeftParameterManager | undefined; public readonly heftConfiguration: HeftConfiguration; @@ -58,7 +58,7 @@ export class InternalHeftSession { this.loggingManager = options.loggingManager; this.metricsCollector = options.metricsCollector; this.debug = options.debug; - this._heftConfigurationJson = heftConfigurationJson; + this.#heftConfigurationJson = heftConfigurationJson; } public static async initializeAsync(options: IInternalHeftSessionOptions): Promise { @@ -118,61 +118,61 @@ export class InternalHeftSession { } public get parameterManager(): HeftParameterManager { - if (!this._parameterManager) { + if (!this.#parameterManager) { throw new InternalError('A parameter manager for the session has not been provided.'); } - return this._parameterManager; + return this.#parameterManager; } public set parameterManager(value: HeftParameterManager) { - this._parameterManager = value; + this.#parameterManager = value; } public get actionReferencesByAlias(): ReadonlyMap { - if (!this._actionReferencesByAlias) { - this._actionReferencesByAlias = new Map( - Object.entries(this._heftConfigurationJson.aliasesByName || {}) + if (!this.#actionReferencesByAlias) { + this.#actionReferencesByAlias = new Map( + Object.entries(this.#heftConfigurationJson.aliasesByName || {}) ); } - return this._actionReferencesByAlias; + return this.#actionReferencesByAlias; } public get lifecycle(): HeftLifecycle { - if (!this._lifecycle) { - this._lifecycle = new HeftLifecycle(this, this._heftConfigurationJson.heftPlugins || []); + if (!this.#lifecycle) { + this.#lifecycle = new HeftLifecycle(this, this.#heftConfigurationJson.heftPlugins || []); } - return this._lifecycle; + return this.#lifecycle; } public get phases(): ReadonlySet { this._ensurePhases(); - return this._phases!; + return this.#phases!; } public get phasesByName(): ReadonlyMap { this._ensurePhases(); - return this._phasesByName!; + return this.#phasesByName!; } public getSessionForPhase(phase: HeftPhase): HeftPhaseSession { - let phaseSession: HeftPhaseSession | undefined = this._phaseSessionsByPhase.get(phase); + let phaseSession: HeftPhaseSession | undefined = this.#phaseSessionsByPhase.get(phase); if (!phaseSession) { phaseSession = new HeftPhaseSession({ internalHeftSession: this, phase }); - this._phaseSessionsByPhase.set(phase, phaseSession); + this.#phaseSessionsByPhase.set(phase, phaseSession); } return phaseSession; } private _ensurePhases(): void { - if (!this._phases || !this._phasesByName) { - this._phasesByName = new Map(); + if (!this.#phases || !this.#phasesByName) { + this.#phasesByName = new Map(); for (const [phaseName, phaseSpecifier] of Object.entries( - this._heftConfigurationJson.phasesByName || {} + this.#heftConfigurationJson.phasesByName || {} )) { const phase: HeftPhase = new HeftPhase(this, phaseName, phaseSpecifier); - this._phasesByName.set(phaseName, phase); + this.#phasesByName.set(phaseName, phase); } - this._phases = new Set(this._phasesByName.values()); + this.#phases = new Set(this.#phasesByName.values()); } } } diff --git a/apps/heft/src/pluginFramework/StaticFileSystemAdapter.ts b/apps/heft/src/pluginFramework/StaticFileSystemAdapter.ts index 89129078af2..cc4cc65f7fa 100644 --- a/apps/heft/src/pluginFramework/StaticFileSystemAdapter.ts +++ b/apps/heft/src/pluginFramework/StaticFileSystemAdapter.ts @@ -35,7 +35,7 @@ const IS_WINDOWS: boolean = process.platform === 'win32'; * required for filesystem traversal performed by the globber. */ export class StaticFileSystemAdapter implements FileSystemAdapter { - private _directoryMap: Map = new Map(); + #directoryMap: Map = new Map(); /** { @inheritdoc fs.lstat } */ public lstat: FileSystemAdapter['lstat'] = ((filePath: string, callback: StatCallback) => { @@ -55,7 +55,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { /** { @inheritdoc fs.lstatSync } */ public lstatSync: FileSystemAdapter['lstatSync'] = ((filePath: string) => { filePath = this._normalizePath(filePath); - const entry: IVirtualFileSystemEntry | undefined = this._directoryMap.get(filePath); + const entry: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(filePath); if (!entry) { const error: NodeJS.ErrnoException = new Error(`ENOENT: no such file or directory, stat '${filePath}'`); error.code = 'ENOENT'; @@ -127,7 +127,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { /** { @inheritdoc fs.readdirSync } */ public readdirSync: FileSystemAdapter['readdirSync'] = ((filePath: string, options?: IReaddirOptions) => { filePath = this._normalizePath(filePath); - const virtualDirectory: IVirtualFileSystemEntry | undefined = this._directoryMap.get(filePath); + const virtualDirectory: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(filePath); if (!virtualDirectory) { // Immitate a missing directory read from fs.readdir const error: NodeJS.ErrnoException = new Error( @@ -184,18 +184,18 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { */ public addFile(filePath: string): void { filePath = this._normalizePath(filePath); - const existingPath: IVirtualFileSystemEntry | undefined = this._directoryMap.get(filePath); + const existingPath: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(filePath); if (!existingPath) { // Set an entry without children for the file. Entries with undefined children are assumed to be files. let childPath: string = filePath; let childEntry: IVirtualFileSystemEntry = { name: path.basename(childPath) }; - this._directoryMap.set(childPath, childEntry); + this.#directoryMap.set(childPath, childEntry); // Loop through the path segments and create entries for each directory, if they don't already exist. // If they do, append to the existing children set and continue. let parentPath: string | undefined; while ((parentPath = path.dirname(childPath)) !== childPath) { - const existingParentEntry: IVirtualFileSystemEntry | undefined = this._directoryMap.get(parentPath); + const existingParentEntry: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(parentPath); if (existingParentEntry) { // If there is already an existing parent entry, add the child entry to the existing children set // and exit early, since the parent entries already exist. @@ -207,7 +207,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { name: path.basename(parentPath), children: new Set([childEntry]) }; - this._directoryMap.set(parentPath, parentEntry); + this.#directoryMap.set(parentPath, parentEntry); childEntry = parentEntry; childPath = parentPath; } @@ -220,11 +220,11 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { */ public removeFile(filePath: string): void { filePath = this._normalizePath(filePath); - const existingEntry: IVirtualFileSystemEntry | undefined = this._directoryMap.get(filePath); + const existingEntry: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(filePath); if (existingEntry) { // Remove the entry from the map and the parent's children set - this._directoryMap.delete(filePath); - this._directoryMap.get(path.dirname(filePath))!.children!.delete(existingEntry); + this.#directoryMap.delete(filePath); + this.#directoryMap.get(path.dirname(filePath))!.children!.delete(existingEntry); } } @@ -232,7 +232,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { * Remove all files from the static virtual filesystem. */ public removeAllFiles(): void { - this._directoryMap.clear(); + this.#directoryMap.clear(); } private _normalizePath(filePath: string): string { diff --git a/apps/heft/src/pluginFramework/logging/LoggingManager.ts b/apps/heft/src/pluginFramework/logging/LoggingManager.ts index 36c243a8084..c598d7a5ecb 100644 --- a/apps/heft/src/pluginFramework/logging/LoggingManager.ts +++ b/apps/heft/src/pluginFramework/logging/LoggingManager.ts @@ -14,49 +14,49 @@ export interface ILoggingManagerOptions { } export class LoggingManager { - private _options: ILoggingManagerOptions; - private _scopedLoggers: Map = new Map(); - private _shouldPrintStacks: boolean = false; - private _hasAnyWarnings: boolean = false; - private _hasAnyErrors: boolean = false; + #options: ILoggingManagerOptions; + #scopedLoggers: Map = new Map(); + #shouldPrintStacks: boolean = false; + #hasAnyWarnings: boolean = false; + #hasAnyErrors: boolean = false; public get errorsHaveBeenEmitted(): boolean { - return this._hasAnyErrors; + return this.#hasAnyErrors; } public get warningsHaveBeenEmitted(): boolean { - return this._hasAnyWarnings; + return this.#hasAnyWarnings; } public constructor(options: ILoggingManagerOptions) { - this._options = options; + this.#options = options; } public enablePrintStacks(): void { - this._shouldPrintStacks = true; + this.#shouldPrintStacks = true; } public resetScopedLoggerErrorsAndWarnings(): void { - this._hasAnyErrors = false; - this._hasAnyWarnings = false; - for (const scopedLogger of this._scopedLoggers.values()) { + this.#hasAnyErrors = false; + this.#hasAnyWarnings = false; + for (const scopedLogger of this.#scopedLoggers.values()) { scopedLogger.resetErrorsAndWarnings(); } } public requestScopedLogger(loggerName: string): ScopedLogger { - const existingScopedLogger: ScopedLogger | undefined = this._scopedLoggers.get(loggerName); + const existingScopedLogger: ScopedLogger | undefined = this.#scopedLoggers.get(loggerName); if (existingScopedLogger) { throw new Error(`A named logger with name ${JSON.stringify(loggerName)} has already been requested.`); } else { const scopedLogger: ScopedLogger = new ScopedLogger({ loggerName, - terminalProvider: this._options.terminalProvider, - getShouldPrintStacks: () => this._shouldPrintStacks, - errorHasBeenEmittedCallback: () => (this._hasAnyErrors = true), - warningHasBeenEmittedCallback: () => (this._hasAnyWarnings = true) + terminalProvider: this.#options.terminalProvider, + getShouldPrintStacks: () => this.#shouldPrintStacks, + errorHasBeenEmittedCallback: () => (this.#hasAnyErrors = true), + warningHasBeenEmittedCallback: () => (this.#hasAnyWarnings = true) }); - this._scopedLoggers.set(loggerName, scopedLogger); + this.#scopedLoggers.set(loggerName, scopedLogger); return scopedLogger; } } @@ -64,7 +64,7 @@ export class LoggingManager { public getErrorStrings(fileLocationStyle?: FileLocationStyle): string[] { const result: string[] = []; - for (const scopedLogger of this._scopedLoggers.values()) { + for (const scopedLogger of this.#scopedLoggers.values()) { result.push( ...scopedLogger.errors.map( (error) => @@ -80,7 +80,7 @@ export class LoggingManager { public getWarningStrings(fileErrorFormat?: FileLocationStyle): string[] { const result: string[] = []; - for (const scopedLogger of this._scopedLoggers.values()) { + for (const scopedLogger of this.#scopedLoggers.values()) { result.push( ...scopedLogger.warnings.map( (warning) => diff --git a/apps/heft/src/pluginFramework/logging/ScopedLogger.ts b/apps/heft/src/pluginFramework/logging/ScopedLogger.ts index 357289ecc5d..12cf26cf399 100644 --- a/apps/heft/src/pluginFramework/logging/ScopedLogger.ts +++ b/apps/heft/src/pluginFramework/logging/ScopedLogger.ts @@ -57,21 +57,21 @@ export interface IScopedLoggerOptions { } export class ScopedLogger implements IScopedLogger { - private readonly _options: IScopedLoggerOptions; - private _errors: Error[] = []; - private _warnings: Error[] = []; + readonly #options: IScopedLoggerOptions; + #errors: Error[] = []; + #warnings: Error[] = []; private get _shouldPrintStacks(): boolean { // TODO: Consider dumping stacks and more verbose logging to a file - return this._options.getShouldPrintStacks(); + return this.#options.getShouldPrintStacks(); } public get errors(): ReadonlyArray { - return [...this._errors]; + return [...this.#errors]; } public get warnings(): ReadonlyArray { - return [...this._warnings]; + return [...this.#warnings]; } public readonly loggerName: string; @@ -84,7 +84,7 @@ export class ScopedLogger implements IScopedLogger { * @internal */ public constructor(options: IScopedLoggerOptions) { - this._options = options; + this.#options = options; this.loggerName = options.loggerName; this.terminalProvider = new PrefixProxyTerminalProvider({ @@ -98,15 +98,15 @@ export class ScopedLogger implements IScopedLogger { * {@inheritdoc IScopedLogger.hasErrors} */ public get hasErrors(): boolean { - return this._errors.length > 0; + return this.#errors.length > 0; } /** * {@inheritdoc IScopedLogger.emitError} */ public emitError(error: Error): void { - this._options.errorHasBeenEmittedCallback(); - this._errors.push(error); + this.#options.errorHasBeenEmittedCallback(); + this.#errors.push(error); this.terminal.writeErrorLine(`Error: ${LoggingManager.getErrorMessage(error)}`); if (this._shouldPrintStacks && error.stack) { this.terminal.writeErrorLine(error.stack); @@ -117,8 +117,8 @@ export class ScopedLogger implements IScopedLogger { * {@inheritdoc IScopedLogger.emitWarning} */ public emitWarning(warning: Error): void { - this._options.warningHasBeenEmittedCallback(); - this._warnings.push(warning); + this.#options.warningHasBeenEmittedCallback(); + this.#warnings.push(warning); this.terminal.writeWarningLine(`Warning: ${LoggingManager.getErrorMessage(warning)}`); if (this._shouldPrintStacks && warning.stack) { this.terminal.writeWarningLine(warning.stack); @@ -129,7 +129,7 @@ export class ScopedLogger implements IScopedLogger { * {@inheritdoc IScopedLogger.resetErrorsAndWarnings} */ public resetErrorsAndWarnings(): void { - this._errors = []; - this._warnings = []; + this.#errors = []; + this.#warnings = []; } } diff --git a/apps/heft/src/plugins/NodeServicePlugin.ts b/apps/heft/src/plugins/NodeServicePlugin.ts index 40b2753f55f..35da94dfe6f 100644 --- a/apps/heft/src/plugins/NodeServicePlugin.ts +++ b/apps/heft/src/plugins/NodeServicePlugin.ts @@ -58,12 +58,12 @@ enum State { } export default class NodeServicePlugin implements IHeftTaskPlugin { - private _activeChildProcess: child_process.ChildProcess | undefined; - private _childProcessExitPromise: Promise | undefined; - private _childProcessExitPromiseResolveFn: (() => void) | undefined; - private _childProcessExitPromiseRejectFn: ((e: unknown) => void) | undefined; - private _state: State = State.Stopped; - private _logger!: IScopedLogger; + #activeChildProcess: child_process.ChildProcess | undefined; + #childProcessExitPromise: Promise | undefined; + #childProcessExitPromiseResolveFn: (() => void) | undefined; + #childProcessExitPromiseRejectFn: ((e: unknown) => void) | undefined; + #state: State = State.Stopped; + #logger!: IScopedLogger; /** * The state machine schedules at most one setInterval() timeout at any given time. It is for: @@ -71,28 +71,28 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { * - waitForTerminateMs in State.Stopping * - waitForKillMs in State.Killing */ - private _timeout: NodeJS.Timeout | undefined = undefined; + #timeout: NodeJS.Timeout | undefined = undefined; /** * The data read from the node-service.json config file, or "undefined" if the file is missing. */ - private _rawConfiguration: INodeServicePluginConfiguration | undefined = undefined; + #rawConfiguration: INodeServicePluginConfiguration | undefined = undefined; /** * The effective configuration, with defaults applied. */ - private _configuration!: INodeServicePluginCompleteConfiguration; + #configuration!: INodeServicePluginCompleteConfiguration; /** * The script body obtained from the "scripts" section in the project's package.json. */ - private _shellCommand: string | undefined; + #shellCommand: string | undefined; - private _pluginEnabled: boolean = false; + #pluginEnabled: boolean = false; public apply(taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration): void { // Set this immediately to make it available to the internal methods that use it - this._logger = taskSession.logger; + this.#logger = taskSession.logger; const isServeMode: boolean = taskSession.parameters.getFlagParameter(SERVE_PARAMETER_LONG_NAME).value; @@ -125,15 +125,15 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration ): Promise { - if (!this._rawConfiguration) { - this._rawConfiguration = await CoreConfigFiles.tryLoadNodeServiceConfigurationFileAsync( + if (!this.#rawConfiguration) { + this.#rawConfiguration = await CoreConfigFiles.tryLoadNodeServiceConfigurationFileAsync( taskSession.logger.terminal, heftConfiguration.buildFolderPath, heftConfiguration.rigConfig ); // defaults - this._configuration = { + this.#configuration = { commandName: 'serve', ignoreMissingScript: false, waitForTerminateMs: 2000, @@ -141,39 +141,39 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { }; // TODO: @rushstack/heft-config-file should be able to read a *.defaults.json file - if (this._rawConfiguration) { - this._pluginEnabled = true; + if (this.#rawConfiguration) { + this.#pluginEnabled = true; - if (this._rawConfiguration.commandName !== undefined) { - this._configuration.commandName = this._rawConfiguration.commandName; + if (this.#rawConfiguration.commandName !== undefined) { + this.#configuration.commandName = this.#rawConfiguration.commandName; } - if (this._rawConfiguration.ignoreMissingScript !== undefined) { - this._configuration.ignoreMissingScript = this._rawConfiguration.ignoreMissingScript; + if (this.#rawConfiguration.ignoreMissingScript !== undefined) { + this.#configuration.ignoreMissingScript = this.#rawConfiguration.ignoreMissingScript; } - if (this._rawConfiguration.waitForTerminateMs !== undefined) { - this._configuration.waitForTerminateMs = this._rawConfiguration.waitForTerminateMs; + if (this.#rawConfiguration.waitForTerminateMs !== undefined) { + this.#configuration.waitForTerminateMs = this.#rawConfiguration.waitForTerminateMs; } - if (this._rawConfiguration.waitForKillMs !== undefined) { - this._configuration.waitForKillMs = this._rawConfiguration.waitForKillMs; + if (this.#rawConfiguration.waitForKillMs !== undefined) { + this.#configuration.waitForKillMs = this.#rawConfiguration.waitForKillMs; } - this._shellCommand = (heftConfiguration.projectPackageJson.scripts || {})[ - this._configuration.commandName + this.#shellCommand = (heftConfiguration.projectPackageJson.scripts || {})[ + this.#configuration.commandName ]; - if (this._shellCommand === undefined) { - if (this._configuration.ignoreMissingScript) { + if (this.#shellCommand === undefined) { + if (this.#configuration.ignoreMissingScript) { taskSession.logger.terminal.writeLine( `The node service cannot be started because the project's package.json` + - ` does not have a "${this._configuration.commandName}" script` + ` does not have a "${this.#configuration.commandName}" script` ); } else { throw new Error( `The node service cannot be started because the project's package.json ` + - `does not have a "${this._configuration.commandName}" script` + `does not have a "${this.#configuration.commandName}" script` ); } - this._pluginEnabled = false; + this.#pluginEnabled = false; } } else { throw new Error( @@ -189,21 +189,21 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { heftConfiguration: HeftConfiguration ): Promise { await this._loadStageConfigurationAsync(taskSession, heftConfiguration); - if (!this._pluginEnabled) { + if (!this.#pluginEnabled) { return; } - this._logger.terminal.writeLine(`Starting Node service...`); + this.#logger.terminal.writeLine(`Starting Node service...`); await this._stopChildAsync(); this._startChild(); } private async _stopChildAsync(): Promise { - if (this._state !== State.Running) { - if (this._childProcessExitPromise) { + if (this.#state !== State.Running) { + if (this.#childProcessExitPromise) { // If we have an active process but are not in the running state, we must be in the process of // terminating or the process is already stopped. - await this._childProcessExitPromise; + await this.#childProcessExitPromise; } return; } @@ -212,84 +212,84 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { // On Windows, SIGTERM can kill Cmd.exe and leave its children running in the background this._transitionToKilling(); } else { - if (!this._activeChildProcess) { + if (!this.#activeChildProcess) { // All the code paths that set _activeChildProcess=undefined should also leave the Running state throw new InternalError('_activeChildProcess should not be undefined'); } - this._state = State.Stopping; - this._logger.terminal.writeVerboseLine('Sending SIGTERM to gracefully shut down the service process'); + this.#state = State.Stopping; + this.#logger.terminal.writeVerboseLine('Sending SIGTERM to gracefully shut down the service process'); // Passing a negative PID terminates the entire group instead of just the one process. // This works because we set detached=true for child_process.spawn() - const pid: number | undefined = this._activeChildProcess.pid; + const pid: number | undefined = this.#activeChildProcess.pid; if (pid !== undefined) { // If pid was undefined, the process failed to spawn process.kill(-pid, 'SIGTERM'); } this._clearTimeout(); - this._timeout = setTimeout(() => { + this.#timeout = setTimeout(() => { try { - if (this._state !== State.Stopped) { - this._logger.terminal.writeWarningLine('The service process is taking too long to terminate'); + if (this.#state !== State.Stopped) { + this.#logger.terminal.writeWarningLine('The service process is taking too long to terminate'); this._transitionToKilling(); } } catch (e: unknown) { - this._childProcessExitPromiseRejectFn!(e); + this.#childProcessExitPromiseRejectFn!(e); } - }, this._configuration.waitForTerminateMs); + }, this.#configuration.waitForTerminateMs); } - await this._childProcessExitPromise; + await this.#childProcessExitPromise; } private _transitionToKilling(): void { - this._state = State.Killing; + this.#state = State.Killing; - if (!this._activeChildProcess) { + if (!this.#activeChildProcess) { // All the code paths that set _activeChildProcess=undefined should also leave the Running state throw new InternalError('_activeChildProcess should not be undefined'); } - this._logger.terminal.writeVerboseLine('Attempting to killing the service process'); + this.#logger.terminal.writeVerboseLine('Attempting to killing the service process'); - SubprocessTerminator.killProcessTree(this._activeChildProcess, SubprocessTerminator.RECOMMENDED_OPTIONS); + SubprocessTerminator.killProcessTree(this.#activeChildProcess, SubprocessTerminator.RECOMMENDED_OPTIONS); this._clearTimeout(); - this._timeout = setTimeout(() => { + this.#timeout = setTimeout(() => { try { - if (this._state !== State.Stopped) { - this._logger.terminal.writeErrorLine( + if (this.#state !== State.Stopped) { + this.#logger.terminal.writeErrorLine( 'Abandoning the service process because it could not be killed' ); this._transitionToStopped(); } } catch (e: unknown) { - this._childProcessExitPromiseRejectFn!(e); + this.#childProcessExitPromiseRejectFn!(e); } - }, this._configuration.waitForKillMs); + }, this.#configuration.waitForKillMs); } private _transitionToStopped(): void { // Failed to start - this._state = State.Stopped; + this.#state = State.Stopped; this._clearTimeout(); - this._activeChildProcess = undefined; - this._childProcessExitPromiseResolveFn!(); + this.#activeChildProcess = undefined; + this.#childProcessExitPromiseResolveFn!(); } private _startChild(): void { - if (this._state !== State.Stopped) { + if (this.#state !== State.Stopped) { throw new InternalError('Invalid state'); } - this._state = State.Running; + this.#state = State.Running; this._clearTimeout(); - this._logger.terminal.writeLine(`Invoking command: "${this._shellCommand!}"`); + this.#logger.terminal.writeLine(`Invoking command: "${this.#shellCommand!}"`); - const childProcess: child_process.ChildProcess = child_process.spawn(this._shellCommand!, { + const childProcess: child_process.ChildProcess = child_process.spawn(this.#shellCommand!, { shell: true, ...SubprocessTerminator.RECOMMENDED_OPTIONS }); @@ -299,19 +299,19 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { if (childPid === undefined) { throw new InternalError(`Failed to spawn child process`); } - this._logger.terminal.writeVerboseLine(`Started service process #${childPid}`); + this.#logger.terminal.writeVerboseLine(`Started service process #${childPid}`); // Create a promise that resolves when the child process exits - this._childProcessExitPromise = new Promise((resolve, reject) => { - this._childProcessExitPromiseResolveFn = resolve; - this._childProcessExitPromiseRejectFn = reject; + this.#childProcessExitPromise = new Promise((resolve, reject) => { + this.#childProcessExitPromiseResolveFn = resolve; + this.#childProcessExitPromiseRejectFn = reject; childProcess.stdout?.on('data', (data: Buffer) => { - this._logger.terminal.write(data.toString()); + this.#logger.terminal.write(data.toString()); }); childProcess.stderr?.on('data', (data: Buffer) => { - this._logger.terminal.writeError(data.toString()); + this.#logger.terminal.writeError(data.toString()); }); childProcess.on('close', (exitCode: number | null, signal: NodeJS.Signals | null): void => { @@ -321,8 +321,8 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { // same stdio streams. The 'close' event will always emit after 'exit' was already emitted, // or 'error' if the child failed to spawn. - if (this._state === State.Running) { - this._logger.terminal.writeWarningLine( + if (this.#state === State.Running) { + this.#logger.terminal.writeWarningLine( `The service process #${childPid} terminated unexpectedly` + this._formatCodeOrSignal(exitCode, signal) ); @@ -330,8 +330,8 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { return; } - if (this._state === State.Stopping || this._state === State.Killing) { - this._logger.terminal.writeVerboseLine( + if (this.#state === State.Stopping || this.#state === State.Killing) { + this.#logger.terminal.writeVerboseLine( `The service process #${childPid} terminated successfully` + this._formatCodeOrSignal(exitCode, signal) ); @@ -347,7 +347,7 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { try { // Under normal conditions we don't reject the promise here, because 'data' events can continue // to fire as data is flushed, before finally concluding with the 'close' event. - this._logger.terminal.writeVerboseLine( + this.#logger.terminal.writeVerboseLine( `The service process fired its "exit" event` + this._formatCodeOrSignal(code, signal) ); } catch (e: unknown) { @@ -365,22 +365,22 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { // The 'exit' event may or may not fire after an error has occurred. When listening to both the 'exit' // and 'error' events, guard against accidentally invoking handler functions multiple times." - if (this._state === State.Running) { - this._logger.terminal.writeErrorLine(`Failed to start: ` + err.toString()); + if (this.#state === State.Running) { + this.#logger.terminal.writeErrorLine(`Failed to start: ` + err.toString()); this._transitionToStopped(); return; } - if (this._state === State.Stopping) { - this._logger.terminal.writeWarningLine( + if (this.#state === State.Stopping) { + this.#logger.terminal.writeWarningLine( `The service process #${childPid} rejected the shutdown signal: ` + err.toString() ); this._transitionToKilling(); return; } - if (this._state === State.Killing) { - this._logger.terminal.writeErrorLine( + if (this.#state === State.Killing) { + this.#logger.terminal.writeErrorLine( `The service process #${childPid} could not be killed: ` + err.toString() ); this._transitionToStopped(); @@ -392,13 +392,13 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { }); }); - this._activeChildProcess = childProcess; + this.#activeChildProcess = childProcess; } private _clearTimeout(): void { - if (this._timeout) { - clearTimeout(this._timeout); - this._timeout = undefined; + if (this.#timeout) { + clearTimeout(this.#timeout); + this.#timeout = undefined; } } diff --git a/apps/heft/src/utilities/GitUtilities.ts b/apps/heft/src/utilities/GitUtilities.ts index a0f918b1242..d1b9596f431 100644 --- a/apps/heft/src/utilities/GitUtilities.ts +++ b/apps/heft/src/utilities/GitUtilities.ts @@ -28,24 +28,24 @@ interface IExecuteGitCommandOptions { } export class GitUtilities { - private readonly _workingDirectory: string; - private _ignoreMatcherByGitignoreFolder: Map | undefined; - private _gitPath: string | undefined | typeof UNINITIALIZED = UNINITIALIZED; - private _gitInfo: IGitRepoInfo | undefined | typeof UNINITIALIZED = UNINITIALIZED; - private _gitVersion: IGitVersion | undefined | typeof UNINITIALIZED = UNINITIALIZED; + readonly #workingDirectory: string; + #ignoreMatcherByGitignoreFolder: Map | undefined; + #gitPath: string | undefined | typeof UNINITIALIZED = UNINITIALIZED; + #gitInfo: IGitRepoInfo | undefined | typeof UNINITIALIZED = UNINITIALIZED; + #gitVersion: IGitVersion | undefined | typeof UNINITIALIZED = UNINITIALIZED; public constructor(workingDirectory: string) { - this._workingDirectory = path.resolve(process.cwd(), workingDirectory); + this.#workingDirectory = path.resolve(process.cwd(), workingDirectory); } /** * Returns the path to the Git binary if found. Otherwise, return undefined. */ public get gitPath(): string | undefined { - if (this._gitPath === UNINITIALIZED) { - this._gitPath = Executable.tryResolve('git'); + if (this.#gitPath === UNINITIALIZED) { + this.#gitPath = Executable.tryResolve('git'); } - return this._gitPath; + return this.#gitPath; } /** @@ -53,7 +53,7 @@ export class GitUtilities { * Returns undefined if the current path is not under a Git working tree. */ public getGitInfo(): Readonly | undefined { - if (this._gitInfo === UNINITIALIZED) { + if (this.#gitInfo === UNINITIALIZED) { let repoInfo: IGitRepoInfo | undefined; try { // getGitRepoInfo() shouldn't usually throw, but wrapping in a try/catch just in case @@ -61,16 +61,16 @@ export class GitUtilities { } catch (ex) { // if there's an error, assume we're not in a Git working tree } - this._gitInfo = repoInfo && this.isPathUnderGitWorkingTree(repoInfo) ? repoInfo : undefined; + this.#gitInfo = repoInfo && this.isPathUnderGitWorkingTree(repoInfo) ? repoInfo : undefined; } - return this._gitInfo; + return this.#gitInfo; } /** * Gets the Git version and returns it. */ public getGitVersion(): IGitVersion | undefined { - if (this._gitVersion === UNINITIALIZED) { + if (this.#gitVersion === UNINITIALIZED) { if (this.gitPath) { const result: SpawnSyncReturns = Executable.spawnSync(this.gitPath, ['version']); if (result.status !== 0) { @@ -79,12 +79,12 @@ export class GitUtilities { `status ${result.status}: ${result.stderr}` ); } - this._gitVersion = this._parseGitVersion(result.stdout); + this.#gitVersion = this._parseGitVersion(result.stdout); } else { - this._gitVersion = undefined; + this.#gitVersion = undefined; } } - return this._gitVersion; + return this.#gitVersion; } /** @@ -174,10 +174,10 @@ export class GitUtilities { private async _getIgnoreMatchersAsync(gitRepoRootPath: string): Promise> { // Return early if we've already parsed the .gitignore matchers - if (this._ignoreMatcherByGitignoreFolder !== undefined) { - return this._ignoreMatcherByGitignoreFolder; + if (this.#ignoreMatcherByGitignoreFolder !== undefined) { + return this.#ignoreMatcherByGitignoreFolder; } else { - this._ignoreMatcherByGitignoreFolder = new Map(); + this.#ignoreMatcherByGitignoreFolder = new Map(); } // Store the raw loaded ignore patterns in a map, keyed by the directory they were loaded from @@ -186,7 +186,7 @@ export class GitUtilities { // Load the .gitignore files for the working directory and all parent directories. We can loop through // and compare the currentPath length to the gitRepoRootPath length because we know the currentPath // must be under the gitRepoRootPath - const normalizedWorkingDirectory: string = Path.convertToSlashes(this._workingDirectory); + const normalizedWorkingDirectory: string = Path.convertToSlashes(this.#workingDirectory); let currentPath: string = normalizedWorkingDirectory; while (currentPath.length >= gitRepoRootPath.length) { const gitIgnoreFilePath: string = `${currentPath}/.gitignore`; @@ -266,10 +266,10 @@ export class GitUtilities { currentPath = currentPath.slice(0, currentPath.lastIndexOf('/')); } - this._ignoreMatcherByGitignoreFolder.set(gitIgnoreParentPath, ignore().add(ignoreMatcherPatterns)); + this.#ignoreMatcherByGitignoreFolder.set(gitIgnoreParentPath, ignore().add(ignoreMatcherPatterns)); } - return this._ignoreMatcherByGitignoreFolder; + return this.#ignoreMatcherByGitignoreFolder; } private async _tryReadGitIgnoreFileAsync(filePath: string): Promise { @@ -327,7 +327,7 @@ export class GitUtilities { const gitPath: string = this._getGitPathOrThrow(); const processArgs: string[] = [options.command].concat(options.args || []); const childProcess: ChildProcess = Executable.spawn(gitPath, processArgs, { - currentWorkingDirectory: this._workingDirectory, + currentWorkingDirectory: this.#workingDirectory, stdio: ['ignore', 'pipe', 'pipe'] }); if (!childProcess.stdout || !childProcess.stderr) { @@ -400,7 +400,7 @@ export class GitUtilities { private _ensurePathIsUnderGitWorkingTree(): void { if (!this.isPathUnderGitWorkingTree()) { - throw new Error(`The path "${this._workingDirectory}" is not under a Git working tree`); + throw new Error(`The path "${this.#workingDirectory}" is not under a Git working tree`); } } diff --git a/apps/heft/src/utilities/WatchFileSystemAdapter.ts b/apps/heft/src/utilities/WatchFileSystemAdapter.ts index 97c1ae5bdd3..cc886e24a27 100644 --- a/apps/heft/src/utilities/WatchFileSystemAdapter.ts +++ b/apps/heft/src/utilities/WatchFileSystemAdapter.ts @@ -134,15 +134,15 @@ interface ITimeEntry { * to initialize `watchpack`. */ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { - private _files: Map = new Map(); - private _contexts: Map = new Map(); - private _missing: Map = new Map(); + #files: Map = new Map(); + #contexts: Map = new Map(); + #missing: Map = new Map(); - private _watcher: Watchpack | undefined; + #watcher: Watchpack | undefined; - private _lastFiles: Map | undefined; - private _lastQueryTime: number | undefined; - private _times: Map | undefined; + #lastFiles: Map | undefined; + #lastQueryTime: number | undefined; + #times: Map | undefined; /** { @inheritdoc fs.readdirSync } */ public readdirSync: IWatchFileSystemAdapter['readdirSync'] = (( @@ -154,15 +154,15 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { try { if (options?.withFileTypes) { const results: fs.Dirent[] = fs.readdirSync(filePath, options); - this._contexts.set(filePath, Date.now()); + this.#contexts.set(filePath, Date.now()); return results; } else { const results: string[] = fs.readdirSync(filePath); - this._contexts.set(filePath, Date.now()); + this.#contexts.set(filePath, Date.now()); return results; } } catch (err) { - this._missing.set(filePath, Date.now()); + this.#missing.set(filePath, Date.now()); throw err; } }) as IWatchFileSystemAdapter['readdirSync']; @@ -185,18 +185,18 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { if (options?.withFileTypes) { fs.readdir(filePath, options, (err: NodeJS.ErrnoException | null, entries: fs.Dirent[]) => { if (err) { - this._missing.set(filePath, Date.now()); + this.#missing.set(filePath, Date.now()); } else { - this._contexts.set(filePath, Date.now()); + this.#contexts.set(filePath, Date.now()); } (callback as ReaddirDirentCallback)(err, entries); }); } else { fs.readdir(filePath, (err: NodeJS.ErrnoException | null, entries: string[]) => { if (err) { - this._missing.set(filePath, Date.now()); + this.#missing.set(filePath, Date.now()); } else { - this._contexts.set(filePath, Date.now()); + this.#contexts.set(filePath, Date.now()); } (callback as ReaddirStringCallback)(err, entries); }); @@ -208,9 +208,9 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { filePath = path.normalize(filePath); fs.lstat(filePath, (err: NodeJS.ErrnoException | null, stats: fs.Stats) => { if (err) { - this._missing.set(filePath, Date.now()); + this.#missing.set(filePath, Date.now()); } else { - this._files.set(filePath, stats.mtime.getTime() || stats.ctime.getTime() || Date.now()); + this.#files.set(filePath, stats.mtime.getTime() || stats.ctime.getTime() || Date.now()); } callback(err, stats); }); @@ -221,10 +221,10 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { filePath = path.normalize(filePath); try { const stats: fs.Stats = fs.lstatSync(filePath); - this._files.set(filePath, stats.mtime.getTime() || stats.ctime.getTime() || Date.now()); + this.#files.set(filePath, stats.mtime.getTime() || stats.ctime.getTime() || Date.now()); return stats; } catch (err) { - this._missing.set(filePath, Date.now()); + this.#missing.set(filePath, Date.now()); throw err; } }; @@ -234,9 +234,9 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { filePath = path.normalize(filePath); fs.stat(filePath, (err: NodeJS.ErrnoException | null, stats: fs.Stats) => { if (err) { - this._missing.set(filePath, Date.now()); + this.#missing.set(filePath, Date.now()); } else { - this._files.set(filePath, stats.mtime.getTime() || stats.ctime.getTime() || Date.now()); + this.#files.set(filePath, stats.mtime.getTime() || stats.ctime.getTime() || Date.now()); } callback(err, stats); }); @@ -247,10 +247,10 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { filePath = path.normalize(filePath); try { const stats: fs.Stats = fs.statSync(filePath); - this._files.set(filePath, stats.mtime.getTime() || stats.ctime.getTime() || Date.now()); + this.#files.set(filePath, stats.mtime.getTime() || stats.ctime.getTime() || Date.now()); return stats; } catch (err) { - this._missing.set(filePath, Date.now()); + this.#missing.set(filePath, Date.now()); throw err; } }; @@ -259,13 +259,13 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { * @inheritdoc */ public setBaseline(): void { - this._lastQueryTime = Date.now(); + this.#lastQueryTime = Date.now(); - if (this._watcher) { + if (this.#watcher) { const times: Map = new Map(); - this._watcher.pause(); - this._watcher.collectTimeInfoEntries(times, times); - this._times = times; + this.#watcher.pause(); + this.#watcher.collectTimeInfoEntries(times, times); + this.#times = times; } } @@ -273,7 +273,7 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { * @inheritdoc */ public watch(onChange: () => void): void { - if (this._files.size === 0 && this._contexts.size === 0 && this._missing.size === 0) { + if (this.#files.size === 0 && this.#contexts.size === 0 && this.#missing.size === 0) { return; } @@ -282,18 +282,18 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { followSymlinks: false }); - this._watcher = watcher; + this.#watcher = watcher; watcher.watch({ - files: this._files.keys(), - directories: this._contexts.keys(), - missing: this._missing.keys(), - startTime: this._lastQueryTime + files: this.#files.keys(), + directories: this.#contexts.keys(), + missing: this.#missing.keys(), + startTime: this.#lastQueryTime }); - this._lastFiles = this._files; - this._files = new Map(); - this._contexts.clear(); - this._missing.clear(); + this.#lastFiles = this.#files; + this.#files = new Map(); + this.#contexts.clear(); + this.#missing.clear(); watcher.once('aggregated', onChange); } @@ -303,8 +303,8 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { */ public async getStateAndTrackAsync(filePath: string): Promise { const normalizedSourcePath: string = path.normalize(filePath); - const oldTime: number | undefined = this._lastFiles?.get(normalizedSourcePath); - let newTimeEntry: ITimeEntry | undefined = this._times?.get(normalizedSourcePath); + const oldTime: number | undefined = this.#lastFiles?.get(normalizedSourcePath); + let newTimeEntry: ITimeEntry | undefined = this.#times?.get(normalizedSourcePath); if (!newTimeEntry) { // Need to record a timestamp, otherwise first rerun will select everything @@ -316,15 +316,15 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { safeTime: rounded }; } catch (err) { - this._missing.set(normalizedSourcePath, Date.now()); + this.#missing.set(normalizedSourcePath, Date.now()); } } const newTime: number | undefined = - (newTimeEntry && (newTimeEntry.timestamp ?? newTimeEntry.safeTime)) || this._lastQueryTime; + (newTimeEntry && (newTimeEntry.timestamp ?? newTimeEntry.safeTime)) || this.#lastQueryTime; if (newTime) { - this._files.set(normalizedSourcePath, newTime); + this.#files.set(normalizedSourcePath, newTime); } return { @@ -337,8 +337,8 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { */ public getStateAndTrack(filePath: string): IWatchedFileState { const normalizedSourcePath: string = path.normalize(filePath); - const oldTime: number | undefined = this._lastFiles?.get(normalizedSourcePath); - let newTimeEntry: ITimeEntry | undefined = this._times?.get(normalizedSourcePath); + const oldTime: number | undefined = this.#lastFiles?.get(normalizedSourcePath); + let newTimeEntry: ITimeEntry | undefined = this.#times?.get(normalizedSourcePath); if (!newTimeEntry) { // Need to record a timestamp, otherwise first rerun will select everything @@ -350,15 +350,15 @@ export class WatchFileSystemAdapter implements IWatchFileSystemAdapter { safeTime: rounded }; } else { - this._missing.set(normalizedSourcePath, Date.now()); + this.#missing.set(normalizedSourcePath, Date.now()); } } const newTime: number | undefined = - (newTimeEntry && (newTimeEntry.timestamp ?? newTimeEntry.safeTime)) || this._lastQueryTime; + (newTimeEntry && (newTimeEntry.timestamp ?? newTimeEntry.safeTime)) || this.#lastQueryTime; if (newTime) { - this._files.set(normalizedSourcePath, newTime); + this.#files.set(normalizedSourcePath, newTime); } return { From 26918f981d5f493e4aecf201a7067b1ad9ef8388 Mon Sep 17 00:00:00 2001 From: Bharat Middha <5100938+bmiddha@users.noreply.github.com> Date: Wed, 19 Aug 2026 15:22:29 -0700 Subject: [PATCH 2/3] refactor(heft): convert private methods/accessors to #private Convert private instance methods and get/set accessors in apps/heft to ECMAScript # private syntax, complementing the earlier private field conversion on this branch. Symbol-aware analysis reported 41 eligible members across 17 files with 0 skipped (private constructors are correctly excluded since they have no valid #private syntax). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ebd5bf2-c44b-42d5-be25-e7936d4b0a14 --- apps/heft/src/cli/HeftActionRunner.ts | 14 ++--- apps/heft/src/cli/HeftCommandLineParser.ts | 14 ++--- apps/heft/src/cli/actions/CleanAction.ts | 4 +- .../src/configuration/HeftConfiguration.ts | 6 +-- .../configuration/HeftPluginConfiguration.ts | 20 +++---- .../src/configuration/RigPackageResolver.ts | 4 +- .../operations/runners/TaskOperationRunner.ts | 4 +- .../heft/src/pluginFramework/HeftLifecycle.ts | 4 +- .../pluginFramework/HeftParameterManager.ts | 20 +++---- apps/heft/src/pluginFramework/HeftPhase.ts | 10 ++-- apps/heft/src/pluginFramework/HeftTask.ts | 8 +-- .../pluginFramework/InternalHeftSession.ts | 6 +-- .../StaticFileSystemAdapter.ts | 10 ++-- .../pluginFramework/logging/ScopedLogger.ts | 6 +-- apps/heft/src/plugins/NodeServicePlugin.ts | 54 +++++++++---------- apps/heft/src/plugins/RunScriptPlugin.ts | 4 +- apps/heft/src/utilities/GitUtilities.ts | 38 ++++++------- 17 files changed, 113 insertions(+), 113 deletions(-) diff --git a/apps/heft/src/cli/HeftActionRunner.ts b/apps/heft/src/cli/HeftActionRunner.ts index 9b51129a7b5..1a9f0ef99ef 100644 --- a/apps/heft/src/cli/HeftActionRunner.ts +++ b/apps/heft/src/cli/HeftActionRunner.ts @@ -311,7 +311,7 @@ export class HeftActionRunner { initializeHeft(this.#heftConfiguration, terminal, this.parameterManager.defaultParameters.verbose); const operations: ReadonlySet> = - this._generateOperations(); + this.#generateOperations(); const executionManager: OperationExecutionManager< IHeftTaskOperationMetadata, @@ -324,7 +324,7 @@ export class HeftActionRunner { await _startLifecycleAsync(this.#internalHeftSession); if (this.#action.watch) { - const watchLoop: WatchLoop = this._createWatchLoop(executionManager); + const watchLoop: WatchLoop = this.#createWatchLoop(executionManager); if (process.send) { await watchLoop.runIPCAsync(); @@ -335,7 +335,7 @@ export class HeftActionRunner { }); } } else { - await this._executeOnceAsync(executionManager, cliAbortSignal); + await this.#executeOnceAsync(executionManager, cliAbortSignal); } } finally { // Invoke this here both to ensure it always runs and that it does so after recordMetrics @@ -346,7 +346,7 @@ export class HeftActionRunner { } } - private _createWatchLoop(executionManager: OperationExecutionManager): WatchLoop { + #createWatchLoop(executionManager: OperationExecutionManager): WatchLoop { const terminal: ITerminal = this.#terminal; const watchLoop: WatchLoop = new WatchLoop({ onBeforeExecute: () => { @@ -356,7 +356,7 @@ export class HeftActionRunner { terminal.writeLine(Colorize.bold('Starting incremental build...')); }, executeAsync: (state: IWatchLoopState): Promise => { - return this._executeOnceAsync(executionManager, state.abortSignal, state.requestRun); + return this.#executeOnceAsync(executionManager, state.abortSignal, state.requestRun); }, onRequestRun: (requestor?: string) => { terminal.writeLine(Colorize.bold(`New run requested by ${requestor || 'unknown task'}`)); @@ -368,7 +368,7 @@ export class HeftActionRunner { return watchLoop; } - private async _executeOnceAsync( + async #executeOnceAsync( executionManager: OperationExecutionManager, abortSignal: AbortSignal, requestRun?: OperationRequestRunCallback @@ -428,7 +428,7 @@ export class HeftActionRunner { ); } - private _generateOperations(): Set> { + #generateOperations(): Set> { const { selectedPhases } = this.#action; const operations: Map< diff --git a/apps/heft/src/cli/HeftCommandLineParser.ts b/apps/heft/src/cli/HeftCommandLineParser.ts index 272b09c3d7b..0b26079c855 100644 --- a/apps/heft/src/cli/HeftCommandLineParser.ts +++ b/apps/heft/src/cli/HeftCommandLineParser.ts @@ -73,7 +73,7 @@ export class HeftCommandLineParser extends CommandLineParser { // Pre-initialize with known argument values to determine state of "--debug" const preInitializationArgumentValues: IPreInitializationArgumentValues = - this._getPreInitializationArgumentValues(); + this.#getPreInitializationArgumentValues(); this.#debug = !!preInitializationArgumentValues.debug; // Enable debug and verbose logging if the "--debug" flag is set @@ -105,7 +105,7 @@ export class HeftCommandLineParser extends CommandLineParser { process.exitCode = 1; try { - this._normalizeCwd(); + this.#normalizeCwd(); const internalHeftSession: InternalHeftSession = await InternalHeftSession.initializeAsync({ debug: this.#debug, @@ -172,7 +172,7 @@ export class HeftCommandLineParser extends CommandLineParser { return await super.executeAsync(args); } catch (e) { - await this._reportErrorAndSetExitCodeAsync(e as Error); + await this.#reportErrorAndSetExitCodeAsync(e as Error); return false; } } @@ -199,14 +199,14 @@ export class HeftCommandLineParser extends CommandLineParser { }; await super.onExecuteAsync(); } catch (e) { - await this._reportErrorAndSetExitCodeAsync(e as Error); + await this.#reportErrorAndSetExitCodeAsync(e as Error); } // If we make it here, things are fine and reset the exit code back to 0 process.exitCode = 0; } - private _normalizeCwd(): void { + #normalizeCwd(): void { const buildFolder: string = this.#heftConfiguration.buildFolderPath; const currentCwd: string = process.cwd(); if (currentCwd !== buildFolder) { @@ -220,7 +220,7 @@ export class HeftCommandLineParser extends CommandLineParser { } } - private _getPreInitializationArgumentValues( + #getPreInitializationArgumentValues( args: string[] = process.argv ): IPreInitializationArgumentValues { if (!this.#debugFlag) { @@ -239,7 +239,7 @@ export class HeftCommandLineParser extends CommandLineParser { }; } - private async _reportErrorAndSetExitCodeAsync(error: Error): Promise { + async #reportErrorAndSetExitCodeAsync(error: Error): Promise { if (!(error instanceof AlreadyReportedError)) { this.globalTerminal.writeErrorLine(error.toString()); } diff --git a/apps/heft/src/cli/actions/CleanAction.ts b/apps/heft/src/cli/actions/CleanAction.ts index 1d91b5f0522..d9527c93bc6 100644 --- a/apps/heft/src/cli/actions/CleanAction.ts +++ b/apps/heft/src/cli/actions/CleanAction.ts @@ -84,7 +84,7 @@ export class CleanAction extends CommandLineAction implements IHeftAction { this.#metricsCollector.setStartTime(); initializeHeft(heftConfiguration, this.#terminal, this.#verboseFlag.value); await runWithLoggingAsync( - this._cleanFilesAsync.bind(this), + this.#cleanFilesAsync.bind(this), this, this.#internalHeftSession.loggingManager, this.#terminal, @@ -93,7 +93,7 @@ export class CleanAction extends CommandLineAction implements IHeftAction { ); } - private async _cleanFilesAsync(): Promise { + async #cleanFilesAsync(): Promise { const deleteOperations: IDeleteOperation[] = []; for (const phase of this.selectedPhases) { // Add the temp folder and cache folder (if requested) for each task diff --git a/apps/heft/src/configuration/HeftConfiguration.ts b/apps/heft/src/configuration/HeftConfiguration.ts index 44f68f64d50..85dc64200ba 100644 --- a/apps/heft/src/configuration/HeftConfiguration.ts +++ b/apps/heft/src/configuration/HeftConfiguration.ts @@ -183,7 +183,7 @@ export class HeftConfiguration { options: IProjectConfigurationFileSpecification, terminal: ITerminal ): TConfigFile | undefined { - const loader: ProjectConfigurationFile = this._getConfigFileLoader(options); + const loader: ProjectConfigurationFile = this.#getConfigFileLoader(options); return loader.tryLoadConfigurationFileForProject(terminal, this.buildFolderPath, this.#rigConfig); } @@ -197,7 +197,7 @@ export class HeftConfiguration { options: IProjectConfigurationFileSpecification, terminal: ITerminal ): Promise { - const loader: ProjectConfigurationFile = this._getConfigFileLoader(options); + const loader: ProjectConfigurationFile = this.#getConfigFileLoader(options); return loader.tryLoadConfigurationFileForProjectAsync(terminal, this.buildFolderPath, this.#rigConfig); } @@ -228,7 +228,7 @@ export class HeftConfiguration { return configuration; } - private _getConfigFileLoader( + #getConfigFileLoader( options: IProjectConfigurationFileSpecification ): ProjectConfigurationFile { let entry: IProjectConfigurationFileEntry | undefined = this.#knownConfigurationFiles.get( diff --git a/apps/heft/src/configuration/HeftPluginConfiguration.ts b/apps/heft/src/configuration/HeftPluginConfiguration.ts index 5e117b4b40b..ac2ab9334c4 100644 --- a/apps/heft/src/configuration/HeftPluginConfiguration.ts +++ b/apps/heft/src/configuration/HeftPluginConfiguration.ts @@ -51,7 +51,7 @@ export class HeftPluginConfiguration { this.#heftPluginConfigurationJson = heftPluginConfigurationJson; this.packageRoot = packageRoot; this.packageName = packageName; - this._validate(heftPluginConfigurationJson, packageName); + this.#validate(heftPluginConfigurationJson, packageName); } /** @@ -87,8 +87,8 @@ export class HeftPluginConfiguration { ): HeftPluginDefinitionBase { if (!pluginSpecifier.pluginName) { const pluginDefinitions: HeftPluginDefinitionBase[] = ([] as HeftPluginDefinitionBase[]).concat( - Array.from(this._getLifecyclePluginDefinitions()), - Array.from(this._getTaskPluginDefinitions()) + Array.from(this.#getLifecyclePluginDefinitions()), + Array.from(this.#getTaskPluginDefinitions()) ); // Make an attempt at resolving the plugin without the name by looking for the first plugin if (pluginDefinitions.length > 1) { @@ -119,7 +119,7 @@ export class HeftPluginConfiguration { public isLifecyclePluginDefinition( pluginDefinition: HeftPluginDefinitionBase ): pluginDefinition is HeftLifecyclePluginDefinition { - return this._getLifecyclePluginDefinitions().has(pluginDefinition); + return this.#getLifecyclePluginDefinitions().has(pluginDefinition); } /** @@ -128,7 +128,7 @@ export class HeftPluginConfiguration { public isTaskPluginDefinition( pluginDefinition: HeftPluginDefinitionBase ): pluginDefinition is HeftTaskPluginDefinition { - return this._getTaskPluginDefinitions().has(pluginDefinition); + return this.#getTaskPluginDefinitions().has(pluginDefinition); } /** @@ -140,7 +140,7 @@ export class HeftPluginConfiguration { ): HeftLifecyclePluginDefinition | undefined { if (!this.#lifecyclePluginDefinitionsMap) { this.#lifecyclePluginDefinitionsMap = new Map( - Array.from(this._getLifecyclePluginDefinitions()).map((d: HeftLifecyclePluginDefinition) => [ + Array.from(this.#getLifecyclePluginDefinitions()).map((d: HeftLifecyclePluginDefinition) => [ d.pluginName, d ]) @@ -156,13 +156,13 @@ export class HeftPluginConfiguration { public tryGetTaskPluginDefinitionByName(taskPluginName: string): HeftTaskPluginDefinition | undefined { if (!this.#taskPluginDefinitionsMap) { this.#taskPluginDefinitionsMap = new Map( - Array.from(this._getTaskPluginDefinitions()).map((d: HeftTaskPluginDefinition) => [d.pluginName, d]) + Array.from(this.#getTaskPluginDefinitions()).map((d: HeftTaskPluginDefinition) => [d.pluginName, d]) ); } return this.#taskPluginDefinitionsMap.get(taskPluginName); } - private _getLifecyclePluginDefinitions(): ReadonlySet { + #getLifecyclePluginDefinitions(): ReadonlySet { if (!this.#lifecyclePluginDefinitions) { this.#lifecyclePluginDefinitions = new Set(); for (const lifecyclePluginDefinitionJson of this.#heftPluginConfigurationJson.lifecyclePlugins || []) { @@ -181,7 +181,7 @@ export class HeftPluginConfiguration { /** * Task plugin definitions sourced from the heft-plugin.json file. */ - private _getTaskPluginDefinitions(): ReadonlySet { + #getTaskPluginDefinitions(): ReadonlySet { if (!this.#taskPluginDefinitions) { this.#taskPluginDefinitions = new Set(); for (const taskPluginDefinitionJson of this.#heftPluginConfigurationJson.taskPlugins || []) { @@ -197,7 +197,7 @@ export class HeftPluginConfiguration { return this.#taskPluginDefinitions; } - private _validate(heftPluginConfigurationJson: IHeftPluginConfigurationJson, packageName: string): void { + #validate(heftPluginConfigurationJson: IHeftPluginConfigurationJson, packageName: string): void { if ( !heftPluginConfigurationJson.lifecyclePlugins?.length && !heftPluginConfigurationJson.taskPlugins?.length diff --git a/apps/heft/src/configuration/RigPackageResolver.ts b/apps/heft/src/configuration/RigPackageResolver.ts index 5f91418a73f..ff5643407e0 100644 --- a/apps/heft/src/configuration/RigPackageResolver.ts +++ b/apps/heft/src/configuration/RigPackageResolver.ts @@ -70,14 +70,14 @@ export class RigPackageResolver implements IRigPackageResolver { const cacheKey: string = `${projectFolder};${packageName}`; let resolutionPromise: Promise | undefined = this.#resolverCache.get(cacheKey); if (!resolutionPromise) { - resolutionPromise = this._resolvePackageInnerAsync(packageName, terminal); + resolutionPromise = this.#resolvePackageInnerAsync(packageName, terminal); this.#resolverCache.set(cacheKey, resolutionPromise); } return await resolutionPromise; } - private async _resolvePackageInnerAsync(toolPackageName: string, terminal: ITerminal): Promise { + async #resolvePackageInnerAsync(toolPackageName: string, terminal: ITerminal): Promise { // See if the project has a devDependency on the package if ( this.#projectPackageJson.devDependencies && diff --git a/apps/heft/src/operations/runners/TaskOperationRunner.ts b/apps/heft/src/operations/runners/TaskOperationRunner.ts index 30bf1ab1f8d..86b642235f0 100644 --- a/apps/heft/src/operations/runners/TaskOperationRunner.ts +++ b/apps/heft/src/operations/runners/TaskOperationRunner.ts @@ -82,10 +82,10 @@ export class TaskOperationRunner implements IOperationRunner { const { parentPhase } = task; const phaseSession: HeftPhaseSession = internalHeftSession.getSessionForPhase(parentPhase); const taskSession: HeftTaskSession = phaseSession.getSessionForTask(task); - return await this._executeTaskAsync(context, taskSession); + return await this.#executeTaskAsync(context, taskSession); } - private async _executeTaskAsync( + async #executeTaskAsync( context: IOperationRunnerContext, taskSession: HeftTaskSession ): Promise { diff --git a/apps/heft/src/pluginFramework/HeftLifecycle.ts b/apps/heft/src/pluginFramework/HeftLifecycle.ts index fa9682904db..b227208d0e1 100644 --- a/apps/heft/src/pluginFramework/HeftLifecycle.ts +++ b/apps/heft/src/pluginFramework/HeftLifecycle.ts @@ -104,7 +104,7 @@ export class HeftLifecycle extends HeftPluginHost { }); } loadPluginPromises.push( - this._getLifecyclePluginForPluginDefinitionAsync(pluginDefinition, lifecycleContext.lifecycleSession) + this.#getLifecyclePluginForPluginDefinitionAsync(pluginDefinition, lifecycleContext.lifecycleSession) ); } @@ -219,7 +219,7 @@ export class HeftLifecycle extends HeftPluginHost { return lifecycleContext.lifecycleSession; } - private async _getLifecyclePluginForPluginDefinitionAsync( + async #getLifecyclePluginForPluginDefinitionAsync( pluginDefinition: HeftLifecyclePluginDefinition, lifecycleSession: IHeftLifecycleSession ): Promise> { diff --git a/apps/heft/src/pluginFramework/HeftParameterManager.ts b/apps/heft/src/pluginFramework/HeftParameterManager.ts index 8a0cd4defee..17538c851f9 100644 --- a/apps/heft/src/pluginFramework/HeftParameterManager.ts +++ b/apps/heft/src/pluginFramework/HeftParameterManager.ts @@ -191,7 +191,7 @@ export class HeftParameterManager { } this.#isFinalized = true; for (const pluginDefinition of this.#parametersByDefinition.keys()) { - this._addParametersToProvider(pluginDefinition, commandLineParameterProvider); + this.#addParametersToProvider(pluginDefinition, commandLineParameterProvider); } } @@ -218,19 +218,19 @@ export class HeftParameterManager { ...this.defaultParameters, getChoiceParameter: (parameterLongName: string) => - this._getParameter(parameters, parameterLongName, CommandLineParameterKind.Choice), + this.#getParameter(parameters, parameterLongName, CommandLineParameterKind.Choice), getChoiceListParameter: (parameterLongName: string) => - this._getParameter(parameters, parameterLongName, CommandLineParameterKind.ChoiceList), + this.#getParameter(parameters, parameterLongName, CommandLineParameterKind.ChoiceList), getFlagParameter: (parameterLongName: string) => - this._getParameter(parameters, parameterLongName, CommandLineParameterKind.Flag), + this.#getParameter(parameters, parameterLongName, CommandLineParameterKind.Flag), getIntegerParameter: (parameterLongName: string) => - this._getParameter(parameters, parameterLongName, CommandLineParameterKind.Integer), + this.#getParameter(parameters, parameterLongName, CommandLineParameterKind.Integer), getIntegerListParameter: (parameterLongName: string) => - this._getParameter(parameters, parameterLongName, CommandLineParameterKind.IntegerList), + this.#getParameter(parameters, parameterLongName, CommandLineParameterKind.IntegerList), getStringParameter: (parameterLongName: string) => - this._getParameter(parameters, parameterLongName, CommandLineParameterKind.String), + this.#getParameter(parameters, parameterLongName, CommandLineParameterKind.String), getStringListParameter: (parameterLongName: string) => - this._getParameter(parameters, parameterLongName, CommandLineParameterKind.StringList) + this.#getParameter(parameters, parameterLongName, CommandLineParameterKind.StringList) }; this.#heftParametersByDefinition.set(pluginDefinition, heftParameters); } @@ -244,7 +244,7 @@ export class HeftParameterManager { * "--:". If there is no duplicate parameter, it will also be * referenceable by the CLI argument "--". */ - private _addParametersToProvider( + #addParametersToProvider( pluginDefinition: HeftPluginDefinitionBase, commandLineParameterProvider: CommandLineParameterProvider ): void { @@ -376,7 +376,7 @@ export class HeftParameterManager { } } - private _getParameter( + #getParameter( parametersByLongName: Map, parameterLongName: string, expectedParameterKind: CommandLineParameterKind diff --git a/apps/heft/src/pluginFramework/HeftPhase.ts b/apps/heft/src/pluginFramework/HeftPhase.ts index 541a2237870..815447fc804 100644 --- a/apps/heft/src/pluginFramework/HeftPhase.ts +++ b/apps/heft/src/pluginFramework/HeftPhase.ts @@ -43,7 +43,7 @@ export class HeftPhase implements IHeftPhase { this.#phaseName = phaseName; this.#phaseSpecifier = phaseSpecifier; - this._validate(); + this.#validate(); } /** @@ -118,7 +118,7 @@ export class HeftPhase implements IHeftPhase { * Returns the set of tasks contained by this phase. */ public get tasks(): ReadonlySet { - this._ensureTasks(); + this.#ensureTasks(); return this.#tasks!; } @@ -126,11 +126,11 @@ export class HeftPhase implements IHeftPhase { * Returns a map of tasks by name. */ public get tasksByName(): ReadonlyMap { - this._ensureTasks(); + this.#ensureTasks(); return this.#tasksByName!; } - private _ensureTasks(): void { + #ensureTasks(): void { if (!this.#tasks || !this.#tasksByName) { this.#tasks = new Set(); this.#tasksByName = new Map(); @@ -142,7 +142,7 @@ export class HeftPhase implements IHeftPhase { } } - private _validate(): void { + #validate(): void { if (RESERVED_PHASE_NAMES.has(this.phaseName)) { throw new Error( `Phase name ${JSON.stringify(this.phaseName)} is reserved and cannot be used as a phase name.` diff --git a/apps/heft/src/pluginFramework/HeftTask.ts b/apps/heft/src/pluginFramework/HeftTask.ts index a1813197f9c..ee9f9870789 100644 --- a/apps/heft/src/pluginFramework/HeftTask.ts +++ b/apps/heft/src/pluginFramework/HeftTask.ts @@ -112,12 +112,12 @@ export class HeftTask implements IHeftTask { this.#taskName = taskName; this.#taskSpecifier = taskSpecifier; - this._validate(); + this.#validate(); } public async ensureInitializedAsync(): Promise { if (!this.#taskPluginDefinition) { - this.#taskPluginDefinition = await this._loadTaskPluginDefinitionAsync(); + this.#taskPluginDefinition = await this.#loadTaskPluginDefinitionAsync(); this.pluginDefinition.validateOptions(this.pluginOptions); } } @@ -130,7 +130,7 @@ export class HeftTask implements IHeftTask { return this.#taskPlugin; } - private async _loadTaskPluginDefinitionAsync(): Promise { + async #loadTaskPluginDefinitionAsync(): Promise { // taskPlugin.pluginPackage should already be resolved to the package root. // See CoreConfigFiles.heftConfigFileLoader const pluginSpecifier: IHeftConfigurationJsonPluginSpecifier = this.#taskSpecifier.taskPlugin; @@ -151,7 +151,7 @@ export class HeftTask implements IHeftTask { return pluginDefinition; } - private _validate(): void { + #validate(): void { if (RESERVED_TASK_NAMES.has(this.taskName)) { throw new Error( `Task name ${JSON.stringify(this.taskName)} is reserved and cannot be used as a task name.` diff --git a/apps/heft/src/pluginFramework/InternalHeftSession.ts b/apps/heft/src/pluginFramework/InternalHeftSession.ts index 2296b1add7c..b4c3dfff514 100644 --- a/apps/heft/src/pluginFramework/InternalHeftSession.ts +++ b/apps/heft/src/pluginFramework/InternalHeftSession.ts @@ -145,12 +145,12 @@ export class InternalHeftSession { } public get phases(): ReadonlySet { - this._ensurePhases(); + this.#ensurePhases(); return this.#phases!; } public get phasesByName(): ReadonlyMap { - this._ensurePhases(); + this.#ensurePhases(); return this.#phasesByName!; } @@ -163,7 +163,7 @@ export class InternalHeftSession { return phaseSession; } - private _ensurePhases(): void { + #ensurePhases(): void { if (!this.#phases || !this.#phasesByName) { this.#phasesByName = new Map(); for (const [phaseName, phaseSpecifier] of Object.entries( diff --git a/apps/heft/src/pluginFramework/StaticFileSystemAdapter.ts b/apps/heft/src/pluginFramework/StaticFileSystemAdapter.ts index cc4cc65f7fa..ad87f925862 100644 --- a/apps/heft/src/pluginFramework/StaticFileSystemAdapter.ts +++ b/apps/heft/src/pluginFramework/StaticFileSystemAdapter.ts @@ -54,7 +54,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { /** { @inheritdoc fs.lstatSync } */ public lstatSync: FileSystemAdapter['lstatSync'] = ((filePath: string) => { - filePath = this._normalizePath(filePath); + filePath = this.#normalizePath(filePath); const entry: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(filePath); if (!entry) { const error: NodeJS.ErrnoException = new Error(`ENOENT: no such file or directory, stat '${filePath}'`); @@ -126,7 +126,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { /** { @inheritdoc fs.readdirSync } */ public readdirSync: FileSystemAdapter['readdirSync'] = ((filePath: string, options?: IReaddirOptions) => { - filePath = this._normalizePath(filePath); + filePath = this.#normalizePath(filePath); const virtualDirectory: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(filePath); if (!virtualDirectory) { // Immitate a missing directory read from fs.readdir @@ -183,7 +183,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { * Add a file and it's parent directories to the static virtual filesystem. */ public addFile(filePath: string): void { - filePath = this._normalizePath(filePath); + filePath = this.#normalizePath(filePath); const existingPath: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(filePath); if (!existingPath) { // Set an entry without children for the file. Entries with undefined children are assumed to be files. @@ -219,7 +219,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { * Remove a file from the static virtual filesystem. */ public removeFile(filePath: string): void { - filePath = this._normalizePath(filePath); + filePath = this.#normalizePath(filePath); const existingEntry: IVirtualFileSystemEntry | undefined = this.#directoryMap.get(filePath); if (existingEntry) { // Remove the entry from the map and the parent's children set @@ -235,7 +235,7 @@ export class StaticFileSystemAdapter implements FileSystemAdapter { this.#directoryMap.clear(); } - private _normalizePath(filePath: string): string { + #normalizePath(filePath: string): string { // On Windows, normalize to backslashes so that errors have the correct path format return IS_WINDOWS ? Path.convertToBackslashes(filePath) : filePath; } diff --git a/apps/heft/src/pluginFramework/logging/ScopedLogger.ts b/apps/heft/src/pluginFramework/logging/ScopedLogger.ts index 12cf26cf399..50ec990a18a 100644 --- a/apps/heft/src/pluginFramework/logging/ScopedLogger.ts +++ b/apps/heft/src/pluginFramework/logging/ScopedLogger.ts @@ -61,7 +61,7 @@ export class ScopedLogger implements IScopedLogger { #errors: Error[] = []; #warnings: Error[] = []; - private get _shouldPrintStacks(): boolean { + get #shouldPrintStacks(): boolean { // TODO: Consider dumping stacks and more verbose logging to a file return this.#options.getShouldPrintStacks(); } @@ -108,7 +108,7 @@ export class ScopedLogger implements IScopedLogger { this.#options.errorHasBeenEmittedCallback(); this.#errors.push(error); this.terminal.writeErrorLine(`Error: ${LoggingManager.getErrorMessage(error)}`); - if (this._shouldPrintStacks && error.stack) { + if (this.#shouldPrintStacks && error.stack) { this.terminal.writeErrorLine(error.stack); } } @@ -120,7 +120,7 @@ export class ScopedLogger implements IScopedLogger { this.#options.warningHasBeenEmittedCallback(); this.#warnings.push(warning); this.terminal.writeWarningLine(`Warning: ${LoggingManager.getErrorMessage(warning)}`); - if (this._shouldPrintStacks && warning.stack) { + if (this.#shouldPrintStacks && warning.stack) { this.terminal.writeWarningLine(warning.stack); } } diff --git a/apps/heft/src/plugins/NodeServicePlugin.ts b/apps/heft/src/plugins/NodeServicePlugin.ts index 35da94dfe6f..98441617c6c 100644 --- a/apps/heft/src/plugins/NodeServicePlugin.ts +++ b/apps/heft/src/plugins/NodeServicePlugin.ts @@ -116,12 +116,12 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { taskSession.hooks.runIncremental.tapPromise( PLUGIN_NAME, async (runIncrementalOptions: IHeftTaskRunIncrementalHookOptions) => { - await this._runCommandAsync(taskSession, heftConfiguration); + await this.#runCommandAsync(taskSession, heftConfiguration); } ); } - private async _loadStageConfigurationAsync( + async #loadStageConfigurationAsync( taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration ): Promise { @@ -184,21 +184,21 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { } } - private async _runCommandAsync( + async #runCommandAsync( taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration ): Promise { - await this._loadStageConfigurationAsync(taskSession, heftConfiguration); + await this.#loadStageConfigurationAsync(taskSession, heftConfiguration); if (!this.#pluginEnabled) { return; } this.#logger.terminal.writeLine(`Starting Node service...`); - await this._stopChildAsync(); - this._startChild(); + await this.#stopChildAsync(); + this.#startChild(); } - private async _stopChildAsync(): Promise { + async #stopChildAsync(): Promise { if (this.#state !== State.Running) { if (this.#childProcessExitPromise) { // If we have an active process but are not in the running state, we must be in the process of @@ -210,7 +210,7 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { if (_isWindows) { // On Windows, SIGTERM can kill Cmd.exe and leave its children running in the background - this._transitionToKilling(); + this.#transitionToKilling(); } else { if (!this.#activeChildProcess) { // All the code paths that set _activeChildProcess=undefined should also leave the Running state @@ -229,12 +229,12 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { process.kill(-pid, 'SIGTERM'); } - this._clearTimeout(); + this.#clearTimeout(); this.#timeout = setTimeout(() => { try { if (this.#state !== State.Stopped) { this.#logger.terminal.writeWarningLine('The service process is taking too long to terminate'); - this._transitionToKilling(); + this.#transitionToKilling(); } } catch (e: unknown) { this.#childProcessExitPromiseRejectFn!(e); @@ -245,7 +245,7 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { await this.#childProcessExitPromise; } - private _transitionToKilling(): void { + #transitionToKilling(): void { this.#state = State.Killing; if (!this.#activeChildProcess) { @@ -257,14 +257,14 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { SubprocessTerminator.killProcessTree(this.#activeChildProcess, SubprocessTerminator.RECOMMENDED_OPTIONS); - this._clearTimeout(); + this.#clearTimeout(); this.#timeout = setTimeout(() => { try { if (this.#state !== State.Stopped) { this.#logger.terminal.writeErrorLine( 'Abandoning the service process because it could not be killed' ); - this._transitionToStopped(); + this.#transitionToStopped(); } } catch (e: unknown) { this.#childProcessExitPromiseRejectFn!(e); @@ -272,21 +272,21 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { }, this.#configuration.waitForKillMs); } - private _transitionToStopped(): void { + #transitionToStopped(): void { // Failed to start this.#state = State.Stopped; - this._clearTimeout(); + this.#clearTimeout(); this.#activeChildProcess = undefined; this.#childProcessExitPromiseResolveFn!(); } - private _startChild(): void { + #startChild(): void { if (this.#state !== State.Stopped) { throw new InternalError('Invalid state'); } this.#state = State.Running; - this._clearTimeout(); + this.#clearTimeout(); this.#logger.terminal.writeLine(`Invoking command: "${this.#shellCommand!}"`); const childProcess: child_process.ChildProcess = child_process.spawn(this.#shellCommand!, { @@ -324,18 +324,18 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { if (this.#state === State.Running) { this.#logger.terminal.writeWarningLine( `The service process #${childPid} terminated unexpectedly` + - this._formatCodeOrSignal(exitCode, signal) + this.#formatCodeOrSignal(exitCode, signal) ); - this._transitionToStopped(); + this.#transitionToStopped(); return; } if (this.#state === State.Stopping || this.#state === State.Killing) { this.#logger.terminal.writeVerboseLine( `The service process #${childPid} terminated successfully` + - this._formatCodeOrSignal(exitCode, signal) + this.#formatCodeOrSignal(exitCode, signal) ); - this._transitionToStopped(); + this.#transitionToStopped(); return; } } catch (e: unknown) { @@ -348,7 +348,7 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { // Under normal conditions we don't reject the promise here, because 'data' events can continue // to fire as data is flushed, before finally concluding with the 'close' event. this.#logger.terminal.writeVerboseLine( - `The service process fired its "exit" event` + this._formatCodeOrSignal(code, signal) + `The service process fired its "exit" event` + this.#formatCodeOrSignal(code, signal) ); } catch (e: unknown) { reject(e); @@ -367,7 +367,7 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { if (this.#state === State.Running) { this.#logger.terminal.writeErrorLine(`Failed to start: ` + err.toString()); - this._transitionToStopped(); + this.#transitionToStopped(); return; } @@ -375,7 +375,7 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { this.#logger.terminal.writeWarningLine( `The service process #${childPid} rejected the shutdown signal: ` + err.toString() ); - this._transitionToKilling(); + this.#transitionToKilling(); return; } @@ -383,7 +383,7 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { this.#logger.terminal.writeErrorLine( `The service process #${childPid} could not be killed: ` + err.toString() ); - this._transitionToStopped(); + this.#transitionToStopped(); return; } } catch (e: unknown) { @@ -395,14 +395,14 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { this.#activeChildProcess = childProcess; } - private _clearTimeout(): void { + #clearTimeout(): void { if (this.#timeout) { clearTimeout(this.#timeout); this.#timeout = undefined; } } - private _formatCodeOrSignal(code: number | null | undefined, signal: string | null | undefined): string { + #formatCodeOrSignal(code: number | null | undefined, signal: string | null | undefined): string { if (signal) { return ` (signal=${code})`; } diff --git a/apps/heft/src/plugins/RunScriptPlugin.ts b/apps/heft/src/plugins/RunScriptPlugin.ts index 6c74d9dfd56..43809ffb5a5 100644 --- a/apps/heft/src/plugins/RunScriptPlugin.ts +++ b/apps/heft/src/plugins/RunScriptPlugin.ts @@ -45,11 +45,11 @@ export default class RunScriptPlugin implements IHeftTaskPlugin { - await this._runScriptAsync(heftTaskSession, heftConfiguration, pluginOptions, runOptions); + await this.#runScriptAsync(heftTaskSession, heftConfiguration, pluginOptions, runOptions); }); } - private async _runScriptAsync( + async #runScriptAsync( heftTaskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration, pluginOptions: IRunScriptPluginOptions, diff --git a/apps/heft/src/utilities/GitUtilities.ts b/apps/heft/src/utilities/GitUtilities.ts index d1b9596f431..a8cc6ca4c5c 100644 --- a/apps/heft/src/utilities/GitUtilities.ts +++ b/apps/heft/src/utilities/GitUtilities.ts @@ -79,7 +79,7 @@ export class GitUtilities { `status ${result.status}: ${result.stderr}` ); } - this.#gitVersion = this._parseGitVersion(result.stdout); + this.#gitVersion = this.#parseGitVersion(result.stdout); } else { this.#gitVersion = undefined; } @@ -120,11 +120,11 @@ export class GitUtilities { return; } const gitRepoRootPath: string = gitInfo.root; - const ignoreMatcherMap: Map = await this._getIgnoreMatchersAsync(gitRepoRootPath); + const ignoreMatcherMap: Map = await this.#getIgnoreMatchersAsync(gitRepoRootPath); const matcherFiltersByMatcher: Map boolean> = new Map(); return (filePath: string) => { - const matcher: IIgnoreMatcher = this._findIgnoreMatcherForFilePath(filePath, ignoreMatcherMap); + const matcher: IIgnoreMatcher = this.#findIgnoreMatcherForFilePath(filePath, ignoreMatcherMap); let matcherFilter: ((filePath: string) => boolean) | undefined = matcherFiltersByMatcher.get(matcher); if (!matcherFilter) { matcherFilter = matcher.createFilter(); @@ -140,7 +140,7 @@ export class GitUtilities { }; } - private _findIgnoreMatcherForFilePath( + #findIgnoreMatcherForFilePath( filePath: string, ignoreMatcherMap: Map ): IIgnoreMatcher { @@ -172,7 +172,7 @@ export class GitUtilities { return foundMatcher; } - private async _getIgnoreMatchersAsync(gitRepoRootPath: string): Promise> { + async #getIgnoreMatchersAsync(gitRepoRootPath: string): Promise> { // Return early if we've already parsed the .gitignore matchers if (this.#ignoreMatcherByGitignoreFolder !== undefined) { return this.#ignoreMatcherByGitignoreFolder; @@ -191,7 +191,7 @@ export class GitUtilities { while (currentPath.length >= gitRepoRootPath.length) { const gitIgnoreFilePath: string = `${currentPath}/.gitignore`; const gitIgnorePatterns: string[] | undefined = - await this._tryReadGitIgnoreFileAsync(gitIgnoreFilePath); + await this.#tryReadGitIgnoreFileAsync(gitIgnoreFilePath); if (gitIgnorePatterns) { rawIgnorePatternsByGitignoreFolder.set(currentPath, gitIgnorePatterns); } @@ -199,11 +199,11 @@ export class GitUtilities { } // Load the .gitignore files for all subdirectories - const gitignoreRelativeFilePaths: string[] = await this._findUnignoredFilesAsync('*.gitignore'); + const gitignoreRelativeFilePaths: string[] = await this.#findUnignoredFilesAsync('*.gitignore'); for (const gitignoreRelativeFilePath of gitignoreRelativeFilePaths) { const gitignoreFilePath: string = `${normalizedWorkingDirectory}/${gitignoreRelativeFilePath}`; const gitIgnorePatterns: string[] | undefined = - await this._tryReadGitIgnoreFileAsync(gitignoreFilePath); + await this.#tryReadGitIgnoreFileAsync(gitignoreFilePath); if (gitIgnorePatterns) { const parentPath: string = gitignoreFilePath.slice(0, gitignoreFilePath.lastIndexOf('/')); rawIgnorePatternsByGitignoreFolder.set(parentPath, gitIgnorePatterns); @@ -272,7 +272,7 @@ export class GitUtilities { return this.#ignoreMatcherByGitignoreFolder; } - private async _tryReadGitIgnoreFileAsync(filePath: string): Promise { + async #tryReadGitIgnoreFileAsync(filePath: string): Promise { let gitIgnoreContent: string | undefined; try { gitIgnoreContent = await FileSystem.readFileAsync(filePath); @@ -299,9 +299,9 @@ export class GitUtilities { return foundIgnorePatterns.length ? foundIgnorePatterns : undefined; } - private async _findUnignoredFilesAsync(searchPattern: string | undefined): Promise { - this._ensureGitMinimumVersion({ major: 2, minor: 22, patch: 0 }); - this._ensurePathIsUnderGitWorkingTree(); + async #findUnignoredFilesAsync(searchPattern: string | undefined): Promise { + this.#ensureGitMinimumVersion({ major: 2, minor: 22, patch: 0 }); + this.#ensurePathIsUnderGitWorkingTree(); const args: string[] = [ '--cached', @@ -314,17 +314,17 @@ export class GitUtilities { if (searchPattern) { args.push(searchPattern); } - return await this._executeGitCommandAndCaptureOutputAsync({ + return await this.#executeGitCommandAndCaptureOutputAsync({ command: 'ls-files', args, delimiter: '\0' }); } - private async _executeGitCommandAndCaptureOutputAsync( + async #executeGitCommandAndCaptureOutputAsync( options: IExecuteGitCommandOptions ): Promise { - const gitPath: string = this._getGitPathOrThrow(); + const gitPath: string = this.#getGitPathOrThrow(); const processArgs: string[] = [options.command].concat(options.args || []); const childProcess: ChildProcess = Executable.spawn(gitPath, processArgs, { currentWorkingDirectory: this.#workingDirectory, @@ -370,7 +370,7 @@ export class GitUtilities { }); } - private _getGitPathOrThrow(): string { + #getGitPathOrThrow(): string { const gitPath: string | undefined = this.gitPath; if (!gitPath) { throw new Error('Git is not present'); @@ -379,7 +379,7 @@ export class GitUtilities { } } - private _ensureGitMinimumVersion(minimumGitVersion: IGitVersion): void { + #ensureGitMinimumVersion(minimumGitVersion: IGitVersion): void { const gitVersion: IGitVersion | undefined = this.getGitVersion(); if (!gitVersion) { throw new Error('Git is not present'); @@ -398,13 +398,13 @@ export class GitUtilities { } } - private _ensurePathIsUnderGitWorkingTree(): void { + #ensurePathIsUnderGitWorkingTree(): void { if (!this.isPathUnderGitWorkingTree()) { throw new Error(`The path "${this.#workingDirectory}" is not under a Git working tree`); } } - private _parseGitVersion(gitVersionOutput: string): IGitVersion { + #parseGitVersion(gitVersionOutput: string): IGitVersion { // This regexp matches output of "git version" that looks like // `git version ..(+whatever)` // Examples: From 6d76463d9a1f2d292d3b809dd3194e3527d526b4 Mon Sep 17 00:00:00 2001 From: Bharat Middha <5100938+bmiddha@users.noreply.github.com> Date: Wed, 19 Aug 2026 16:21:07 -0700 Subject: [PATCH 3/3] fix(heft): suppress legacy null warnings The decoupled ESLint plugin does not recognize native private methods, causing no-new-null to report false positives. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ebd5bf2-c44b-42d5-be25-e7936d4b0a14 --- apps/heft/src/plugins/NodeServicePlugin.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/heft/src/plugins/NodeServicePlugin.ts b/apps/heft/src/plugins/NodeServicePlugin.ts index 98441617c6c..1b3730619be 100644 --- a/apps/heft/src/plugins/NodeServicePlugin.ts +++ b/apps/heft/src/plugins/NodeServicePlugin.ts @@ -402,6 +402,7 @@ export default class NodeServicePlugin implements IHeftTaskPlugin { } } + // eslint-disable-next-line @rushstack/no-new-null -- The decoupled ESLint plugin does not recognize native private methods yet. #formatCodeOrSignal(code: number | null | undefined, signal: string | null | undefined): string { if (signal) { return ` (signal=${code})`;