<commit_before>import { basename, join } from 'path';
import { BuildContext, TaskInfo } from './util/interfaces';
import { copy as fsCopy, emptyDirSync, outputJsonSync, readFileSync, statSync } from 'fs-extra';
import { endsWith } from './util/helpers';
import { fillConfigDefaults, generateContext, getUserConfigFile, getNodeBinExecutable } from './util/config';
import { getTsConfigPath } from './transpile';
import { BuildError, Logger } from './util/logger';
import * as ts from 'typescript';


export function ngc(context?: BuildContext, configFile?: string) {
  context = generateContext(context);
  configFile = getUserConfigFile(context, taskInfo, configFile);

  const logger = new Logger('ngc');

  return ngcWorker(context, configFile)
    .then(() => {
      logger.finish();
    })
    .catch(err => {
      throw logger.fail(err);
    });
}


export function ngcWorker(context: BuildContext, configFile: string) {
  // first make a copy of src TS files
  // and copy them into the tmp directory
  return copySrcTsToTmpDir(context).then(() => {
    return runNgc(context, configFile);
  });
}


function runNgc(context: BuildContext, configFile: string) {
  return new Promise((resolve, reject) => {
    const ngcConfig: NgcConfig = fillConfigDefaults(configFile, taskInfo.defaultConfigFile);

    // make a copy of the users src tsconfig file
    // and save the modified copy into the tmp directory
    createTmpTsConfig(context, ngcConfig);

    const ngcCmd = getNodeBinExecutable(context, 'ngc');
    if (!ngcCmd) {
      reject(new BuildError(`Unable to find Angular Compiler "ngc" command: ${ngcCmd}. Please ensure @angular/compiler-cli has been installed with NPM.`));
      return;
    }

    // let's kick off the actual ngc command on our copied TS files
    // use the user's ngc in their node_modules to ensure ngc
    // versioned and working along with the user's ng2 version
    const spawn = require('cross-spawn');
    const ngcCmdArgs = [
      '--project', getTmpTsConfigPath(context)
    ];

    Logger.debug(`run: ${ngcCmd} ${ngcCmdArgs.join(' ')}`);

    // would love to not use spawn here but import and run ngc directly
    const cp = spawn(ngcCmd, ngcCmdArgs);

    let errorMsgs: string[] = [];

    cp.stdout.on('data', (data: string) => {
      Logger.info(data);
    });

    cp.stderr.on('data', (data: string) => {
      if (data) {
        data.toString().split('\n').forEach(line => {
          if (!line.trim().length) {
            // if it's got no data then don't bother
            return;
          }
          if (line.substr(0, 4) === '    ' || line === 'Compilation failed') {
            // if it's indented then it's some callstack message we don't care about
            return;
          }
          // split by the : character, then rebuild the line until it's too long
          // and make a new line
          const lineSections = line.split(': ');
          let msgSections: string[] = [];
          for (var i = 0; i < lineSections.length; i++) {
            msgSections.push(lineSections[i]);
            if (msgSections.join(': ').length > 40) {
              errorMsgs.push(msgSections.join(': '));
              msgSections = [];
            }
          }
          if (msgSections.length) {
            errorMsgs.push(msgSections.join(': '));
          }
        });
      }
    });

    cp.on('close', (code: string) => {
      if (errorMsgs.length) {
        errorMsgs.forEach(errorMsg => {
          Logger.error(errorMsg);
        });
        reject(new BuildError());

      } else {
        resolve();
      }
    });
  });
}


function createTmpTsConfig(context: BuildContext, ngcConfig: NgcConfig) {
  // create the tsconfig from the original src
  const tsConfigPath = getTsConfigPath(context);
  const tsConfigFile = ts.readConfigFile(tsConfigPath, path => readFileSync(path, 'utf8'));

  if (!tsConfigFile || !tsConfigFile.config) {
    throw new BuildError(`invalid tsconfig: ${tsConfigPath}`);
  }

  if (!tsConfigFile.config.compilerOptions) {
    throw new BuildError(`invalid tsconfig compilerOptions: ${tsConfigPath}`);
  }

  // delete outDir if it's set since we only want
  // to compile to the same directory we're in
  delete tsConfigFile.config.compilerOptions.outDir;

  // save the modified copy into the tmp directory
  outputJsonSync(getTmpTsConfigPath(context), tsConfigFile.config);
}


