<commit_before>/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import 'symbol-observable';
// symbol polyfill must go first
import { promises as fs } from 'fs';
import * as path from 'path';
import { SemVer, major } from 'semver';
import { colors } from '../src/utilities/color';
import { isWarningEnabled } from '../src/utilities/config';
import { disableVersionCheck } from '../src/utilities/environment-options';
import { VERSION } from '../src/utilities/version';

/**
 * Angular CLI versions prior to v14 may not exit correctly if not forcibly exited
 * via `process.exit()`. When bootstrapping, `forceExit` will be set to `true`
 * if the local CLI version is less than v14 to prevent the CLI from hanging on
 * exit in those cases.
 */
let forceExit = false;

(async () => {
  /**
   * Disable Browserslist old data warning as otherwise with every release we'd need to update this dependency
   * which is cumbersome considering we pin versions and the warning is not user actionable.
   * `Browserslist: caniuse-lite is outdated. Please run next command `npm update`
   * See: https://github.com/browserslist/browserslist/blob/819c4337456996d19db6ba953014579329e9c6e1/node.js#L324
   */
  process.env.BROWSERSLIST_IGNORE_OLD_DATA = '1';

  /**
   * Disable CLI version mismatch checks and forces usage of the invoked CLI
   * instead of invoking the local installed version.
   */
  if (disableVersionCheck) {
    return (await import('./cli')).default;
  }

  let cli;
  try {
    // No error implies a projectLocalCli, which will load whatever
    // version of ng-cli you have installed in a local package.json
    const projectLocalCli = require.resolve('@angular/cli', { paths: [process.cwd()] });
    cli = await import(projectLocalCli);

    const globalVersion = new SemVer(VERSION.full);

    // Older versions might not have the VERSION export
    let localVersion = cli.VERSION?.full;
    if (!localVersion) {
      try {
        const localPackageJson = await fs.readFile(
          path.join(path.dirname(projectLocalCli), '../../package.json'),
          'utf-8',
        );
        localVersion = (JSON.parse(localPackageJson) as { version: string }).version;
      } catch (error) {
        // eslint-disable-next-line  no-console
        console.error('Version mismatch check skipped. Unable to retrieve local version: ' + error);
      }
    }

    // Ensure older versions of the CLI fully exit
    if (major(localVersion) < 14) {
      forceExit = true;
    }

    let isGlobalGreater = false;
    try {
      isGlobalGreater = !!localVersion && globalVersion.compare(localVersion) > 0;
    } catch (error) {
      // eslint-disable-next-line  no-console
      console.error('Version mismatch check skipped. Unable to compare local version: ' + error);
    }

    const rawCommandName = process.argv[2];
    // When using the completion command, don't show the warning as otherwise this will break completion.
    if (isGlobalGreater && rawCommandName !== 'completion') {
      // If using the update command and the global version is greater, use the newer update command
      // This allows improvements in update to be used in older versions that do not have bootstrapping
      if (
        rawCommandName === 'update' &&
        cli.VERSION &&
        cli.VERSION.major - globalVersion.major <= 1
      ) {
        cli = await import('./cli');
      } else if (await isWarningEnabled('versionMismatch')) {
        // Otherwise, use local version and warn if global is newer than local
        const warning =
          `Your global Angular CLI version (${globalVersion}) is greater than your local ` +
          `version (${localVersion}). The local Angular CLI version is used.\n\n` +
          'To disable this warning use "ng config -g cli.warnings.versionMismatch false".';

        // eslint-disable-next-line  no-console
        console.error(colors.yellow(warning));
      }
    }
  } catch {
    // If there is an error, resolve could not find the ng-cli
    // library from a package.json. Instead, include it from a relative
    // path to this script file (which is likely a globally installed
    // npm package). Most common cause for hitting this is `ng new`
    cli = await import('./cli');
  }

  if ('default' in cli) {
    cli = cli['default'];
  }

  return cli;
})()
  .then((cli) => {
    return cli({
      cliArgs: process.argv.slice(2),
      inputStream: process.stdin,
      outputStream: process.stdout,
    });
  })
  .then((exitCode: number) => {
    if (forceExit) {
      process.exit(exitCode);<commit_msg>fix(@angular/cli): handle cases when completion is enabled and running in an older CLI workspace<commit_after>/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

import 'symbol-observable';
// symbol polyfill must go first
import { promises as fs } from 'fs';
import * as path from 'path';
import { SemVer, major } from 'semver';
import { colors } from '../src/utilities/color';
import { isWarningEnabled } from '../src/utilities/config';
import { disableVersionCheck } from '../src/utilities/environment-options';
import { VERSION } from '../src/utilities/version';

/**
 * Angular CLI versions prior to v14 may not exit correctly if not forcibly exited
 * via `process.exit()`. When bootstrapping, `forceExit` will be set to `true`
 * if the local CLI version is less than v14 to prevent the CLI from hanging on
 * exit in those cases.
 */
let forceExit = false;

(async (): Promise<typeof import('./cli').default | null> => {
  /**
   * Disable Browserslist old data warning as otherwise with every release we'd need to update this dependency
   * which is cumbersome considering we pin versions and the warning is not user actionable.
   * `Browserslist: caniuse-lite is outdated. Please run next command `npm update`
   * See: https://github.com/browserslist/browserslist/blob/819c4337456996d19db6ba953014579329e9c6e1/node.js#L324
   */
  process.env.BROWSERSLIST_IGNORE_OLD_DATA = '1';

  /**
   * Disable CLI version mismatch checks and forces usage of the invoked CLI
   * instead of invoking the local installed version.
   */
  if (disableVersionCheck) {
    return (await import('./cli')).default;
  }

  let cli;
  const rawCommandName = process.argv[2];

  try {
    // No error implies a projectLocalCli, which will load whatever
    // version of ng-cli you have installed in a local package.json
    const projectLocalCli = require.resolve('@angular/cli', { paths: [process.cwd()] });
    cli = await import(projectLocalCli);

    const globalVersion = new SemVer(VERSION.full);

    // Older versions might not have the VERSION export
    let localVersion = cli.VERSION?.full;
    if (!localVersion) {
      try {
        const localPackageJson = await fs.readFile(
          path.join(path.dirname(projectLocalCli), '../../package.json'),
          'utf-8',
        );
        localVersion = (JSON.parse(localPackageJson) as { version: string }).version;
      } catch (error) {
        // eslint-disable-next-line  no-console
        console.error('Version mismatch check skipped. Unable to retrieve local version: ' + error);
      }
    }

    // Ensure older versions of the CLI fully exit
    if (major(localVersion) < 14) {
      forceExit = true;

      // Versions prior to 14 didn't implement completion command.
      if (rawCommandName === 'completion') {
        return null;
      }
    }

    let isGlobalGreater = false;
    try {
      isGlobalGreater = !!localVersion && globalVersion.compare(localVersion) > 0;
    } catch (error) {
      // eslint-disable-next-line  no-console
      console.error('Version mismatch check skipped. Unable to compare local version: ' + error);
    }

    // When using the completion command, don't show the warning as otherwise this will break completion.
    if (isGlobalGreater && rawCommandName !== 'completion') {
      // If using the update command and the global version is greater, use the newer update command
      // This allows improvements in update to be used in older versions that do not have bootstrapping
      if (
        rawCommandName === 'update' &&
        cli.VERSION &&
        cli.VERSION.major - globalVersion.major <= 1
      ) {
        cli = await import('./cli');
      } else if (await isWarningEnabled('versionMismatch')) {
        // Otherwise, use local version and warn if global is newer than local
        const warning =
          `Your global Angular CLI version (${globalVersion}) is greater than your local ` +
          `version (${localVersion}). The local Angular CLI version is used.\n\n` +
          'To disable this warning use "ng config -g cli.warnings.versionMismatch false".';

        // eslint-disable-next-line  no-console
        console.error(colors.yellow(warning));
      }
    }
  } catch {
    // If there is an error, resolve could not find the ng-cli
    // library from a package.json. Instead, include it from a relative
    // path to this script file (which is likely a globally installed
    // npm package). Most common cause for hitting this is `ng new`
    cli = await import('./cli');
  }

  if ('default' in cli) {
    cli = cli['default'];
  }

  return cli;
})()
  .then((cli) =>
    cli?.({
      cliArgs: process.argv.slice(2),
    }),
  )
  .then((exitCode = 0) => {
    if (forceExit) {
      process.exit(exitCode);
{'fraction_non_alphanumeric': 0.10908336789713811, 'fraction_numerical': 0.009850684363334717, 'mean_word_length': 2.8734939759036147, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 12, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1057557', 'n_tokens_mistral': 2811, 'n_tokens_neox': 2659, 'n_words': 979}