<commit_before>import { FILE_CHANGE_EVENT, FILE_DELETE_EVENT } from './util/constants';
import { BuildContext, BuildState, BuildUpdateMessage, ChangedFile } from './util/interfaces';
import { BuildError } from './util/errors';
import { readFileAsync, setContext } from './util/helpers';
import { bundle, bundleUpdate } from './bundle';
import { clean } from './clean';
import { copy } from './copy';
import { emit, EventType } from './util/events';
import { lint, lintUpdate } from './lint';
import { Logger } from './logger/logger';
import { minifyCss, minifyJs } from './minify';
import { ngc } from './ngc';
import { sass, sassUpdate } from './sass';
import { templateUpdate } from './template';
import { transpile, transpileUpdate, transpileDiagnosticsOnly } from './transpile';

export function build(context: BuildContext) {
  setContext(context);
  const logger = new Logger(`build ${(context.isProd ? 'prod' : 'dev')}`);

  return buildWorker(context)
    .then(() => {
      // congrats, we did it!  (•_•) / ( •_•)>⌐■-■ / (⌐■_■)
      logger.finish();
    })
    .catch(err => {
      if (err.isFatal) { throw err; }
      throw logger.fail(err);
    });
}

function buildWorker(context: BuildContext) {
  return Promise.resolve().then(() => {
    // load any 100% required files to ensure they exist
    return validateRequiredFilesExist();
  })
  .then(([appEntryPointContents, tsConfigContents]) => {
    return validateTsConfigSettings(tsConfigContents);
  })
  .then(() => {
    return buildProject(context);
  });
}

function validateRequiredFilesExist() {
  return Promise.all([
    readFileAsync(process.env.IONIC_APP_ENTRY_POINT),
    readFileAsync(process.env.IONIC_TS_CONFIG)
  ]).catch((error) => {
    if (error.code === 'ENOENT' && error.path === process.env.IONIC_APP_ENTRY_POINT) {
      error = new BuildError(`${error.path} was not found. The "main.dev.ts" and "main.prod.ts" files have been deprecated. Please create a new file "main.ts" containing the content of "main.dev.ts", and then delete the deprecated files.
                            For more information, please see the default Ionic project main.ts file here:
                            https://github.com/driftyco/ionic2-app-base/tree/master/src/app/main.ts`);
      error.isFatal = true;
      throw error;
    }
    if (error.code === 'ENOENT' && error.path === process.env.IONIC_TS_CONFIG) {
      error = new BuildError([`${error.path} was not found. The "tsconfig.json" file is missing. This file is required.`,
        'For more information please see the default Ionic project tsconfig.json file here:',
        'https://github.com/driftyco/ionic2-app-base/blob/master/tsconfig.json'].join('\n'));
      error.isFatal = true;
      throw error;
    }
    error.isFatal = true;
    throw error;
  });
}

function validateTsConfigSettings(tsConfigFileContents: string) {

  return new Promise((resolve, reject) => {
    try {
      const tsConfigJson = JSON.parse(tsConfigFileContents);
      const isValid = tsConfigJson.hasOwnProperty('compilerOptions') &&
        tsConfigJson.compilerOptions.hasOwnProperty('sourceMap') &&
        tsConfigJson.compilerOptions.sourceMap === true;

      if (!isValid) {
        const error = new BuildError(['Your "tsconfig.json" file must have compilerOptions.sourceMap set to true.',
          'For more information please see the default Ionic project tsconfig.json file here:',
          'https://github.com/driftyco/ionic2-app-base/blob/master/tsconfig.json'].join('\n'));
        error.isFatal = true;
        return reject(error);
      }
      resolve();
    } catch (e) {
      const error = new BuildError('Your "tsconfig.json" file contains malformed JSON.');
      error.isFatal = true;
      return reject(error);
    }
  });
}

