"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.Rush = void 0;
const path = __importStar(require("node:path"));
const node_core_library_1 = require("@rushstack/node-core-library");
require("../utilities/SetRushLibPath");
const RushCommandLineParser_1 = require("../cli/RushCommandLineParser");
const RushStartupBanner_1 = require("../cli/RushStartupBanner");
const RushXCommandLine_1 = require("../cli/RushXCommandLine");
const CommandLineMigrationAdvisor_1 = require("../cli/CommandLineMigrationAdvisor");
const EnvironmentConfiguration_1 = require("./EnvironmentConfiguration");
const RushPnpmCommandLine_1 = require("../cli/RushPnpmCommandLine");
const performance_1 = require("../utilities/performance");
/**
 * General operations for the Rush engine.
 *
 * @public
 */
class Rush {
    /**
     * This API is used by the `@microsoft/rush` front end to launch the "rush" command-line.
     * Third-party tools should not use this API.  Instead, they should execute the "rush" binary
     * and start a new Node.js process.
     *
     * @remarks
     * Earlier versions of the rush frontend used a different API contract. In the old contract,
     * the second argument was the `isManaged` value of the {@link ILaunchOptions} object.
     *
     * Even though this API isn't documented, it is still supported for legacy compatibility.
     */
    static launch(launcherVersion, options) {
        options = Rush._normalizeLaunchOptions(options);
        if (!RushCommandLineParser_1.RushCommandLineParser.shouldRestrictConsoleOutput()) {
            RushStartupBanner_1.RushStartupBanner.logBanner(Rush.version, options.isManaged);
        }
        if (!CommandLineMigrationAdvisor_1.CommandLineMigrationAdvisor.checkArgv(process.argv)) {
            // The migration advisor recognized an obsolete command-line
            process.exitCode = 1;
            return;
        }
        Rush._assignRushInvokedFolder();
        const parser = new RushCommandLineParser_1.RushCommandLineParser({
            alreadyReportedNodeTooNewError: options.alreadyReportedNodeTooNewError,
            builtInPluginConfigurations: options.builtInPluginConfigurations
        });
        // CommandLineParser.executeAsync() should never reject the promise
        // eslint-disable-next-line no-console
        (0, performance_1.measureAsyncFn)('rush:parser:executeAsync', () => parser.executeAsync()).catch(console.error);
    }
    /**
     * This API is used by the `@microsoft/rush` front end to launch the "rushx" command-line.
     * Third-party tools should not use this API.  Instead, they should execute the "rushx" binary
     * and start a new Node.js process.
     */
    static launchRushX(launcherVersion, options) {
        options = Rush._normalizeLaunchOptions(options);
        Rush._assignRushInvokedFolder();
        // eslint-disable-next-line no-console
        RushXCommandLine_1.RushXCommandLine.launchRushXAsync(launcherVersion, options).catch(console.error); // CommandLineParser.executeAsync() should never reject the promise
    }
    /**
     * This API is used by the `@microsoft/rush` front end to launch the "rush-pnpm" command-line.
     * Third-party tools should not use this API.  Instead, they should execute the "rush-pnpm" binary
     * and start a new Node.js process.
     */
    static launchRushPnpm(launcherVersion, options) {
        Rush._assignRushInvokedFolder();
        RushPnpmCommandLine_1.RushPnpmCommandLine.launch(launcherVersion, { ...options });
    }
    /**
     * The currently executing version of the "rush-lib" library.
     * This is the same as the Rush tool version for that release.
     */
    static get version() {
        return this._rushLibPackageJson.version;
    }
    /**
     * @internal
     */
    static get _rushLibPackageJson() {
        Rush._ensureOwnPackageJsonIsLoaded();
        return Rush.__rushLibPackageJson;
    }
    static get _rushLibPackageFolder() {
        Rush._ensureOwnPackageJsonIsLoaded();
        return Rush.__rushLibPackageFolder;
    }
    static _ensureOwnPackageJsonIsLoaded() {
        if (!Rush.__rushLibPackageJson) {
            const packageJsonFilePath = node_core_library_1.PackageJsonLookup.instance.tryGetPackageJsonFilePathFor(__dirname);
            if (!packageJsonFilePath) {
                throw new node_core_library_1.InternalError('Unable to locate the package.json file for this module');
            }
            Rush.__rushLibPackageFolder = path.dirname(packageJsonFilePath);
            Rush.__rushLibPackageJson = node_core_library_1.PackageJsonLookup.instance.loadPackageJson(packageJsonFilePath);
        }
    }
    /**
     * Assign the `RUSH_INVOKED_FOLDER` environment variable during startup.  This is only applied when
     * Rush is invoked via the CLI, not via the `@microsoft/rush-lib` automation API.
     *
     * @remarks
     * Modifying the parent process's environment is not a good design.  The better design is (1) to consolidate
     * Rush's code paths that invoke scripts, and (2) to pass down the invoked folder with each code path,
     * so that it can finally be applied in a centralized helper like `Utilities._createEnvironmentForRushCommand()`.
     * The natural time to do that refactoring is when we rework `Utilities.executeCommand()` to use
     * `Executable.spawn()` or rushell.
     */
    static _assignRushInvokedFolder() {
        process.env[EnvironmentConfiguration_1.EnvironmentVariableNames.RUSH_INVOKED_FOLDER] = process.cwd();
    }
    /**
     * This function normalizes legacy options to the current {@link ILaunchOptions} object.
     */
    static _normalizeLaunchOptions(arg) {
        return typeof arg === 'boolean'
            ? { isManaged: arg } // In older versions of Rush, this the `launch` functions took a boolean arg for "isManaged"
            : arg;
    }
}
exports.Rush = Rush;
Rush.__rushLibPackageJson = undefined;
Rush.__rushLibPackageFolder = undefined;
//# sourceMappingURL=Rush.js.map