<commit_before>// Copyright 2019, University of Colorado Boulder

/**
 * Runs webpack - DO NOT RUN MULTIPLE CONCURRENTLY
 *
 * @author <NAME> <<EMAIL>>
 */

'use strict';

// modules
const chipperGlobals = require( './chipperGlobals' );
const fs = require( 'fs' );
const path = require( 'path' );
const webpack = require( 'webpack' );

const activeRepos = fs.readFileSync( path.resolve( __dirname, '../../../perennial/data/active-repos' ), 'utf-8' ).trim().split( /\r?\n/ ).map( s => s.trim() );
const reposByNamespace = {};
const aliases = {};

for ( const repo of activeRepos ) {
  const packageFile = path.resolve( __dirname, `../../../${repo}/package.json` );
  if ( fs.existsSync( packageFile ) ) {
    const packageObject = JSON.parse( fs.readFileSync( packageFile, 'utf-8' ) );
    if ( packageObject.phet && packageObject.phet.requirejsNamespace ) {
      reposByNamespace[ packageObject.phet.requirejsNamespace ] = repo;
      aliases[ packageObject.phet.requirejsNamespace ] = path.resolve( __dirname, `../../../${repo}${repo === 'brand' ? '/phet' : ''}/js` );
    }
  }
}

const usedModules = [];

class ListUsedModulesPlugin {
  apply( compiler ) {
    compiler.hooks.emit.tap( 'ListUsedModulesPlugin', compilation => {
      compilation.chunks.forEach( chunk => {
        usedModules.push( ...Array.from( chunk.entryModule.buildInfo.fileDependencies ) );
      } );
    } );
  }
}

const getRelativeModules = () => {
  for ( let i = 0; i < usedModules[ 0 ].length; i++ ) {
    for ( const usedModule of usedModules ) {
      if ( usedModule[ i ] !== usedModules[ 0 ][ i ] ) {
        return usedModules.map( module => module.slice( i ) );
      }
    }
  }
  throw new Error( 'modules are all the same?' );
};

/**
 * Runs webpack - DO NOT RUN MULTIPLE CONCURRENTLY
 * @public
 *
 * @param {string} repo
 * @param {string} brand
 * @returns {Promise.<string>} - The combined JS output from the process
 */
module.exports = function( repo, brand ) {
  return new Promise( ( resolve, reject ) => {
    // Initialize global state in preparation for the require.js step.
    chipperGlobals.beforeBuild( 'phet' );

    // Zero out used modules
    usedModules.length = 0;

    const compiler = webpack( {
      optimization: {
        minimize: false
      },

      entry: {
        repo: `../${repo}/js/${repo}-main.js`
      },
      output: {
        path: path.resolve( __dirname, '../../build' ),
        filename: `${repo}.js`
      },

      resolveLoader: {
        alias: {
          'url-loader': path.resolve( __dirname, '../../node_modules/url-loader/dist/index.js' )
        }
      },

      plugins: [
        new ListUsedModulesPlugin()
      ],
      module: {

        // rules for modules (configure loaders, parser options, etc.)
        rules: [

          ...( brand === 'phet-io' ? [] : [

            {
              test: /phetio/,
              use: path.resolve( __dirname, '../../test-webpack-multi-brands/phetioStub-loader.js' )
            }
          ] )
        ]
      }
    } );

    compiler.run( ( err, stats ) => {<commit_msg>Allow builds without phet-io/ repo checked out, see https://github.com/phetsims/chipper/issues/844<commit_after>// Copyright 2019, University of Colorado Boulder

/**
 * Runs webpack - DO NOT RUN MULTIPLE CONCURRENTLY
 *
 * @author <NAME> <<EMAIL>>
 */

'use strict';

// modules
const chipperGlobals = require( './chipperGlobals' );
const fs = require( 'fs' );
const path = require( 'path' );
const webpack = require( 'webpack' );

const activeRepos = fs.readFileSync( path.resolve( __dirname, '../../../perennial/data/active-repos' ), 'utf-8' ).trim().split( /\r?\n/ ).map( s => s.trim() );
const reposByNamespace = {};
const aliases = {};

for ( const repo of activeRepos ) {
  const packageFile = path.resolve( __dirname, `../../../${repo}/package.json` );
  if ( fs.existsSync( packageFile ) ) {
    const packageObject = JSON.parse( fs.readFileSync( packageFile, 'utf-8' ) );
    if ( packageObject.phet && packageObject.phet.requirejsNamespace ) {
      reposByNamespace[ packageObject.phet.requirejsNamespace ] = repo;
      aliases[ packageObject.phet.requirejsNamespace ] = path.resolve( __dirname, `../../../${repo}${repo === 'brand' ? '/phet' : ''}/js` );
    }
  }
}

const usedModules = [];

class ListUsedModulesPlugin {
  apply( compiler ) {
    compiler.hooks.emit.tap( 'ListUsedModulesPlugin', compilation => {
      compilation.chunks.forEach( chunk => {
        usedModules.push( ...Array.from( chunk.entryModule.buildInfo.fileDependencies ) );
      } );
    } );
  }
}

const getRelativeModules = () => {
  for ( let i = 0; i < usedModules[ 0 ].length; i++ ) {
    for ( const usedModule of usedModules ) {
      if ( usedModule[ i ] !== usedModules[ 0 ][ i ] ) {
        return usedModules.map( module => module.slice( i ) );
      }
    }
  }
  throw new Error( 'modules are all the same?' );
};

/**
 * Runs webpack - DO NOT RUN MULTIPLE CONCURRENTLY
 * @public
 *
 * @param {string} repo
 * @param {string} brand
 * @returns {Promise.<string>} - The combined JS output from the process
 */
module.exports = function( repo, brand ) {
  return new Promise( ( resolve, reject ) => {
    // Initialize global state in preparation for the require.js step.
    chipperGlobals.beforeBuild( 'phet' );

    // Zero out used modules
    usedModules.length = 0;

    const compiler = webpack( {
      optimization: {
        minimize: false
      },

      entry: {
        repo: `../${repo}/js/${repo}-main.js`
      },
      output: {
        path: path.resolve( __dirname, '../../build' ),
        filename: `${repo}.js`
      },

      resolveLoader: {
        alias: {
          'url-loader': path.resolve( __dirname, '../../node_modules/url-loader/dist/index.js' )
        }
      },

      plugins: [
        new ListUsedModulesPlugin(),

        // Allow builds for developers that do not have the phet-io repo checked out. IgnorePlugin will skip any require
        // that matches the following regex.
        ...( brand === 'phet-io' ? [] : [ new webpack.IgnorePlugin( /phetioEngine/ ) ] )
      ],
      module: {

        // rules for modules (configure loaders, parser options, etc.)
        rules: []
      }
    } );

    compiler.run( ( err, stats ) => {
{'fraction_non_alphanumeric': 0.16347075743048897, 'fraction_numerical': 0.0036752956216043464, 'mean_word_length': 2.456101601325235, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 1, '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': '1171548', 'n_tokens_mistral': 1962, 'n_tokens_neox': 1952, 'n_words': 486}