diff --git a/lib/commands/ls.js b/lib/commands/ls.js index 073ca0c6992e8..5249958e45547 100644 --- a/lib/commands/ls.js +++ b/lib/commands/ls.js @@ -329,6 +329,11 @@ const getHumanOutputItem = (node, { args, color, global, long }) => { ? ' ' + (color ? chalk.green.bgBlack('extraneous') : 'extraneous') : '' ) + + ( + node.overridden + ? ' ' + (color ? chalk.gray('overridden') : 'overridden') + : '' + ) + (isGitNode(node) ? ` (${node.resolved})` : '') + (node.isLink ? ` -> ${relativePrefix}${targetLocation}` : '') + (long ? `${EOL}${node.package.description || ''}` : '') @@ -347,6 +352,10 @@ const getJsonOutputItem = (node, { global, long }) => { item.resolved = node.resolved } + if (node.overridden) { + item.overridden = true + } + item[_name] = node.name // special formatting for top-level package name @@ -555,6 +564,7 @@ const parseableOutput = ({ global, long, seenNodes }) => { out += node.path !== node.realpath ? `:${node.realpath}` : '' out += isExtraneous(node, { global }) ? ':EXTRANEOUS' : '' out += node[_invalid] ? ':INVALID' : '' + out += node.overridden ? ':OVERRIDDEN' : '' } out += EOL } diff --git a/tap-snapshots/test/lib/commands/ls.js.test.cjs b/tap-snapshots/test/lib/commands/ls.js.test.cjs index 9b6749acfe3bb..f511dec7cf205 100644 --- a/tap-snapshots/test/lib/commands/ls.js.test.cjs +++ b/tap-snapshots/test/lib/commands/ls.js.test.cjs @@ -255,6 +255,12 @@ exports[`test/lib/commands/ls.js TAP ls --parseable no args > should output pars {CWD}/tap-testdir-ls-ls---parseable-no-args/node_modules/dog ` +exports[`test/lib/commands/ls.js TAP ls --parseable overridden dep > should contain overridden outout 1`] = ` +{CWD}/tap-testdir-ls-ls---parseable-overridden-dep:test-overridden@1.0.0 +{CWD}/tap-testdir-ls-ls---parseable-overridden-dep/node_modules/foo:foo@1.0.0 +{CWD}/tap-testdir-ls-ls---parseable-overridden-dep/node_modules/bar:bar@1.0.0:OVERRIDDEN +` + exports[`test/lib/commands/ls.js TAP ls --parseable resolved points to git ref > should output tree containing git refs 1`] = ` {CWD}/tap-testdir-ls-ls---parseable-resolved-points-to-git-ref {CWD}/tap-testdir-ls-ls---parseable-resolved-points-to-git-ref/node_modules/abbrev @@ -567,6 +573,20 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-no-args ` +exports[`test/lib/commands/ls.js TAP ls overridden dep > should contain overridden outout 1`] = ` +test-overridden@1.0.0 {CWD}/tap-testdir-ls-ls-overridden-dep +\`-- foo@1.0.0 + \`-- bar@1.0.0 overridden + +` + +exports[`test/lib/commands/ls.js TAP ls overridden dep w/ color > should contain overridden outout 1`] = ` +test-overridden@1.0.0 {CWD}/tap-testdir-ls-ls-overridden-dep-w-color +\`-- foo@1.0.0 + \`-- bar@1.0.0 overridden + +` + exports[`test/lib/commands/ls.js TAP ls print deduped symlinks > should output tree containing linked deps 1`] = ` print-deduped-symlinks@1.0.0 {CWD}/tap-testdir-ls-ls-print-deduped-symlinks +-- a@1.0.0 diff --git a/test/lib/commands/ls.js b/test/lib/commands/ls.js index f4cd4ef33d58e..7aebe8bd50968 100644 --- a/test/lib/commands/ls.js +++ b/test/lib/commands/ls.js @@ -231,6 +231,88 @@ t.test('ls', t => { t.matchSnapshot(redactCwd(result), 'should output containing problems info') }) + t.test('overridden dep', async t => { + config.all = true + t.teardown(() => { + config.all = false + }) + + npm.prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'test-overridden', + version: '1.0.0', + dependencies: { + foo: '^1.0.0', + }, + overrides: { + bar: '1.0.0', + }, + }), + node_modules: { + foo: { + 'package.json': JSON.stringify({ + name: 'foo', + version: '1.0.0', + dependencies: { + bar: '^2.0.0', + }, + }), + }, + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + }) + + await ls.exec([]) + t.matchSnapshot(redactCwd(result), 'should contain overridden outout') + }) + + t.test('overridden dep w/ color', async t => { + config.all = true + npm.color = true + t.teardown(() => { + config.all = false + npm.color = false + }) + + npm.prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'test-overridden', + version: '1.0.0', + dependencies: { + foo: '^1.0.0', + }, + overrides: { + bar: '1.0.0', + }, + }), + node_modules: { + foo: { + 'package.json': JSON.stringify({ + name: 'foo', + version: '1.0.0', + dependencies: { + bar: '^2.0.0', + }, + }), + }, + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + }) + + await ls.exec([]) + t.matchSnapshot(redactCwd(result), 'should contain overridden outout') + }) + t.test('with filter arg', async t => { npm.color = true npm.prefix = t.testdir({ @@ -1621,6 +1703,47 @@ t.test('ls --parseable', t => { t.matchSnapshot(redactCwd(result), 'should output containing problems info') }) + t.test('overridden dep', async t => { + config.all = true + config.long = true + t.teardown(() => { + config.all = false + config.long = false + }) + npm.prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'test-overridden', + version: '1.0.0', + dependencies: { + foo: '^1.0.0', + }, + overrides: { + bar: '1.0.0', + }, + }), + node_modules: { + foo: { + 'package.json': JSON.stringify({ + name: 'foo', + version: '1.0.0', + dependencies: { + bar: '^2.0.0', + }, + }), + }, + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + }) + + await ls.exec([]) + t.matchSnapshot(redactCwd(result), 'should contain overridden outout') + }) + t.test('with filter arg', async t => { npm.prefix = t.testdir({ 'package.json': JSON.stringify({ @@ -2523,6 +2646,57 @@ t.test('ls --json', t => { ) }) + t.test('overridden dep', async t => { + config.all = true + t.teardown(() => config.all = false) + npm.prefix = t.testdir({ + 'package.json': JSON.stringify({ + name: 'test-overridden', + version: '1.0.0', + dependencies: { + foo: '^1.0.0', + }, + overrides: { + bar: '1.0.0', + }, + }), + node_modules: { + foo: { + 'package.json': JSON.stringify({ + name: 'foo', + version: '1.0.0', + dependencies: { + bar: '^2.0.0', + }, + }), + }, + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + }) + + await ls.exec([]) + t.same(JSON.parse(result), { + name: 'test-overridden', + version: '1.0.0', + dependencies: { + foo: { + version: '1.0.0', + dependencies: { + bar: { + version: '1.0.0', + overridden: true, + }, + }, + }, + }, + }) + }) + t.test('missing deps --long', async t => { t.plan(3) config.long = true