UNPKG

@rushstack/heft

Version:

Build all your JavaScript projects the same way: A way that works.

147 lines 8.45 kB
"use strict"; // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. // See LICENSE in the project root for license information. Object.defineProperty(exports, "__esModule", { value: true }); exports.HeftLifecycle = void 0; const tapable_1 = require("tapable"); const node_core_library_1 = require("@rushstack/node-core-library"); const HeftPluginConfiguration_1 = require("../configuration/HeftPluginConfiguration"); const HeftPluginHost_1 = require("./HeftPluginHost"); const HeftLifecycleSession_1 = require("./HeftLifecycleSession"); class HeftLifecycle extends HeftPluginHost_1.HeftPluginHost { get hooks() { return this._lifecycleHooks; } get pluginDefinitions() { if (!this._isInitialized) { throw new node_core_library_1.InternalError('HeftLifecycle.ensureInitializedAsync() must be called before accessing HeftLifecycle.pluginDefinitions.'); } return this._lifecycleContextByDefinition.keys(); } constructor(internalHeftSession, lifecyclePluginSpecifiers) { super(); this._lifecycleContextByDefinition = new Map(); this._lifecyclePluginsByDefinition = new Map(); this._isInitialized = false; this._internalHeftSession = internalHeftSession; this._lifecyclePluginSpecifiers = lifecyclePluginSpecifiers; this._lifecycleHooks = { clean: new tapable_1.AsyncParallelHook(), toolStart: new tapable_1.AsyncParallelHook(), toolFinish: new tapable_1.AsyncParallelHook(), recordMetrics: internalHeftSession.metricsCollector.recordMetricsHook, taskStart: new tapable_1.AsyncParallelHook(['task']), taskFinish: new tapable_1.AsyncParallelHook(['task']), phaseStart: new tapable_1.AsyncParallelHook(['phase']), phaseFinish: new tapable_1.AsyncParallelHook(['phase']) }; } async applyPluginsInternalAsync() { await this.ensureInitializedAsync(); // Load up all plugins concurrently const loadPluginPromises = []; for (const [pluginDefinition, lifecycleContext] of this._lifecycleContextByDefinition) { if (!lifecycleContext.lifecycleSession) { // Generate the plugin-specific session lifecycleContext.lifecycleSession = new HeftLifecycleSession_1.HeftLifecycleSession({ 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), pluginDefinition: pluginDefinition, pluginHost: this }); } loadPluginPromises.push(this._getLifecyclePluginForPluginDefinitionAsync(pluginDefinition, lifecycleContext.lifecycleSession)); } // Promise.all maintains the order of the input array const plugins = await Promise.all(loadPluginPromises); // Iterate through and apply the plugins let pluginIndex = 0; for (const [pluginDefinition, lifecycleContext] of this._lifecycleContextByDefinition) { const lifecyclePlugin = plugins[pluginIndex++]; try { // Apply the plugin. We know the session should exist because we generated it above. lifecyclePlugin.apply(lifecycleContext.lifecycleSession, this._internalHeftSession.heftConfiguration, lifecycleContext.pluginOptions); } catch (error) { throw new Error(`Error applying plugin ${JSON.stringify(pluginDefinition.pluginName)} from package ` + `${JSON.stringify(pluginDefinition.pluginPackageName)}: ${error}`); } } // Do a second pass to apply the plugin access requests for each plugin pluginIndex = 0; for (const [pluginDefinition] of this._lifecycleContextByDefinition) { const lifecyclePlugin = plugins[pluginIndex++]; this.resolvePluginAccessRequests(lifecyclePlugin, pluginDefinition); } } async ensureInitializedAsync() { if (!this._isInitialized) { this._isInitialized = true; // Load up all plugin configurations concurrently const pluginConfigurationPromises = []; for (const pluginSpecifier of this._lifecyclePluginSpecifiers) { const { pluginPackageRoot, pluginPackage } = pluginSpecifier; pluginConfigurationPromises.push(HeftPluginConfiguration_1.HeftPluginConfiguration.loadFromPackageAsync(pluginPackageRoot, pluginPackage)); } // Promise.all maintains the order of the input array const pluginConfigurations = await Promise.all(pluginConfigurationPromises); // Iterate through and generate the lifecycle context for each plugin let pluginConfigurationIndex = 0; for (const pluginSpecifier of this._lifecyclePluginSpecifiers) { const pluginConfiguration = pluginConfigurations[pluginConfigurationIndex++]; const pluginDefinition = pluginConfiguration.getPluginDefinitionBySpecifier(pluginSpecifier); // Ensure the plugin is a lifecycle plugin const isLifecyclePlugin = pluginConfiguration.isLifecyclePluginDefinition(pluginDefinition); if (!isLifecyclePlugin) { throw new Error(`Plugin ${JSON.stringify(pluginDefinition.pluginName)} from package ` + `${JSON.stringify(pluginSpecifier.pluginPackage)} is not a lifecycle plugin.`); } // Ensure there are no duplicate plugin names within the same package 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.`); } // Validate the plugin options const pluginOptions = pluginSpecifier.options; pluginDefinition.validateOptions(pluginOptions); // Partially populate the context. The session will be populated while applying the plugins. const lifecycleContext = { pluginOptions }; this._lifecycleContextByDefinition.set(pluginDefinition, lifecycleContext); } } } get lifecycleLogger() { let logger = this._lifecycleLogger; if (!logger) { logger = this._internalHeftSession.loggingManager.requestScopedLogger(`lifecycle`); this._lifecycleLogger = logger; } return logger; } async getSessionForPluginDefinitionAsync(pluginDefinition) { await this.ensureInitializedAsync(); const lifecycleContext = this._lifecycleContextByDefinition.get(pluginDefinition); if (!lifecycleContext) { throw new node_core_library_1.InternalError(`Could not find lifecycle context for plugin ${JSON.stringify(pluginDefinition.pluginName)}.`); } if (!lifecycleContext.lifecycleSession) { throw new node_core_library_1.InternalError(`Lifecycle session for plugin ${JSON.stringify(pluginDefinition.pluginName)} has not been created yet.`); } return lifecycleContext.lifecycleSession; } async _getLifecyclePluginForPluginDefinitionAsync(pluginDefinition, lifecycleSession) { let lifecyclePlugin = this._lifecyclePluginsByDefinition.get(pluginDefinition); if (!lifecyclePlugin) { lifecyclePlugin = await pluginDefinition.loadPluginAsync(lifecycleSession.logger); this._lifecyclePluginsByDefinition.set(pluginDefinition, lifecyclePlugin); } return lifecyclePlugin; } } exports.HeftLifecycle = HeftLifecycle; //# sourceMappingURL=HeftLifecycle.js.map