diff --git a/apps/heft/src/cli/HeftActionRunner.ts b/apps/heft/src/cli/HeftActionRunner.ts index 5ee37a193c3..8fff0cd5d89 100644 --- a/apps/heft/src/cli/HeftActionRunner.ts +++ b/apps/heft/src/cli/HeftActionRunner.ts @@ -76,6 +76,35 @@ export function initializeHeft( terminal.writeVerboseLine(''); } +let _cliAbortSignal: AbortSignal | undefined; +export function ensureCliAbortSignal(terminal: ITerminal): AbortSignal { + if (!_cliAbortSignal) { + // Set up the ability to terminate the build via Ctrl+C and have it exit gracefully if pressed once, + // less gracefully if pressed a second time. + const cliAbortController: AbortController = new AbortController(); + _cliAbortSignal = cliAbortController.signal; + const cli: ReadlineInterface = createInterface(process.stdin, undefined, undefined, true); + let forceTerminate: boolean = false; + cli.on('SIGINT', () => { + cli.close(); + + if (forceTerminate) { + terminal.writeErrorLine(`Forcibly terminating.`); + process.exit(1); + } else { + terminal.writeLine( + Colors.yellow(Colors.bold(`Canceling... Press Ctrl+C again to forcibly terminate.`)) + ); + } + + forceTerminate = true; + cliAbortController.abort(); + }); + } + + return _cliAbortSignal; +} + export async function runWithLoggingAsync( fn: () => Promise, action: IHeftAction, @@ -272,7 +301,7 @@ export class HeftActionRunner { const executionManager: OperationExecutionManager = new OperationExecutionManager(operations); - const cliAbortSignal: AbortSignal = this._createCliAbortSignal(); + const cliAbortSignal: AbortSignal = ensureCliAbortSignal(this._terminal); try { await _startLifecycleAsync(this._internalHeftSession); @@ -300,33 +329,6 @@ export class HeftActionRunner { } } - private _createCliAbortSignal(): AbortSignal { - // Set up the ability to terminate the build via Ctrl+C and have it exit gracefully if pressed once, - // less gracefully if pressed a second time. - const cliAbortController: AbortController = new AbortController(); - const cliAbortSignal: AbortSignal = cliAbortController.signal; - const cli: ReadlineInterface = createInterface(process.stdin, undefined, undefined, true); - const terminal: ITerminal = this._terminal; - let forceTerminate: boolean = false; - cli.on('SIGINT', () => { - cli.close(); - - if (forceTerminate) { - terminal.writeErrorLine(`Forcibly terminating.`); - process.exit(1); - } else { - terminal.writeLine( - Colors.yellow(Colors.bold(`Canceling build... Press Ctrl+C again to forcibly terminate.`)) - ); - } - - forceTerminate = true; - cliAbortController.abort(); - }); - - return cliAbortSignal; - } - private _createWatchLoop(executionManager: OperationExecutionManager): WatchLoop { const { _terminal: terminal } = this; const watchLoop: WatchLoop = new WatchLoop({ diff --git a/apps/heft/src/cli/actions/CleanAction.ts b/apps/heft/src/cli/actions/CleanAction.ts index c76bf852c66..db0a7db7a7b 100644 --- a/apps/heft/src/cli/actions/CleanAction.ts +++ b/apps/heft/src/cli/actions/CleanAction.ts @@ -18,7 +18,7 @@ import type { HeftTaskSession } from '../../pluginFramework/HeftTaskSession'; import { Constants } from '../../utilities/Constants'; import { definePhaseScopingParameters, expandPhases } from './RunAction'; import { deleteFilesAsync, type IDeleteOperation } from '../../plugins/DeleteFilesPlugin'; -import { initializeHeft, runWithLoggingAsync } from '../HeftActionRunner'; +import { ensureCliAbortSignal, initializeHeft, runWithLoggingAsync } from '../HeftActionRunner'; export class CleanAction extends CommandLineAction implements IHeftAction { public readonly watch: boolean = false; @@ -78,7 +78,7 @@ export class CleanAction extends CommandLineAction implements IHeftAction { protected async onExecute(): Promise { const { heftConfiguration } = this._internalHeftSession; - const abortSignal: AbortSignal = new AbortSignal(); + const abortSignal: AbortSignal = ensureCliAbortSignal(this._terminal); initializeHeft(heftConfiguration, this._terminal, this._verboseFlag.value); await runWithLoggingAsync( diff --git a/common/changes/@rushstack/heft/fix-heft-clean_2023-09-26-20-16.json b/common/changes/@rushstack/heft/fix-heft-clean_2023-09-26-20-16.json new file mode 100644 index 00000000000..2a6be3d1d50 --- /dev/null +++ b/common/changes/@rushstack/heft/fix-heft-clean_2023-09-26-20-16.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@rushstack/heft", + "comment": "Fix an issue where `heft clean` would crash with `ERR_ILLEGAL_CONSTRUCTOR`.", + "type": "patch" + } + ], + "packageName": "@rushstack/heft" +} \ No newline at end of file