<commit_before>'use strict';

var Promise = require('bluebird');
var fs = require('fs');
var _eval = require('eval');
var _ = require('lodash');

var readFile = Promise.promisify(fs.readFile);


/**
 * Return given value as array.  If already an array, just return as-is.
 * Undefined will return an empty array.
 *
 * @private
 * @param {Array|mixed} ary     Value to return as an array
 * @returns {Array}
 */
function makeArray(ary){
  return ((ary === undefined)?[]:(_.isArray(ary)?ary:[ary]));
}

/**
 * Load a module or return a default value.  Can take an array to try.  Will load module asychronously.
 *
 * @private
 * @param {string|Array} modulePath             Module path or array of paths.
 * @param {mixed} [defaultReturnValue=false]    The default value to return if module load fails.
 * @returns {Promise}
 */
function getModule(modulePath, defaultReturnValue){
  if(modulePath){
    modulePath = makeArray(modulePath);
    return requireAsync(modulePath.shift()).then(function(module){
      if((module === undefined) && (modulePath.length)){
        return requireAsync(modulePath);
      }

      return module;
    })
  }

  return Promise.resolve(defaultReturnValue || false);
}


/**
 * Load a module asychronously, this is an async version of require().
 *
 * @private
 * @param {string} moduleName     Module name or path, same format as for require().
 * @returns {Promise}             Promise, resolved with the module or undefined.
 */
function requireAsync(moduleName){
  try{
    var modulePath = require.resolve(moduleName);

    return readFile(modulePath, 'utf8').then(function(moduleText){
      return _eval(moduleText, modulePath, {}, true);
    }, function(error){
      return undefined;
    }).catch(function(error){
      return undefined;
    });
  }catch(error){
  }

  return Promise.resolve(undefined);
}

module.exports = {
  getModule: getModule,
  require: requireAsync
}<commit_msg>Refactor to provide node-style callback as well as promises and to return error messages<commit_after>'use strict';

var Promise = require('bluebird');
var fs = require('fs');
var _eval = require('eval');
var _ = require('lodash');

var readFile = Promise.promisify(fs.readFile);


/**
 * Return given value as array.  If already an array, just return as-is.
 * Undefined will return an empty array.
 *
 * @private
 * @param {Array|mixed} ary     Value to return as an array
 * @returns {Array}
 */
function makeArray(ary){
  return ((ary === undefined)?[]:(_.isArray(ary)?ary:[ary]));
}

/**
 * Load a module or return a default value.  Can take an array to try.  Will load module asychronously.
 *
 * @private
 * @param {string|Array} modulePath             Module path or array of paths.
 * @param {mixed} [defaultReturnValue=false]    The default value to return if module load fails.
 * @returns {Promise}
 */
function getModule(modulePath, defaultReturnValue){
  if(modulePath){
    modulePath = makeArray(modulePath);
    return requireAsync(modulePath.shift()).catch(function(error){
      if(modulePath.length){
        return requireAsync(modulePath);
      }

      return Promise.resolve(defaultReturnValue || false);
    });
  }

  return Promise.resolve(defaultReturnValue || false);
}

/**
 * Read text from a file and handle any errors.
 *
 * @param {string} fileName
 * @returns {string|undefined}
 */
function loadModuleText(fileName){
  return readFile(fileName, 'utf8').then(function(moduleText){
    return moduleText;
  });
}

/**
 * Evaluate module text in similar fashion to require evaluations.
 *
 * @param {string} modulePath   The path of the evaluated module.
 * @param {string} moduleText   The text content of the module.
 * @returns {mixed}
 */
function evalModuleText(modulePath, moduleText){
  return ((moduleText !== undefined)?_eval(moduleText, modulePath, {}, true):undefined);
}

/**
 * Load and evaluate a module returning undefined to promise resolve on failure.
 *
 * @param {string} modulePath   The path of the evaluated module.
 * @param {string} moduleText   The text content of the module.
 * @returns {mixed}
 */
function loadModule(modulePath){
  return loadModuleText(modulePath).then(function(moduleText){
    return evalModuleText(modulePath, moduleText);
  });
}


/**
 * Load a module asychronously, this is an async version of require().
 *
 * @private
 * @param {string} moduleName     Module name or path, same format as for require().
 * @param {function} [callback]   Node-style callback to use instead of (or as well as) returned promise.
 * @returns {Promise}             Promise, resolved with the module or undefined.
 */
function requireAsync(moduleName, callback){
  var async;

  try{
    async = loadModule(require.resolve(moduleName));
  }catch(error){
    async = Promise.reject(error);
  }

  if(callback){
    async.nodeify(callback);
  }

  return async;
}

module.exports = {
  getModule: getModule,
  require: requireAsync
}
{'fraction_non_alphanumeric': 0.12378246753246754, 'fraction_numerical': 0.00040584415584415587, 'mean_word_length': 3.8323529411764707, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '6128081', 'n_tokens_mistral': 1415, 'n_tokens_neox': 1394, 'n_words': 459}