Repository: remy/nodemon (js)

Issue:
Cannot use chrome debugger with nodemon v1.12.7 (latest)
- `nodemon -v`:
1.12.7

- `node -v`:
v8.9.0

- Command you ran:
`nodemon --inspect index`


### Expected behaviour
Chrome debugger activates and allows step-by-step debugging of the executing node app

### Actual behaviour
Chrome debugger doesn't work.... it does though when replacing `nodemon` by `node`. Used to work flawlessly weeks ago. In fact, that tool was a very important part of my toolset, had to revert to basic node interpreter.

### Steps to reproduce
with an express app in an index.js file, run `nodemon --inspect index`
notice that Chrome debugger doesn't react as it would using `node --inspect index`

---

If applicable, please append the `--dump` flag on your command and include the output here **ensuring to remove any sensitive/personal details or tokens.


Pull request:
fix: support nodemon index to expand to index.js
With support for custom extensions (picking only the first).

Fixes #1165

Patch:
diff --git a/lib/config/exec.js b/lib/config/exec.js
index de0cd30..09c15c0 100644
--- a/lib/config/exec.js
+++ b/lib/config/exec.js
@@ -1,7 +1,10 @@
-var path = require('path');
-var utils = require('../utils');
+const path = require('path');
+const fs = require('fs');
+const existsSync = fs.existsSync;
+const utils = require('../utils');
 
 module.exports = exec;
