<commit_before>import fs from 'fs';
import path from 'path';
import semver from 'semver';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';

import { normalizeCondition } from 'webpack/lib/RuleSet';

const cssExtensions = ['.css', '.scss', '.sass'];
const cssModuleExtensions = ['.module.css', '.module.scss', '.module.sass'];
const typeScriptExtensions = ['.ts', '.tsx'];

let reactScriptsPath;

export function getReactScriptsPath({ noCache } = {}) {
  if (reactScriptsPath && !noCache) return reactScriptsPath;

  const appDirectory = fs.realpathSync(process.cwd());
  const reactScriptsScriptPath = fs.realpathSync(
    path.join(appDirectory, '/node_modules/.bin/react-scripts')
  );

  reactScriptsPath = path.join(reactScriptsScriptPath, '../..');
  const scriptsPkgJson = path.join(reactScriptsPath, 'package.json');

  if (!fs.existsSync(scriptsPkgJson)) {
    reactScriptsPath = 'react-scripts';
  }

  return reactScriptsPath;
}

export function isReactScriptsInstalled(requiredVersion = '2.0.0') {
  try {
    // eslint-disable-next-line import/no-dynamic-require,global-require
    const reactScriptsJson = require(path.join(getReactScriptsPath(), 'package.json'));
    return !semver.lt(reactScriptsJson.version, requiredVersion);
  } catch (e) {
    return false;
  }
}

export const getRules = extensions => rules =>
  rules.reduce((craRules, rule) => {
    // If at least one style extension satisfies the rule test, the rule is one
    // we want to extract
    if (rule.test && extensions.some(normalizeCondition(rule.test))) {
      // If the base test is for styles, return early
      return craRules.concat(rule);
    }

    //  Get any style rules contained in rule.oneOf
    if (!rule.test && rule.oneOf) {
      craRules.push(...getRules(extensions)(rule.oneOf));
    }

    // Get any style rules contained in rule.rules
    if (!rule.test && rule.rules) {
      craRules.push(...getRules(extensions)(rule.rules));
    }

    return craRules;
  }, []);

const getStyleRules = getRules(cssExtensions.concat(cssModuleExtensions));
const getTypeScriptRules = getRules(typeScriptExtensions);

export function getCraWebpackConfig(mode) {
  const craWebpackConfig =
    mode === 'production' ? 'config/webpack.config.prod' : 'config/webpack.config.dev';

  const pathToWebpackConfig = path.join(getReactScriptsPath(), craWebpackConfig);

  // eslint-disable-next-line import/no-dynamic-require,global-require
  return require(pathToWebpackConfig);
}

export function applyCRAWebpackConfig(baseConfig) {
  // Check if the user can use TypeScript (react-scripts version 2.1+).
  const hasTsSupport = isReactScriptsInstalled('2.1.0');

  const tsExtensions = hasTsSupport ? typeScriptExtensions : [];
  const extensions = [...cssExtensions, ...tsExtensions];

  // Remove any rules from baseConfig that test true for any one of the extensions
  const filteredBaseRules = baseConfig.module.rules.filter(
    rule => !rule.test || !extensions.some(normalizeCondition(rule.test))
  );

  //  Load create-react-app config
  const craWebpackConfig = getCraWebpackConfig(baseConfig.mode);

  const craStyleRules = getStyleRules(craWebpackConfig.module.rules);
  const craTypeScriptRules = hasTsSupport ? getTypeScriptRules(craWebpackConfig.module.rules) : [];

  //  Add css minification for production
  const plugins = [...baseConfig.plugins];
  if (baseConfig.mode === 'production') {
    plugins.push(new MiniCssExtractPlugin());
  }

  return {
    ...baseConfig,
    module: {
      ...baseConfig.module,
      rules: [...filteredBaseRules, ...craStyleRules, ...craTypeScriptRules],
    },
    plugins,
    resolve: {
      ...baseConfig.resolve,
      extensions: [...baseConfig.resolve.extensions, ...tsExtensions],
    },
  };
}
<commit_msg>Support CRA's new format of webpack.config<commit_after>import fs from 'fs';
import path from 'path';
import semver from 'semver';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';

import { normalizeCondition } from 'webpack/lib/RuleSet';

const cssExtensions = ['.css', '.scss', '.sass'];
const cssModuleExtensions = ['.module.css', '.module.scss', '.module.sass'];
const typeScriptExtensions = ['.ts', '.tsx'];

