<commit_before>'use strict';

// @TODO: Wait to node.js achieve harmony module.
const BashChildProcess = require('./BashChildProcess.js');

const path = require('path');

class HookProcess {
  constructor({ pluginNames = [], cwd = '' }) {
    this[Symbol.for('cwd')] = cwd;
    this[Symbol.for('pluginNames')] = pluginNames;
    this[Symbol.for('bashChildProcessArray')] = [];
  }

  startProcess() {
    let pluginNames = this.getPluginNames();
    this[Symbol.for('traversingPluginNames')](pluginNames);
  }

  getCwd() {
    return this[Symbol.for('cwd')];
  }

  getPluginNames() {
    // @TODO: Change to set.
    return this[Symbol.for('pluginNames')];
  }

  [Symbol.for('getPathByPluginName')](pluginName = '') {
    const shellName = `${pluginName}.plugin.sh`;
    const cwd = this.getCwd();
    const shellPath = path.join(cwd, 'plugins', pluginName, shellName);

    return shellPath;
  }

  [Symbol.for('traversingPluginNames')](pluginNames = []) {
    let processArray = pluginNames.map((pluginName, idx, arr) => {
      let scriptPath = this[Symbol.for('getPathByPluginName')](pluginName);
      let isStdout = idx ? false : true;
      let bashChildProcess = new BashChildProcess({ isStdout, scriptPath });
      return bashChildProcess;
    });

    let rejectPromises = processArray.map((bashChildProcess, idx, arr) => {
      return bashChildProcess.getErrorPromise();
    });

    let closePromises = processArray.map((bashChildProcess, idx, arr) => {
      return bashChildProcess.getClosePromise();
    });

    this[Symbol.for('bindExitCallback')](rejectPromises);
    this[Symbol.for('bindCloseCallback')](closePromises);
    this[Symbol.for('bashChildProcessArray')] = [...processArray];
  }

  [Symbol.for('bindCloseCallback')](closePromises = []) {
    closePromises.forEach((promise, idx, arr) => {
      promise.then((flag) => {
        if (flag) {
          this[Symbol.for('switchChildProcessOutput')](idx);
        }
      });
    });
  }

  [Symbol.for('switchChildProcessOutput')](currentIdx = 0) {
    const bashChildProcessArray = this[Symbol.for('bashChildProcessArray')];
    const prevChildProcess = bashChildProcessArray[currentIdx - 1];
    const currentChildProcess = bashChildProcessArray[currentIdx]

    if (currentIdx === bashChildProcessArray.length &&
      !currentChildProcess.isStdout()) {
      this[Symbol.for('setProcessAsStdout')](currentChildProcess);
    }

    if (prevChildProcess === void 0 || prevChildProcess.isClose()) {
      this[Symbol.for('traversingNextUnCloseChildProcess')](currentIdx + 1);
    }
  }

  [Symbol.for('traversingNextUnCloseChildProcess')](nextIdx = 1) {
    const bashChildProcessArray = this[Symbol.for('bashChildProcessArray')];
    const setProcessAsStdout = this[Symbol.for('setProcessAsStdout')];
    const nextChildProcessArray = bashChildProcessArray.slice(nextIdx);

    nextChildProcessArray.forEach((nextChildProcess, idx, arr) => {
      setProcessAsStdout(nextChildProcess);
    });
  }

  [Symbol.for('setProcessAsStdout')](nextChildProcess) {
    let outputIterator = nextChildProcess.getOutputIterator();

    // ouput caching results
    for (let output of outputIterator) {
      process.stdout.write(output);
    }

    // switching output child process
    nextChildProcess.setStdout(true);
  }

  [Symbol.for('bindExitCallback')](rejectPromises = []) {
    const getAnyRejectPromise = this[Symbol.for('getAnyRejectPromise')];
    const anyRejectPromise = getAnyRejectPromise(rejectPromises);

    anyRejectPromise.catch((error) => {
      console.log(error);
      console.log('hook process abnormal exit.');
      process.exit(1);
    });
  }

  [Symbol.for('getAnyRejectPromise')](promises = []) {
    // @TODO: Print error process outputQueue.
    let anyRejectPromise = new Promise((fulfillOuter, rejectOuter) => {
      for (let promise of promises) {
        promise.catch((error) => {
          rejectOuter(error);
        });
      }
    });
    return anyRejectPromise;
  }
}

module.exports = HookProcess;
<commit_msg>bugfix<commit_after>'use strict';

// @TODO: Wait to node.js achieve harmony module.
const BashChildProcess = require('./BashChildProcess.js');

