From 1b6013a9c855d48159ffea0d240717f23d7e8e01 Mon Sep 17 00:00:00 2001 From: Vladimir Grinenko Date: Sun, 16 Oct 2016 00:59:18 +0300 Subject: [PATCH] Use native npm ls to find modules --- index.js | 105 ++++++++++++++++++++++++++++++++++----------------- package.json | 4 +- 2 files changed, 72 insertions(+), 37 deletions(-) diff --git a/index.js b/index.js index 048313c..f49d969 100644 --- a/index.js +++ b/index.js @@ -2,9 +2,7 @@ var PLUGIN_PREFIX = 'bem-tools-'; var fs = require('fs'), path = require('path'), - npmls = require('npmls'), - npmRootPath = require('global-modules'), - uniq = require('lodash.uniq'); + npm = require('npm'); var bem = require('coa').Cmd() .name(process.argv[1]) @@ -21,40 +19,81 @@ var bem = require('coa').Cmd() }) .end(); -var globalModules = [], - localModules = []; +function getBemToolsPlugins() { + var globalModules, localModules; -try { - globalModules = npmls(true); -} catch (err) { - if (err.code !== 'ENOENT') throw new Error(err); -} + return new Promise(function(resolve, reject) { + npm.load(function() { + npm.config.set('global', true); + require('npm/lib/ls')([], true, function(err, ls) { + if (err) return reject(err); + + globalModules = _getBemToolsPlugins(ls.dependencies); + + if (localModules) { + resolve(Object.assign(globalModules, localModules)); + } + }); + + npm.config.set('global', false) + require('npm/lib/ls')([], true, function(err, ls) { + if (err) return reject(err); + + localModules = _getBemToolsPlugins(ls.dependencies); + + if (globalModules) { + resolve(Object.assign(globalModules, localModules)); + } + }); + }); + }); +}; + +function _getBemToolsPlugins(tree) { + var plugins = {}, + deps = Object.keys(tree); + + deps.forEach(function(depName) { + var dep = tree[depName]; -try { - localModules = npmls(); -} catch (err) { - if (err.code !== 'ENOENT') throw new Error(err); + if (!plugins[depName] && depName !== 'bem-tools-core' && depName.indexOf(PLUGIN_PREFIX) === 0) { + plugins[depName] = dep._where; + } + }); + + // higher level deps override inner ones + deps.forEach(function(depName) { + var dep = tree[depName] || {}; + + if (dep.dependencies) { + plugins = Object.assign(_getBemToolsPlugins(dep.dependencies), plugins); + } + }); + + return plugins; } -var plugins = uniq(localModules.concat(globalModules).filter(function(module) { - return module.indexOf(PLUGIN_PREFIX) === 0 && module !== 'bem-tools-core'; -})); - -plugins.forEach(function(plugin) { - var commandName = plugin.replace(PLUGIN_PREFIX, ''), - localPluginDir = path.join('node_modules', plugin), - globalPluginDir = path.join(npmRootPath, plugin); - pluginPath = path.resolve(path.join(fs.existsSync(localPluginDir) ? localPluginDir: globalPluginDir, 'cli')), - pluginModule = null; - try { - pluginModule = require(pluginPath); - } catch(err) { - // TODO: implement verbose logging - // console.warn('Cannot find module', plugin); - } +getBemToolsPlugins().then(function(plugins) { + Object.keys(plugins).forEach(function(plugin) { + var commandName = plugin.replace(PLUGIN_PREFIX, ''), + localPluginDir = path.join('node_modules', plugin), + // globalPluginDir = path.join(npmRootPath, plugin); + // pluginPath = path.resolve(path.join(fs.existsSync(localPluginDir) ? localPluginDir: globalPluginDir, 'cli')), + pluginPath = path.resolve(plugins[plugin], 'node_modules', plugin, 'cli'), + pluginModule = null; - pluginModule && bem.cmd().name(commandName).apply(pluginModule).end(); -}); + try { + pluginModule = require(pluginPath); + } catch(err) { + // TODO: implement verbose logging + // console.warn('Cannot find module', plugin); + } + + pluginModule && bem.cmd().name(commandName).apply(pluginModule).end(); + }); + + bem.run(process.argv.slice(2)); +}).catch(console.error); bem.act(function(opts, args) { if (!Object.keys(opts).length && !Object.keys(args).length) { @@ -62,6 +101,4 @@ bem.act(function(opts, args) { } }); -bem.run(process.argv.slice(2)); - module.exports = bem; diff --git a/package.json b/package.json index 485dbd0..0c3bf27 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,6 @@ "license": "MPL-2.0", "dependencies": { "coa": "^1.0.1", - "lodash.uniq": "^4.2.1", - "npmls": "^3.0.0", - "global-modules": "^0.2.0" + "npm": "^3.10.8" } }