<commit_before>'use strict';

/**
 * project-core
 *
 * @author <NAME> <<EMAIL>>
 */

import path from 'path';
import fs from 'fs';
import { EventEmitter } from 'events';
import { Namespace } from 'lei-ns';
import rd from 'rd';
import yaml from 'js-yaml';
import utils from './utils';
const debug = utils.debug('core');

export default class ProjectCore {

  constructor() {

    this.utils = utils.extends();

    this._event = new EventEmitter();
    this._event.setMaxListeners(0);
    this.event = {};
    this.event.on = (e, fn) => this._event.on(e, utils.wrapFn(fn, this));
    this.event.once = (e, fn) => this._event.once(e, utils.wrapFn(fn, this));
    this.event.emit = (e, ...args) => {
      args.push(err => this.emit('error', err));
      this._event.emit(e, ...args);
    };
    this._event.on('error', err => {
      if (this._event._events.error.length < 2) {
        console.error(err.stack || err);
      }
    });

    this.init._queue = [];
    this.init.add = (fn) => {
      this._checkInited();
      // eslint-disable-next-line
      fn.__sourceLine = utils.getCallerSourceLine();
      debug('init.add: at %s', fn.__sourceLine);
      this.init._queue.push(fn);
    };
    this.init._loadFile = (f) => {
      const m = require(f);
      let ret;
      if (typeof m === 'function') ret = m;
      else if (typeof m.default === 'function') ret = m.default;
      else throw new Error(`module "${ f }" must export as a function`);
      ret.level = m.level || ret.level || 0;
      return ret;
    };
    this.init.load = (f) => {
      if (this.initing) throw new Error('cannot call init.load() after init()');
      const s = fs.statSync(f);
      if (s.isFile()) {
        debug('init.load: %s', f);
        this.init.add(this.init._loadFile(f));
      } else if (s.isDirectory()) {
        const list = rd.readFileFilterSync(f, /\.js$/)
                       .map(f => {
                         debug('init.load: %s', f);
                         return this.init._loadFile(f);
                       })
                       .sort((a, b) => b.level - a.level);
        for (const fn of list) {
          this.init.add(fn);
        }
      } else {
        throw new Error(`"${ f }" is not a file or directory`);
      }
    };

    this.config = new Namespace();
    this.config.load = file => {
      debug('config.load: %s', file);
      try {
        const fullPath = path.resolve(file);
        const ext = path.extname(fullPath).toLowerCase();
        if (ext === '.yaml' || ext === '.yml') {
          this.config.merge(yaml.safeLoad(fs.readFileSync(fullPath).toString()));
        } else if (ext === '.json') {
          this.config.merge(require(fullPath));
        } else if (ext === '.js' || ext === '') {
          const initConfig = require(fullPath);
          if (typeof initConfig !== 'function') {
            throw new Error(`incorrect config file format in file "${ file }"`);
          }
          const args = [
            (n, v) => this.config.set(n, v),
            (n) => this.config.get(n),
            (n) => this.config.has(n),
            this.config,
          ];
          initConfig.call(this.config, ...args);
        }
      } catch (err) {
        throw new Error(`failed to load config file "${ file }": ${ err.message }`);
      }
    };
    this.config._get = this.config.get;
    this.config.get = (n) => {
      const v = this.config._get(n);
      if (v === undefined) {
        throw new TypeError(`config field "${ n }" is undefined`);
      }
      return v;
    };

    this._extends = {
      before: [],
      init: [],
      after: [],
    };

    this._lazycallMethods = new Map();
    this._methodHooks = [];
    this.event.once('ready', () => this._lazycallMethods.clear());

    this.inited = false;
    this.event.once('ready', () => {
      this.inited = true;
    });

  }

  _checkInited() {
    if (this.inited) {
      throw new Error('you cannot change project-core after it has been inited');
    }
  }

