mirror of
https://github.com/SrIzan10/nodemon.git
synced 2026-05-01 10:55:09 +00:00
If I have a nodemon.json config file with an `exec` property, then this is automatically appended with ` index.js` when running `nodemon` standalone. I would expect this to be equivalent to running `nodemon --exec "my cmd"` - that is providing an `exec` prevents defaulting of `script` to index.js. To resolve, move the code which defaults the `script` property when `exec` is undefined to after the config files have been read, so that the behaviour is the same irrespective of whether properties are set in CLI flags or in nodemon.json.
226 lines
5.8 KiB
JavaScript
226 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--;
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if (arg === '--legacy-watch' || arg === '-L') {
|
|
options.legacyWatch = true;
|
|
} else
|
|
|
|
if (arg === '--polling-interval' || arg === '-P') {
|
|
options.pollingInterval = parseInt(eatNext(), 10);
|
|
} 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 === '--config') {
|
|
options.configFile = eatNext();
|
|
} 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 === '--no-colours' || arg === '--no-colors') {
|
|
options.colours = false;
|
|
} else
|
|
|
|
if (arg === '--signal' || arg === '-s') {
|
|
options.signal = 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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|