"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseRushAction = exports.BaseConfiglessRushAction = void 0;
const path = __importStar(require("node:path"));
const ts_command_line_1 = require("@rushstack/ts-command-line");
const node_core_library_1 = require("@rushstack/node-core-library");
const terminal_1 = require("@rushstack/terminal");
const EventHooksManager_1 = require("../../logic/EventHooksManager");
const RushCommandLineParser_1 = require("../RushCommandLineParser");
const Utilities_1 = require("../../utilities/Utilities");
const performance_1 = require("../../utilities/performance");
const PERF_PREFIX = 'rush:action';
/**
 * The base class for a few specialized Rush command-line actions that
 * can be used without a rush.json configuration.
 */
class BaseConfiglessRushAction extends ts_command_line_1.CommandLineAction {
    constructor(options) {
        super(options);
        const { parser, safeForSimultaneousRushProcesses } = options;
        this.parser = parser;
        const { rushConfiguration, terminal, rushSession, rushGlobalFolder } = parser;
        this._safeForSimultaneousRushProcesses = !!safeForSimultaneousRushProcesses;
        this.rushConfiguration = rushConfiguration;
        this.terminal = terminal;
        this.rushSession = rushSession;
        this.rushGlobalFolder = rushGlobalFolder;
    }
    async onExecuteAsync() {
        this._ensureEnvironment();
        if (this.rushConfiguration) {
            if (!this._safeForSimultaneousRushProcesses) {
                if (!node_core_library_1.LockFile.tryAcquire(this.rushConfiguration.commonTempFolder, 'rush')) {
                    this.terminal.writeLine(terminal_1.Colorize.red(`Another Rush command is already running in this repository.`));
                    process.exit(1);
                }
            }
        }
        if (!RushCommandLineParser_1.RushCommandLineParser.shouldRestrictConsoleOutput()) {
            this.terminal.write(`Starting "rush ${this.actionName}"\n`);
        }
        await (0, performance_1.measureAsyncFn)(`${PERF_PREFIX}:runAsync`, () => this.runAsync());
    }
    _ensureEnvironment() {
        if (this.rushConfiguration) {
            // eslint-disable-next-line dot-notation
            let environmentPath = process.env['PATH'];
            environmentPath =
                path.join(this.rushConfiguration.commonTempFolder, 'node_modules', '.bin') +
                    path.delimiter +
                    environmentPath;
            // eslint-disable-next-line dot-notation
            process.env['PATH'] = environmentPath;
        }
    }
}
exports.BaseConfiglessRushAction = BaseConfiglessRushAction;
/**
 * The base class that most Rush command-line actions should extend.
 */
class BaseRushAction extends BaseConfiglessRushAction {
    get eventHooksManager() {
        if (!this._eventHooksManager) {
            this._eventHooksManager = new EventHooksManager_1.EventHooksManager(this.rushConfiguration);
        }
        return this._eventHooksManager;
    }
    async onExecuteAsync() {
        if (!this.rushConfiguration) {
            throw Utilities_1.Utilities.getRushConfigNotFoundError();
        }
        this._throwPluginErrorIfNeed();
        await (0, performance_1.measureAsyncFn)(`${PERF_PREFIX}:initializePluginsAsync`, () => this.parser.pluginManager.tryInitializeAssociatedCommandPluginsAsync(this.actionName));
        this._throwPluginErrorIfNeed();
        const { hooks: sessionHooks } = this.rushSession;
        await (0, performance_1.measureAsyncFn)(`${PERF_PREFIX}:initializePlugins`, async () => {
            if (sessionHooks.initialize.isUsed()) {
                // Avoid the cost of compiling the hook if it wasn't tapped.
                await sessionHooks.initialize.promise(this);
            }
        });
        return super.onExecuteAsync();
    }
    /**
     * If an error is encountered while trying to load plugins, it is saved in the `PluginManager.error`
     * property, so we can defer throwing it until when `_throwPluginErrorIfNeed()` is called.
     */
    _throwPluginErrorIfNeed() {
        // If the plugin configuration is broken, these three commands are used to fix the problem:
        //
        //   "rush update"
        //   "rush init-autoinstaller"
        //   "rush update-autoinstaller"
        //
        // In addition, the "rush setup" command is designed to help new users configure their access
        // to a private NPM registry, which means it can't rely on plugins that might live in that
        // registry.
        //
        // Thus we do not report plugin errors when invoking these commands.
        if (!['update', 'init-autoinstaller', 'update-autoinstaller', 'setup'].includes(this.actionName)) {
            const pluginError = this.parser.pluginManager.error;
            if (pluginError) {
                throw pluginError;
            }
        }
    }
}
exports.BaseRushAction = BaseRushAction;
//# sourceMappingURL=BaseRushAction.js.map