let reactScriptsPath;

export function getReactScriptsPath({ noCache } = {}) {
  if (reactScriptsPath && !noCache) return reactScriptsPath;

  const appDirectory = fs.realpathSync(process.cwd());
  const reactScriptsScriptPath = fs.realpathSync(
    path.join(appDirectory, '/node_modules/.bin/react-scripts')
  );

  reactScriptsPath = path.join(reactScriptsScriptPath, '../..');
  const scriptsPkgJson = path.join(reactScriptsPath, 'package.json');

  if (!fs.existsSync(scriptsPkgJson)) {
    reactScriptsPath = 'react-scripts';
  }

  return reactScriptsPath;
}

export function isReactScriptsInstalled(requiredVersion = '2.0.0') {
  try {
    // eslint-disable-next-line import/no-dynamic-require,global-require
    const reactScriptsJson = require(path.join(getReactScriptsPath(), 'package.json'));
    return !semver.lt(reactScriptsJson.version, requiredVersion);
  } catch (e) {
    return false;
  }
}

export const getRules = extensions => rules =>
  rules.reduce((craRules, rule) => {
    // If at least one style extension satisfies the rule test, the rule is one
    // we want to extract
    if (rule.test && extensions.some(normalizeCondition(rule.test))) {
      // If the base test is for styles, return early
      return craRules.concat(rule);
    }

    //  Get any style rules contained in rule.oneOf
    if (!rule.test && rule.oneOf) {
      craRules.push(...getRules(extensions)(rule.oneOf));
    }

    // Get any style rules contained in rule.rules
    if (!rule.test && rule.rules) {
      craRules.push(...getRules(extensions)(rule.rules));
    }

    return craRules;
  }, []);

const getStyleRules = getRules(cssExtensions.concat(cssModuleExtensions));
const getTypeScriptRules = getRules(typeScriptExtensions);

export function getCraWebpackConfig(mode) {
  const pathToReactScripts = getReactScriptsPath();

  const craWebpackConfig =
    mode === 'production' ? 'config/webpack.config.prod' : 'config/webpack.config.dev';

  let pathToWebpackConfig = require.resolve(path.join(pathToReactScripts, craWebpackConfig));

  if (!fs.existsSync(pathToWebpackConfig)) {
    pathToWebpackConfig = path.join(pathToReactScripts, 'config/webpack.config');
  }

  // eslint-disable-next-line import/no-dynamic-require,global-require
  const webpackConfig = require(pathToWebpackConfig);

  if (typeof webpackConfig === 'function') {
    return webpackConfig(mode);
  }

  return webpackConfig;
}

export function applyCRAWebpackConfig(baseConfig) {
  // Check if the user can use TypeScript (react-scripts version 2.1+).
  const hasTsSupport = isReactScriptsInstalled('2.1.0');

  const tsExtensions = hasTsSupport ? typeScriptExtensions : [];
  const extensions = [...cssExtensions, ...tsExtensions];

  // Remove any rules from baseConfig that test true for any one of the extensions
  const filteredBaseRules = baseConfig.module.rules.filter(
    rule => !rule.test || !extensions.some(normalizeCondition(rule.test))
  );

  //  Load create-react-app config
  const craWebpackConfig = getCraWebpackConfig(baseConfig.mode);

  const craStyleRules = getStyleRules(craWebpackConfig.module.rules);
  const craTypeScriptRules = hasTsSupport ? getTypeScriptRules(craWebpackConfig.module.rules) : [];

  //  Add css minification for production
  const plugins = [...baseConfig.plugins];
  if (baseConfig.mode === 'production') {
    plugins.push(new MiniCssExtractPlugin());
  }

  return {
    ...baseConfig,
    module: {
      ...baseConfig.module,
      rules: [...filteredBaseRules, ...craStyleRules, ...craTypeScriptRules],
    },
    plugins,
    resolve: {
      ...baseConfig.resolve,
      extensions: [...baseConfig.resolve.extensions, ...tsExtensions],
    },
  };
}

{'fraction_non_alphanumeric': 0.13241256969082615, 'fraction_numerical': 0.0020273694880892043, 'mean_word_length': 4.005072923272036, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, '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': '4208610', 'n_tokens_mistral': 2409, 'n_tokens_neox': 2352, 'n_words': 528}