private constructor()

in apps/rush-lib/src/api/RushConfiguration.ts [514:758]


  private constructor(rushConfigurationJson: IRushConfigurationJson, rushJsonFilename: string) {
    this._rushConfigurationJson = rushConfigurationJson;
    EnvironmentConfiguration.validate();

    if (rushConfigurationJson.nodeSupportedVersionRange) {
      if (!semver.validRange(rushConfigurationJson.nodeSupportedVersionRange)) {
        throw new Error(
          'Error parsing the node-semver expression in the "nodeSupportedVersionRange"' +
            ` field from rush.json: "${rushConfigurationJson.nodeSupportedVersionRange}"`
        );
      }
      if (!semver.satisfies(process.version, rushConfigurationJson.nodeSupportedVersionRange)) {
        const message: string =
          `Your dev environment is running Node.js version ${process.version} which does` +
          ` not meet the requirements for building this repository.  (The rush.json configuration` +
          ` requires nodeSupportedVersionRange="${rushConfigurationJson.nodeSupportedVersionRange}")`;
        if (EnvironmentConfiguration.allowUnsupportedNodeVersion) {
          console.warn(message);
        } else {
          throw new Error(message);
        }
      }
    }

    this._rushJsonFile = rushJsonFilename;
    this._rushJsonFolder = path.dirname(rushJsonFilename);

    this._commonFolder = path.resolve(path.join(this._rushJsonFolder, RushConstants.commonFolderName));

    this._commonRushConfigFolder = path.join(this._commonFolder, 'config', 'rush');

    this._commonTempFolder =
      EnvironmentConfiguration.rushTempFolderOverride ||
      path.join(this._commonFolder, RushConstants.rushTempFolderName);

    this._commonScriptsFolder = path.join(this._commonFolder, 'scripts');

    this._npmCacheFolder = path.resolve(path.join(this._commonTempFolder, 'npm-cache'));
    this._npmTmpFolder = path.resolve(path.join(this._commonTempFolder, 'npm-tmp'));
    this._yarnCacheFolder = path.resolve(path.join(this._commonTempFolder, 'yarn-cache'));

    this._changesFolder = path.join(this._commonFolder, RushConstants.changeFilesFolderName);

    this._currentVariantJsonFilename = path.join(this._commonTempFolder, 'current-variant.json');

    this._suppressNodeLtsWarning = !!rushConfigurationJson.suppressNodeLtsWarning;

    this._ensureConsistentVersions = !!rushConfigurationJson.ensureConsistentVersions;

    const experimentsConfigFile: string = path.join(
      this._commonRushConfigFolder,
      RushConstants.experimentsFilename
    );
    this._experimentsConfiguration = new ExperimentsConfiguration(experimentsConfigFile);

    const rushPluginsConfigFilename: string = path.join(
      this._commonRushConfigFolder,
      RushConstants.rushPluginsConfigFilename
    );
    this.__rushPluginsConfiguration = new RushPluginsConfiguration(rushPluginsConfigFilename);

    this._npmOptions = new NpmOptionsConfiguration(rushConfigurationJson.npmOptions || {});
    this._pnpmOptions = new PnpmOptionsConfiguration(
      rushConfigurationJson.pnpmOptions || {},
      this._commonTempFolder
    );
    this._yarnOptions = new YarnOptionsConfiguration(rushConfigurationJson.yarnOptions || {});

    // TODO: Add an actual "packageManager" field in rush.json
    const packageManagerFields: string[] = [];

    if (rushConfigurationJson.npmVersion) {
      this._packageManager = 'npm';
      this._packageManagerConfigurationOptions = this._npmOptions;
      packageManagerFields.push('npmVersion');
    }
    if (rushConfigurationJson.pnpmVersion) {
      this._packageManager = 'pnpm';
      this._packageManagerConfigurationOptions = this._pnpmOptions;
      packageManagerFields.push('pnpmVersion');
    }
    if (rushConfigurationJson.yarnVersion) {
      this._packageManager = 'yarn';
      this._packageManagerConfigurationOptions = this._yarnOptions;
      packageManagerFields.push('yarnVersion');
    }

    if (packageManagerFields.length === 0) {
      throw new Error(
        `The rush.json configuration must specify one of: npmVersion, pnpmVersion, or yarnVersion`
      );
    }

    if (packageManagerFields.length > 1) {
      throw new Error(
        `The rush.json configuration cannot specify both ${packageManagerFields[0]}` +
          ` and ${packageManagerFields[1]} `
      );
    }

    if (this._packageManager === 'npm') {
      this._packageManagerToolVersion = rushConfigurationJson.npmVersion!;
      this._packageManagerWrapper = new NpmPackageManager(this._packageManagerToolVersion);
    } else if (this._packageManager === 'pnpm') {
      this._packageManagerToolVersion = rushConfigurationJson.pnpmVersion!;
      this._packageManagerWrapper = new PnpmPackageManager(this._packageManagerToolVersion);
    } else {
      this._packageManagerToolVersion = rushConfigurationJson.yarnVersion!;
      this._packageManagerWrapper = new YarnPackageManager(this._packageManagerToolVersion);
    }

    this._shrinkwrapFilename = this._packageManagerWrapper.shrinkwrapFilename;

    this._tempShrinkwrapFilename = path.join(this._commonTempFolder, this._shrinkwrapFilename);
    this._packageManagerToolFilename = path.resolve(
      path.join(
        this._commonTempFolder,
        `${this.packageManager}-local`,
        'node_modules',
        '.bin',
        `${this.packageManager}`
      )
    );

    /// From "C:\repo\common\temp\pnpm-lock.yaml" --> "C:\repo\common\temp\pnpm-lock-preinstall.yaml"
    const parsedPath: path.ParsedPath = path.parse(this._tempShrinkwrapFilename);
    this._tempShrinkwrapPreinstallFilename = path.join(
      parsedPath.dir,
      parsedPath.name + '-preinstall' + parsedPath.ext
    );

    RushConfiguration._validateCommonRushConfigFolder(
      this._commonRushConfigFolder,
      this._packageManagerWrapper,
      this._experimentsConfiguration
    );

    this._projectFolderMinDepth =
      rushConfigurationJson.projectFolderMinDepth !== undefined
        ? rushConfigurationJson.projectFolderMinDepth
        : 1;
    if (this._projectFolderMinDepth < 1) {
      throw new Error('Invalid projectFolderMinDepth; the minimum possible value is 1');
    }

    this._projectFolderMaxDepth =
      rushConfigurationJson.projectFolderMaxDepth !== undefined
        ? rushConfigurationJson.projectFolderMaxDepth
        : 2;
    if (this._projectFolderMaxDepth < this._projectFolderMinDepth) {
      throw new Error('The projectFolderMaxDepth cannot be smaller than the projectFolderMinDepth');
    }

    this._allowMostlyStandardPackageNames = !!rushConfigurationJson.allowMostlyStandardPackageNames;
    this._packageNameParser = this._allowMostlyStandardPackageNames
      ? PackageNameParsers.mostlyStandard
      : PackageNameParsers.rushDefault;

    this._approvedPackagesPolicy = new ApprovedPackagesPolicy(this, rushConfigurationJson);

    this._gitAllowedEmailRegExps = [];
    this._gitSampleEmail = '';
    if (rushConfigurationJson.gitPolicy) {
      if (rushConfigurationJson.gitPolicy.sampleEmail) {
        this._gitSampleEmail = rushConfigurationJson.gitPolicy.sampleEmail;
      }

      if (rushConfigurationJson.gitPolicy.allowedEmailRegExps) {
        this._gitAllowedEmailRegExps = rushConfigurationJson.gitPolicy.allowedEmailRegExps;

        if (this._gitSampleEmail.trim().length < 1) {
          throw new Error(
            'The rush.json file is missing the "sampleEmail" option, ' +
              'which is required when using "allowedEmailRegExps"'
          );
        }
      }

      if (rushConfigurationJson.gitPolicy.versionBumpCommitMessage) {
        this._gitVersionBumpCommitMessage = rushConfigurationJson.gitPolicy.versionBumpCommitMessage;
      }

      if (rushConfigurationJson.gitPolicy.changeLogUpdateCommitMessage) {
        this._gitChangeLogUpdateCommitMessage = rushConfigurationJson.gitPolicy.changeLogUpdateCommitMessage;
      }

      if (rushConfigurationJson.gitPolicy.tagSeparator) {
        this._gitTagSeparator = rushConfigurationJson.gitPolicy.tagSeparator;
      }
    }

    this._hotfixChangeEnabled = false;
    if (rushConfigurationJson.hotfixChangeEnabled) {
      this._hotfixChangeEnabled = rushConfigurationJson.hotfixChangeEnabled;
    }

    if (!rushConfigurationJson.repository) {
      rushConfigurationJson.repository = {};
    }

    this._repositoryDefaultBranch = rushConfigurationJson.repository.defaultBranch || DEFAULT_BRANCH;
    this._repositoryDefaultRemote = rushConfigurationJson.repository.defaultRemote || DEFAULT_REMOTE;
    const repositoryFieldWithMultipleUrls: IRushRepositoryJsonMultipleUrls =
      rushConfigurationJson.repository as IRushRepositoryJsonMultipleUrls;
    const repositoryFieldWithSingleUrl: IRushRepositoryJsonSingleUrl =
      rushConfigurationJson.repository as IRushRepositoryJsonSingleUrl;
    if (repositoryFieldWithMultipleUrls.urls) {
      if (repositoryFieldWithSingleUrl.url) {
        throw new Error("The 'repository.url' field cannot be used when 'repository.urls' is present");
      }

      this._repositoryUrls = repositoryFieldWithMultipleUrls.urls;
    } else if (repositoryFieldWithSingleUrl.url) {
      this._repositoryUrls = [repositoryFieldWithSingleUrl.url];
    } else {
      this._repositoryUrls = [];
    }

    this._telemetryEnabled = !!rushConfigurationJson.telemetryEnabled;
    this._eventHooks = new EventHooks(rushConfigurationJson.eventHooks || {});

    this._versionPolicyConfigurationFilePath = path.join(
      this._commonRushConfigFolder,
      RushConstants.versionPoliciesFilename
    );
    this._versionPolicyConfiguration = new VersionPolicyConfiguration(
      this._versionPolicyConfigurationFilePath
    );

    this._variants = new Set<string>();

    if (rushConfigurationJson.variants) {
      for (const variantOptions of rushConfigurationJson.variants) {
        const { variantName } = variantOptions;

        if (this._variants.has(variantName)) {
          throw new Error(`Duplicate variant named '${variantName}' specified in configuration.`);
        }

        this._variants.add(variantName);
      }
    }

    this._pathTrees = new Map();
  }