@rushstack/heft
Advanced tools
Comparing version 0.58.0 to 0.58.1
@@ -395,3 +395,5 @@ /** | ||
* The `toolFinish` hook is called at the end of Heft execution. It is called after all phases have | ||
* completed execution. To use it, call | ||
* completed execution. Plugins that tap this hook are resposible for handling the scenario in which | ||
* `toolStart` threw an error, since this hook is used to clean up any resources allocated earlier | ||
* in the lifecycle and therefore runs even in error conditions. To use it, call | ||
* `toolFinish.tapPromise(<pluginName>, <callback>)`. | ||
@@ -402,2 +404,10 @@ * | ||
toolFinish: AsyncParallelHook<IHeftLifecycleToolFinishHookOptions>; | ||
/** | ||
* The `recordMetrics` hook is called at the end of every Heft execution pass. It is called after all | ||
* phases have completed execution (or been canceled). In a watch run, it will be called several times | ||
* in between `toolStart` and (if the session is gracefully interrupted via Ctrl+C), `toolFinish`. | ||
* In a non-watch run, it will be invoked exactly once between `toolStart` and `toolFinish`. | ||
* To use it, call `recordMetrics.tapPromise(<pluginName>, <callback>)`. | ||
* @public | ||
*/ | ||
recordMetrics: AsyncParallelHook<IHeftRecordMetricsHookOptions>; | ||
@@ -404,0 +414,0 @@ } |
@@ -18,4 +18,4 @@ "use strict"; | ||
const PhaseOperationRunner_1 = require("../operations/runners/PhaseOperationRunner"); | ||
const LifecycleOperationRunner_1 = require("../operations/runners/LifecycleOperationRunner"); | ||
const CancellationToken_1 = require("../pluginFramework/CancellationToken"); | ||
const DeleteFilesPlugin_1 = require("../plugins/DeleteFilesPlugin"); | ||
const Constants_1 = require("../utilities/Constants"); | ||
@@ -181,4 +181,2 @@ const OperationStatus_1 = require("../operations/OperationStatus"); | ||
this._internalHeftSession.parameterManager = this.parameterManager; | ||
initializeHeft(this._heftConfiguration, terminal, this.parameterManager.defaultParameters.verbose); | ||
const operations = this._generateOperations(); | ||
// Set up the ability to terminate the build via Ctrl+C and have it exit gracefully if pressed once, | ||
@@ -202,8 +200,20 @@ // less gracefully if pressed a second time. | ||
}); | ||
initializeHeft(this._heftConfiguration, terminal, this.parameterManager.defaultParameters.verbose); | ||
const operations = this._generateOperations(); | ||
const executionManager = new OperationExecutionManager_1.OperationExecutionManager(operations); | ||
if (this._action.watch) { | ||
await this._executeWatchAsync(executionManager, cliCancellationToken); | ||
try { | ||
await _startLifecycleAsync(this._internalHeftSession); | ||
if (this._action.watch) { | ||
await this._executeWatchAsync(executionManager, cliCancellationToken); | ||
} | ||
else { | ||
await this._executeOnceAsync(executionManager, cliCancellationToken); | ||
} | ||
} | ||
else { | ||
await this._executeOnceAsync(executionManager, cliCancellationToken); | ||
finally { | ||
// Invoke this here both to ensure it always runs and that it does so after recordMetrics | ||
// 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); | ||
} | ||
@@ -290,5 +300,2 @@ } | ||
const internalHeftSession = this._internalHeftSession; | ||
const cleanLifecycleOperation = _getOrCreateLifecycleOperation(internalHeftSession, 'clean', operations); | ||
const startLifecycleOperation = _getOrCreateLifecycleOperation(internalHeftSession, 'start', operations); | ||
const finishLifecycleOperation = _getOrCreateLifecycleOperation(internalHeftSession, 'finish', operations); | ||
let hasWarnedAboutSkippedPhases = false; | ||
@@ -310,11 +317,2 @@ for (const phase of selectedPhases) { | ||
const phaseOperation = _getOrCreatePhaseOperation(internalHeftSession, phase, operations); | ||
// Set the 'start' lifecycle operation as a dependency of all phases to ensure the 'start' lifecycle | ||
// operation runs first | ||
phaseOperation.addDependency(startLifecycleOperation); | ||
// Set the lifecycle clean operation as a dependency of the 'start' lifecycle operation to ensure the | ||
// clean operation runs first | ||
startLifecycleOperation.addDependency(cleanLifecycleOperation); | ||
// Set the phase operation as a dependency of the 'end' lifecycle operation to ensure the phase | ||
// operation runs first | ||
finishLifecycleOperation.addDependency(phaseOperation); | ||
// Create operations for each task | ||
@@ -325,5 +323,2 @@ for (const task of phase.tasks) { | ||
taskOperation.addDependency(phaseOperation); | ||
// Set the task operation as a dependency of the 'stop' lifecycle operation to ensure the task operation | ||
// runs first | ||
finishLifecycleOperation.addDependency(taskOperation); | ||
// Set all dependency tasks as dependencies of the task operation | ||
@@ -350,14 +345,2 @@ for (const dependencyTask of task.dependencyTasks) { | ||
exports.HeftActionRunner = HeftActionRunner; | ||
function _getOrCreateLifecycleOperation(internalHeftSession, type, operations) { | ||
const key = `lifecycle.${type}`; | ||
let operation = operations.get(key); | ||
if (!operation) { | ||
operation = new Operation_1.Operation({ | ||
groupName: 'lifecycle', | ||
runner: new LifecycleOperationRunner_1.LifecycleOperationRunner({ type, internalHeftSession }) | ||
}); | ||
operations.set(key, operation); | ||
} | ||
return operation; | ||
} | ||
function _getOrCreatePhaseOperation(internalHeftSession, phase, operations) { | ||
@@ -391,2 +374,61 @@ const key = phase.phaseName; | ||
} | ||
async function _startLifecycleAsync(internalHeftSession) { | ||
const { clean } = internalHeftSession.parameterManager.defaultParameters; | ||
// Load and apply the lifecycle plugins | ||
const lifecycle = internalHeftSession.lifecycle; | ||
const { lifecycleLogger } = lifecycle; | ||
await lifecycle.applyPluginsAsync(lifecycleLogger.terminal); | ||
if (lifecycleLogger.hasErrors) { | ||
throw new node_core_library_1.AlreadyReportedError(); | ||
} | ||
if (clean) { | ||
const startTime = perf_hooks_1.performance.now(); | ||
lifecycleLogger.terminal.writeVerboseLine('Starting clean'); | ||
// Grab the additional clean operations from the phase | ||
const deleteOperations = []; | ||
// Delete all temp folders for tasks by default | ||
for (const pluginDefinition of lifecycle.pluginDefinitions) { | ||
const lifecycleSession = await lifecycle.getSessionForPluginDefinitionAsync(pluginDefinition); | ||
deleteOperations.push({ sourcePath: lifecycleSession.tempFolderPath }); | ||
} | ||
// Create the options and provide a utility method to obtain paths to delete | ||
const cleanHookOptions = { | ||
addDeleteOperations: (...deleteOperationsToAdd) => deleteOperations.push(...deleteOperationsToAdd) | ||
}; | ||
// Run the plugin clean hook | ||
if (lifecycle.hooks.clean.isUsed()) { | ||
try { | ||
await lifecycle.hooks.clean.promise(cleanHookOptions); | ||
} | ||
catch (e) { | ||
// Log out using the clean logger, and return an error status | ||
if (!(e instanceof node_core_library_1.AlreadyReportedError)) { | ||
lifecycleLogger.emitError(e); | ||
} | ||
throw new node_core_library_1.AlreadyReportedError(); | ||
} | ||
} | ||
// Delete the files if any were specified | ||
if (deleteOperations.length) { | ||
const rootFolderPath = internalHeftSession.heftConfiguration.buildFolderPath; | ||
await (0, DeleteFilesPlugin_1.deleteFilesAsync)(rootFolderPath, deleteOperations, lifecycleLogger.terminal); | ||
} | ||
lifecycleLogger.terminal.writeVerboseLine(`Finished clean (${perf_hooks_1.performance.now() - startTime}ms)`); | ||
if (lifecycleLogger.hasErrors) { | ||
throw new node_core_library_1.AlreadyReportedError(); | ||
} | ||
} | ||
// Run the start hook | ||
if (lifecycle.hooks.toolStart.isUsed()) { | ||
const lifecycleToolStartHookOptions = {}; | ||
await lifecycle.hooks.toolStart.promise(lifecycleToolStartHookOptions); | ||
if (lifecycleLogger.hasErrors) { | ||
throw new node_core_library_1.AlreadyReportedError(); | ||
} | ||
} | ||
} | ||
async function _finishLifecycleAsync(internalHeftSession) { | ||
const lifecycleToolFinishHookOptions = {}; | ||
await internalHeftSession.lifecycle.hooks.toolFinish.promise(lifecycleToolFinishHookOptions); | ||
} | ||
//# sourceMappingURL=HeftActionRunner.js.map |
@@ -7,3 +7,2 @@ import { HeftPluginHost } from './HeftPluginHost'; | ||
import type { ScopedLogger } from './logging/ScopedLogger'; | ||
import type { LifecycleOperationRunnerType } from '../operations/runners/LifecycleOperationRunner'; | ||
export interface IHeftLifecycleContext { | ||
@@ -19,3 +18,3 @@ lifecycleSession?: HeftLifecycleSession; | ||
private readonly _lifecyclePluginsByDefinition; | ||
private readonly _lifecycleLoggersByType; | ||
private _lifecycleLogger; | ||
private _isInitialized; | ||
@@ -27,3 +26,3 @@ get hooks(): IHeftLifecycleHooks; | ||
ensureInitializedAsync(): Promise<void>; | ||
getLifecycleLoggerByType(type: LifecycleOperationRunnerType | undefined): ScopedLogger; | ||
get lifecycleLogger(): ScopedLogger; | ||
getSessionForPluginDefinitionAsync(pluginDefinition: HeftLifecyclePluginDefinition): Promise<IHeftLifecycleSession>; | ||
@@ -30,0 +29,0 @@ private _getLifecyclePluginForPluginDefinitionAsync; |
@@ -25,3 +25,2 @@ "use strict"; | ||
this._lifecyclePluginsByDefinition = new Map(); | ||
this._lifecycleLoggersByType = new Map(); | ||
this._isInitialized = false; | ||
@@ -116,7 +115,7 @@ this._internalHeftSession = internalHeftSession; | ||
} | ||
getLifecycleLoggerByType(type) { | ||
let logger = this._lifecycleLoggersByType.get(type); | ||
get lifecycleLogger() { | ||
let logger = this._lifecycleLogger; | ||
if (!logger) { | ||
logger = this._internalHeftSession.loggingManager.requestScopedLogger(`lifecycle${type === undefined ? '' : `:${type}`}`); | ||
this._lifecycleLoggersByType.set(type, logger); | ||
logger = this._internalHeftSession.loggingManager.requestScopedLogger(`lifecycle`); | ||
this._lifecycleLogger = logger; | ||
} | ||
@@ -123,0 +122,0 @@ return logger; |
@@ -79,3 +79,5 @@ import type { AsyncParallelHook } from 'tapable'; | ||
* The `toolFinish` hook is called at the end of Heft execution. It is called after all phases have | ||
* completed execution. To use it, call | ||
* completed execution. Plugins that tap this hook are resposible for handling the scenario in which | ||
* `toolStart` threw an error, since this hook is used to clean up any resources allocated earlier | ||
* in the lifecycle and therefore runs even in error conditions. To use it, call | ||
* `toolFinish.tapPromise(<pluginName>, <callback>)`. | ||
@@ -86,2 +88,10 @@ * | ||
toolFinish: AsyncParallelHook<IHeftLifecycleToolFinishHookOptions>; | ||
/** | ||
* The `recordMetrics` hook is called at the end of every Heft execution pass. It is called after all | ||
* phases have completed execution (or been canceled). In a watch run, it will be called several times | ||
* in between `toolStart` and (if the session is gracefully interrupted via Ctrl+C), `toolFinish`. | ||
* In a non-watch run, it will be invoked exactly once between `toolStart` and `toolFinish`. | ||
* To use it, call `recordMetrics.tapPromise(<pluginName>, <callback>)`. | ||
* @public | ||
*/ | ||
recordMetrics: AsyncParallelHook<IHeftRecordMetricsHookOptions>; | ||
@@ -88,0 +98,0 @@ } |
{ | ||
"name": "@rushstack/heft", | ||
"version": "0.58.0", | ||
"version": "0.58.1", | ||
"description": "Build all your JavaScript projects the same way: A way that works.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10
984862
220
10172