From 745e24cc53df9202db95c4e0696d3aef3fa683c2 Mon Sep 17 00:00:00 2001 From: Remy Sharp Date: Sat, 10 Jul 2021 16:18:58 +0100 Subject: [PATCH] refactor: move to prettier and update eslint --- .eslintrc.json | 40 ++++++----- bin/postinstall.js | 11 ++- lib/cli/index.js | 4 +- lib/cli/parse.js | 95 ++++++++----------------- lib/config/command.js | 25 ++++--- lib/config/defaults.js | 6 +- lib/config/exec.js | 43 ++++++----- lib/config/index.js | 21 +++--- lib/config/load.js | 42 ++++++----- lib/help/index.js | 5 +- lib/index.js | 2 +- lib/monitor/match.js | 102 ++++++++++++++------------ lib/monitor/run.js | 85 ++++++++++++---------- lib/monitor/signals.js | 2 +- lib/monitor/watch.js | 72 ++++++++++--------- lib/nodemon.js | 157 +++++++++++++++++++++++++---------------- lib/rules/add.js | 25 ++++--- lib/rules/index.js | 5 +- lib/rules/parse.js | 6 +- lib/spawn.js | 17 +++-- lib/utils/clone.js | 4 +- lib/utils/colour.js | 4 +- lib/utils/index.js | 22 +++--- lib/utils/merge.js | 4 +- lib/version.js | 24 +++---- package-lock.json | 5 ++ package.json | 4 ++ 27 files changed, 454 insertions(+), 378 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 3128bc6..3a0a6c6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,19 +1,21 @@ -{ - "env": { - "browser": true, - "commonjs": true, - "es2021": true - }, - "parserOptions": { - "ecmaVersion": 12 - }, - "rules": { - "space-before-function-paren": [ - 2, - { - "anonymous": "ignore", - "named": "never" - } - ] - } -} +{ + "env": { + "es6": true, + "node": true + }, + "extends": ["eslint:recommended"], + "parserOptions": { + "ecmaVersion": 9, + "sourceType": "module" + }, + "rules": { + "no-console": 0, + "no-restricted-globals": [ + "error", + { + "name": "name", + "message": "Use local parameter instead." + } + ] + } +} diff --git a/bin/postinstall.js b/bin/postinstall.js index 34c8194..f86e950 100755 --- a/bin/postinstall.js +++ b/bin/postinstall.js @@ -1,11 +1,16 @@ #!/usr/bin/env node function main() { - if (process.env.SUPPRESS_SUPPORT || process.env.OPENCOLLECTIVE_HIDE || process.env.CI) { + if ( + process.env.SUPPRESS_SUPPORT || + process.env.OPENCOLLECTIVE_HIDE || + process.env.CI + ) { return; } - - const message = '\u001b[32mLove nodemon? You can now support the project via the open collective:\u001b[22m\u001b[39m\n > \u001b[96m\u001b[1mhttps://opencollective.com/nodemon/donate\u001b[0m\n'; + + const message = + '\u001b[32mLove nodemon? You can now support the project via the open collective:\u001b[22m\u001b[39m\n > \u001b[96m\u001b[1mhttps://opencollective.com/nodemon/donate\u001b[0m\n'; try { const Configstore = require('configstore'); diff --git a/lib/cli/index.js b/lib/cli/index.js index bf9e809..77da8f0 100644 --- a/lib/cli/index.js +++ b/lib/cli/index.js @@ -21,7 +21,7 @@ function stringToArgs(string) { for (; i < length; i++) { lead = parts[i].substring(0, 1); - if (lead === '"' || lead === '\'') { + if (lead === '"' || lead === "'") { open = lead; grouped = parts[i].substring(1); } else if (open && parts[i].slice(-1) === open) { @@ -46,4 +46,4 @@ module.exports = { return parse(argv); }, -}; \ No newline at end of file +}; diff --git a/lib/cli/parse.js b/lib/cli/parse.js index ad74003..887b7b4 100644 --- a/lib/cli/parse.js +++ b/lib/cli/parse.js @@ -92,7 +92,6 @@ function parse(argv) { return nodemonOptions; } - /** * Given an argument (ie. from process.argv), sets nodemon * options and can eat up the argument value @@ -107,92 +106,56 @@ function nodemonOption(options, arg, eatNext) { if (arg === '--help' || arg === '-h' || arg === '-?') { var help = eatNext(); options.help = help ? help : true; - } else - - if (arg === '--version' || arg === '-v') { + } else if (arg === '--version' || arg === '-v') { options.version = true; - } else - - if (arg === '--no-update-notifier') { + } else if (arg === '--no-update-notifier') { options.noUpdateNotifier = true; - } else - - if (arg === '--spawn') { + } else if (arg === '--spawn') { options.spawn = true; - } else - - if (arg === '--dump') { + } else if (arg === '--dump') { options.dump = true; - } else - - if (arg === '--verbose' || arg === '-V') { + } else if (arg === '--verbose' || arg === '-V') { options.verbose = true; - } else - - if (arg === '--legacy-watch' || arg === '-L') { + } else if (arg === '--legacy-watch' || arg === '-L') { options.legacyWatch = true; - } else - - if (arg === '--polling-interval' || arg === '-P') { + } else if (arg === '--polling-interval' || arg === '-P') { options.pollingInterval = parseInt(eatNext(), 10); - } else + } // Depricated as this is "on" by default - if (arg === '--js') { + else if (arg === '--js') { options.js = true; - } else - - if (arg === '--quiet' || arg === '-q') { + } else if (arg === '--quiet' || arg === '-q') { options.quiet = true; - } else - - if (arg === '--config') { + } else if (arg === '--config') { options.configFile = eatNext(); - } else - - if (arg === '--watch' || arg === '-w') { - if (!options.watch) { options.watch = []; } + } 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 = []; } + } else if (arg === '--ignore' || arg === '-i') { + if (!options.ignore) { + options.ignore = []; + } options.ignore.push(eatNext()); - } else - - if (arg === '--exitcrash') { + } else if (arg === '--exitcrash') { options.exitcrash = true; - } else - - if (arg === '--delay' || arg === '-d') { + } else if (arg === '--delay' || arg === '-d') { options.delay = parseDelay(eatNext()); - } else - - if (arg === '--exec' || arg === '-x') { + } else if (arg === '--exec' || arg === '-x') { options.exec = eatNext(); - } else - - if (arg === '--no-stdin' || arg === '-I') { + } else if (arg === '--no-stdin' || arg === '-I') { options.stdin = false; - } else - - if (arg === '--on-change-only' || arg === '-C') { + } else if (arg === '--on-change-only' || arg === '-C') { options.runOnChangeOnly = true; - } else - - if (arg === '--ext' || arg === '-e') { + } else if (arg === '--ext' || arg === '-e') { options.ext = eatNext(); - } else - - if (arg === '--no-colours' || arg === '--no-colors') { + } else if (arg === '--no-colours' || arg === '--no-colors') { options.colours = false; - } else - - if (arg === '--signal' || arg === '-s') { + } else if (arg === '--signal' || arg === '-s') { options.signal = eatNext(); - } else - - if (arg === '--cwd') { + } else if (arg === '--cwd') { options.cwd = eatNext(); // go ahead and change directory. This is primarily for nodemon tools like @@ -200,7 +163,6 @@ function nodemonOption(options, arg, eatNext) { // user script is searched for. process.chdir(path.resolve(options.cwd)); } else { - // this means we didn't match return false; } @@ -227,4 +189,3 @@ function parseDelay(value) { return isNaN(millis) ? 0 : millis; } - diff --git a/lib/config/command.js b/lib/config/command.js index 9839b5c..227e669 100644 --- a/lib/config/command.js +++ b/lib/config/command.js @@ -1,17 +1,19 @@ module.exports = command; +/** + * @typedef {object} Setting + * @property {object} execOptions + * @property {string} execOptions.exec + * @property {string} [execOptions.script] + * @property {number} [execOptions.scriptPosition] + * @property {string[]} [execOptions.execArgs] + */ + /** * command constructs the executable command to run in a shell including the * user script, the command arguments. * - * @param {Object} settings Object as: - * { execOptions: { - * exec: String, - * [script: String], - * [scriptPosition: Number], - * [execArgs: Array] - * } - * } + * @param {Setting} settings * @return {Object} an object with the node executable and the * arguments to the command */ @@ -32,8 +34,11 @@ function command(settings) { // after the "executable" goes the user's script if (options.script) { - args.splice((options.scriptPosition || 0) + - options.execArgs.length, 0, options.script); + args.splice( + (options.scriptPosition || 0) + options.execArgs.length, + 0, + options.script + ); } return { diff --git a/lib/config/defaults.js b/lib/config/defaults.js index e2a448b..36f9125 100644 --- a/lib/config/defaults.js +++ b/lib/config/defaults.js @@ -12,7 +12,7 @@ module.exports = { // compatible with linux, mac and windows, or make the default.js // dynamically append the `.cmd` for node based utilities }, - ignoreRoot: ignoreRoot.map(_ => `**/${_}/**`), + ignoreRoot: ignoreRoot.map((_) => `**/${_}/**`), watch: ['*.*'], stdin: true, runOnChangeOnly: false, @@ -22,7 +22,5 @@ module.exports = { // but also includes stderr. If this is false, data is still dispatched via // nodemon.on('stdout/stderr') stdout: true, - watchOptions: { - - }, + watchOptions: {}, }; diff --git a/lib/config/exec.js b/lib/config/exec.js index 68c2a2d..f523ecb 100644 --- a/lib/config/exec.js +++ b/lib/config/exec.js @@ -27,7 +27,9 @@ function execFromPackage() { if (pkg.scripts && pkg.scripts.start) { return { exec: pkg.scripts.start }; } - } catch (e) { } + } catch (e) { + //ignore + } return null; } @@ -78,8 +80,10 @@ function exec(nodemonOptions, execMap) { // if there's no script passed, try to get it from the first argument if (!options.script && (options.args || []).length) { - script = expandScript(options.args[0], - options.ext && ('.' + (options.ext || 'js').split(',')[0])); + script = expandScript( + options.args[0], + options.ext && '.' + (options.ext || 'js').split(',')[0] + ); // if the script was found, shift it off our args if (script !== options.args[0]) { @@ -101,8 +105,7 @@ function exec(nodemonOptions, execMap) { if (!options.script) { options.script = found.script; } - if (Array.isArray(options.args) && - options.scriptPosition === null) { + if (Array.isArray(options.args) && options.scriptPosition === null) { options.scriptPosition = options.args.length; } } @@ -116,7 +119,7 @@ function exec(nodemonOptions, execMap) { var extension = options.ext; if (extension === undefined) { var isJS = scriptExt === 'js' || scriptExt === 'mjs'; - extension = (isJS || !scriptExt) ? 'js,mjs' : scriptExt; + extension = isJS || !scriptExt ? 'js,mjs' : scriptExt; extension += ',json'; // Always watch JSON files } @@ -147,8 +150,10 @@ function exec(nodemonOptions, execMap) { }); var newExec = substitution(options.exec); - if (newExec !== options.exec && - options.exec.indexOf('{{filename}}') !== -1) { + if ( + newExec !== options.exec && + options.exec.indexOf('{{filename}}') !== -1 + ) { options.script = null; } options.exec = newExec; @@ -160,14 +165,16 @@ function exec(nodemonOptions, execMap) { } } - if (options.exec === 'node' && options.nodeArgs && options.nodeArgs.length) { options.execArgs = options.execArgs.concat(options.nodeArgs); } // note: indexOf('coffee') handles both .coffee and .litcoffee - if (!execDefined && options.exec === 'node' && - scriptExt.indexOf('coffee') !== -1) { + if ( + !execDefined && + options.exec === 'node' && + scriptExt.indexOf('coffee') !== -1 + ) { options.exec = 'coffee'; // we need to get execArgs set before the script @@ -187,7 +194,9 @@ function exec(nodemonOptions, execMap) { if (options.exec === 'coffee') { // don't override user specified extension tracking if (options.ext === undefined) { - if (extension) { extension += ','; } + if (extension) { + extension += ','; + } extension += 'coffee,litcoffee'; } @@ -203,19 +212,21 @@ function exec(nodemonOptions, execMap) { // because the terminal will automatically expand the glob against // the file system :( extension = (extension.match(/[^,*\s]+/g) || []) - .map(ext => ext.replace(/^\./, '')) + .map((ext) => ext.replace(/^\./, '')) .join(','); options.ext = extension; if (options.script) { - options.script = expandScript(options.script, - extension && ('.' + extension.split(',')[0])); + options.script = expandScript( + options.script, + extension && '.' + extension.split(',')[0] + ); } options.env = {}; // make sure it's an object (and since we don't have ) - if (({}).toString.apply(nodemonOptions.env) === '[object Object]') { + if ({}.toString.apply(nodemonOptions.env) === '[object Object]') { options.env = utils.clone(nodemonOptions.env); } else if (nodemonOptions.env !== undefined) { throw new Error('nodemon env values must be an object: { PORT: 8000 }'); diff --git a/lib/config/index.js b/lib/config/index.js index c78c435..d65be74 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -53,7 +53,8 @@ config.load = function (settings, ready) { options.watch.push('*.*'); } - if (options['watch_interval']) { // jshint ignore:line + if (options['watch_interval']) { + // jshint ignore:line options.watchInterval = options['watch_interval']; // jshint ignore:line } @@ -78,13 +79,17 @@ config.load = function (settings, ready) { } bus.emit('config:update', config); - pinVersion().then(function () { - ready(config); - }).catch(e => { - // this doesn't help testing, but does give exposure on syntax errors - console.error(e.stack); - setTimeout(() => { throw e; }, 0); - }); + pinVersion() + .then(function () { + ready(config); + }) + .catch((e) => { + // this doesn't help testing, but does give exposure on syntax errors + console.error(e.stack); + setTimeout(() => { + throw e; + }, 0); + }); }); }; diff --git a/lib/config/load.js b/lib/config/load.js index bd5a03d..b809652 100644 --- a/lib/config/load.js +++ b/lib/config/load.js @@ -1,4 +1,3 @@ -var debug = require('debug')('nodemon'); var fs = require('fs'); var path = require('path'); var exists = fs.exists || path.exists; @@ -62,7 +61,6 @@ function load(settings, options, config, callback) { options.ignore = defaults.ignore.concat(options.ignore); } - // add in any missing defaults options = utils.merge(options, defaults); @@ -74,11 +72,14 @@ function load(settings, options, config, callback) { } // if the script is found as a result of not being on the command // line, then we move any of the pre double-dash args in execArgs - const n = options.scriptPosition === null ? - options.args.length : options.scriptPosition; + const n = + options.scriptPosition === null + ? options.args.length + : options.scriptPosition; - options.execArgs = (options.execArgs || []) - .concat(options.args.splice(0, n)); + options.execArgs = (options.execArgs || []).concat( + options.args.splice(0, n) + ); options.scriptPosition = null; options.script = found; @@ -170,7 +171,7 @@ function normaliseRules(options, ready) { */ function loadFile(options, config, dir, ready) { if (!ready) { - ready = function () { }; + ready = function () {}; } var callback = function (settings) { @@ -222,29 +223,32 @@ function loadFile(options, config, dir, ready) { function loadPackageJSON(config, ready) { if (!ready) { - ready = () => { }; + ready = () => {}; } const dir = process.cwd(); const filename = path.join(dir, 'package.json'); const packageLoadOptions = { configFile: filename }; - return loadFile(packageLoadOptions, config, dir, settings => { + return loadFile(packageLoadOptions, config, dir, (settings) => { ready(settings.nodemonConfig || {}); }); } function mutateExecOptions(options) { // work out the execOptions based on the final config we have - options.execOptions = exec({ - script: options.script, - exec: options.exec, - args: options.args, - scriptPosition: options.scriptPosition, - nodeArgs: options.nodeArgs, - execArgs: options.execArgs, - ext: options.ext, - env: options.env, - }, options.execMap); + options.execOptions = exec( + { + script: options.script, + exec: options.exec, + args: options.args, + scriptPosition: options.scriptPosition, + nodeArgs: options.nodeArgs, + execArgs: options.execArgs, + ext: options.ext, + env: options.env, + }, + options.execMap + ); // clean up values that we don't need at the top level delete options.scriptPosition; diff --git a/lib/help/index.js b/lib/help/index.js index 1054b60..f361c0c 100644 --- a/lib/help/index.js +++ b/lib/help/index.js @@ -4,12 +4,13 @@ const supportsColor = require('supports-color'); module.exports = help; -const highlight = supportsColor.stdout ? '\x1B\[$1m' : ''; +const highlight = supportsColor.stdout ? '\x1B[$1m' : ''; function help(item) { if (!item) { item = 'help'; - } else if (item === true) { // if used with -h or --help and no args + } else if (item === true) { + // if used with -h or --help and no args item = 'help'; } diff --git a/lib/index.js b/lib/index.js index 0eca5c4..bcbda1c 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1 +1 @@ -module.exports = require('./nodemon'); \ No newline at end of file +module.exports = require('./nodemon'); diff --git a/lib/monitor/match.js b/lib/monitor/match.js index 2ac3b29..4c669fa 100644 --- a/lib/monitor/match.js +++ b/lib/monitor/match.js @@ -31,9 +31,12 @@ function rulesToMonitor(watch, ignore, config) { } if (ignore) { - [].push.apply(monitor, (ignore || []).map(function (rule) { - return '!' + rule; - })); + [].push.apply( + monitor, + (ignore || []).map(function (rule) { + return '!' + rule; + }) + ); } var cwd = process.cwd(); @@ -87,16 +90,16 @@ function rulesToMonitor(watch, ignore, config) { // if the url ends with * but not **/* and not *.* // then convert to **/* - somehow it was missed :-\ - if (rule.slice(-4) !== '**/*' && + if ( + rule.slice(-4) !== '**/*' && rule.slice(-1) === '*' && - rule.indexOf('*.') === -1) { - + rule.indexOf('*.') === -1 + ) { if (rule.slice(-2) !== '**') { rule += '*/*'; } } - return (not ? '!' : '') + rule; }); @@ -105,9 +108,10 @@ function rulesToMonitor(watch, ignore, config) { function tryBaseDir(dir) { var stat; - if (/[?*\{\[]+/.test(dir)) { // if this is pattern, then try to find the base + if (/[?*{[]+/.test(dir)) { + // if this is pattern, then try to find the base try { - var base = path.dirname(dir.replace(/([?*\{\[]+.*$)/, 'foo')); + var base = path.dirname(dir.replace(/([?*{[]+.*$)/, 'foo')); stat = fs.statSync(base); if (stat.isDirectory()) { return base; @@ -123,7 +127,9 @@ function tryBaseDir(dir) { if (stat.isFile() || stat.isDirectory()) { return dir; } - } catch (e) { } + } catch (e) { + // ignore + } } return false; @@ -133,50 +139,52 @@ function match(files, monitor, ext) { // sort the rules by highest specificity (based on number of slashes) // ignore rules (!) get sorted highest as they take precedent const cwd = process.cwd(); - var rules = monitor.sort(function (a, b) { - var r = b.split(path.sep).length - a.split(path.sep).length; - var aIsIgnore = a.slice(0, 1) === '!'; - var bIsIgnore = b.slice(0, 1) === '!'; + var rules = monitor + .sort(function (a, b) { + var r = b.split(path.sep).length - a.split(path.sep).length; + var aIsIgnore = a.slice(0, 1) === '!'; + var bIsIgnore = b.slice(0, 1) === '!'; - if (aIsIgnore || bIsIgnore) { - if (aIsIgnore) { - return -1; + if (aIsIgnore || bIsIgnore) { + if (aIsIgnore) { + return -1; + } + + return 1; } - return 1; - } + if (r === 0) { + return b.length - a.length; + } + return r; + }) + .map(function (s) { + var prefix = s.slice(0, 1); - if (r === 0) { - return b.length - a.length; - } - return r; - }).map(function (s) { - var prefix = s.slice(0, 1); + if (prefix === '!') { + if (s.indexOf('!' + cwd) === 0) { + return s; + } - if (prefix === '!') { - if (s.indexOf('!' + cwd) === 0) { - return s; + // if it starts with a period, then let's get the relative path + if (s.indexOf('!.') === 0) { + return '!' + path.resolve(cwd, s.substring(1)); + } + + return '!**' + (prefix !== path.sep ? path.sep : '') + s.slice(1); } // if it starts with a period, then let's get the relative path - if (s.indexOf('!.') === 0) { - return '!' + path.resolve(cwd, s.substring(1)); + if (s.indexOf('.') === 0) { + return path.resolve(cwd, s); } - return '!**' + (prefix !== path.sep ? path.sep : '') + s.slice(1); - } + if (s.indexOf(cwd) === 0) { + return s; + } - // if it starts with a period, then let's get the relative path - if (s.indexOf('.') === 0) { - return path.resolve(cwd, s); - } - - if (s.indexOf(cwd) === 0) { - return s; - } - - return '**' + (prefix !== path.sep ? path.sep : '') + s; - }); + return '**' + (prefix !== path.sep ? path.sep : '') + s; + }); debug('rules', rules); @@ -221,8 +229,10 @@ function match(files, monitor, ext) { // but *does* match a rule that ends with *.*, then // white list it - in that we don't run it through // the extension check too. - if (rules[i] !== '**' + path.sep + '*.*' && - rules[i].slice(-3) === '*.*') { + if ( + rules[i] !== '**' + path.sep + '*.*' && + rules[i].slice(-3) === '*.*' + ) { whitelist.push(file); } else if (path.basename(file) === path.basename(rules[i])) { // if the file matches the actual rule, then it's put on whitelist @@ -242,7 +252,7 @@ function match(files, monitor, ext) { } }); - debug('good', good) + debug('good', good); // finally check the good files against the extensions that we're monitoring if (ext) { diff --git a/lib/monitor/run.js b/lib/monitor/run.js index 464e719..a40b1f7 100644 --- a/lib/monitor/run.js +++ b/lib/monitor/run.js @@ -16,7 +16,7 @@ var restart = null; var psTree = require('pstree.remy'); var path = require('path'); var signals = require('./signals'); -const osRelease = parseInt(require('os').release().split(".")[0], 10); +const osRelease = parseInt(require('os').release().split('.')[0], 10); function run(options) { var cmd = config.command.raw; @@ -67,7 +67,7 @@ function run(options) { PATH: binPath + ':' + process.env.PATH, }), stdio: stdio, - } + }; var executable = cmd.executable; @@ -76,12 +76,15 @@ function run(options) { // but *only* apply to the first command, and none of the arguments. // ref #1251 and #1236 if (executable.indexOf('/') !== -1) { - executable = executable.split(' ').map((e, i) => { - if (i === 0) { - return path.normalize(e); - } - return e; - }).join(' '); + executable = executable + .split(' ') + .map((e, i) => { + if (i === 0) { + return path.normalize(e); + } + return e; + }) + .join(' '); } // taken from npm's cli: https://git.io/vNFD4 sh = process.env.comspec || 'cmd'; @@ -97,7 +100,9 @@ function run(options) { var inBinPath = false; try { inBinPath = statSync(`${binPath}/${executable}`).isFile(); - } catch (e) {} + } catch (e) { + // ignore + } // hasStdio allows us to correctly handle stdin piping // see: https://git.io/vNtX3 @@ -111,7 +116,7 @@ function run(options) { !(firstArg.indexOf('-') === 0) && // don't fork if there's a node exec arg firstArg !== 'inspect' && // don't fork it's `inspect` debugger executable === 'node' && // only fork if node - utils.version.major > 4 // only fork if node version > 4 + utils.version.major > 4; // only fork if node version > 4 if (shouldFork) { // this assumes the first argument is the script and slices it out, since @@ -125,7 +130,7 @@ function run(options) { silent: !hasStdio, }); utils.log.detail('forking'); - debug('fork', sh, shFlag, args) + debug('fork', sh, shFlag, args); } else { utils.log.detail('spawning'); child = spawn.apply(null, spawnArgs); @@ -181,8 +186,9 @@ function run(options) { } if (code === 127) { - utils.log.error('failed to start process, "' + cmd.executable + - '" exec not found'); + utils.log.error( + 'failed to start process, "' + cmd.executable + '" exec not found' + ); bus.emit('error', code); process.exit(); } @@ -227,7 +233,8 @@ function run(options) { return restart(); } - if (code === 0) { // clean exit - wait until file change to restart + if (code === 0) { + // clean exit - wait until file change to restart if (runCmd) { utils.log.status('clean exit - waiting for changes before restart'); } @@ -241,8 +248,9 @@ function run(options) { process.exit(1); } } else { - utils.log.fail('app crashed - waiting for file changes before' + - ' starting...'); + utils.log.fail( + 'app crashed - waiting for file changes before' + ' starting...' + ); child = null; } } @@ -267,21 +275,25 @@ function run(options) { // swallow the stdin error if it happens // ref: https://github.com/remy/nodemon/issues/1195 if (hasStdio) { - child.stdin.on('error', () => { }); + child.stdin.on('error', () => {}); process.stdin.pipe(child.stdin); } else { if (child.stdout) { child.stdout.pipe(process.stdout); } else { - utils.log.error('running an unsupported version of node ' + - process.version); - utils.log.error('nodemon may not work as expected - ' + - 'please consider upgrading to LTS'); + utils.log.error( + 'running an unsupported version of node ' + process.version + ); + utils.log.error( + 'nodemon may not work as expected - ' + + 'please consider upgrading to LTS' + ); } } bus.once('exit', function () { - if (child && process.stdin.unpipe) { // node > 0.8 + if (child && process.stdin.unpipe) { + // node > 0.8 process.stdin.unpipe(child.stdin); } }); @@ -300,14 +312,16 @@ function waitForSubProcesses(pid, callback) { return callback(); } - utils.log.status(`still waiting for ${pids.length} sub-process${ - pids.length > 2 ? 'es' : ''} to finish...`); + utils.log.status( + `still waiting for ${pids.length} sub-process${ + pids.length > 2 ? 'es' : '' + } to finish...` + ); setTimeout(() => waitForSubProcesses(pid, callback), 1000); }); } function kill(child, signal, callback) { - if (!callback) { callback = noop; } @@ -317,15 +331,14 @@ function kill(child, signal, callback) { try { exec('taskkill /pid ' + child.pid + ' /T /F'); } catch (e) { - utils.log.error("Could not shutdown sub process cleanly"); + utils.log.error('Could not shutdown sub process cleanly'); } - } + }; // We are handling a 'SIGKILL' POSIX signal under Windows the // same way it is handled on a UNIX system: We are performing // a hard shutdown without waiting for the process to clean-up. if (signal === 'SIGKILL' || osRelease < 10) { - debug('terminating process group by force: %s', child.pid); // We are using the taskkill utility to terminate the whole @@ -373,7 +386,6 @@ function kill(child, signal, callback) { taskKill(); } callback(); - } else { // we use psTree to kill the full subtree of nodemon, because when // spawning processes like `coffee` under the `--debug` flag, it'll spawn @@ -395,15 +407,13 @@ function kill(child, signal, callback) { child.kill(signal); - pids.sort().forEach(pid => exec(`kill -${sig} ${pid}`, noop)); + pids.sort().forEach((pid) => exec(`kill -${sig} ${pid}`, noop)); waitForSubProcesses(child.pid, () => { // finally kill the main user process exec(`kill -${sig} ${child.pid}`, callback); }); - }); - } } @@ -510,7 +520,9 @@ bus.on('restart', function () { // remove the child file on exit process.on('exit', function () { utils.log.detail('exiting'); - if (child) { child.kill(); } + if (child) { + child.kill(); + } }); // because windows borks when listening for the SIG* events @@ -520,10 +532,11 @@ if (!utils.isWindows) { process.once('SIGINT', () => bus.emit('quit', 130)); process.once('SIGTERM', () => { bus.emit('quit', 143); - if (child) { child.kill('SIGTERM'); } + if (child) { + child.kill('SIGTERM'); + } }); - }) + }); } - module.exports = run; diff --git a/lib/monitor/signals.js b/lib/monitor/signals.js index daff6e0..350d516 100644 --- a/lib/monitor/signals.js +++ b/lib/monitor/signals.js @@ -31,4 +31,4 @@ module.exports = { SIGPWR: 30, SIGSYS: 31, SIGRTMIN: 35, -} +}; diff --git a/lib/monitor/watch.js b/lib/monitor/watch.js index 1ef1408..f718312 100644 --- a/lib/monitor/watch.js +++ b/lib/monitor/watch.js @@ -39,13 +39,15 @@ function watch() { const promise = new Promise(function (resolve) { const dotFilePattern = /[/\\]\./; - var ignored = match.rulesToMonitor( - [], // not needed - Array.from(rootIgnored), - config - ).map(pattern => pattern.slice(1)); + var ignored = match + .rulesToMonitor( + [], // not needed + Array.from(rootIgnored), + config + ) + .map((pattern) => pattern.slice(1)); - const addDotFile = dirs.filter(dir => dir.match(dotFilePattern)); + const addDotFile = dirs.filter((dir) => dir.match(dotFilePattern)); // don't ignore dotfiles if explicitly watched. if (addDotFile.length === 0) { @@ -104,8 +106,8 @@ function watch() { if (error.code === 'EINVAL') { utils.log.error( 'Internal watch failed. Likely cause: too many ' + - 'files being watched (perhaps from the root of a drive?\n' + - 'See https://github.com/paulmillr/chokidar/issues/229 for details' + 'files being watched (perhaps from the root of a drive?\n' + + 'See https://github.com/paulmillr/chokidar/issues/229 for details' ); } else { utils.log.error('Internal watch failed: ' + error.message); @@ -116,17 +118,22 @@ function watch() { watchers.push(watcher); }); - return promise.catch(e => { - // this is a core error and it should break nodemon - so I have to break - // out of a promise using the setTimeout - setTimeout(() => { - throw e; + return promise + .catch((e) => { + // this is a core error and it should break nodemon - so I have to break + // out of a promise using the setTimeout + setTimeout(() => { + throw e; + }); + }) + .then(function () { + utils.log.detail( + `watching ${watchedFiles.length} file${ + watchedFiles.length === 1 ? '' : 's' + }` + ); + return watchedFiles; }); - }).then(function () { - utils.log.detail(`watching ${watchedFiles.length} file${ - watchedFiles.length === 1 ? '' : 's'}`); - return watchedFiles; - }); } function filterAndRestart(files) { @@ -142,29 +149,30 @@ function filterAndRestart(files) { utils.log.detail( 'files triggering change check: ' + - files - .map(file => { - const res = path.relative(cwd, file); - return res; - }) - .join(', ') + files + .map((file) => { + const res = path.relative(cwd, file); + return res; + }) + .join(', ') ); // make sure the path is right and drop an empty // filenames (sometimes on windows) - files = files.filter(Boolean).map(file => { + files = files.filter(Boolean).map((file) => { return path.relative(process.cwd(), path.relative(cwd, file)); }); if (utils.isWindows) { // ensure the drive letter is in uppercase (c:\foo -> C:\foo) - files = files.map(f => { - if (f.indexOf(':') === -1) { return f; } + files = files.map((f) => { + if (f.indexOf(':') === -1) { + return f; + } return f[0].toUpperCase() + f.slice(1); }); } - debug('filterAndRestart on', files); var matched = match( @@ -181,7 +189,7 @@ function filterAndRestart(files) { const script = path.resolve(config.options.execOptions.script); if (matched.result.length === 0 && script) { const length = script.length; - files.find(file => { + files.find((file) => { if (file.substr(-length, length) === script) { matched = { result: [file], @@ -195,7 +203,7 @@ function filterAndRestart(files) { utils.log.detail( 'changes after filters (before/after): ' + - [files.length, matched.result.length].join('/') + [files.length, matched.result.length].join('/') ); // reset the last check so we're only looking at recently modified files @@ -217,7 +225,7 @@ function filterAndRestart(files) { function restartBus(matched) { utils.log.status('restarting due to changes...'); - matched.result.map(file => { + matched.result.map((file) => { utils.log.detail(path.relative(process.cwd(), file)); }); @@ -234,6 +242,6 @@ function debounce(fn, delay) { const context = this; const args = arguments; clearTimeout(timer); - timer = setTimeout(() =>fn.apply(context, args), delay); + timer = setTimeout(() => fn.apply(context, args), delay); }; } diff --git a/lib/nodemon.js b/lib/nodemon.js index ce649cb..ff36648 100644 --- a/lib/nodemon.js +++ b/lib/nodemon.js @@ -9,7 +9,7 @@ var bus = utils.bus; var help = require('./help'); var config = require('./config'); var spawn = require('./spawn'); -const defaults = require('./config/defaults') +const defaults = require('./config/defaults'); var eventHandlers = {}; // this is fairly dirty, but theoretically sound since it's part of the @@ -69,11 +69,12 @@ function nodemon(settings) { } } - const cwd = process.cwd(); - config.load(settings, function (config) { - if (!config.options.dump && !config.options.execOptions.script && - config.options.execOptions.exec === 'node') { + if ( + !config.options.dump && + !config.options.execOptions.script && + config.options.execOptions.exec === 'node' + ) { if (!config.required) { console.log(help('usage')); process.exit(); @@ -93,21 +94,24 @@ function nodemon(settings) { utils.log.detail('process root: ' + cwd); } - config.loaded.map(file => file.replace(cwd, '.')).forEach(file => { - utils.log.detail('reading config ' + file); - }); + config.loaded + .map((file) => file.replace(cwd, '.')) + .forEach((file) => { + utils.log.detail('reading config ' + file); + }); if (config.options.stdin && config.options.restartable) { // allow nodemon to restart when the use types 'rs\n' process.stdin.resume(); process.stdin.setEncoding('utf8'); - process.stdin.on('data', data => { + process.stdin.on('data', (data) => { const str = data.toString().trim().toLowerCase(); // if the keys entered match the restartable value, then restart! if (str === config.options.restartable) { bus.emit('restart'); - } else if (data.charCodeAt(0) === 12) { // ctrl+l + } else if (data.charCodeAt(0) === 12) { + // ctrl+l console.clear(); } }); @@ -131,11 +135,14 @@ function nodemon(settings) { ctrlC = true; return; - } else if (buffer === '.exit' || chr === 4) { // ctrl+d + } else if (buffer === '.exit' || chr === 4) { + // ctrl+d process.exit(); - } else if (chr === 13 || chr === 10) { // enter / carriage return + } else if (chr === 13 || chr === 10) { + // enter / carriage return buffer = ''; - } else if (chr === 12) { // ctrl+l + } else if (chr === 12) { + // ctrl+l console.clear(); buffer = ''; } @@ -147,54 +154,74 @@ function nodemon(settings) { } if (config.options.restartable) { - utils.log.info('to restart at any time, enter `' + - config.options.restartable + '`'); + utils.log.info( + 'to restart at any time, enter `' + config.options.restartable + '`' + ); } if (!config.required) { - const restartSignal = config.options.signal === 'SIGUSR2' ? 'SIGHUP' : 'SIGUSR2'; + const restartSignal = + config.options.signal === 'SIGUSR2' ? 'SIGHUP' : 'SIGUSR2'; process.on(restartSignal, nodemon.restart); utils.bus.on('error', () => { - utils.log.fail((new Error().stack)); + utils.log.fail(new Error().stack); }); - utils.log.detail((config.options.restartable ? 'or ' : '') + 'send ' + - restartSignal + ' to ' + process.pid + ' to restart'); + utils.log.detail( + (config.options.restartable ? 'or ' : '') + + 'send ' + + restartSignal + + ' to ' + + process.pid + + ' to restart' + ); } - const ignoring = config.options.monitor.map(function (rule) { - if (rule.slice(0, 1) !== '!') { - return false; - } + const ignoring = config.options.monitor + .map(function (rule) { + if (rule.slice(0, 1) !== '!') { + return false; + } - rule = rule.slice(1); + rule = rule.slice(1); - // don't notify of default ignores - if (defaults.ignoreRoot.indexOf(rule) !== -1) { - return false; - return rule.slice(3).slice(0, -3); - } + // don't notify of default ignores + if (defaults.ignoreRoot.indexOf(rule) !== -1) { + return false; + } - if (rule.startsWith(cwd)) { - return rule.replace(cwd, '.'); - } - - return rule; - }).filter(Boolean).join(' '); - if (ignoring) utils.log.detail('ignoring: ' + ignoring); - - utils.log.info('watching path(s): ' + config.options.monitor.map(function (rule) { - if (rule.slice(0, 1) !== '!') { - try { - rule = path.relative(process.cwd(), rule); - } catch (e) {} + if (rule.startsWith(cwd)) { + return rule.replace(cwd, '.'); + } return rule; - } + }) + .filter(Boolean) + .join(' '); + if (ignoring) utils.log.detail('ignoring: ' + ignoring); - return false; - }).filter(Boolean).join(' ')); + utils.log.info( + 'watching path(s): ' + + config.options.monitor + .map(function (rule) { + if (rule.slice(0, 1) !== '!') { + try { + rule = path.relative(process.cwd(), rule); + } catch (e) { + // ignore + } - utils.log.info('watching extensions: ' + (config.options.execOptions.ext || '(all)')); + return rule; + } + + return false; + }) + .filter(Boolean) + .join(' ') + ); + + utils.log.info( + 'watching extensions: ' + (config.options.execOptions.ext || '(all)') + ); if (config.options.dump) { utils.log._log('log', '--------------'); @@ -226,19 +253,22 @@ function nodemon(settings) { if (config.options.events && Object.keys(config.options.events).length) { Object.keys(config.options.events).forEach(function (key) { - utils.log.detail('bind ' + key + ' -> `' + - config.options.events[key] + '`'); + utils.log.detail( + 'bind ' + key + ' -> `' + config.options.events[key] + '`' + ); nodemon.on(key, function () { if (config.options && config.options.events) { - spawn(config.options.events[key], config, - [].slice.apply(arguments)); + spawn( + config.options.events[key], + config, + [].slice.apply(arguments) + ); } }); }); } monitor.run(config.options); - }); return nodemon; @@ -251,14 +281,18 @@ nodemon.restart = function () { }; nodemon.addListener = nodemon.on = function (event, handler) { - if (!eventHandlers[event]) { eventHandlers[event] = []; } + 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] = []; } + if (!eventHandlers[event]) { + eventHandlers[event] = []; + } eventHandlers[event].push(handler); bus.once(event, function () { debug('bus.once(%s)', event); @@ -275,14 +309,16 @@ nodemon.emit = function () { nodemon.removeAllListeners = 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); + 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; }; @@ -308,4 +344,3 @@ bus.on('reset', function (done) { nodemon.config = config; module.exports = nodemon; - diff --git a/lib/rules/add.js b/lib/rules/add.js index de85bb7..cb290ae 100644 --- a/lib/rules/add.js +++ b/lib/rules/add.js @@ -31,9 +31,11 @@ module.exports = add; * @param {String|RegExp} the actual rule. */ function add(rules, which, rule) { - if (!{ ignore: 1, watch: 1}[which]) { - throw new Error('rules/index.js#add requires "ignore" or "watch" as the ' + - 'first argument'); + if (!{ ignore: 1, watch: 1 }[which]) { + throw new Error( + 'rules/index.js#add requires "ignore" or "watch" as the ' + + 'first argument' + ); } if (Array.isArray(rule)) { @@ -55,9 +57,11 @@ function add(rules, which, rule) { // this mess of replace methods is escaping "\#" to allow for emacs temp files // first up strip comments and remove blank head or tails - rule = (rule || '').replace(reEscComments, '^^') - .replace(reComments, '') - .replace(reUnescapeComments, '#').trim(); + rule = (rule || '') + .replace(reEscComments, '^^') + .replace(reComments, '') + .replace(reUnescapeComments, '#') + .trim(); var regexp = false; @@ -78,10 +82,11 @@ function add(rules, which, rule) { rules[which].push(rule); // compile a regexp of all the rules for this ignore or watch - var re = rules[which].map(function (rule) { - return rule.replace(reEscapeChars, '\\$&') - .replace(reAsterisk, '.*'); - }).join('|'); + var re = rules[which] + .map(function (rule) { + return rule.replace(reEscapeChars, '\\$&').replace(reAsterisk, '.*'); + }) + .join('|'); // used for the directory matching rules[which].re = new RegExp(re); diff --git a/lib/rules/index.js b/lib/rules/index.js index 04aa92f..2eddcb9 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -34,7 +34,8 @@ function load(filename, callback) { } module.exports = { - reset: function () { // just used for testing + reset: function () { + // just used for testing rules.ignore.length = rules.watch.length = 0; delete rules.ignore.re; delete rules.watch.re; @@ -50,4 +51,4 @@ module.exports = { }, add: add.bind(null, rules), rules: rules, -}; \ No newline at end of file +}; diff --git a/lib/rules/parse.js b/lib/rules/parse.js index 6e1cace..7b8d3d7 100644 --- a/lib/rules/parse.js +++ b/lib/rules/parse.js @@ -15,7 +15,6 @@ function parse(filename, callback) { }; fs.readFile(filename, 'utf8', function (err, content) { - if (err) { return callback(err); } @@ -23,7 +22,9 @@ function parse(filename, callback) { var json = null; try { json = JSON.parse(content); - } catch (e) {} + } catch (e) { + // ignore + } if (json !== null) { rules = { @@ -40,4 +41,3 @@ function parse(filename, callback) { } module.exports = parse; - diff --git a/lib/spawn.js b/lib/spawn.js index 9aa4f80..fb6e3ca 100644 --- a/lib/spawn.js +++ b/lib/spawn.js @@ -28,17 +28,20 @@ module.exports = function spawnCommand(command, config, eventArgs) { // if the exec includes a forward slash, reverse it for windows compat // but *only* apply to the first command, and none of the arguments. // ref #1251 and #1236 - command = command.map(executable => { + command = command.map((executable) => { if (executable.indexOf('/') === -1) { return executable; } - return executable.split(' ').map((e, i) => { - if (i === 0) { - return path.normalize(e); - } - return e; - }).join(' '); + return executable + .split(' ') + .map((e, i) => { + if (i === 0) { + return path.normalize(e); + } + return e; + }) + .join(' '); }); // taken from npm's cli: https://git.io/vNFD4 sh = process.env.comspec || 'cmd'; diff --git a/lib/utils/clone.js b/lib/utils/clone.js index 6ba6330..cb8c63b 100644 --- a/lib/utils/clone.js +++ b/lib/utils/clone.js @@ -36,5 +36,5 @@ function clone(obj) { return copy; } - throw new Error('Unable to copy obj! Its type isn\'t supported.'); -} \ No newline at end of file + throw new Error("Unable to copy obj! Its type isn't supported."); +} diff --git a/lib/utils/colour.js b/lib/utils/colour.js index 8c1b590..0dee7c4 100644 --- a/lib/utils/colour.js +++ b/lib/utils/colour.js @@ -18,7 +18,9 @@ colour.yellow = '\x1B[33m'; colour.green = '\x1B[32m'; colour.black = '\x1B[39m'; -var reStr = Object.keys(colour).map(key => colour[key]).join('|'); +var reStr = Object.keys(colour) + .map((key) => colour[key]) + .join('|'); var re = new RegExp(('(' + reStr + ')').replace(/\[/g, '\\['), 'g'); colour.strip = strip; diff --git a/lib/utils/index.js b/lib/utils/index.js index c480338..32043a7 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -1,11 +1,11 @@ -var noop = function () { }; +var noop = function () {}; var path = require('path'); const semver = require('semver'); var version = process.versions.node.split('.') || [null, null, null]; var utils = (module.exports = { semver: semver, - satisfies: test => semver.satisfies(process.versions.node, test), + satisfies: (test) => semver.satisfies(process.versions.node, test), version: { major: parseInt(version[0] || 0, 10), minor: parseInt(version[1] || 0, 10), @@ -66,15 +66,15 @@ var utils = (module.exports = { return [exec] .concat( - args.map(function (arg) { - // if an argument contains a space, we want to show it with quotes - // around it to indicate that it is a single argument - if (arg.length > 0 && arg.indexOf(' ') === -1) { - return arg; - } - // this should correctly escape nested quotes - return JSON.stringify(arg); - }) + args.map(function (arg) { + // if an argument contains a space, we want to show it with quotes + // around it to indicate that it is a single argument + if (arg.length > 0 && arg.indexOf(' ') === -1) { + return arg; + } + // this should correctly escape nested quotes + return JSON.stringify(arg); + }) ) .join(' ') .trim(); diff --git a/lib/utils/merge.js b/lib/utils/merge.js index 1f3440b..1104cff 100644 --- a/lib/utils/merge.js +++ b/lib/utils/merge.js @@ -3,7 +3,7 @@ var clone = require('./clone'); module.exports = merge; function typesMatch(a, b) { - return (typeof a === typeof b) && (Array.isArray(a) === Array.isArray(b)); + return typeof a === typeof b && Array.isArray(a) === Array.isArray(b); } /** @@ -44,4 +44,4 @@ function merge(source, target, result) { }); return result; -} \ No newline at end of file +} diff --git a/lib/version.js b/lib/version.js index d0f5104..f0987e1 100644 --- a/lib/version.js +++ b/lib/version.js @@ -7,9 +7,7 @@ var exec = require('child_process').exec; var root = null; function pin() { - return version().then(function (v) { - version.pinned = v; - }); + return version().then((v) => (version.pinned = v)); } function version(callback) { @@ -28,13 +26,13 @@ function version(callback) { // else we're in development, give the commit out // get the last commit and whether the working dir is dirty var promises = [ - branch().catch(function () { return 'master'; }), - commit().catch(function () { return ''; }), - dirty().catch(function () { return 0; }), + branch().catch(() => 'master'), + commit().catch(() => ''), + dirty().catch(() => 0), ]; // use the cached result as the export - return Promise.all(promises).then(function (res) { + return Promise.all(promises).then((res) => { var branch = res[0]; var commit = res[1]; var dirtyCount = parseInt(res[2], 10); @@ -45,15 +43,14 @@ function version(callback) { return curr; }); - }).catch(function (error) { + }) + .catch(function (error) { console.log(error.stack); throw error; }); if (callback) { - promise.then(function (res) { - callback(null, res); - }, callback); + promise.then((res) => callback(null, res), callback); } return promise; @@ -95,6 +92,7 @@ function branch() { } function dirty() { - return command('expr $(git status --porcelain 2>/dev/null| ' + - 'egrep "^(M| M)" | wc -l)'); + return command( + 'expr $(git status --porcelain 2>/dev/null| ' + 'egrep "^(M| M)" | wc -l)' + ); } diff --git a/package-lock.json b/package-lock.json index c316874..39f7d4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6481,6 +6481,11 @@ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, + "prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", diff --git a/package.json b/package.json index b6634cd..f8e90c9 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,9 @@ "name": "Remy Sharp", "url": "https://github.com/remy" }, + "prettier": { + "singleQuote": true + }, "bin": { "nodemon": "./bin/nodemon.js" }, @@ -59,6 +62,7 @@ "debug": "^3.2.6", "ignore-by-default": "^1.0.1", "minimatch": "^3.0.4", + "prettier": "^2.3.2", "pstree.remy": "^1.1.7", "semver": "^5.7.1", "supports-color": "^5.5.0",