From 6e839d4a33079b856234c1e520cc4222e9b227cb Mon Sep 17 00:00:00 2001 From: Remy Sharp Date: Thu, 28 Dec 2017 21:59:53 +0000 Subject: [PATCH] fix: support implicit filename extension Fixes #1193 --- README.md | 2 +- lib/config/command.js | 2 +- lib/config/exec.js | 28 ++++++++++++++++++++-------- lib/config/load.js | 41 ++++++++++++++++++++++++----------------- test/cli/parse.test.js | 36 ++++++++++++++++++++++++------------ 5 files changed, 70 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 5652477f..752783b8 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ Simply specify the config in the same format as you would for a config file but "...": "... other standard package.json values", "nodemonConfig": { "ignore": ["test/*", "docs/*"], -"delay": "2500" + "delay": "2500" } } ``` diff --git a/lib/config/command.js b/lib/config/command.js index 2ce46346..9839b5c7 100644 --- a/lib/config/command.js +++ b/lib/config/command.js @@ -40,4 +40,4 @@ function command(settings) { executable: executable, args: args, }; -} \ No newline at end of file +} diff --git a/lib/config/exec.js b/lib/config/exec.js index 852186f6..0c0d234b 100644 --- a/lib/config/exec.js +++ b/lib/config/exec.js @@ -73,27 +73,39 @@ function exec(nodemonOptions, execMap) { execMap = {}; } + var options = utils.clone(nodemonOptions || {}); + + if (!options.script && options.args.length) { // try with the first argument + const script = expandScript(options.args[0], + options.ext && ('.' + (options.ext || 'js').split(',')[0])); + + if (script !== options.args[0]) { // if the script was found, shift it off our args + options.script = script; + options.args.shift(); + } + } + // if there's no exec found yet, then try to read it from the local // package.json this logic used to sit in the cli/parse, but actually the cli // should be parsed first, then the user options (via nodemon.json) then // finally default down to pot shots at the directory via package.json - if (!nodemonOptions.exec && !nodemonOptions.script) { + if (!options.exec && !options.script) { var found = execFromPackage(); if (found !== null) { if (found.exec) { - nodemonOptions.exec = found.exec; + options.exec = found.exec; } - if (!nodemonOptions.script) { - nodemonOptions.script = found.script; + if (!options.script) { + options.script = found.script; } - if (Array.isArray(nodemonOptions.args) && - nodemonOptions.scriptPosition === null) { - nodemonOptions.scriptPosition = nodemonOptions.args.length; + if (Array.isArray(options.args) && + options.scriptPosition === null) { + options.scriptPosition = options.args.length; } } } - var options = utils.clone(nodemonOptions || {}); + // var options = utils.clone(nodemonOptions || {}); var script = path.basename(options.script || ''); var scriptExt = path.extname(script).slice(1); diff --git a/lib/config/load.js b/lib/config/load.js index ca4dd3c9..39b1d05b 100644 --- a/lib/config/load.js +++ b/lib/config/load.js @@ -9,6 +9,7 @@ var exec = require('./exec'); var defaults = require('./defaults'); module.exports = load; +module.exports.mutateExecOptions = mutateExecOptions; var existsSync = fs.existsSync || path.existsSync; @@ -72,23 +73,7 @@ function load(settings, options, config, callback) { } } - // 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); - - // clean up values that we don't need at the top level - delete options.scriptPosition; - delete options.script; - delete options.args; - delete options.ext; + mutateExecOptions(options); if (options.quiet) { utils.quiet(); @@ -230,3 +215,25 @@ function loadPackageJSON(config, ready) { 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); + + // clean up values that we don't need at the top level + delete options.scriptPosition; + delete options.script; + delete options.args; + delete options.ext; + + return options; +} diff --git a/test/cli/parse.test.js b/test/cli/parse.test.js index 15e16d78..636feb5f 100644 --- a/test/cli/parse.test.js +++ b/test/cli/parse.test.js @@ -7,6 +7,8 @@ var cli = require('../../lib/cli/'), command = require('../../lib/config/command'), utils = require('../../lib/utils'); +const mutateExecOptions = require('../../lib/config/load').mutateExecOptions; + function asCLI(cmd) { return ('node nodemon ' + (cmd || '')).trim(); } @@ -26,6 +28,7 @@ function parse(cmd) { }); return parsed; + return mutateExecOptions(cli.parse(cmd)); } function commandToString(command) { @@ -97,18 +100,6 @@ describe('nodemon CLI parser', function () { assert(cmd === 'node --harmony app.js', 'command is ' + cmd); }); - // it('should put the script at the end if found in package.scripts.start', function () { - // var pwd = process.cwd(); - // process.chdir('test/fixtures/packages/start'); // allows us to load text/fixtures/package.json - // var settings = parse(asCLI('--harmony')), - // cmd = commandToString(command(settings)); - - // process.chdir(pwd); - // console.log(settings, cmd); - - // assert(cmd === 'node --harmony app.js', 'command is ' + cmd); - // }); - it('should support default express4 format', function () { var pwd = process.cwd(); process.chdir('test/fixtures/packages/express4'); // allows us to load text/fixtures/package.json @@ -274,6 +265,27 @@ describe('nodemon respects custom "ext" and "execMap"', function () { }); }); +describe('nodemon should support implicit extensions', () => { + it('should expand script to script.js', () => { + const cwd = process.cwd(); + process.chdir('test/fixtures/'); + const settings = parse(asCLI('env')); + process.chdir(cwd); + var cmd = commandToString(command(settings)); + assert.equal(cmd, 'node env.js', 'implicit extension added'); + }); + + it('should support non-js', () => { + const cwd = process.cwd(); + process.chdir('test/fixtures/'); + const settings = parse(asCLI('hello --ext py')); + process.chdir(cwd); + var cmd = commandToString(command(settings)); + assert.equal(cmd, 'node hello.py', 'implicit extension added'); + }); + +}); + describe('nodemon should slurp properly', () => { it('should read quotes as a single entity', () => { const settings = parse(asCLI('notindex.js -- -b "hello - world"'));