Repository: remy/nodemon
Pull request #1206 (2018-01-03 17:10:51)

Fix/config logging


Patch:
diff --git a/doc/rules.md b/doc/rules.md
index da9cbdc..ef97139 100644
--- a/doc/rules.md
+++ b/doc/rules.md
@@ -12,23 +12,23 @@ Given a nodemon.json file that contains:
 Then nodemon detects changes, but what causes nodemon to restart? The ignored files or the watched files? Which wins?
 
 ```js
-var files = ['server/foo.coffee', 'server/app.js'];
+const files = ['server/foo.coffee', 'server/app.js'];
 
 // afterIgnore = ['server/app.js'] now since foo.coffee matches *.coffee
-var afterIgnore = files.filter(applyIgnore);
+const afterIgnore = files.filter(applyIgnore);
 
 // watch = ['server/foo.coffee'] as it's under the watch
-var watched = files.filter(applyWatch);
+const watched = files.filter(applyWatch);
 ```
 
 What about:
 
 ```js
-var files = ['test/app.js', 'test/app.coffee'];
+const files = ['test/app.js', 'test/app.coffee'];
 
 // afterIgnore = ['test/app.js'] now since test/app.coffee matches *.coffee
-var afterIgnore = files.filter(applyIgnore);
+const afterIgnore = files.filter(applyIgnore);
 
 // watch.length = 2 as watch implies test/*.*
-var watched = files.filter(applyWatch);
+const watched = files.filter(applyWatch);
 ```
diff --git a/faq.md b/faq.md
index efbd349..22ea572 100644
--- a/faq.md
+++ b/faq.md
@@ -38,7 +38,7 @@ nodemon -x 'mocha test/bad.test.js || exit 1'
 
 # Can't install nodemon: permission issue
 
