<commit_before>/*
 * forever.js: Top level include for the forever module
 *
 * (C) 2010 and <NAME>
 * MIT LICENCE
 *
 */

require.paths.unshift(__dirname);

var fs = require('fs'),
    colors = require('colors'),
    async = require('async'),
    path = require('path'),
    events = require('events'),
    exec = require('child_process').exec,
    timespan = require('timespan'),
    daemon = require('daemon');

var forever = exports, config;

//
// ### Export Components / Settings
// Export `version` and important Prototypes from `lib/forever/*`
//
forever.version     = [0, 4, 0];
forever.initialized = false;
forever.root        = path.join('/tmp', 'forever');
forever.Forever     = forever.Monitor = require('forever/monitor').Monitor; 

//
// ### function load (options, [callback])
// #### @options {Object} Options to load into the forever module
// Initializes configuration for forever module
//
forever.load = function (options) {
  //
  // Setup the incoming options with default options.
  //
  options         = options || {};
  options.root    = options.root || forever.root,
  options.pidPath = options.pidPath || path.join(options.root, 'pids');
  
  //
  // If forever is initalized and the config directories are identical
  // simply return without creating directories
  //
  if (forever.initialized && forever.config.root === options.root && 
    forever.config.pidPath === options.pidPath) {
    return;
  }
  
  forever.config  = config = options;
  
  //
  // Syncronously create the `root` directory
  // and the `pid` directory for forever. Although there is
  // an additional overhead here of the sync action. It simplifies
  // the setup of forever dramatically.  
  //
  function tryCreate (dir) {
    try { fs.mkdirSync(dir, 0755); }
    catch (ex) { }
  }

  tryCreate(config.root);
  tryCreate(config.pidPath);
  forever.initialized = true;
};

//
// Ensure forever will always be loaded the first time it is required.
//
forever.load();

//
// ### function stat (logFile, script, callback)
// #### @logFile {string} Path to the log file for this script
// #### @logAppend {boolean} Optional. True Prevent failure if the log file exists.
// #### @script {string} Path to the target script.
// #### @callback {function} Continuation to pass control back to 
// Ensures that the logFile doesn't exist and that
// the target script does exist before executing callback.
//
forever.stat = function (logFile, script, callback) {
  var logAppend,
      realCallback = callback;
  if (arguments.length === 4) {
    logAppend = callback;
    realCallback = arguments[3];
  }

  fs.stat(script, function (err, stats) {
    if (err) return realCallback(new Error('script ' + script + ' does not exist.'));

    if (logAppend) {
      realCallback(null);
      return;
    }

    fs.stat(logFile, function (err, stats) {
      if (!err) return realCallback(new Error('log file ' + logFile + ' exists.'));
      realCallback(null);
    });
  });
};

//
// ### function start (script, options) 
// #### @script {string} Location of the script to run.
// #### @options {Object} Configuration for forever instance.
// Starts a script with forever
//
forever.start = function (script, options) {
  return new forever.Monitor(script, options).start();
};

//
// ### function startDaemon (script, options)
// #### @script {string} Location of the script to run.
// #### @options {Object} Configuration for forever instance.
// Starts a script with forever as a daemon
//
forever.startDaemon = function (script, options) {
  options.logFile = forever.logFilePath(options.logFile);
  options.pidFile = forever.pidFilePath(options.pidFile);
  var runner = new forever.Monitor(script, options);

  daemon.daemonize(options.logFile, options.pidFile, function (err, pid) {
    if (err) return runner.emit('error', err);
    
    //
    // Remark: This should work, but the fd gets screwed up 
    //         with the daemon process.
    //
    // process.on('exit', function () {
    //   fs.unlinkSync(options.pidFile);
    // });
    
    process.pid = pid;
    runner.start();
  });
  
  return runner;
};

