From 212305dadbf59cfc4841243b3a777c359e47a0f1 Mon Sep 17 00:00:00 2001 From: sripberger Date: Mon, 24 Jun 2019 10:11:36 -0400 Subject: [PATCH] Add localOnly argument to generator lookup (#113) * Add localOnly argument to generator lookup * Simplify hanlding of omitted localOnly argument --- lib/resolver.js | 66 ++++++++++++++++++++++++++++++++++++++---------- test/resolver.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 14 deletions(-) diff --git a/lib/resolver.js b/lib/resolver.js index a56ea481..cf09c872 100644 --- a/lib/resolver.js +++ b/lib/resolver.js @@ -28,11 +28,19 @@ const resolver = module.exports; * So this index file `node_modules/generator-dummy/lib/generators/yo/index.js` would be * registered as `dummy:yo` generator. * + * @param {boolean} [localOnly = false] - Set trueto skip lookups of + * globally-installed generators. * @param {function} cb - Callback called once the lookup is done. Take err as first * parameter. */ -resolver.lookup = function (cb) { - const generatorsModules = this.findGeneratorsIn(this.getNpmPaths().reverse()); +resolver.lookup = function (localOnly = false, cb) { + // Resolve signature where localOnly is omitted. + if (typeof localOnly === 'function') { + cb = localOnly; + localOnly = false; + } + + const generatorsModules = this.findGeneratorsIn(this.getNpmPaths(localOnly).reverse()); const patterns = []; for (const lookup of this.lookups) { @@ -123,9 +131,50 @@ resolver._tryRegistering = function (generatorReference) { /** * Get the npm lookup directories (`node_modules/`) + * @param {boolean} [localOnly = false] - Set true to exclude global lookup + * directories. + * @return {Array} lookup paths + */ +resolver.getNpmPaths = function (localOnly = false) { + // Start with the local paths. + let paths = this._getLocalNpmPaths(); + + // Append global paths, unless they should be excluded. + if (!localOnly) { + paths = paths.concat(this._getGlobalNpmPaths()); + } + + return _.uniq(paths); +}; + +/** + * Get the local npm lookup directories + * @private * @return {Array} lookup paths */ -resolver.getNpmPaths = function () { +resolver._getLocalNpmPaths = function () { + const paths = []; + + // Walk up the CWD and add `node_modules/` folder lookup on each level + process.cwd().split(path.sep).forEach((part, i, parts) => { + let lookup = path.join(...parts.slice(0, i + 1), 'node_modules'); + + if (!win32) { + lookup = `/${lookup}`; + } + + paths.push(lookup); + }); + + return _.uniq(paths.reverse()); +}; + +/** + * Get the global npm lookup directories + * @private + * @return {Array} lookup paths + */ +resolver._getGlobalNpmPaths = function () { let paths = []; // Default paths for each system @@ -176,17 +225,6 @@ resolver.getNpmPaths = function () { paths.push(path.join(path.dirname(process.argv[1]), '../..')); } - // Walk up the CWD and add `node_modules/` folder lookup on each level - process.cwd().split(path.sep).forEach((part, i, parts) => { - let lookup = path.join(...parts.slice(0, i + 1), 'node_modules'); - - if (!win32) { - lookup = `/${lookup}`; - } - - paths.push(lookup); - }); - return _.uniq(paths.reverse()); }; diff --git a/test/resolver.js b/test/resolver.js index 8ad9215c..dd862197 100644 --- a/test/resolver.js +++ b/test/resolver.js @@ -107,6 +107,36 @@ describe('Environment Resolver', function () { assert.ok(resolved.indexOf('subdir') !== -1, `Couldn't find 'subdir' in ${resolved}`); }); }); + + describe('when localOnly argument is true', () => { + beforeEach(function () { + this.env = new Environment(); + assert.equal(this.env.namespaces().length, 0, 'ensure env is empty'); + this.env.lookup(true); + }); + + it('register local generators', function () { + assert.ok(this.env.get('dummy:app')); + assert.ok(this.env.get('dummy:yo')); + }); + + it('register generators in scoped packages', function () { + assert.ok(this.env.get('@dummyscope/scoped:app')); + }); + + it('register non-dependency local generator', function () { + assert.ok(this.env.get('jquery:app')); + }); + + it('register symlinked generators', function () { + assert.ok(this.env.get('extend:support')); + }); + + globalLookupTest('does not register global generators', function () { + assert.ok(!this.env.get('dummytest:app')); + assert.ok(!this.env.get('dummytest:controller')); + }); + }); }); describe('#getNpmPaths()', () => { @@ -204,6 +234,41 @@ describe('Environment Resolver', function () { }); }); + describe('when localOnly argument is true', () => { + afterEach(() => { + delete process.env.NODE_PATH; + delete process.env.NVM_PATH; + }); + + it('walk up the CWD lookups dir', function () { + const paths = this.env.getNpmPaths(); + assert.equal(paths[0], path.join(process.cwd(), 'node_modules')); + assert.equal(paths[1], path.join(process.cwd(), '../node_modules')); + }); + + it('does not append NODE_PATH', function () { + process.env.NODE_PATH = '/some/dummy/path'; + assert(this.env.getNpmPaths(true).indexOf(process.env.NODE_PATH) === -1); + }); + + it('does not append NVM_PATH', function () { + process.env.NVM_PATH = '/some/dummy/path'; + assert(this.env.getNpmPaths(true).indexOf(path.join(path.dirname(process.env.NVM_PATH), 'node_modules')) === -1); + }); + + it('does not append best bet', function () { + assert(this.env.getNpmPaths(true).indexOf(this.bestBet) === -1); + }); + + it('does not append default NPM dir depending on your OS', function () { + if (process.platform === 'win32') { + assert(this.env.getNpmPaths(true).indexOf(path.join(process.env.APPDATA, 'npm/node_modules')) === -1); + } else { + assert(this.env.getNpmPaths(true).indexOf('/usr/lib/node_modules') === -1); + } + }); + }); + describe('with npm global prefix', () => { it('append npm modules path depending on your OS', function () { const npmPrefix = '/npm_prefix';