"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.EnvironmentConfiguration = exports.EnvironmentVariableNames = void 0;
const path = __importStar(require("node:path"));
const true_case_path_1 = require("true-case-path");
const executionUtilities_1 = require("../utilities/executionUtilities");
/**
 * Names of environment variables used by Rush.
 * @beta
 */
// eslint-disable-next-line @typescript-eslint/typedef
exports.EnvironmentVariableNames = {
    /**
     * This variable overrides the temporary folder used by Rush.
     * The default value is "common/temp" under the repository root.
     *
     * @remarks This environment variable is not compatible with workspace installs. If attempting
     * to move the PNPM store path, see the `RUSH_PNPM_STORE_PATH` environment variable.
     */
    RUSH_TEMP_FOLDER: 'RUSH_TEMP_FOLDER',
    /**
     * This variable overrides the version of Rush that will be installed by
     * the version selector.  The default value is determined by the "rushVersion"
     * field from rush.json.
     */
    RUSH_PREVIEW_VERSION: 'RUSH_PREVIEW_VERSION',
    /**
     * If this variable is set to "1", Rush will not fail the build when running a version
     * of Node that does not match the criteria specified in the "nodeSupportedVersionRange"
     * field from rush.json.
     */
    RUSH_ALLOW_UNSUPPORTED_NODEJS: 'RUSH_ALLOW_UNSUPPORTED_NODEJS',
    /**
     * Setting this environment variable overrides the value of `allowWarningsInSuccessfulBuild`
     * in the `command-line.json` configuration file. Specify `1` to allow warnings in a successful build,
     * or `0` to disallow them. (See the comments in the command-line.json file for more information).
     */
    RUSH_ALLOW_WARNINGS_IN_SUCCESSFUL_BUILD: 'RUSH_ALLOW_WARNINGS_IN_SUCCESSFUL_BUILD',
    /**
     * This variable selects a specific installation variant for Rush to use when installing
     * and linking package dependencies.
     * For more information, see the command-line help for the `--variant` parameter
     * and this article:  https://rushjs.io/pages/advanced/installation_variants/
     */
    RUSH_VARIANT: 'RUSH_VARIANT',
    /**
     * Specifies the maximum number of concurrent processes to launch during a build.
     * For more information, see the command-line help for the `--parallelism` parameter for "rush build".
     */
    RUSH_PARALLELISM: 'RUSH_PARALLELISM',
    /**
     * If this variable is set to "1", Rush will create symlinks with absolute paths instead
     * of relative paths. This can be necessary when a repository is moved during a build or
     * if parts of a repository are moved into a sandbox.
     */
    RUSH_ABSOLUTE_SYMLINKS: 'RUSH_ABSOLUTE_SYMLINKS',
    /**
     * When using PNPM as the package manager, this variable can be used to configure the path that
     * PNPM will use as the store directory.
     *
     * If a relative path is used, then the store path will be resolved relative to the process's
     * current working directory.  An absolute path is recommended.
     */
    RUSH_PNPM_STORE_PATH: 'RUSH_PNPM_STORE_PATH',
    /**
     * When using PNPM as the package manager, this variable can be used to control whether or not PNPM
     * validates the integrity of the PNPM store during installation. The value of this environment variable must be
     * `1` (for true) or `0` (for false). If not specified, defaults to the value in .npmrc.
     */
    RUSH_PNPM_VERIFY_STORE_INTEGRITY: 'RUSH_PNPM_VERIFY_STORE_INTEGRITY',
    /**
     * This environment variable can be used to specify the `--target-folder` parameter
     * for the "rush deploy" command.
     */
    RUSH_DEPLOY_TARGET_FOLDER: 'RUSH_DEPLOY_TARGET_FOLDER',
    /**
     * Overrides the location of the `~/.rush` global folder where Rush stores temporary files.
     *
     * @remarks
     *
     * Most of the temporary files created by Rush are stored separately for each monorepo working folder,
     * to avoid issues of concurrency and compatibility between tool versions.  However, a small set
     * of files (e.g. installations of the `@microsoft/rush-lib` engine and the package manager) are stored
     * in a global folder to speed up installations.  The default location is `~/.rush` on POSIX-like
     * operating systems or `C:\Users\YourName` on Windows.
     *
     * Use `RUSH_GLOBAL_FOLDER` to specify a different folder path.  This is useful for example if a Windows
     * group policy forbids executing scripts installed in a user's home directory.
     *
     * POSIX is a registered trademark of the Institute of Electrical and Electronic Engineers, Inc.
     */
    RUSH_GLOBAL_FOLDER: 'RUSH_GLOBAL_FOLDER',
    /**
     * Provides a credential for a remote build cache, if configured.  This credential overrides any cached credentials.
     *
     * @remarks
     * Setting this environment variable overrides whatever credential has been saved in the
     * local cloud cache credentials using `rush update-cloud-credentials`.
     *
     *
     * If Azure Blob Storage is used to store cache entries, this must be a SAS token serialized as query
     * parameters.
     *
     * For information on SAS tokens, see here: https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overview
     */
    RUSH_BUILD_CACHE_CREDENTIAL: 'RUSH_BUILD_CACHE_CREDENTIAL',
    /**
     * Setting this environment variable overrides the value of `buildCacheEnabled` in the `build-cache.json`
     * configuration file.
     *
     * @remarks
     * Specify `1` to enable the build cache or `0` to disable it.
     *
     * If there is no build cache configured, then this environment variable is ignored.
     */
    RUSH_BUILD_CACHE_ENABLED: 'RUSH_BUILD_CACHE_ENABLED',
    /**
     * Overrides the value of `isCacheWriteAllowed` in the `build-cache.json` configuration file. The value of this
     * environment variable must be `1` (for true) or `0` (for false). If there is no build cache configured, then
     * this environment variable is ignored.
     */
    RUSH_BUILD_CACHE_WRITE_ALLOWED: 'RUSH_BUILD_CACHE_WRITE_ALLOWED',
    /**
     * Set this environment variable to a JSON string to override the build cache configuration that normally lives
     * at `common/config/rush/build-cache.json`.
     *
     * This is useful for testing purposes, or for OSS repos that are have a local-only cache, but can have
     * a different cache configuration in CI/CD pipelines.
     *
     * @remarks
     * This is similar to {@link EnvironmentVariableNames.RUSH_BUILD_CACHE_OVERRIDE_JSON_FILE_PATH}, but it allows you to specify
     * a JSON string instead of a file path. The two environment variables are mutually exclusive, meaning you can
     * only use one of them at a time.
     */
    RUSH_BUILD_CACHE_OVERRIDE_JSON: 'RUSH_BUILD_CACHE_OVERRIDE_JSON',
    /**
     * Set this environment variable to the path to a `build-cache.json` file to override the build cache configuration
     * that normally lives at `common/config/rush/build-cache.json`.
     *
     * This is useful for testing purposes, or for OSS repos that are have a local-only cache, but can have
     * a different cache configuration in CI/CD pipelines.
     *
     * @remarks
     * This is similar to {@link EnvironmentVariableNames.RUSH_BUILD_CACHE_OVERRIDE_JSON}, but it allows you to specify
     * a file path instead of a JSON string. The two environment variables are mutually exclusive, meaning you can
     * only use one of them at a time.
     */
    RUSH_BUILD_CACHE_OVERRIDE_JSON_FILE_PATH: 'RUSH_BUILD_CACHE_OVERRIDE_JSON_FILE_PATH',
    /**
     * Setting this environment variable opts into running with cobuilds. The context id should be the same across
     * multiple VMs, but changed when it is a new round of cobuilds.
     *
     * e.g. `Build.BuildNumber` in Azure DevOps Pipeline.
     *
     * @remarks
     * If there is no cobuild configured, then this environment variable is ignored.
     */
    RUSH_COBUILD_CONTEXT_ID: 'RUSH_COBUILD_CONTEXT_ID',
    /**
     * Explicitly specifies a name for each participating cobuild runner.
     *
     * Setting this environment variable opts into running with cobuilds.
     *
     * @remarks
     * This environment variable is optional, if it is not provided, a random id is used.
     *
     * If there is no cobuild configured, then this environment variable is ignored.
     */
    RUSH_COBUILD_RUNNER_ID: 'RUSH_COBUILD_RUNNER_ID',
    /**
     * If this variable is set to "1", When getting distributed builds, Rush will automatically handle the leaf project
     * with build cache "disabled" by writing to the cache in a special "log files only mode". This is useful when you
     * want to use Cobuilds to improve the performance in CI validations and the leaf projects have not enabled cache.
     */
    RUSH_COBUILD_LEAF_PROJECT_LOG_ONLY_ALLOWED: 'RUSH_COBUILD_LEAF_PROJECT_LOG_ONLY_ALLOWED',
    /**
     * Explicitly specifies the path for the Git binary that is invoked by certain Rush operations.
     */
    RUSH_GIT_BINARY_PATH: 'RUSH_GIT_BINARY_PATH',
    /**
     * Explicitly specifies the path for the `tar` binary that is invoked by certain Rush operations.
     */
    RUSH_TAR_BINARY_PATH: 'RUSH_TAR_BINARY_PATH',
    /**
     * Internal variable used by `rushx` when recursively invoking another `rushx` process, to avoid
     * nesting event hooks.
     */
    _RUSH_RECURSIVE_RUSHX_CALL: '_RUSH_RECURSIVE_RUSHX_CALL',
    /**
     * Internal variable that explicitly specifies the path for the version of `@microsoft/rush-lib` being executed.
     * Will be set upon loading Rush.
     */
    _RUSH_LIB_PATH: '_RUSH_LIB_PATH',
    /**
     * When Rush executes shell scripts, it sometimes changes the working directory to be a project folder or
     * the repository root folder.  The original working directory (where the Rush command was invoked) is assigned
     * to the the child process's `RUSH_INVOKED_FOLDER` environment variable, in case it is needed by the script.
     *
     * @remarks
     * The `RUSH_INVOKED_FOLDER` variable is the same idea as the `INIT_CWD` variable that package managers
     * assign when they execute lifecycle scripts.
     */
    RUSH_INVOKED_FOLDER: 'RUSH_INVOKED_FOLDER',
    /**
     * When running a hook script, this environment variable communicates the original arguments
     * passed to the `rush` or `rushx` command.
     *
     * @remarks
     * Unlike `RUSH_INVOKED_FOLDER`, the `RUSH_INVOKED_ARGS` variable is only available for hook scripts.
     * Other lifecycle scripts should not make assumptions about Rush's command line syntax
     * if Rush did not explicitly pass along command-line parameters to their process.
     */
    RUSH_INVOKED_ARGS: 'RUSH_INVOKED_ARGS'
};
/**
 * Provides Rush-specific environment variable data. All Rush environment variables must start with "RUSH_". This class
 * is designed to be used by RushConfiguration.
 * @beta
 *
 * @remarks
 * Initialize will throw if any unknown parameters are present.
 */