//
// ### function stop (target, [format])
// #### @target {string} Index or script name to stop
// #### @format {boolean} Indicated if we should CLI format the returned output.
// Stops the process(es) with the specified index or script name 
// in the list of all processes
//
forever.stop = function (target, format, restart) {
  var emitter = new events.EventEmitter(),
      processes = getAllProcesses(),<commit_msg>Append log implementation<commit_after>/*
 * forever.js: Top level include for the forever module
 *
 * (C) 2010 and <NAME>
 * MIT LICENCE
 *
 */

require.paths.unshift(__dirname);

var fs = require('fs'),
    colors = require('colors'),
    async = require('async'),
    path = require('path'),
    events = require('events'),
    exec = require('child_process').exec,
    timespan = require('timespan'),
    daemon = require('daemon');

var forever = exports, config;

//
// ### Export Components / Settings
// Export `version` and important Prototypes from `lib/forever/*`
//
forever.version     = [0, 4, 0];
forever.initialized = false;
forever.root        = path.join('/tmp', 'forever');
forever.Forever     = forever.Monitor = require('forever/monitor').Monitor; 

//
// ### function load (options, [callback])
// #### @options {Object} Options to load into the forever module
// Initializes configuration for forever module
//
forever.load = function (options) {
  //
  // Setup the incoming options with default options.
  //
  options         = options || {};
  options.root    = options.root || forever.root,
  options.pidPath = options.pidPath || path.join(options.root, 'pids');
  
  //
  // If forever is initalized and the config directories are identical
  // simply return without creating directories
  //
  if (forever.initialized && forever.config.root === options.root && 
    forever.config.pidPath === options.pidPath) {
    return;
  }
  
  forever.config  = config = options;
  
  //
  // Syncronously create the `root` directory
  // and the `pid` directory for forever. Although there is
  // an additional overhead here of the sync action. It simplifies
  // the setup of forever dramatically.  
  //
  function tryCreate (dir) {
    try { fs.mkdirSync(dir, 0755); }
    catch (ex) { }
  }

  tryCreate(config.root);
  tryCreate(config.pidPath);
  forever.initialized = true;
};

//
// Ensure forever will always be loaded the first time it is required.
//
forever.load();

//
// ### function stat (logFile, script, callback)
// #### @logFile {string} Path to the log file for this script
// #### @logAppend {boolean} Optional. True Prevent failure if the log file exists.
// #### @script {string} Path to the target script.
// #### @callback {function} Continuation to pass control back to 
// Ensures that the logFile doesn't exist and that
// the target script does exist before executing callback.
//
forever.stat = function (logFile, script, callback) {
  var logAppend,
      realCallback = callback;
  if (arguments.length === 4) {
    logAppend = callback;
    realCallback = arguments[3];
  }

  fs.stat(script, function (err, stats) {
    if (err) return realCallback(new Error('script ' + script + ' does not exist.'));

    if (logAppend) {
      realCallback(null);
      return;
    }

    fs.stat(logFile, function (err, stats) {
      if (!err) return realCallback(new Error('log file ' + logFile + ' exists.'));
      realCallback(null);
    });
  });
};

//
// ### function start (script, options) 
// #### @script {string} Location of the script to run.
// #### @options {Object} Configuration for forever instance.
// Starts a script with forever
//
forever.start = function (script, options) {
  return new forever.Monitor(script, options).start();
};

//
// ### function startDaemon (script, options)
// #### @script {string} Location of the script to run.
// #### @options {Object} Configuration for forever instance.
// Starts a script with forever as a daemon
//
forever.startDaemon = function (script, options) {
  options.logFile = forever.logFilePath(options.logFile);
  options.pidFile = forever.pidFilePath(options.pidFile);
  var runner = new forever.Monitor(script, options);


  fs.open(options.logFile, options.appendLog ? 'a+' : 'w+', function (err, fd) {
    if (err) return runner.emit('error', err);

    var pid = daemon.start(fd);
    daemon.lock(options.pidFile);

    //
    // Remark: This should work, but the fd gets screwed up 
    //         with the daemon process.
    //
    // process.on('exit', function () {
    //   fs.unlinkSync(options.pidFile);
    // });

    process.pid = pid;
    runner.start();
  });
  
  return runner;
};

//
// ### function stop (target, [format])
// #### @target {string} Index or script name to stop
// #### @format {boolean} Indicated if we should CLI format the returned output.
// Stops the process(es) with the specified index or script name 
// in the list of all processes
//
forever.stop = function (target, format, restart) {
  var emitter = new events.EventEmitter(),
      processes = getAllProcesses(),
{'fraction_non_alphanumeric': 0.1450381679389313, 'fraction_numerical': 0.0028353326063249727, 'mean_word_length': 3.114401076716016, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '7269542', 'n_tokens_mistral': 2706, 'n_tokens_neox': 2690, 'n_words': 867}