  extends(info) {

    this._checkInited();

    if (typeof info.before === 'function') {
      this._extends.before.push(info.before);
    }
    if (typeof info.init === 'function') {
      this._extends.init.push(info.init);
    }
    if (typeof info.after === 'function') {
      this._extends.after.push(info.after);<commit_msg>fix: remove no use codes<commit_after>'use strict';

/**
 * project-core
 *
 * @author <NAME> <<EMAIL>>
 */

import path from 'path';
import fs from 'fs';
import { EventEmitter } from 'events';
import { Namespace } from 'lei-ns';
import rd from 'rd';
import yaml from 'js-yaml';
import utils from './utils';
const debug = utils.debug('core');

export default class ProjectCore {

  constructor() {

    this.utils = utils.extends();

    this._event = new EventEmitter();
    this._event.setMaxListeners(0);
    this.event = {};
    this.event.on = (e, fn) => this._event.on(e, utils.wrapFn(fn, this));
    this.event.once = (e, fn) => this._event.once(e, utils.wrapFn(fn, this));
    this.event.emit = (e, ...args) => {
      args.push(err => this.emit('error', err));
      this._event.emit(e, ...args);
    };
    this._event.on('error', err => {
      if (this._event._events.error.length < 2) {
        console.error(err.stack || err);
      }
    });

    this.init._queue = [];
    this.init.add = (fn) => {
      this._checkInited();
      // eslint-disable-next-line
      fn.__sourceLine = utils.getCallerSourceLine();
      debug('init.add: at %s', fn.__sourceLine);
      this.init._queue.push(fn);
    };
    this.init._loadFile = (f) => {
      const m = require(f);
      let ret;
      if (typeof m === 'function') ret = m;
      else if (typeof m.default === 'function') ret = m.default;
      else throw new Error(`module "${ f }" must export as a function`);
      ret.level = m.level || ret.level || 0;
      return ret;
    };
    this.init.load = (f) => {
      if (this.initing) throw new Error('cannot call init.load() after init()');
      const s = fs.statSync(f);
      if (s.isFile()) {
        debug('init.load: %s', f);
        this.init.add(this.init._loadFile(f));
      } else if (s.isDirectory()) {
        const list = rd.readFileFilterSync(f, /\.js$/)
                       .map(f => {
                         debug('init.load: %s', f);
                         return this.init._loadFile(f);
                       })
                       .sort((a, b) => b.level - a.level);
        for (const fn of list) {
          this.init.add(fn);
        }
      } else {
        throw new Error(`"${ f }" is not a file or directory`);
      }
    };

    this.config = new Namespace();
    this.config.load = file => {
      debug('config.load: %s', file);
      try {
        const fullPath = path.resolve(file);
        const ext = path.extname(fullPath).toLowerCase();
        if (ext === '.yaml' || ext === '.yml') {
          this.config.merge(yaml.safeLoad(fs.readFileSync(fullPath).toString()));
        } else if (ext === '.json') {
          this.config.merge(require(fullPath));
        } else if (ext === '.js' || ext === '') {
          const initConfig = require(fullPath);
          if (typeof initConfig !== 'function') {
            throw new Error(`incorrect config file format in file "${ file }"`);
          }
          const args = [
            (n, v) => this.config.set(n, v),
            (n) => this.config.get(n),
            (n) => this.config.has(n),
            this.config,
          ];
          initConfig.call(this.config, ...args);
        }
      } catch (err) {
        throw new Error(`failed to load config file "${ file }": ${ err.message }`);
      }
    };
    this.config._get = this.config.get;
    this.config.get = (n) => {
      const v = this.config._get(n);
      if (v === undefined) {
        throw new TypeError(`config field "${ n }" is undefined`);
      }
      return v;
    };

    this._extends = {
      before: [],
      init: [],
      after: [],
    };

    this.inited = false;
    this.event.once('ready', () => {
      this.inited = true;
    });

  }

  _checkInited() {
    if (this.inited) {
      throw new Error('you cannot change project-core after it has been inited');
    }
  }

  extends(info) {

    this._checkInited();

    if (typeof info.before === 'function') {
      this._extends.before.push(info.before);
    }
    if (typeof info.init === 'function') {
      this._extends.init.push(info.init);
    }
    if (typeof info.after === 'function') {
      this._extends.after.push(info.after);
{'fraction_non_alphanumeric': 0.17831184056271981, 'fraction_numerical': 0.0007033997655334115, 'mean_word_length': 1.9964875307341061, 'pattern_counts': {'":': 2, '<': 11, '<?xml version=': 0, '>': 42, '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': '3465036', 'n_tokens_mistral': 2745, 'n_tokens_neox': 2723, 'n_words': 627}