Code coverage report for lib/nodemon.js

Statements: 54.03% (67 / 124)      Branches: 35.38% (23 / 65)      Functions: 78.95% (15 / 19)      Lines: 53.28% (65 / 122)     

All files » lib/ » nodemon.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 2331 1                           1   1 3       3                       3 2     3             3                   3               3 3                 3   3       3 4       3   3 3 3                                                                     3 3     3 18     3 9     3 9     3     3                           3 3       3     1           1 9 9 9 9     1 5 5 5 4 4   5     1 7 6     1   8 24   24 5 5       8     1   8 8 8 8       1     1                       1    
'use strict';
var path = require('path'),
    monitor = require('./monitor'),
    cli = require('./cli'),
    version = require('./version'),
    util = require('util'),
    utils = require('./utils'),
    rules = require('./rules'),
    bus = utils.bus,
    help = require('./help'),
    config = require('./config'),
    eventHandlers = {};
 
// this is fairly dirty, but theoretically sound since it's part of the
// stable module API
config.required = utils.isRequired;
 
function nodemon(settings) {
  nodemon.reset();
 
  // allow the cli string as the argument to nodemon, and allow for
  // `node nodemon -V app.js` or just `-V app.js`
  Iif (typeof settings === 'string') {
    settings = settings.trim();
    if (settings.indexOf('node') !== 0) {
      if (settings.indexOf('nodemon') !== 0) {
        settings = 'nodemon ' + settings;
      }
      settings = 'node ' + settings;
    }
    settings = cli.parse(settings);
  }
 
  // set the debug flag as early as possible to get all the detailed logging
  if (settings.verbose) {
    utils.debug = true;
  }
 
  Iif (settings.help) {
    console.log(help(settings.help));
    if (!config.required) {
      process.exit(0);
    }
  }
 
  Iif (settings.version) {
    console.log(version);
    if (!config.required) {
      process.exit(0);
    }
  }
 
  // nodemon tools like grunt-nodemon. This affects where
  // the script is being run from, and will affect where
  // nodemon looks for the nodemon.json files
  Iif (settings.cwd) {
    // this is protection to make sure we haven't dont the chdir already...
    // say like in cli/parse.js (which is where we do this once already!)
    if (process.cwd() !== path.resolve(config.system.cwd, settings.cwd)) {
      process.chdir(settings.cwd);
    }
  }
 
  config.load(settings, function (config) {
    Iif (!config.options.dump && !config.options.script && config.options.execOptions.exec === 'node') {
      if (!config.required) {
        console.log(help('usage'));
        process.exit();
      }
      return;
    }
 
    // always echo out the current version
    utils.log.info(version);
 
    Iif (config.options.cwd) {
      utils.log.detail('process root: ' + process.cwd());
    }
 
    config.loaded.forEach(function (filename) {
      utils.log.detail('reading config ' + filename);
    });
 
    // echo out notices about running state
    Eif (config.options.restartable) {
      // allow nodemon to restart when the use types 'rs\n'
      process.stdin.resume();
      process.stdin.setEncoding('utf8');
      process.stdin.on('data', function (data) {
        data = (data + '').trim().toLowerCase();
 
        // if the keys entered match the restartable value, then restart!
        if (data === config.options.restartable) {
          bus.emit('restart');
        }
      });
    } else {
      // if 'restartable' is disabled (via a nodemon.json)
      // then it's possible we're being used with a REPL
      // so let's make sure we don't eat the key presses
      // but also, since we're wrapping, watch out for
      // special keys, like ctrl+c x 2 or '.exit' or ctrl+d
      var ctrlC = false,
          buffer = '';
 
      process.stdin.on('data', function (data) {
        buffer += data;
        var chr = data.charCodeAt(0);
        if (chr === 3) {
          if (ctrlC) {
            process.exit();
          }
          ctrlC = true;
        } else if (buffer === '.exit' || chr === 4) {
          process.exit();
        } else if (ctrlC || chr === 10) {
          ctrlC = false;
          buffer = '';
        }
      });
      process.stdin.setRawMode(true);
    }
 
    Eif (config.options.restartable) {
      utils.log.info('to restart at any time, enter `' + config.options.restartable + '`');
    }
 
    var none = function (v) {
      return v;
    };
 
    utils.log.detail('ignoring: ' + config.options.monitor.map(function (rule) {
      return rule.slice(0, 1) === '!' ? rule.slice(1) : false;
    }).filter(none).join(' '));
 
    utils.log.info('watching: ' + config.options.monitor.map(function (rule) {
      return rule.slice(0, 1) !== '!' ? rule : false;
    }).filter(none).join(' '));
 
    utils.log.detail('watching extensions: ' + config.options.ext);
 
 
    Iif (config.options.dump) {
      utils.log._log('log', '--------------');
      utils.log._log('log', util.inspect(config, { depth: null }));
      utils.log._log('log', '--------------');
      utils.log._log('log', ['OS:', process.platform, process.arch].join(' '));
      utils.log._log('log', 'node: ' + process.version);
      utils.log._log('log', 'nodemon: ' + version);
      utils.log._log('log', 'cwd: ' + process.cwd());
      utils.log._log('log', 'command: ' + process.argv.join(' '));
      utils.log._log('log', '--------------');
      if (!config.required) {
        process.exit();
      }
    } else {
      config.run = true;
      monitor.run(config.options);
    }
  });
 
  return nodemon;
}
 
nodemon.restart = function () {
  utils.log.status('restarting child process');
  bus.emit('restart');
  return nodemon;
};
 
nodemon.addListener = nodemon.on = function (event, handler) {
  if (!eventHandlers[event]) { eventHandlers[event] = []; }
  eventHandlers[event].push(handler);
  bus.on(event, handler);
  return nodemon;
};
 
nodemon.once = function (event, handler) {
  if (!eventHandlers[event]) { eventHandlers[event] = []; }
  eventHandlers[event].push(handler);
  bus.once(event, function () {
    eventHandlers[event].splice(eventHandlers[event].indexOf(handler), 1);
    handler.apply(this, arguments);
  });
  return nodemon;
};
 
nodemon.emit = function () {
  bus.emit.apply(bus, [].slice.call(arguments));
  return nodemon;
};
 
nodemon.removeAllListners = function (event) {
  // unbind only the `nodemon.on` event handlers
  Object.keys(eventHandlers).filter(function (e) {
    return event ? e === event : true;
  }).forEach(function (event) {
    eventHandlers[event].forEach(function (handler) {
      bus.removeListener(event, handler);
      eventHandlers[event].splice(eventHandlers[event].indexOf(handler), 1);
    });
  });
 
  return nodemon;
};
 
nodemon.reset = function () {
  // console.trace();
  nodemon.removeAllListners();
  utils.reset();
  rules.reset();
  config.run = false;
};
 
// expose the full config
nodemon.config = config;
 
// on exception *inside* nodemon, shutdown wrapped node app
Iif (!config.required) {
  process.on('uncaughtException', function (err) {
    console.error('exception in nodemon killing node');
    console.error(err.stack);
    console.error();
    console.error('If appropriate, please file an error: http://github.com/remy/nodemon/issues/new\n');
    if (!config.required) {
      process.exit(1);
    }
  });
}
 
module.exports = nodemon;