<commit_before>'use strict';
let generator = require('yeoman-generator');
let utils = require('../../utils/all');
let prompts = require('./prompts');
let path = require('path');
let fs = require('fs');

// Set the base root directory for our files
let baseRootPath = path.dirname(require.resolve('react-webpack-template'));

module.exports = generator.Base.extend({

  constructor: function() {
    generator.Base.apply(this, arguments);

    // Make options available
    this.option('skip-welcome-message', {
      desc: 'Skip the welcome message',
      type: Boolean,
      defaults: false
    });
    this.option('skip-install');

    // Use our plain template as source
    this.sourceRoot(baseRootPath);

    this.config.save();
  },

  initializing: function() {
    if(!this.options['skip-welcome-message']) {
      this.log(require('yeoman-welcome'));
      this.log('Out of the box I include Webpack and some default React components.\n');
    }
  },

  prompting: function() {
    let done = this.async();
    this.prompt(prompts, function(props) {

      // Make sure to get the correct app name if it is not the default
      if(props.appName !== utils.yeoman.getAppName()) {
        props.appName = utils.yeoman.getAppName(props.appName);
      }

      // Set needed global vars for yo
      this.appName = props.appName;
      this.style = props.style;
      this.postcss = props.postcss

      // Set needed keys into config
      this.config.set('appName', this.appName);
      this.config.set('appPath', this.appPath);
      this.config.set('style', this.style);
      this.config.set('postcss', this.postcss);

      this.config.save();

      done();
    }.bind(this));
  },

  configuring: function() {

    // Generate our package.json. Make sure to also include the required dependencies for styles
    let defaultSettings = this.fs.readJSON(path.join(baseRootPath, 'package.json'));
    let packageSettings = {
      name: this.appName,
      private: true,
      version: '0.0.1',
      description: 'YOUR DESCRIPTION - Generated by generator-react-webpack',
      main: '',
      scripts: defaultSettings.scripts,
      repository: '',
      keywords: [],
      author: '<NAME>',
      devDependencies: defaultSettings.devDependencies,
      dependencies: defaultSettings.dependencies
    };

    // Add needed loaders if we have special styles
    let styleConfig = utils.config.getChoiceByKey('style', this.style);
    if(styleConfig && styleConfig.packages) {

      for(let dependency of styleConfig.packages) {
        packageSettings.dependencies[dependency.name] = dependency.version;
      }
    }

    // Add postcss module if enabled
    let postcssConfig = utils.config.getChoiceByKey('postcss', 'postcss');
    if(this.postcss && postcssConfig && postcssConfig.packages) {

      for(let dependency of postcssConfig.packages) {
        packageSettings.dependencies[dependency.name] = dependency.version;
      }
    }

    this.fs.writeJSON(this.destinationPath('package.json'), packageSettings);
  },

  writing: function() {

    let excludeList = [
      'LICENCE',
      'README.md',
      'CHANGELOG.md',
      'node_modules',
      'package.json'
    ];

    // Get all files in our repo and copy the ones we should
    fs.readdir(this.sourceRoot(), (err, items) => {

      for(let item of items) {

        // Skip the item if it is in our exclude list
        if(excludeList.indexOf(item) !== -1) {
          continue;
        }

        // Copy all items to our root
        let fullPath = path.join(baseRootPath, item);
        if(fs.lstatSync(fullPath).isDirectory()) {
          this.bulkDirectory(item, item);
        } else {
          if (item === '.npmignore') {
            this.copy(item, '.gitignore');
          }
          this.copy(item, item);
        }
      }
    });
  },

  install: function() {
    // Update base cfg if postcss is enabled
    if(this.postcss) {
      var baseConfigPath = path.join(this.destinationRoot(), 'cfg/base.js');
      var data = fs.readFileSync(baseConfigPath, 'utf8');
      var result = data.replace(/(style-loader.*)'/g,
        function(match, $1) {
          return $1 + '!postcss-loader\'';
        }
      );
      result = result.replace(/style!css/, 'style-loader!css-loader!postcss-loader');
      result = result.replace(/\s\s\}\n};/, '  },\n  postcss: function () {\n    return [\n\n    ];\n  }\n};');

      fs.writeFileSync(baseConfigPath, result, 'utf8');
    }

    if(!this.options['skip-install']) {
      this.installDependencies({ bower: false });
    }
  }
});
<commit_msg>Refactored regex in favor of traversing via AST<commit_after>'use strict';
let generator = require('yeoman-generator');
let utils = require('../../utils/all');
let prompts = require('./prompts');
let path = require('path');
let fs = require('fs');

// Set the base root directory for our files
let baseRootPath = path.dirname(require.resolve('react-webpack-template'));

