Skip to content

Commit 6e839d4

Browse files
committed
fix: support implicit filename extension
Fixes #1193
1 parent 48048aa commit 6e839d4

File tree

5 files changed

+70
-39
lines changed

5 files changed

+70
-39
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Simply specify the config in the same format as you would for a config file but
112112
"...": "... other standard package.json values",
113113
"nodemonConfig": {
114114
"ignore": ["test/*", "docs/*"],
115-
"delay": "2500"
115+
"delay": "2500"
116116
}
117117
}
118118
```

lib/config/command.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ function command(settings) {
4040
executable: executable,
4141
args: args,
4242
};
43-
}
43+
}

lib/config/exec.js

+20-8
Original file line numberDiff line numberDiff line change
@@ -73,27 +73,39 @@ function exec(nodemonOptions, execMap) {
7373
execMap = {};
7474
}
7575

76+
var options = utils.clone(nodemonOptions || {});
77+
78+
if (!options.script && options.args.length) { // try with the first argument
79+
const script = expandScript(options.args[0],
80+
options.ext && ('.' + (options.ext || 'js').split(',')[0]));
81+
82+
if (script !== options.args[0]) { // if the script was found, shift it off our args
83+
options.script = script;
84+
options.args.shift();
85+
}
86+
}
87+
7688
// if there's no exec found yet, then try to read it from the local
7789
// package.json this logic used to sit in the cli/parse, but actually the cli
7890
// should be parsed first, then the user options (via nodemon.json) then
7991
// finally default down to pot shots at the directory via package.json
80-
if (!nodemonOptions.exec && !nodemonOptions.script) {
92+
if (!options.exec && !options.script) {
8193
var found = execFromPackage();
8294
if (found !== null) {
8395
if (found.exec) {
84-
nodemonOptions.exec = found.exec;
96+
options.exec = found.exec;
8597
}
86-
if (!nodemonOptions.script) {
87-
nodemonOptions.script = found.script;
98+
if (!options.script) {
99+
options.script = found.script;
88100
}
89-
if (Array.isArray(nodemonOptions.args) &&
90-
nodemonOptions.scriptPosition === null) {
91-
nodemonOptions.scriptPosition = nodemonOptions.args.length;
101+
if (Array.isArray(options.args) &&
102+
options.scriptPosition === null) {
103+
options.scriptPosition = options.args.length;
92104
}
93105
}
94106
}
95107

96-
var options = utils.clone(nodemonOptions || {});
108+
// var options = utils.clone(nodemonOptions || {});
97109
var script = path.basename(options.script || '');
98110

99111
var scriptExt = path.extname(script).slice(1);

lib/config/load.js

+24-17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ var exec = require('./exec');
99
var defaults = require('./defaults');
1010

1111
module.exports = load;
12+
module.exports.mutateExecOptions = mutateExecOptions;
1213

1314
var existsSync = fs.existsSync || path.existsSync;
1415

@@ -72,23 +73,7 @@ function load(settings, options, config, callback) {
7273
}
7374
}
7475

75-
// work out the execOptions based on the final config we have
76-
options.execOptions = exec({
77-
script: options.script,
78-
exec: options.exec,
79-
args: options.args,
80-
scriptPosition: options.scriptPosition,
81-
nodeArgs: options.nodeArgs,
82-
execArgs: options.execArgs,
83-
ext: options.ext,
84-
env: options.env,
85-
}, options.execMap);
86-
87-
// clean up values that we don't need at the top level
88-
delete options.scriptPosition;
89-
delete options.script;
90-
delete options.args;
91-
delete options.ext;
76+
mutateExecOptions(options);
9277

9378
if (options.quiet) {
9479
utils.quiet();
@@ -230,3 +215,25 @@ function loadPackageJSON(config, ready) {
230215
ready(settings.nodemonConfig || {});
231216
});
232217
}
218+
219+
function mutateExecOptions(options) {
220+
// work out the execOptions based on the final config we have
221+
options.execOptions = exec({
222+
script: options.script,
223+
exec: options.exec,
224+
args: options.args,
225+
scriptPosition: options.scriptPosition,
226+
nodeArgs: options.nodeArgs,
227+
execArgs: options.execArgs,
228+
ext: options.ext,
229+
env: options.env,
230+
}, options.execMap);
231+
232+
// clean up values that we don't need at the top level
233+
delete options.scriptPosition;
234+
delete options.script;
235+
delete options.args;
236+
delete options.ext;
237+
238+
return options;
239+
}

test/cli/parse.test.js

+24-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ var cli = require('../../lib/cli/'),
77
command = require('../../lib/config/command'),
88
utils = require('../../lib/utils');
99

10+
const mutateExecOptions = require('../../lib/config/load').mutateExecOptions;
11+
1012
function asCLI(cmd) {
1113
return ('node nodemon ' + (cmd || '')).trim();
1214
}
@@ -26,6 +28,7 @@ function parse(cmd) {
2628
});
2729

2830
return parsed;
31+
return mutateExecOptions(cli.parse(cmd));
2932
}
3033

3134
function commandToString(command) {
@@ -97,18 +100,6 @@ describe('nodemon CLI parser', function () {
97100
assert(cmd === 'node --harmony app.js', 'command is ' + cmd);
98101
});
99102

100-
// it('should put the script at the end if found in package.scripts.start', function () {
101-
// var pwd = process.cwd();
102-
// process.chdir('test/fixtures/packages/start'); // allows us to load text/fixtures/package.json
103-
// var settings = parse(asCLI('--harmony')),
104-
// cmd = commandToString(command(settings));
105-
106-
// process.chdir(pwd);
107-
// console.log(settings, cmd);
108-
109-
// assert(cmd === 'node --harmony app.js', 'command is ' + cmd);
110-
// });
111-
112103
it('should support default express4 format', function () {
113104
var pwd = process.cwd();
114105
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 () {
274265
});
275266
});
276267

268+
describe('nodemon should support implicit extensions', () => {
269+
it('should expand script to script.js', () => {
270+
const cwd = process.cwd();
271+
process.chdir('test/fixtures/');
272+
const settings = parse(asCLI('env'));
273+
process.chdir(cwd);
274+
var cmd = commandToString(command(settings));
275+
assert.equal(cmd, 'node env.js', 'implicit extension added');
276+
});
277+
278+
it('should support non-js', () => {
279+
const cwd = process.cwd();
280+
process.chdir('test/fixtures/');
281+
const settings = parse(asCLI('hello --ext py'));
282+
process.chdir(cwd);
283+
var cmd = commandToString(command(settings));
284+
assert.equal(cmd, 'node hello.py', 'implicit extension added');
285+
});
286+
287+
});
288+
277289
describe('nodemon should slurp properly', () => {
278290
it('should read quotes as a single entity', () => {
279291
const settings = parse(asCLI('notindex.js -- -b "hello - world"'));

0 commit comments

Comments
 (0)