From 819bacc862c8b8b0de6330985f88305c6077be58 Mon Sep 17 00:00:00 2001 From: Ya-Lin Huang Date: Tue, 10 Dec 2019 15:25:04 -0800 Subject: [PATCH] "npm ls --include-extraneous-dep" to output the complete dependency tree, including all extraneous dependencies --- docs/content/cli-commands/npm-ls.md | 8 ++++++++ docs/content/using-npm/config.md | 8 ++++++++ lib/config/defaults.js | 2 ++ lib/ls.js | 4 ++++ test/tap/nested-extraneous.js | 24 ++++++++++++++++++++---- 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/docs/content/cli-commands/npm-ls.md b/docs/content/cli-commands/npm-ls.md index 64a399155ff60..00fa222652ce1 100644 --- a/docs/content/cli-commands/npm-ls.md +++ b/docs/content/cli-commands/npm-ls.md @@ -117,6 +117,14 @@ Display only dependencies which are linked Whether to represent the tree structure using unicode characters. Set it to false in order to use all-ansi output. +#### include-extraneous-dep + +* Type: Boolean +* Default: false + +Display the complete dependency tree, including the nested dependencies +brought in by extraneous packages. + ### See Also * [npm config](/cli-commands/npm-config) diff --git a/docs/content/using-npm/config.md b/docs/content/using-npm/config.md index a6947b17d58d1..17d930da5af47 100644 --- a/docs/content/using-npm/config.md +++ b/docs/content/using-npm/config.md @@ -563,6 +563,14 @@ If true, npm will not run `prepublish` scripts. If true, npm does not run scripts specified in package.json files. +#### include-extraneous-dep + +* Default: false +* Type: Boolean + +If true, `npm ls` outputs the complete dependency tree, +including the nested dependencies brought in by extraneous packages. + #### init-module * Default: ~/.npm-init.js diff --git a/lib/config/defaults.js b/lib/config/defaults.js index e07da3aaf97f4..616330e347fdc 100644 --- a/lib/config/defaults.js +++ b/lib/config/defaults.js @@ -164,6 +164,7 @@ Object.defineProperty(exports, 'defaults', {get: function () { 'if-present': false, 'ignore-prepublish': false, 'ignore-scripts': false, + 'include-extraneous-dep': false, 'init-module': path.resolve(home, '.npm-init.js'), 'init-author-name': '', 'init-author-email': '', @@ -306,6 +307,7 @@ exports.types = { 'if-present': Boolean, 'ignore-prepublish': Boolean, 'ignore-scripts': Boolean, + 'include-extraneous-dep': Boolean, 'init-module': path, 'init-author-name': String, 'init-author-email': String, diff --git a/lib/ls.js b/lib/ls.js index 78a2b1d791c7d..c84d70130589b 100644 --- a/lib/ls.js +++ b/lib/ls.js @@ -120,6 +120,10 @@ var lsFromTree = ls.fromTree = function (dir, physicalTree, args, silent, cb) { } function pruneNestedExtraneous (data, visited) { + if (npm.config.get('include-extraneous-dep')) { + return + } + visited = visited || [] visited.push(data) for (var i in data.dependencies) { diff --git a/test/tap/nested-extraneous.js b/test/tap/nested-extraneous.js index 1764a41c75279..9affe8fb8d05a 100644 --- a/test/tap/nested-extraneous.js +++ b/test/tap/nested-extraneous.js @@ -11,7 +11,7 @@ var pj = { version: '1.2.3' } -var dep = path.resolve(pkg, 'node_modules', 'dep') +var dep = path.resolve(pkg, 'node_modules', 'nested-extraneous-dep') var deppj = { name: 'nested-extraneous-dep', version: '1.2.3', @@ -20,10 +20,10 @@ var deppj = { } } -var depdep = path.resolve(dep, 'node_modules', 'depdep') +var depdep = path.resolve(dep, 'node_modules', 'nested-extra-depdep') var depdeppj = { name: 'nested-extra-depdep', - version: '1.2.3' + version: '2.3.4' } test('setup', function (t) { @@ -40,13 +40,29 @@ test('test', function (t) { cwd: pkg }, function (er, code, sto, ste) { if (er) throw er - t.notEqual(code, 0) + t.strictEqual(code, 1) + t.similar(ste, /dep@1\.2\.3/) t.notSimilar(ste, /depdep/) + t.similar(sto, /dep@1\.2\.3/) t.notSimilar(sto, /depdep/) t.end() }) }) +test('test include-extraneous-dep', function (t) { + common.npm(['ls', '--include-extraneous-dep'], { + cwd: pkg + }, function (er, code, sto, ste) { + if (er) throw er + t.strictEqual(code, 1) + t.similar(ste, /dep@1\.2\.3/) + t.similar(ste, /depdep/) + t.similar(sto, /dep@1\.2\.3/) + t.similar(sto, /depdep/) + t.end() + }) +}) + test('clean', function (t) { rimraf.sync(pkg) t.end()