module.exports = generator.Base.extend({

  constructor: function() {
    generator.Base.apply(this, arguments);

    // Make options available
    this.option('skip-welcome-message', {
      desc: 'Skip the welcome message',
      type: Boolean,
      defaults: false
    });
    this.option('skip-install');

    // Use our plain template as source
    this.sourceRoot(baseRootPath);

    this.config.save();

    this.postcssConfig = function() {
      let esprima = require('esprima');
      let walk = require('esprima-walk');
      let escodegen = require('escodegen');

      let baseConfigPath = path.join(this.destinationRoot(), 'cfg/base.js');

      let css = '/\\.css$/';
      let cssDialects = ['/\\.sass/', '/\\.scss/', '/\\.less/', '/\\.styl/'];

      let postcss = 'var postcss = { postcss: function() { return []; } }';
      postcss = esprima.parse(postcss);
      postcss = postcss.body[0].declarations[0].init.properties[0];

      let data = fs.readFileSync(baseConfigPath, 'utf8');
      let parsed = esprima.parse(data);

      walk.walkAddParent(parsed, function(node) {
        if(node.type === 'AssignmentExpression' && node.left.object.name === 'module') {
          node.right.properties.push(postcss);
        }

        if(node.type === 'Property' && node.key.name === 'test') {
          if(cssDialects.indexOf(node.value.raw) > -1) {
            let current = node.parent.properties[1].value.value;
            current += '!postcss-loader';

            node.parent.properties[1].value.value = current;
          }

          if(node.value.raw === css) {
            let current = 'style-loader!css-loader!postcss-loader';

            node.parent.properties[1].value.value = current;
          }
        }
      });

      let options = { format: { indent: { style: '  ' } } };
      let code = escodegen.generate(parsed, options);
      fs.writeFileSync(baseConfigPath, code, 'utf8');
    }
  },

  initializing: function() {
    if(!this.options['skip-welcome-message']) {
      this.log(require('yeoman-welcome'));
      this.log('Out of the box I include Webpack and some default React components.\n');
    }
  },

  prompting: function() {
    let done = this.async();
    this.prompt(prompts, function(props) {

      // Make sure to get the correct app name if it is not the default
      if(props.appName !== utils.yeoman.getAppName()) {
        props.appName = utils.yeoman.getAppName(props.appName);
      }

      // Set needed global vars for yo
      this.appName = props.appName;
      this.style = props.style;
      this.postcss = props.postcss

      // Set needed keys into config
      this.config.set('appName', this.appName);
      this.config.set('appPath', this.appPath);
      this.config.set('style', this.style);
      this.config.set('postcss', this.postcss);

      this.config.save();

      done();
    }.bind(this));
  },

  configuring: function() {

    // Generate our package.json. Make sure to also include the required dependencies for styles
    let defaultSettings = this.fs.readJSON(path.join(baseRootPath, 'package.json'));
    let packageSettings = {
      name: this.appName,
      private: true,
      version: '0.0.1',
      description: 'YOUR DESCRIPTION - Generated by generator-react-webpack',
      main: '',
      scripts: defaultSettings.scripts,
      repository: '',
      keywords: [],
      author: 'Your <NAME>',
      devDependencies: defaultSettings.devDependencies,
      dependencies: defaultSettings.dependencies
    };

    // Add needed loaders if we have special styles
    let styleConfig = utils.config.getChoiceByKey('style', this.style);
    if(styleConfig && styleConfig.packages) {

      for(let dependency of styleConfig.packages) {
        packageSettings.dependencies[dependency.name] = dependency.version;
      }
    }

    // Add postcss module if enabled
    let postcssConfig = utils.config.getChoiceByKey('postcss', 'postcss');
    if(this.postcss && postcssConfig && postcssConfig.packages) {

      for(let dependency of postcssConfig.packages) {
        packageSettings.dependencies[dependency.name] = dependency.version;
      }
    }

    this.fs.writeJSON(this.destinationPath('package.json'), packageSettings);
  },

  writing: function() {

    let excludeList = [
      'LICENCE',
      'README.md',
      'CHANGELOG.md',
      'node_modules',
      'package.json'
    ];

    // Get all files in our repo and copy the ones we should
    fs.readdir(this.sourceRoot(), (err, items) => {

      for(let item of items) {

        // Skip the item if it is in our exclude list
        if(excludeList.indexOf(item) !== -1) {
          continue;
        }

        // Copy all items to our root
        let fullPath = path.join(baseRootPath, item);
        if(fs.lstatSync(fullPath).isDirectory()) {
          this.bulkDirectory(item, item);
        } else {
          if (item === '.npmignore') {
            this.copy(item, '.gitignore');
          }
          this.copy(item, item);
        }
      }
    });
  },

  install: function() {
    if(this.postcss) {
      this.postcssConfig();
    }

    if(!this.options['skip-install']) {
      this.installDependencies({ bower: false });
    }
  }
});

{'fraction_non_alphanumeric': 0.14473684210526316, 'fraction_numerical': 0.0020620581304006285, 'mean_word_length': 2.5574572127139366, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 8, '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': '1169075', 'n_tokens_mistral': 3064, 'n_tokens_neox': 2984, 'n_words': 685}