class EnvironmentConfiguration {
    /**
     * If true, the environment configuration has been validated and initialized.
     */
    static get hasBeenValidated() {
        return EnvironmentConfiguration._hasBeenValidated;
    }
    /**
     * An override for the common/temp folder path.
     */
    static get rushTempFolderOverride() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._rushTempFolderOverride;
    }
    /**
     * If "1", create symlinks with absolute paths instead of relative paths.
     * See {@link EnvironmentVariableNames.RUSH_ABSOLUTE_SYMLINKS}
     */
    static get absoluteSymlinks() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._absoluteSymlinks;
    }
    /**
     * If this environment variable is set to "1", the Node.js version check will print a warning
     * instead of causing a hard error if the environment's Node.js version doesn't match the
     * version specifier in `rush.json`'s "nodeSupportedVersionRange" property.
     *
     * See {@link EnvironmentVariableNames.RUSH_ALLOW_UNSUPPORTED_NODEJS}.
     */
    static get allowUnsupportedNodeVersion() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._allowUnsupportedNodeVersion;
    }
    /**
     * Setting this environment variable overrides the value of `allowWarningsInSuccessfulBuild`
     * in the `command-line.json` configuration file. Specify `1` to allow warnings in a successful build,
     * or `0` to disallow them. (See the comments in the command-line.json file for more information).
     */
    static get allowWarningsInSuccessfulBuild() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._allowWarningsInSuccessfulBuild;
    }
    /**
     * An override for the PNPM store path, if `pnpmStore` configuration is set to 'path'
     * See {@link EnvironmentVariableNames.RUSH_PNPM_STORE_PATH}
     */
    static get pnpmStorePathOverride() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._pnpmStorePathOverride;
    }
    /**
     * If specified, enables or disables integrity verification of the pnpm store during install.
     * See {@link EnvironmentVariableNames.RUSH_PNPM_VERIFY_STORE_INTEGRITY}
     */
    static get pnpmVerifyStoreIntegrity() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._pnpmVerifyStoreIntegrity;
    }
    /**
     * Overrides the location of the `~/.rush` global folder where Rush stores temporary files.
     * See {@link EnvironmentVariableNames.RUSH_GLOBAL_FOLDER}
     */
    static get rushGlobalFolderOverride() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._rushGlobalFolderOverride;
    }
    /**
     * Provides a credential for reading from and writing to a remote build cache, if configured.
     * See {@link EnvironmentVariableNames.RUSH_BUILD_CACHE_CREDENTIAL}
     */
    static get buildCacheCredential() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._buildCacheCredential;
    }
    /**
     * If set, enables or disables the cloud build cache feature.
     * See {@link EnvironmentVariableNames.RUSH_BUILD_CACHE_ENABLED}
     */
    static get buildCacheEnabled() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._buildCacheEnabled;
    }
    /**
     * If set, enables or disables writing to the cloud build cache.
     * See {@link EnvironmentVariableNames.RUSH_BUILD_CACHE_WRITE_ALLOWED}
     */
    static get buildCacheWriteAllowed() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._buildCacheWriteAllowed;
    }
    /**
     * If set, overrides the build cache configuration that normally lives at `common/config/rush/build-cache.json`.
     * See {@link EnvironmentVariableNames.RUSH_BUILD_CACHE_OVERRIDE_JSON}
     */
    static get buildCacheOverrideJson() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._buildCacheOverrideJson;
    }
    /**
     * If set, overrides the build cache configuration that normally lives at `common/config/rush/build-cache.json`.
     * See {@link EnvironmentVariableNames.RUSH_BUILD_CACHE_OVERRIDE_JSON_FILE_PATH}
     */
    static get buildCacheOverrideJsonFilePath() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._buildCacheOverrideJsonFilePath;
    }
    /**
     * Provides a determined cobuild context id if configured
     * See {@link EnvironmentVariableNames.RUSH_COBUILD_CONTEXT_ID}
     */
    static get cobuildContextId() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._cobuildContextId;
    }
    /**
     * Provides a determined cobuild runner id if configured
     * See {@link EnvironmentVariableNames.RUSH_COBUILD_RUNNER_ID}
     */
    static get cobuildRunnerId() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._cobuildRunnerId;
    }
    /**
     * If set, enables or disables the cobuild leaf project log only feature.
     * See {@link EnvironmentVariableNames.RUSH_COBUILD_LEAF_PROJECT_LOG_ONLY_ALLOWED}
     */
    static get cobuildLeafProjectLogOnlyAllowed() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._cobuildLeafProjectLogOnlyAllowed;
    }
    /**
     * Allows the git binary path to be explicitly provided.
     * See {@link EnvironmentVariableNames.RUSH_GIT_BINARY_PATH}
     */
    static get gitBinaryPath() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._gitBinaryPath;
    }
    /**
     * Allows the tar binary path to be explicitly provided.
     * See {@link EnvironmentVariableNames.RUSH_TAR_BINARY_PATH}
     */
    static get tarBinaryPath() {
        EnvironmentConfiguration._ensureValidated();
        return EnvironmentConfiguration._tarBinaryPath;
    }
    /**
     * The front-end RushVersionSelector relies on `RUSH_GLOBAL_FOLDER`, so its value must be read before
     * `EnvironmentConfiguration` is initialized (and actually before the correct version of `EnvironmentConfiguration`
     * is even installed). Thus we need to read this environment variable differently from all the others.
     * @internal
     */
    static _getRushGlobalFolderOverride(processEnv) {
        const value = processEnv[exports.EnvironmentVariableNames.RUSH_GLOBAL_FOLDER];
        if (value) {
            const normalizedValue = EnvironmentConfiguration._normalizeDeepestParentFolderPath(value);
            return normalizedValue;
        }
    }
    /**
     * Reads and validates environment variables. If any are invalid, this function will throw.
     */
    static validate(options = {}) {
        var _a, _b, _c;
        EnvironmentConfiguration.reset();
        const unknownEnvVariables = [];
        for (const envVarName in process.env) {
            if (process.env.hasOwnProperty(envVarName) && envVarName.match(/^RUSH_/i)) {
                const value = process.env[envVarName];
                // Environment variables are only case-insensitive on Windows
                const normalizedEnvVarName = executionUtilities_1.IS_WINDOWS ? envVarName.toUpperCase() : envVarName;
                switch (normalizedEnvVarName) {
                    case exports.EnvironmentVariableNames.RUSH_TEMP_FOLDER: {
                        EnvironmentConfiguration._rushTempFolderOverride =
                            value && !options.doNotNormalizePaths
                                ? EnvironmentConfiguration._normalizeDeepestParentFolderPath(value) || value
                                : value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_ABSOLUTE_SYMLINKS: {
                        EnvironmentConfiguration._absoluteSymlinks =
                            (_a = EnvironmentConfiguration.parseBooleanEnvironmentVariable(exports.EnvironmentVariableNames.RUSH_ABSOLUTE_SYMLINKS, value)) !== null && _a !== void 0 ? _a : false;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_ALLOW_UNSUPPORTED_NODEJS: {
                        if (value === 'true' || value === 'false') {
                            // Small, undocumented acceptance of old "true" and "false" values for
                            // users of RUSH_ALLOW_UNSUPPORTED_NODEJS in rush pre-v5.46.
                            EnvironmentConfiguration._allowUnsupportedNodeVersion = value === 'true';
                        }
                        else {
                            EnvironmentConfiguration._allowUnsupportedNodeVersion =
                                (_b = EnvironmentConfiguration.parseBooleanEnvironmentVariable(exports.EnvironmentVariableNames.RUSH_ALLOW_UNSUPPORTED_NODEJS, value)) !== null && _b !== void 0 ? _b : false;
                        }
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_ALLOW_WARNINGS_IN_SUCCESSFUL_BUILD: {
                        EnvironmentConfiguration._allowWarningsInSuccessfulBuild =
                            (_c = EnvironmentConfiguration.parseBooleanEnvironmentVariable(exports.EnvironmentVariableNames.RUSH_ALLOW_WARNINGS_IN_SUCCESSFUL_BUILD, value)) !== null && _c !== void 0 ? _c : false;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_PNPM_STORE_PATH: {
                        EnvironmentConfiguration._pnpmStorePathOverride =
                            value && !options.doNotNormalizePaths
                                ? EnvironmentConfiguration._normalizeDeepestParentFolderPath(value) || value
                                : value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_PNPM_VERIFY_STORE_INTEGRITY: {
                        EnvironmentConfiguration._pnpmVerifyStoreIntegrity =
                            value === '1' ? true : value === '0' ? false : undefined;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_GLOBAL_FOLDER: {
                        // Handled specially below
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_CREDENTIAL: {
                        EnvironmentConfiguration._buildCacheCredential = value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_ENABLED: {
                        EnvironmentConfiguration._buildCacheEnabled =
                            EnvironmentConfiguration.parseBooleanEnvironmentVariable(exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_ENABLED, value);
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_WRITE_ALLOWED: {
                        EnvironmentConfiguration._buildCacheWriteAllowed =
                            EnvironmentConfiguration.parseBooleanEnvironmentVariable(exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_WRITE_ALLOWED, value);
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_OVERRIDE_JSON: {
                        EnvironmentConfiguration._buildCacheOverrideJson = value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_OVERRIDE_JSON_FILE_PATH: {
                        EnvironmentConfiguration._buildCacheOverrideJsonFilePath = value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_COBUILD_CONTEXT_ID: {
                        EnvironmentConfiguration._cobuildContextId = value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_COBUILD_RUNNER_ID: {
                        EnvironmentConfiguration._cobuildRunnerId = value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_COBUILD_LEAF_PROJECT_LOG_ONLY_ALLOWED: {
                        EnvironmentConfiguration._cobuildLeafProjectLogOnlyAllowed =
                            EnvironmentConfiguration.parseBooleanEnvironmentVariable(exports.EnvironmentVariableNames.RUSH_COBUILD_LEAF_PROJECT_LOG_ONLY_ALLOWED, value);
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_GIT_BINARY_PATH: {
                        EnvironmentConfiguration._gitBinaryPath = value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_TAR_BINARY_PATH: {
                        EnvironmentConfiguration._tarBinaryPath = value;
                        break;
                    }
                    case exports.EnvironmentVariableNames.RUSH_PARALLELISM:
                    case exports.EnvironmentVariableNames.RUSH_PREVIEW_VERSION:
                    case exports.EnvironmentVariableNames.RUSH_VARIANT:
                    case exports.EnvironmentVariableNames.RUSH_DEPLOY_TARGET_FOLDER:
                        // Handled by @microsoft/rush front end
                        break;
                    case exports.EnvironmentVariableNames.RUSH_INVOKED_FOLDER:
                    case exports.EnvironmentVariableNames.RUSH_INVOKED_ARGS:
                    case exports.EnvironmentVariableNames._RUSH_LIB_PATH:
                        // Assigned by Rush itself
                        break;
                    case exports.EnvironmentVariableNames._RUSH_RECURSIVE_RUSHX_CALL:
                        // Assigned/read internally by RushXCommandLine
                        break;
                    default:
                        unknownEnvVariables.push(envVarName);
                        break;
                }
            }
        }
        // This strictness intends to catch mistakes where variables are misspelled or not used correctly.
        if (unknownEnvVariables.length > 0) {
            throw new Error('The following environment variables were found with the "RUSH_" prefix, but they are not ' +
                `recognized by this version of Rush: ${unknownEnvVariables.join(', ')}`);
        }
        if (EnvironmentConfiguration._buildCacheOverrideJsonFilePath &&
            EnvironmentConfiguration._buildCacheOverrideJson) {
            throw new Error(`Environment variable ${exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_OVERRIDE_JSON_FILE_PATH} and ` +
                `${exports.EnvironmentVariableNames.RUSH_BUILD_CACHE_OVERRIDE_JSON} are mutually exclusive. ` +
                `Only one may be specified.`);
        }
        // See doc comment for EnvironmentConfiguration._getRushGlobalFolderOverride().
        EnvironmentConfiguration._rushGlobalFolderOverride =
            EnvironmentConfiguration._getRushGlobalFolderOverride(process.env);
        EnvironmentConfiguration._hasBeenValidated = true;
    }
    /**
     * Resets EnvironmentConfiguration into an un-initialized state.
     */
    static reset() {
        EnvironmentConfiguration._rushTempFolderOverride = undefined;
        EnvironmentConfiguration._hasBeenValidated = false;
    }
    static _ensureValidated() {
        if (!EnvironmentConfiguration._hasBeenValidated) {
            EnvironmentConfiguration.validate();
        }
    }
    static parseBooleanEnvironmentVariable(name, value) {
        if (value === '' || value === undefined) {
            return undefined;
        }
        else if (value === '0') {
            return false;
        }
        else if (value === '1') {
            return true;
        }
        else {
            throw new Error(`Invalid value "${value}" for the environment variable ${name}. Valid choices are 0 or 1.`);
        }
    }
    /**
     * Given a path to a folder (that may or may not exist), normalize the path, including casing,
     * to the first existing parent folder in the path.
     *
     * If no existing path can be found (for example, if the root is a volume that doesn't exist),
     * this function returns undefined.
     *
     * @example
     * If the following path exists on disk: `C:\Folder1\folder2\`
     * _normalizeFirstExistingFolderPath('c:\\folder1\\folder2\\temp\\subfolder')
     * returns 'C:\\Folder1\\folder2\\temp\\subfolder'
     */
    static _normalizeDeepestParentFolderPath(folderPath) {
        folderPath = path.normalize(folderPath);
        const endsWithSlash = folderPath.charAt(folderPath.length - 1) === path.sep;
        const parsedPath = path.parse(folderPath);
        const pathRoot = parsedPath.root;
        const pathWithoutRoot = parsedPath.dir.substr(pathRoot.length);
        const pathParts = [...pathWithoutRoot.split(path.sep), parsedPath.name].filter((part) => !!part);
        // Starting with all path sections, and eliminating one from the end during each loop iteration,
        // run trueCasePathSync. If trueCasePathSync returns without exception, we've found a subset
        // of the path that exists and we've now gotten the correct casing.
        //
        // Once we've found a parent folder that exists, append the path sections that didn't exist.
        for (let i = pathParts.length; i >= 0; i--) {
            const constructedPath = path.join(pathRoot, ...pathParts.slice(0, i));
            try {
                const normalizedConstructedPath = (0, true_case_path_1.trueCasePathSync)(constructedPath);
                const result = path.join(normalizedConstructedPath, ...pathParts.slice(i));
                if (endsWithSlash) {
                    return `${result}${path.sep}`;
                }
                else {
                    return result;
                }
            }
            catch (e) {
                // This path doesn't exist, continue to the next subpath
            }
        }
        return undefined;
    }
}
exports.EnvironmentConfiguration = EnvironmentConfiguration;
EnvironmentConfiguration._hasBeenValidated = false;
EnvironmentConfiguration._absoluteSymlinks = false;
EnvironmentConfiguration._allowUnsupportedNodeVersion = false;
EnvironmentConfiguration._allowWarningsInSuccessfulBuild = false;
//# sourceMappingURL=EnvironmentConfiguration.js.map