const path = require('path');

class HookProcess {
  constructor({ pluginNames = [], cwd = '' }) {
    this[Symbol.for('cwd')] = cwd;
    this[Symbol.for('pluginNames')] = pluginNames;
    this[Symbol.for('bashChildProcessArray')] = [];
  }

  startProcess() {
    let pluginNames = this.getPluginNames();
    this[Symbol.for('traversingPluginNames')](pluginNames);
  }

  getCwd() {
    return this[Symbol.for('cwd')];
  }

  getPluginNames() {
    // @TODO: Change to set.
    return this[Symbol.for('pluginNames')];
  }

  [Symbol.for('getPathByPluginName')](pluginName = '') {
    const shellName = `${pluginName}.plugin.sh`;
    const cwd = this.getCwd();
    const shellPath = path.join(cwd, 'plugins', pluginName, shellName);

    return shellPath;
  }

  [Symbol.for('traversingPluginNames')](pluginNames = []) {
    let processArray = pluginNames.map((pluginName, idx, arr) => {
      let scriptPath = this[Symbol.for('getPathByPluginName')](pluginName);
      let isStdout = idx ? false : true;
      let bashChildProcess = new BashChildProcess({ isStdout, scriptPath });
      return bashChildProcess;
    });

    let rejectPromises = processArray.map((bashChildProcess, idx, arr) => {
      return bashChildProcess.getErrorPromise();
    });

    let closePromises = processArray.map((bashChildProcess, idx, arr) => {
      return bashChildProcess.getClosePromise();
    });

    this[Symbol.for('bindExitCallback')](rejectPromises);
    this[Symbol.for('bindCloseCallback')](closePromises);
    this[Symbol.for('bashChildProcessArray')] = [...processArray];
  }

  [Symbol.for('bindCloseCallback')](closePromises = []) {
    closePromises.forEach((promise, idx, arr) => {
      promise.then((flag) => {
        if (flag) {
          this[Symbol.for('switchChildProcessOutput')](idx);
        }
      });
    });
  }

  [Symbol.for('switchChildProcessOutput')](currentIdx = 0) {
    const bashChildProcessArray = this[Symbol.for('bashChildProcessArray')];
    const prevChildProcess = bashChildProcessArray[currentIdx - 1];
    const currentChildProcess = bashChildProcessArray[currentIdx];

    // The last element of array need empty itself output queue.
    if (!currentChildProcess.isStdout() &&
      currentIdx === bashChildProcessArray.length) {
      this[Symbol.for('setProcessAsStdout')](currentChildProcess);
    }

    if (prevChildProcess === void 0 || prevChildProcess.isClose()) {
      this[Symbol.for('traversingNextUnCloseChildProcess')](currentIdx + 1);
    }
  }

  [Symbol.for('traversingNextUnCloseChildProcess')](nextIdx = 1) {
    const bashChildProcessArray = this[Symbol.for('bashChildProcessArray')];
    const setProcessAsStdout = this[Symbol.for('setProcessAsStdout')];
    const nextChildProcessArray = bashChildProcessArray.slice(nextIdx);

    nextChildProcessArray.forEach((nextChildProcess, idx, arr) => {
      setProcessAsStdout(nextChildProcess);
    });
  }

  [Symbol.for('setProcessAsStdout')](nextChildProcess) {
    let outputIterator = nextChildProcess.getOutputIterator();

    // ouput caching results
    for (let output of outputIterator) {
      process.stdout.write(output);
    }

    // switching output child process
    nextChildProcess.setStdout(true);
  }

  [Symbol.for('bindExitCallback')](rejectPromises = []) {
    const getAnyRejectPromise = this[Symbol.for('getAnyRejectPromise')];
    const anyRejectPromise = getAnyRejectPromise(rejectPromises);

    anyRejectPromise.catch((error) => {
      console.log(error);
      console.log('hook process abnormal exit.');
      process.exit(1);
    });
  }

  [Symbol.for('getAnyRejectPromise')](promises = []) {
    // @TODO: Print error process outputQueue.
    let anyRejectPromise = new Promise((fulfillOuter, rejectOuter) => {
      for (let promise of promises) {
        promise.catch((error) => {
          rejectOuter(error);
        });
      }
    });
    return anyRejectPromise;
  }
}

module.exports = HookProcess;

{'fraction_non_alphanumeric': 0.14526652714514343, 'fraction_numerical': 0.001477286716730272, 'mean_word_length': 3.8910295003010233, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, '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': '4357461', 'n_tokens_mistral': 2508, 'n_tokens_neox': 2429, 'n_words': 402}