@rushstack/heft
Advanced tools
Comparing version 0.56.3 to 0.57.0
@@ -8,5 +8,5 @@ // This file is read by tools that parse documentation comments conforming to the TSDoc standard. | ||
"packageName": "@microsoft/api-extractor", | ||
"packageVersion": "7.36.1" | ||
"packageVersion": "7.36.2" | ||
} | ||
] | ||
} |
@@ -67,3 +67,6 @@ "use strict"; | ||
// Delete the files | ||
await (0, DeleteFilesPlugin_1.deleteFilesAsync)(deleteOperations, this._terminal); | ||
if (deleteOperations.length > 0) { | ||
const rootFolderPath = this._internalHeftSession.heftConfiguration.buildFolderPath; | ||
await (0, DeleteFilesPlugin_1.deleteFilesAsync)(rootFolderPath, deleteOperations, this._terminal); | ||
} | ||
return deleteOperations.length === 0 ? OperationStatus_1.OperationStatus.NoOp : OperationStatus_1.OperationStatus.Success; | ||
@@ -70,0 +73,0 @@ } |
@@ -142,10 +142,12 @@ "use strict"; | ||
}); | ||
let cleanFlag; | ||
if (!this._action.watch) { | ||
// Only enable the clean flags in non-watch mode | ||
cleanFlag = parameterProvider.defineFlagParameter({ | ||
parameterLongName: Constants_1.Constants.cleanParameterLongName, | ||
description: 'If specified, clean the outputs before running each phase.' | ||
}); | ||
let cleanFlagDescription = 'If specified, clean the outputs at the beginning of the lifecycle and before running each phase.'; | ||
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.`; | ||
} | ||
const cleanFlag = parameterProvider.defineFlagParameter({ | ||
parameterLongName: Constants_1.Constants.cleanParameterLongName, | ||
description: cleanFlagDescription | ||
}); | ||
const parameterManager = new HeftParameterManager_1.HeftParameterManager({ | ||
@@ -286,2 +288,3 @@ getIsDebug: () => this._internalHeftSession.debug, | ||
const internalHeftSession = this._internalHeftSession; | ||
const cleanLifecycleOperation = _getOrCreateLifecycleOperation(internalHeftSession, 'clean', operations); | ||
const startLifecycleOperation = _getOrCreateLifecycleOperation(internalHeftSession, 'start', operations); | ||
@@ -308,2 +311,5 @@ const finishLifecycleOperation = _getOrCreateLifecycleOperation(internalHeftSession, 'finish', operations); | ||
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 | ||
@@ -310,0 +316,0 @@ // operation runs first |
import { OperationStatus } from '../OperationStatus'; | ||
import type { IOperationRunner, IOperationRunnerContext } from '../IOperationRunner'; | ||
import type { InternalHeftSession } from '../../pluginFramework/InternalHeftSession'; | ||
export type LifecycleOperationRunnerType = 'start' | 'finish'; | ||
export type LifecycleOperationRunnerType = 'clean' | 'start' | 'finish'; | ||
export interface ILifecycleOperationRunnerOptions { | ||
@@ -10,4 +10,5 @@ internalHeftSession: InternalHeftSession; | ||
export declare class LifecycleOperationRunner implements IOperationRunner { | ||
readonly silent: boolean; | ||
private readonly _options; | ||
readonly silent: boolean; | ||
private _isClean; | ||
get name(): string; | ||
@@ -14,0 +15,0 @@ constructor(options: ILifecycleOperationRunnerOptions); |
@@ -16,2 +16,3 @@ "use strict"; | ||
this.silent = true; | ||
this._isClean = false; | ||
this._options = options; | ||
@@ -22,50 +23,56 @@ } | ||
const { clean, watch } = internalHeftSession.parameterManager.defaultParameters; | ||
if (watch) { | ||
// Avoid running the lifecycle operation when in watch mode | ||
return OperationStatus_1.OperationStatus.NoOp; | ||
} | ||
// Load and apply the lifecycle plugins | ||
const lifecycle = internalHeftSession.lifecycle; | ||
const lifecycleLogger = internalHeftSession.loggingManager.requestScopedLogger(`lifecycle:${this._options.type}`); | ||
const lifecycleLogger = lifecycle.getLifecycleLoggerByType(undefined); | ||
await lifecycle.applyPluginsAsync(lifecycleLogger.terminal); | ||
const lifecycleTypeLogger = lifecycle.getLifecycleLoggerByType(type); | ||
switch (type) { | ||
case 'start': { | ||
// We can only apply the plugins once, so only do it during the start operation | ||
lifecycleLogger.terminal.writeVerboseLine('Applying lifecycle plugins'); | ||
await lifecycle.applyPluginsAsync(); | ||
// Run the clean hook | ||
if (clean) { | ||
const startTime = perf_hooks_1.performance.now(); | ||
const cleanLogger = internalHeftSession.loggingManager.requestScopedLogger(`lifecycle:clean`); | ||
cleanLogger.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 }); | ||
case 'clean': { | ||
if (this._isClean || !clean) { | ||
return OperationStatus_1.OperationStatus.NoOp; | ||
} | ||
const startTime = perf_hooks_1.performance.now(); | ||
lifecycleTypeLogger.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); | ||
} | ||
// 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)) { | ||
lifecycleTypeLogger.emitError(e); | ||
} | ||
catch (e) { | ||
// Log out using the clean logger, and return an error status | ||
if (!(e instanceof node_core_library_1.AlreadyReportedError)) { | ||
cleanLogger.emitError(e); | ||
} | ||
return OperationStatus_1.OperationStatus.Failure; | ||
} | ||
return OperationStatus_1.OperationStatus.Failure; | ||
} | ||
// Delete the files if any were specified | ||
if (deleteOperations.length) { | ||
await (0, DeleteFilesPlugin_1.deleteFilesAsync)(deleteOperations, cleanLogger.terminal); | ||
} | ||
cleanLogger.terminal.writeVerboseLine(`Finished clean (${perf_hooks_1.performance.now() - startTime}ms)`); | ||
} | ||
// Delete the files if any were specified | ||
if (deleteOperations.length) { | ||
const rootFolderPath = internalHeftSession.heftConfiguration.buildFolderPath; | ||
await (0, DeleteFilesPlugin_1.deleteFilesAsync)(rootFolderPath, deleteOperations, lifecycleTypeLogger.terminal); | ||
} | ||
// Ensure we only run the clean operation once | ||
this._isClean = true; | ||
lifecycleTypeLogger.terminal.writeVerboseLine(`Finished clean (${perf_hooks_1.performance.now() - startTime}ms)`); | ||
break; | ||
} | ||
case 'start': { | ||
// Run the start hook | ||
if (lifecycle.hooks.toolStart.isUsed()) { | ||
if (watch) { | ||
// Avoid running the toolStart hooks if we're in watch mode | ||
lifecycleTypeLogger.terminal.writeVerboseLine(`Lifecycle plugins aren't currently supported in watch mode.`); | ||
return OperationStatus_1.OperationStatus.NoOp; | ||
} | ||
const lifecycleToolStartHookOptions = {}; | ||
@@ -78,2 +85,7 @@ await lifecycle.hooks.toolStart.promise(lifecycleToolStartHookOptions); | ||
if (lifecycle.hooks.toolFinish.isUsed()) { | ||
if (watch) { | ||
// Avoid running the toolFinish hooks if we're in watch mode | ||
lifecycleTypeLogger.terminal.writeWarningLine(`Lifecycle plugins aren't currently supported in watch mode.`); | ||
return OperationStatus_1.OperationStatus.NoOp; | ||
} | ||
const lifeycleToolFinishHookOptions = {}; | ||
@@ -80,0 +92,0 @@ await lifecycle.hooks.toolFinish.promise(lifeycleToolFinishHookOptions); |
@@ -12,2 +12,3 @@ import { OperationStatus } from '../OperationStatus'; | ||
private readonly _options; | ||
private _isClean; | ||
get name(): string; | ||
@@ -14,0 +15,0 @@ constructor(options: IPhaseOperationRunnerOptions); |
@@ -15,2 +15,3 @@ "use strict"; | ||
this.silent = true; | ||
this._isClean = false; | ||
this._options = options; | ||
@@ -20,29 +21,28 @@ } | ||
const { internalHeftSession, phase } = this._options; | ||
const { clean, watch } = internalHeftSession.parameterManager.defaultParameters; | ||
const { clean } = internalHeftSession.parameterManager.defaultParameters; | ||
// Load and apply the plugins for this phase only | ||
const phaseSession = internalHeftSession.getSessionForPhase(phase); | ||
const { phaseLogger, cleanLogger } = phaseSession; | ||
phaseLogger.terminal.writeVerboseLine('Applying task plugins'); | ||
await phaseSession.applyPluginsAsync(); | ||
if (watch) { | ||
// Avoid running the phase operation when in watch mode | ||
await phaseSession.applyPluginsAsync(phaseLogger.terminal); | ||
if (this._isClean || !clean) { | ||
return OperationStatus_1.OperationStatus.NoOp; | ||
} | ||
// Run the clean hook | ||
if (clean) { | ||
const startTime = perf_hooks_1.performance.now(); | ||
// Grab the additional clean operations from the phase | ||
cleanLogger.terminal.writeVerboseLine('Starting clean'); | ||
const deleteOperations = Array.from(phase.cleanFiles); | ||
// Delete all temp folders for tasks by default | ||
for (const task of phase.tasks) { | ||
const taskSession = phaseSession.getSessionForTask(task); | ||
deleteOperations.push({ sourcePath: taskSession.tempFolderPath }); | ||
} | ||
// Delete the files if any were specified | ||
if (deleteOperations.length) { | ||
await (0, DeleteFilesPlugin_1.deleteFilesAsync)(deleteOperations, cleanLogger.terminal); | ||
} | ||
cleanLogger.terminal.writeVerboseLine(`Finished clean (${perf_hooks_1.performance.now() - startTime}ms)`); | ||
const startTime = perf_hooks_1.performance.now(); | ||
// Grab the additional clean operations from the phase | ||
cleanLogger.terminal.writeVerboseLine('Starting clean'); | ||
const deleteOperations = Array.from(phase.cleanFiles); | ||
// Delete all temp folders for tasks by default | ||
for (const task of phase.tasks) { | ||
const taskSession = phaseSession.getSessionForTask(task); | ||
deleteOperations.push({ sourcePath: taskSession.tempFolderPath }); | ||
} | ||
// Delete the files if any were specified | ||
if (deleteOperations.length) { | ||
const rootFolderPath = internalHeftSession.heftConfiguration.buildFolderPath; | ||
await (0, DeleteFilesPlugin_1.deleteFilesAsync)(rootFolderPath, deleteOperations, cleanLogger.terminal); | ||
} | ||
// Ensure we only run the clean operation once | ||
this._isClean = true; | ||
cleanLogger.terminal.writeVerboseLine(`Finished clean (${perf_hooks_1.performance.now() - startTime}ms)`); | ||
// Return success and allow for the TaskOperationRunner to execute tasks | ||
@@ -49,0 +49,0 @@ return OperationStatus_1.OperationStatus.Success; |
@@ -119,8 +119,11 @@ "use strict"; | ||
if (this._fileOperations) { | ||
const rootFolderPath = this._options.internalHeftSession.heftConfiguration.buildFolderPath; | ||
const { copyOperations, deleteOperations } = this._fileOperations; | ||
await Promise.all([ | ||
copyOperations.size > 0 | ||
? (0, CopyFilesPlugin_1.copyFilesAsync)(copyOperations, logger.terminal, isWatchMode ? getWatchFileSystemAdapter() : undefined) | ||
? (0, CopyFilesPlugin_1.copyFilesAsync)(rootFolderPath, copyOperations, logger.terminal, isWatchMode ? getWatchFileSystemAdapter() : undefined) | ||
: Promise.resolve(), | ||
deleteOperations.size > 0 ? (0, DeleteFilesPlugin_1.deleteFilesAsync)(deleteOperations, logger.terminal) : Promise.resolve() | ||
deleteOperations.size > 0 | ||
? (0, DeleteFilesPlugin_1.deleteFilesAsync)(rootFolderPath, deleteOperations, logger.terminal) | ||
: Promise.resolve() | ||
]); | ||
@@ -127,0 +130,0 @@ } |
@@ -6,2 +6,4 @@ import { HeftPluginHost } from './HeftPluginHost'; | ||
import { HeftLifecycleSession, type IHeftLifecycleHooks, type IHeftLifecycleSession } from './HeftLifecycleSession'; | ||
import type { ScopedLogger } from './logging/ScopedLogger'; | ||
import type { LifecycleOperationRunnerType } from '../operations/runners/LifecycleOperationRunner'; | ||
export interface IHeftLifecycleContext { | ||
@@ -17,2 +19,3 @@ lifecycleSession?: HeftLifecycleSession; | ||
private readonly _lifecyclePluginsByDefinition; | ||
private readonly _lifecycleLoggersByType; | ||
private _isInitialized; | ||
@@ -24,2 +27,3 @@ get hooks(): IHeftLifecycleHooks; | ||
ensureInitializedAsync(): Promise<void>; | ||
getLifecycleLoggerByType(type: LifecycleOperationRunnerType | undefined): ScopedLogger; | ||
getSessionForPluginDefinitionAsync(pluginDefinition: HeftLifecyclePluginDefinition): Promise<IHeftLifecycleSession>; | ||
@@ -26,0 +30,0 @@ private _getLifecyclePluginForPluginDefinitionAsync; |
@@ -25,2 +25,3 @@ "use strict"; | ||
this._lifecyclePluginsByDefinition = new Map(); | ||
this._lifecycleLoggersByType = new Map(); | ||
this._isInitialized = false; | ||
@@ -115,2 +116,10 @@ this._internalHeftSession = internalHeftSession; | ||
} | ||
getLifecycleLoggerByType(type) { | ||
let logger = this._lifecycleLoggersByType.get(type); | ||
if (!logger) { | ||
logger = this._internalHeftSession.loggingManager.requestScopedLogger(`lifecycle${type === undefined ? '' : `:${type}`}`); | ||
this._lifecycleLoggersByType.set(type, logger); | ||
} | ||
return logger; | ||
} | ||
async getSessionForPluginDefinitionAsync(pluginDefinition) { | ||
@@ -117,0 +126,0 @@ await this.ensureInitializedAsync(); |
@@ -0,1 +1,2 @@ | ||
import { type ITerminal } from '@rushstack/node-core-library'; | ||
import type { HeftPluginDefinitionBase } from '../configuration/HeftPluginDefinition'; | ||
@@ -6,3 +7,3 @@ import type { IHeftPlugin } from './IHeftPlugin'; | ||
private _pluginsApplied; | ||
applyPluginsAsync(): Promise<void>; | ||
applyPluginsAsync(terminal: ITerminal): Promise<void>; | ||
protected abstract applyPluginsInternalAsync(): Promise<void>; | ||
@@ -9,0 +10,0 @@ /** |
@@ -14,3 +14,3 @@ "use strict"; | ||
} | ||
async applyPluginsAsync() { | ||
async applyPluginsAsync(terminal) { | ||
if (this._pluginsApplied) { | ||
@@ -20,2 +20,3 @@ // No need to apply them a second time. | ||
} | ||
terminal.writeVerboseLine('Applying plugins'); | ||
await this.applyPluginsInternalAsync(); | ||
@@ -22,0 +23,0 @@ this._pluginsApplied = true; |
@@ -51,3 +51,3 @@ import { ITerminal } from '@rushstack/node-core-library'; | ||
} | ||
export declare function copyFilesAsync(copyOperations: Iterable<ICopyOperation>, terminal: ITerminal, watchFileSystemAdapter?: WatchFileSystemAdapter): Promise<void>; | ||
export declare function copyFilesAsync(rootFolderPath: string, copyOperations: Iterable<ICopyOperation>, terminal: ITerminal, watchFileSystemAdapter?: WatchFileSystemAdapter): Promise<void>; | ||
export default class CopyFilesPlugin implements IHeftTaskPlugin<ICopyFilesPluginOptions> { | ||
@@ -54,0 +54,0 @@ apply(taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration, pluginOptions: ICopyFilesPluginOptions): void; |
@@ -33,8 +33,8 @@ "use strict"; | ||
const FileGlobSpecifier_1 = require("./FileGlobSpecifier"); | ||
async function copyFilesAsync(copyOperations, terminal, watchFileSystemAdapter) { | ||
const copyDescriptorByDestination = await _getCopyDescriptorsAsync(copyOperations, watchFileSystemAdapter); | ||
async function copyFilesAsync(rootFolderPath, copyOperations, terminal, watchFileSystemAdapter) { | ||
const copyDescriptorByDestination = await _getCopyDescriptorsAsync(rootFolderPath, copyOperations, watchFileSystemAdapter); | ||
await _copyFilesInnerAsync(copyDescriptorByDestination, terminal); | ||
} | ||
exports.copyFilesAsync = copyFilesAsync; | ||
async function _getCopyDescriptorsAsync(copyConfigurations, fs) { | ||
async function _getCopyDescriptorsAsync(rootFolderPath, copyConfigurations, fs) { | ||
// Create a map to deduplicate and prevent double-writes | ||
@@ -46,2 +46,3 @@ // resolvedDestinationFilePath -> descriptor | ||
// and the filename in "includeGlobs" | ||
copyConfiguration.sourcePath = path.resolve(rootFolderPath, copyConfiguration.sourcePath); | ||
const sourceFolder = copyConfiguration.sourcePath; | ||
@@ -48,0 +49,0 @@ const sourceFilePaths = await (0, FileGlobSpecifier_1.getFilePathsAsync)(copyConfiguration, fs); |
@@ -16,3 +16,3 @@ import { ITerminal } from '@rushstack/node-core-library'; | ||
} | ||
export declare function deleteFilesAsync(deleteOperations: Iterable<IDeleteOperation>, terminal: ITerminal): Promise<void>; | ||
export declare function deleteFilesAsync(rootFolderPath: string, deleteOperations: Iterable<IDeleteOperation>, terminal: ITerminal): Promise<void>; | ||
export default class DeleteFilesPlugin implements IHeftTaskPlugin<IDeleteFilesPluginOptions> { | ||
@@ -19,0 +19,0 @@ apply(taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration, pluginOptions: IDeleteFilesPluginOptions): void; |
@@ -33,6 +33,7 @@ "use strict"; | ||
const FileGlobSpecifier_1 = require("./FileGlobSpecifier"); | ||
async function _getPathsToDeleteAsync(deleteOperations) { | ||
async function _getPathsToDeleteAsync(rootFolderPath, deleteOperations) { | ||
const pathsToDelete = new Set(); | ||
await node_core_library_1.Async.forEachAsync(deleteOperations, async (deleteOperation) => { | ||
var _a, _b, _c; | ||
deleteOperation.sourcePath = path.resolve(rootFolderPath, deleteOperation.sourcePath); | ||
if (!((_a = deleteOperation.fileExtensions) === null || _a === void 0 ? void 0 : _a.length) && | ||
@@ -55,4 +56,4 @@ !((_b = deleteOperation.includeGlobs) === null || _b === void 0 ? void 0 : _b.length) && | ||
} | ||
async function deleteFilesAsync(deleteOperations, terminal) { | ||
const pathsToDelete = await _getPathsToDeleteAsync(deleteOperations); | ||
async function deleteFilesAsync(rootFolderPath, deleteOperations, terminal) { | ||
const pathsToDelete = await _getPathsToDeleteAsync(rootFolderPath, deleteOperations); | ||
await _deleteFilesInnerAsync(pathsToDelete, terminal); | ||
@@ -59,0 +60,0 @@ } |
{ | ||
"name": "@rushstack/heft", | ||
"version": "0.56.3", | ||
"version": "0.57.0", | ||
"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
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
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
992497
10224