+module.exports.expandScript = expandScript;
 
 /**
  * Reads the cwd/package.json file and looks to see if it can load a script
@@ -36,6 +39,24 @@ function replace(map, str) {
   });
 }
 
+function expandScript(script, ext) {
+  if (!ext) {
+    ext = '.js';
+  }
+  if (script.indexOf(ext) !== -1) {
+    return script;
+  }
+
+  if (existsSync(path.resolve(script))) {
+    return script;
+  }
+
+  if (existsSync(path.resolve(script + ext))) {
+    return script + ext;
+  }
+
+  return script;
+}
 
 /**
  * Discovers all the options required to run the script
@@ -74,6 +95,7 @@ function exec(nodemonOptions, execMap) {
 
   var options = utils.clone(nodemonOptions || {});
   var script = path.basename(options.script || '');
+
   var scriptExt = path.extname(script).slice(1);
   var extension = options.ext || (scriptExt ? scriptExt + ',json' : 'js,json');
   var execDefined = !!options.exec;
@@ -163,6 +185,11 @@ function exec(nodemonOptions, execMap) {
 
   options.ext = extension;
 
+  if (options.script) {
+    options.script = expandScript(options.script, '.' +
+      extension.split(',')[0]);
+  }
+
   options.env = {};
   // make sure it's an object (and since we don't have )
   if (({}).toString.apply(nodemonOptions.env) === '[object Object]') {
diff --git a/lib/config/load.js b/lib/config/load.js
index 73ae275..06ec801 100644
--- a/lib/config/load.js
+++ b/lib/config/load.js
@@ -22,11 +22,11 @@ function findAppScript() {
 
 /**
  * Load the nodemon config, first reading the global root/nodemon.json, then
- * the local nodemon.json to the exec and then overwritting using any user
+ * the local nodemon.json to the exec and then overwriting using any user
  * specified settings (i.e. from the cli)
  *
  * @param  {Object} settings user defined settings
- * @param  {Function} ready    callback that recieves complete config
+ * @param  {Function} ready    callback that receives complete config
  */
 function load(settings, options, config, callback) {
   config.loaded = [];
diff --git a/package.json b/package.json
index cfa3736..660ed7f 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,7 @@
     "test": "npm run lint && npm run spec",
     "spec": "for FILE in test/**/*.test.js; do echo $FILE; TEST=1 mocha --exit --timeout 30000 $FILE; if [ $? -ne 0 ]; then exit 1; fi; sleep 1; done",
     "postspec": "npm run clean",
-    "clean": "rm -rf test/fixtures/test*.js",
+    "clean": "rm -rf test/fixtures/test*.js test/fixtures/test*.md",
     "web": "node web",
     "semantic-release": "semantic-release pre && npm publish && semantic-release post",
     "postinstall": "node -e \"console.log('\\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')\""


Test patch:
diff --git a/test/cli/exec.test.js b/test/cli/exec.test.js
index 871b96b..d66ea34 100644
--- a/test/cli/exec.test.js
+++ b/test/cli/exec.test.js
@@ -1,9 +1,11 @@
 'use strict';
 /*global describe:true, it: true */
-var exec = require('../../lib/config/exec'),
-    command = require('../../lib/config/command'),
-    assert = require('assert'),
-    utils = require('../../lib/utils');
+const path = require('path');
+const exec = require('../../lib/config/exec');
+const expandScript = exec.expandScript;
+const command = require('../../lib/config/command');
+const assert = require('assert');
+const utils = require('../../lib/utils');
 
 function toCmd(options) {
   var cmd = command({
@@ -17,7 +19,46 @@ function toCmd(options) {
   };
 }
 
+describe('expandScript', () => {
+  var pwd = process.cwd();
+
+  afterEach(function () {
+    process.chdir(pwd);
+  });
+
+  beforeEach(function () {
+    // move to the fixtures directory to allow for config loading
+    process.chdir(path.resolve(pwd, 'test/fixtures'));
+  });
+
+  it('should expand app.js', () => {
+    const script = expandScript('app');
+    assert.equal(script, 'app.js', script);
+  })
+
+  it('should expand hello.py', () => {
+    const script = expandScript('hello', '.py');
+    assert.equal(script, 'hello.py', script);
+  })
+
+  it('should ignore foo.js', () => {
+    const script = expandScript('foo', '.js');
+    assert.equal(script, 'foo', script);
+  })
+});
+
 describe('nodemon exec', function () {
+  var pwd = process.cwd();
+
+  afterEach(function () {
+    process.chdir(pwd);
+  });
+
+  beforeEach(function () {
+    // move to the fixtures directory to allow for config loading
+    process.chdir(path.resolve(pwd, 'test/fixtures'));
+  });
+
   it('should default to node', function () {
     var options = exec({ script: 'index.js' });
     var cmd = toCmd(options);
@@ -136,4 +177,28 @@ describe('nodemon exec', function () {
     assert(options.ext.indexOf('js') !== -1);
     assert(options.ext.indexOf('jade') !== -1);
   });
+
+  it('should expand app to app.js', function () {
+    var options = exec({ script: 'app' });
+    var cmd = toCmd(options);
+    assert(cmd.string === 'node app.js', cmd.string);
+  });
+
+  it('should expand based on custom extensions to hello.py', function () {
+    var options = exec({ script: 'hello', ext: '.py', exec: 'python' });
+    var cmd = toCmd(options);
+    assert(cmd.string === 'python hello.py', cmd.string);
+  });
+
+  it('should expand based on custom extensions to app.js (js,jsx,mjs)', function () {
+    var options = exec({ script: 'app', ext: 'js,jsx,mjs' });
+    var cmd = toCmd(options);
+    assert(cmd.string === 'node app.js', cmd.string);
+  });
+
+  it('should not expand index to non-existant index.js', function () {
+    var options = exec({ script: 'index' });
+    var cmd = toCmd(options);
+    assert(cmd.string === 'node index', cmd.string);
+  });
 });
diff --git a/test/cli/parse.test.js b/test/cli/parse.test.js
index b0e1fd2..b01b862 100644
--- a/test/cli/parse.test.js
+++ b/test/cli/parse.test.js
@@ -162,7 +162,7 @@ describe('nodemon CLI parser', function () {
 
   it('should support stand alone `nodemon` command', function () {
     var settings = parse(asCLI(''));
-    assert(settings.execOptions.script === pkg.main);
+    assert(settings.execOptions.script === pkg.main + '.js', `${settings.execOptions.script} === ${pkg.main}`);
   });
 
   it('should put --debug in the right place with coffescript', function () {