function copySrcTsToTmpDir(context: BuildContext) {
  return new Promise((resolve, reject) => {

    // ensure the tmp directory is ready to go
    try {
      emptyDirSync(context.tmpDir);
    } catch (e) {
      reject(new BuildError(`tmpDir error: ${e}`));
      return;
    }

    const copyOpts: any = {
      filter: filterCopyFiles
    };<commit_msg>fix(ngc): use config values in the generated tsconfig<commit_after>import { basename, join } from 'path';
import { BuildContext, TaskInfo } from './util/interfaces';
import { copy as fsCopy, emptyDirSync, outputJsonSync, readFileSync, statSync } from 'fs-extra';
import { endsWith, objectAssign } from './util/helpers';
import { fillConfigDefaults, generateContext, getUserConfigFile, getNodeBinExecutable } from './util/config';
import { getTsConfigPath } from './transpile';
import { BuildError, Logger } from './util/logger';
import * as ts from 'typescript';


export function ngc(context?: BuildContext, configFile?: string) {
  context = generateContext(context);
  configFile = getUserConfigFile(context, taskInfo, configFile);

  const logger = new Logger('ngc');

  return ngcWorker(context, configFile)
    .then(() => {
      logger.finish();
    })
    .catch(err => {
      throw logger.fail(err);
    });
}


export function ngcWorker(context: BuildContext, configFile: string) {
  // first make a copy of src TS files
  // and copy them into the tmp directory
  return copySrcTsToTmpDir(context).then(() => {
    return runNgc(context, configFile);
  });
}


function runNgc(context: BuildContext, configFile: string) {
  return new Promise((resolve, reject) => {
    const ngcConfig: NgcConfig = fillConfigDefaults(configFile, taskInfo.defaultConfigFile);

    // make a copy of the users src tsconfig file
    // and save the modified copy into the tmp directory
    createTmpTsConfig(context, ngcConfig);

    const ngcCmd = getNodeBinExecutable(context, 'ngc');
    if (!ngcCmd) {
      reject(new BuildError(`Unable to find Angular Compiler "ngc" command: ${ngcCmd}. Please ensure @angular/compiler-cli has been installed with NPM.`));
      return;
    }

    // let's kick off the actual ngc command on our copied TS files
    // use the user's ngc in their node_modules to ensure ngc
    // versioned and working along with the user's ng2 version
    const spawn = require('cross-spawn');
    const ngcCmdArgs = [
      '--project', getTmpTsConfigPath(context)
    ];

    Logger.debug(`run: ${ngcCmd} ${ngcCmdArgs.join(' ')}`);

    // would love to not use spawn here but import and run ngc directly
    const cp = spawn(ngcCmd, ngcCmdArgs);

    let errorMsgs: string[] = [];

    cp.stdout.on('data', (data: string) => {
      Logger.info(data);
    });

    cp.stderr.on('data', (data: string) => {
      if (data) {
        data.toString().split('\n').forEach(line => {
          if (!line.trim().length) {
            // if it's got no data then don't bother
            return;
          }
          if (line.substr(0, 4) === '    ' || line === 'Compilation failed') {
            // if it's indented then it's some callstack message we don't care about
            return;
          }
          // split by the : character, then rebuild the line until it's too long
          // and make a new line
          const lineSections = line.split(': ');
          let msgSections: string[] = [];
          for (var i = 0; i < lineSections.length; i++) {
            msgSections.push(lineSections[i]);
            if (msgSections.join(': ').length > 40) {
              errorMsgs.push(msgSections.join(': '));
              msgSections = [];
            }
          }
          if (msgSections.length) {
            errorMsgs.push(msgSections.join(': '));
          }
        });
      }
    });

    cp.on('close', (code: string) => {
      if (errorMsgs.length) {
        errorMsgs.forEach(errorMsg => {
          Logger.error(errorMsg);
        });
        reject(new BuildError());

      } else {
        resolve();
      }
    });
  });
}


function createTmpTsConfig(context: BuildContext, ngcConfig: NgcConfig) {
  // create the tsconfig from the original src
  const tsConfigPath = getTsConfigPath(context);
  const tsConfigFile = ts.readConfigFile(tsConfigPath, path => readFileSync(path, 'utf8'));

  if (!tsConfigFile || !tsConfigFile.config) {
    throw new BuildError(`invalid tsconfig: ${tsConfigPath}`);
  }

  if (!tsConfigFile.config.compilerOptions) {
    throw new BuildError(`invalid tsconfig compilerOptions: ${tsConfigPath}`);
  }

  // delete outDir if it's set since we only want
  // to compile to the same directory we're in
  delete tsConfigFile.config.compilerOptions.outDir;

  const mergedConfig = objectAssign({}, tsConfigFile.config, ngcConfig);

  // save the modified copy into the tmp directory
  outputJsonSync(getTmpTsConfigPath(context), mergedConfig);
}


function copySrcTsToTmpDir(context: BuildContext) {
  return new Promise((resolve, reject) => {

    // ensure the tmp directory is ready to go
    try {
      emptyDirSync(context.tmpDir);
    } catch (e) {
      reject(new BuildError(`tmpDir error: ${e}`));
      return;
    }

    const copyOpts: any = {
      filter: filterCopyFiles
    };
{'fraction_non_alphanumeric': 0.1271459785662262, 'fraction_numerical': 0.0014566642388929353, 'mean_word_length': 2.8355945730247405, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 27, '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': '556060', 'n_tokens_mistral': 2896, 'n_tokens_neox': 2802, 'n_words': 813}