mirror of
https://github.com/SrIzan10/nodemon.git
synced 2026-05-01 10:55:09 +00:00
Since we're now using chokidar which has it's own internal way of switching, so we don't need to do it ourselves.
227 lines
5.8 KiB
JavaScript
227 lines
5.8 KiB
JavaScript
/*
|
|
|
|
nodemon is a utility for node, and replaces the use of the executable
|
|
node. So the user calls `nodemon foo.js` instead.
|
|
|
|
nodemon can be run in a number of ways:
|
|
|
|
`nodemon` - tries to use package.json#main property to run
|
|
`nodemon` - if no package, looks for index.js
|
|
`nodemon app.js` - runs app.js
|
|
`nodemon --arg app.js --apparg` - eats arg1, and runs app.js with apparg
|
|
`nodemon --apparg` - as above, but passes apparg to package.json#main (or
|
|
index.js)
|
|
`nodemon --debug app.js
|
|
|
|
*/
|
|
|
|
var fs = require('fs');
|
|
var path = require('path');
|
|
var existsSync = fs.existsSync || path.existsSync;
|
|
|
|
module.exports = parse;
|
|
|
|
/**
|
|
* Parses the command line arguments `process.argv` and returns the
|
|
* nodemon options, the user script and the executable script.
|
|
*
|
|
* @param {Array} full process arguments, including `node` leading arg
|
|
* @return {Object} { options, script, args }
|
|
*/
|
|
function parse(argv) {
|
|
if (typeof argv === 'string') {
|
|
argv = argv.split(' ');
|
|
}
|
|
|
|
var eat = function (i, args) {
|
|
if (i <= args.length) {
|
|
return args.splice(i + 1, 1).pop();
|
|
}
|
|
};
|
|
|
|
var args = argv.slice(2);
|
|
var script = null;
|
|
var nodemonOptions = { scriptPosition: null };
|
|
|
|
var nodemonOpt = nodemonOption.bind(null, nodemonOptions);
|
|
var lookForArgs = true;
|
|
|
|
// move forward through the arguments
|
|
for (var i = 0; i < args.length; i++) {
|
|
// if the argument looks like a file, then stop eating
|
|
if (!script) {
|
|
if (args[i] === '.' || existsSync(args[i])) {
|
|
script = args.splice(i, 1).pop();
|
|
|
|
// we capture the position of the script because we'll reinsert it in
|
|
// the right place in run.js:command (though I'm not sure we should even
|
|
// take it out of the array in the first place, but this solves passing
|
|
// arguments to the exec process for now).
|
|
nodemonOptions.scriptPosition = i;
|
|
i--;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (lookForArgs) {
|
|
// respect the standard way of saying: hereafter belongs to my script
|
|
if (args[i] === '--') {
|
|
args.splice(i, 1);
|
|
// cycle back one argument, as we just ate this one up
|
|
i--;
|
|
|
|
// ignore all further nodemon arguments
|
|
lookForArgs = false;
|
|
|
|
// move to the next iteration
|
|
continue;
|
|
}
|
|
|
|
if (nodemonOpt(args[i], eat.bind(null, i, args)) !== false) {
|
|
args.splice(i, 1);
|
|
// cycle back one argument, as we just ate this one up
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (script === null && !nodemonOptions.exec) {
|
|
var found = findAppScript();
|
|
if (found !== null) {
|
|
if (found.exec) {
|
|
nodemonOptions.exec = found.exec;
|
|
}
|
|
script = found.script;
|
|
nodemonOptions.scriptPosition = args.length;
|
|
}
|
|
}
|
|
|
|
nodemonOptions.script = script;
|
|
nodemonOptions.args = args;
|
|
|
|
return nodemonOptions;
|
|
}
|
|
|
|
|
|
/**
|
|
* Given an argument (ie. from process.argv), sets nodemon
|
|
* options and can eat up the argument value
|
|
*
|
|
* @param {Object} options object that will be updated
|
|
* @param {Sting} current argument from argv
|
|
* @param {Function} the callback to eat up the next argument in argv
|
|
* @return {Boolean} false if argument was not a nodemon arg
|
|
*/
|
|
function nodemonOption(options, arg, eatNext) {
|
|
// line seperation on purpose to help legibility
|
|
if (arg === '--help' || arg === '-h' || arg === '-?') {
|
|
var help = eatNext();
|
|
options.help = help ? help : true;
|
|
} else
|
|
|
|
if (arg === '--version' || arg === '-v') {
|
|
options.version = true;
|
|
} else
|
|
|
|
if (arg === '--dump') {
|
|
options.dump = true;
|
|
} else
|
|
|
|
if (arg === '--verbose' || arg === '-V') {
|
|
options.verbose = true;
|
|
} else
|
|
|
|
// Depricated as this is "on" by default
|
|
if (arg === '--js') {
|
|
options.js = true;
|
|
} else
|
|
|
|
if (arg === '--quiet' || arg === '-q') {
|
|
options.quiet = true;
|
|
} else
|
|
|
|
if (arg === '--hidden') { // TODO document this flag?
|
|
options.hidden = true;
|
|
} else
|
|
|
|
if (arg === '--watch' || arg === '-w') {
|
|
if (!options.watch) { options.watch = []; }
|
|
options.watch.push(eatNext());
|
|
} else
|
|
|
|
if (arg === '--ignore' || arg === '-i') {
|
|
if (!options.ignore) { options.ignore = []; }
|
|
options.ignore.push(eatNext());
|
|
} else
|
|
|
|
if (arg === '--exitcrash') {
|
|
options.exitcrash = true;
|
|
} else
|
|
|
|
if (arg === '--delay' || arg === '-d') {
|
|
options.delay = parseDelay(eatNext());
|
|
} else
|
|
|
|
if (arg === '--exec' || arg === '-x') {
|
|
options.exec = eatNext();
|
|
} else
|
|
|
|
if (arg === '--no-stdin' || arg === '-I') {
|
|
options.stdin = false;
|
|
} else
|
|
|
|
if (arg === '--on-change-only' || arg === '-C') {
|
|
options.runOnChangeOnly = true;
|
|
} else
|
|
|
|
if (arg === '--ext' || arg === '-e') {
|
|
options.ext = eatNext();
|
|
} else
|
|
|
|
if (arg === '--cwd') {
|
|
options.cwd = eatNext();
|
|
|
|
// go ahead and change directory. This is primarily for nodemon tools like
|
|
// grunt-nodemon - we're doing this early because it will affect where the
|
|
// user script is searched for.
|
|
process.chdir(path.resolve(options.cwd));
|
|
} else {
|
|
|
|
// this means we didn't match
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function findAppScript() {
|
|
// nodemon has been run alone, so try to read the package file
|
|
// or try to read the index.js file
|
|
if (existsSync('./index.js')) {
|
|
return { exec: null, script: 'index.js' };
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Given an argument (ie. from nodemonOption()), will parse and return the
|
|
* equivalent millisecond value or 0 if the argument cannot be parsed
|
|
*
|
|
* @param {String} argument value given to the --delay option
|
|
* @return {Number} millisecond equivalent of the argument
|
|
*/
|
|
function parseDelay(value) {
|
|
var millisPerSecond = 1000;
|
|
var millis = 0;
|
|
|
|
if (value.match(/^\d*ms$/)) {
|
|
// Explicitly parse for milliseconds when using ms time specifier
|
|
millis = parseInt(value, 10);
|
|
} else {
|
|
// Otherwise, parse for seconds, with or without time specifier then convert
|
|
millis = parseFloat(value) * millisPerSecond;
|
|
}
|
|
|
|
return isNaN(millis) ? 0 : millis;
|
|
}
|
|
|