function buildProject(context: BuildContext) {
  // sync empty the www/build directory
  clean(context);
<commit_msg>refactor(logging): better error message around sourceMaps setting<commit_after>import { FILE_CHANGE_EVENT, FILE_DELETE_EVENT } from './util/constants';
import { BuildContext, BuildState, BuildUpdateMessage, ChangedFile } from './util/interfaces';
import { BuildError } from './util/errors';
import { readFileAsync, setContext } from './util/helpers';
import { bundle, bundleUpdate } from './bundle';
import { clean } from './clean';
import { copy } from './copy';
import { emit, EventType } from './util/events';
import { lint, lintUpdate } from './lint';
import { Logger } from './logger/logger';
import { minifyCss, minifyJs } from './minify';
import { ngc } from './ngc';
import { sass, sassUpdate } from './sass';
import { templateUpdate } from './template';
import { transpile, transpileUpdate, transpileDiagnosticsOnly } from './transpile';

export function build(context: BuildContext) {
  setContext(context);
  const logger = new Logger(`build ${(context.isProd ? 'prod' : 'dev')}`);

  return buildWorker(context)
    .then(() => {
      // congrats, we did it!  (•_•) / ( •_•)>⌐■-■ / (⌐■_■)
      logger.finish();
    })
    .catch(err => {
      if (err.isFatal) { throw err; }
      throw logger.fail(err);
    });
}

function buildWorker(context: BuildContext) {
  return Promise.resolve().then(() => {
    // load any 100% required files to ensure they exist
    return validateRequiredFilesExist();
  })
  .then(([appEntryPointContents, tsConfigContents]) => {
    return validateTsConfigSettings(tsConfigContents);
  })
  .then(() => {
    return buildProject(context);
  });
}

function validateRequiredFilesExist() {
  return Promise.all([
    readFileAsync(process.env.IONIC_APP_ENTRY_POINT),
    readFileAsync(process.env.IONIC_TS_CONFIG)
  ]).catch((error) => {
    if (error.code === 'ENOENT' && error.path === process.env.IONIC_APP_ENTRY_POINT) {
      error = new BuildError(`${error.path} was not found. The "main.dev.ts" and "main.prod.ts" files have been deprecated. Please create a new file "main.ts" containing the content of "main.dev.ts", and then delete the deprecated files.
                            For more information, please see the default Ionic project main.ts file here:
                            https://github.com/driftyco/ionic2-app-base/tree/master/src/app/main.ts`);
      error.isFatal = true;
      throw error;
    }
    if (error.code === 'ENOENT' && error.path === process.env.IONIC_TS_CONFIG) {
      error = new BuildError([`${error.path} was not found. The "tsconfig.json" file is missing. This file is required.`,
        'For more information please see the default Ionic project tsconfig.json file here:',
        'https://github.com/driftyco/ionic2-app-base/blob/master/tsconfig.json'].join('\n'));
      error.isFatal = true;
      throw error;
    }
    error.isFatal = true;
    throw error;
  });
}

function validateTsConfigSettings(tsConfigFileContents: string) {

  return new Promise((resolve, reject) => {
    try {
      const tsConfigJson = JSON.parse(tsConfigFileContents);
      const isValid = tsConfigJson.hasOwnProperty('compilerOptions') &&
        tsConfigJson.compilerOptions.hasOwnProperty('sourceMap') &&
        tsConfigJson.compilerOptions.sourceMap === true;

      if (!isValid) {
        const error = new BuildError(['The "tsconfig.json" file must have compilerOptions.sourceMap set to true.',
          'For more information please see the default Ionic project tsconfig.json file here:',
          'https://github.com/driftyco/ionic2-app-base/blob/master/tsconfig.json'].join('\n'));
        error.isFatal = true;
        return reject(error);
      }
      resolve();
    } catch (e) {
      const error = new BuildError('The "tsconfig.json" file contains malformed JSON.');
      error.isFatal = true;
      return reject(error);
    }
  });
}

function buildProject(context: BuildContext) {
  // sync empty the www/build directory
  clean(context);

{'fraction_non_alphanumeric': 0.1414901760653228, 'fraction_numerical': 0.0015310028068384791, 'mean_word_length': 3.3333333333333335, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, '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': '3337508', 'n_tokens_mistral': 2339, 'n_tokens_neox': 2316, 'n_words': 604}