-You may need to install nodemon using `sudo` (which isn't recommended, but I understand it's unavoidable in some environemnts). If the install fails with this appearing in the npm error log, then you need the following workaround.
+You may need to install nodemon using `sudo` (which isn't recommended, but I understand it's unavoidable in some environments). If the install fails with this appearing in the npm error log, then you need the following workaround.
 
 ```
 gyp WARN EACCES user "root" does not have permission to access the dev dir "<some-local-dir>"
@@ -198,9 +198,9 @@ For example, on `lib/app.js` being changed:
 
 ## My .nodemonignore is being ignored
 
-The new `nodemon.json` superceeds the `.nodemonignore` file, so if you have both, the `.nodemonignore` is not used at all.
+The new `nodemon.json` supersedes the `.nodemonignore` file, so if you have both, the `.nodemonignore` is not used at all.
 
-Note that if you have a `nodemon.json` in your `$HOME` path, then this will also supersede the old ignore file.
+Note that if you have a `nodemon.json` in your `$HOME` path, then this will also supersede the old ignore file (and the _legacy_ format config is ignored).
 
 ## nodemon does nothing
 
diff --git a/lib/config/load.js b/lib/config/load.js
index 39b1d05..b3a88be 100644
--- a/lib/config/load.js
+++ b/lib/config/load.js
@@ -93,8 +93,7 @@ function load(settings, options, config, callback) {
       // if we didn't pick up a nodemon.json file & there's no cli ignores
       // then try loading an old style .nodemonignore file
       if (config.loaded.length === 0) {
-        // TODO decide whether this is just confusing...
-        var legacy = loadLegacyIgnore.bind(null, options, ready);
+        var legacy = loadLegacyIgnore.bind(null, options, config, ready);
 
         // first try .nodemonignore, if that doesn't exist, try nodemon-ignore
         return legacy('.nodemonignore', function () {
@@ -118,11 +117,12 @@ function load(settings, options, config, callback) {
  * @param  {String} filename   ignore file (.nodemonignore or nodemon-ignore)
  * @param  {Function} fail     (optional) failure callback
  */
-function loadLegacyIgnore(options, success, filename, fail) {
+function loadLegacyIgnore(options, config, success, filename, fail) {
   var ignoreFile = path.join(process.cwd(), filename);
 
   exists(ignoreFile, function (exists) {
     if (exists) {
+      config.loaded.push(ignoreFile);
       return parse(ignoreFile, function (error, rules) {
         options.ignore = rules.raw;
         success(options);
@@ -172,6 +172,12 @@ function loadFile(options, config, dir, ready) {
   }
 
   var filename = options.configFile || path.join(dir, 'nodemon.json');
+
+  if (config.loaded.indexOf(filename) !== -1) {
+    // don't bother re-parsing the same config file
+    return callback({});
+  }
+
   fs.readFile(filename, 'utf8', function (err, data) {
     if (err) {
       if (err.code === 'ENOENT') {
@@ -188,7 +194,9 @@ function loadFile(options, config, dir, ready) {
 
     try {
       settings = JSON.parse(data.toString('utf8').replace(/^\uFEFF/, ''));
-      config.loaded.push(filename);
+      if (!filename.endsWith('package.json') || settings.nodemonConfig) {
+        config.loaded.push(filename);
+      }
     } catch (e) {
       console.error(e);
       utils.log.fail('Failed to parse config ' + filename);
@@ -202,16 +210,13 @@ function loadFile(options, config, dir, ready) {
 
 function loadPackageJSON(config, ready) {
   if (!ready) {
-    ready = function () { };
+    ready = () => {};
   }
 
-  var dir = process.cwd();
-  var filename = path.join(dir, 'package.json');
-  var packageLoadOptions = { configFile: filename };
-  return loadFile(packageLoadOptions, config, dir, function (settings) {
-    if (settings.nodemonConfig) {
-      utils.log.detail('using config in package.json');
-    }
+  const dir = process.cwd();
+  const filename = path.join(dir, 'package.json');
+  const packageLoadOptions = { configFile: filename };
+  return loadFile(packageLoadOptions, config, dir, settings => {
     ready(settings.nodemonConfig || {});
   });
 }
diff --git a/lib/nodemon.js b/lib/nodemon.js
index c71e2e6..1bd2478 100644
--- a/lib/nodemon.js
+++ b/lib/nodemon.js
@@ -81,12 +81,14 @@ function nodemon(settings) {
     // always echo out the current version
     utils.log.info(version.pinned);
 
+    const cwd = process.cwd();
+
     if (config.options.cwd) {
-      utils.log.detail('process root: ' + process.cwd());
+      utils.log.detail('process root: ' + cwd);
     }
 
-    config.loaded.forEach(function (filename) {
-      utils.log.detail('reading config ' + filename);
+    config.loaded.map(file => file.replace(cwd, '.')).forEach(file => {
+      utils.log.detail('reading config ' + file);
     });
 
     // echo out notices about running state
diff --git a/package-lock.json b/package-lock.json
index a5623e2..aaee6f4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -283,12 +283,6 @@
       "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
       "dev": true
     },
-    "assert-plus": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
-      "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
-      "dev": true
-    },
     "async": {
       "version": "1.4.2",
       "resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz",
@@ -2593,6 +2587,14 @@
         "assert-plus": "0.2.0",
         "jsprim": "1.4.1",
         "sshpk": "1.13.1"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+          "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+          "dev": true
+        }
       }
     },
     "https-proxy-agent": {


Test patch:
diff --git a/test/config/load-logging.test.js b/test/config/load-logging.test.js
new file mode 100644
index 0000000..70e1031
--- /dev/null
+++ b/test/config/load-logging.test.js
@@ -0,0 +1,83 @@
+'use strict';
+/*global describe, it, afterEach, beforeEach, after */
+const load = require('../../lib/config/load');
+const utils = require('../../lib/utils')
+const path = require('path');
+const testUtils = require('../utils');
+const assert = require('assert');
+const noop = {};
+
+describe('config logging', () => {
+  const pwd = process.cwd();
+  const oldHome = utils.home;
+
+  beforeEach(() => {
+    // move to the fixtures directory to allow for config loading
+    process.chdir(path.resolve(pwd, 'test/fixtures'));
+    utils.home = path.resolve(pwd, ['test', 'fixtures', 'global'].join(path.sep));
+  });
+
+  afterEach(() => {
+    process.chdir(pwd);
+    utils.home = oldHome;
+  });
+
+  it('should show package is being used', done => {
+    process.chdir(path.resolve(pwd, 'test/fixtures/packages/package-json-settings'));
+    const config = {};
+
+    load(noop, noop, config, () => {
+      assert.equal(config.loaded.length, 2, 'global nodemon and local package');
+      done();
+    });
+  });
+
+  it('should not read package if no nodemonConfig', done => {
+    utils.home = process.cwd();
+    process.chdir(path.resolve(pwd, 'test/fixtures'));
+    const config = {};
+
+    load(noop, noop, config, () => {
+      const files = config.loaded.map(_ => path.relative(pwd, _));
+      assert.equal(files.length, 1, 'global nodemon');
+      assert.deepEqual(files, ['test/fixtures/nodemon.json'], 'global nodemon');
+      done();
+    });
+  });
+
+  it('should ignore legacy if new format is found', done => {
+    utils.home = process.cwd();
+    process.chdir(path.resolve(pwd, 'test/fixtures/legacy'));
+    const config = {};
+
+    load(noop, noop, config, () => {
+      const loaded = config.loaded.map(_ => path.relative(pwd, _));
+      assert.equal(loaded.length, 1, 'global nodemon is loaded and legacy is ignored');
+      done();
+    });
+  });
+
+  it('should load legacy if no nodemon.json found', done => {
+    utils.home = path.resolve(pwd, 'test/fixtures/configs'); // no valid nodemon.json files
+    process.chdir(path.resolve(pwd, 'test/fixtures/legacy'));
+    const config = {};
+
+    load(noop, noop, config, () => {
+      const loaded = config.loaded.map(_ => path.relative(pwd, _));
+      assert.equal(loaded.length, 1, 'legacy loaded');
+      done();
+    });
+  });
+
+  it('should load nothing if nothing found', done => {
+    utils.home = path.resolve(pwd, 'test/fixtures/configs'); // no valid nodemon.json files
+    process.chdir(pwd);
+    const config = {};
+
+    load(noop, noop, config, () => {
+      const loaded = config.loaded.map(_ => path.relative(pwd, _));
+      assert.deepEqual(loaded, [], 'nothing loaded');
+      done();
+    });
+  });
+});