Skip to content

Commit 79fd6e0

Browse files
ruyadornoisaacs
authored andcommitted
fix: more dedupe edge cases
PR-URL: #1545 Credit: @ruyadorno Close: #1545 Reviewed-by: @isaacs
1 parent 1f82ba9 commit 79fd6e0

File tree

3 files changed

+150
-12
lines changed

3 files changed

+150
-12
lines changed

lib/ls.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,27 +115,27 @@ const getHumanOutputItem = (node, { args, color, global, long }) => {
115115
const missingColor = isOptional(node)
116116
? chalk.yellow.bgBlack
117117
: chalk.red.bgBlack
118-
const missingMsg = `UNMET ${isOptional(node) ? 'OPTIONAL ' : ''}DEPENDENCY `
118+
const missingMsg = `UNMET ${isOptional(node) ? 'OPTIONAL ' : ''}DEPENDENCY`
119119
const label =
120120
(
121121
node[_missing]
122-
? (color ? missingColor(missingMsg) : missingMsg)
122+
? (color ? missingColor(missingMsg) : missingMsg) + ' '
123123
: ''
124124
) +
125125
`${highlightDepName ? chalk.yellow.bgBlack(printable) : printable}` +
126126
(
127127
node[_dedupe]
128-
? (color ? chalk.gray(' deduped') : ' deduped')
128+
? ' ' + (color ? chalk.gray('deduped') : 'deduped')
129129
: ''
130130
) +
131131
(
132132
node[_invalid]
133-
? (color ? chalk.red.bgBlack(' invalid') : ' invalid')
133+
? ' ' + (color ? chalk.red.bgBlack('invalid') : 'invalid')
134134
: ''
135135
) +
136136
(
137137
isExtraneous(node, { global })
138-
? (color ? chalk.green.bgBlack(' extraneous') : ' extraneous')
138+
? ' ' + (color ? chalk.green.bgBlack('extraneous') : 'extraneous')
139139
: ''
140140
) +
141141
(isGitNode(node) ? ` (${node.resolved})` : '') +
@@ -263,6 +263,9 @@ const augmentNodesWithMetadata = ({
263263
pkgid: node.pkgid,
264264
package: node.package,
265265
path: node.path,
266+
isLink: node.isLink,
267+
realpath: node.realpath,
268+
[_invalid]: node[_invalid],
266269
[_missing]: node[_missing],
267270
[_dedupe]: true
268271
}

tap-snapshots/test-lib-ls.js-TAP.test.js

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,10 @@ [email protected] {CWD}/ls-ls-broken-resolved-field
321321

322322
exports[`test/lib/ls.js TAP ls coloured output > should output tree containing color info 1`] = `
323323
[[email protected] {CWD}/ls-ls-coloured-output
324-
[0m+-- [email protected][31m[40m invalid[49m[39m[0m
324+
[0m+-- [email protected] [31m[40minvalid[49m[39m[0m
325325
| \`-- [email protected]
326-
[0m+-- [31m[40mUNMET DEPENDENCY [49m[39mipsum@^1.0.0[0m
327-
[0m\`-- [email protected][32m[40m extraneous[49m[39m[0m
326+
[0m+-- [31m[40mUNMET DEPENDENCY[49m[39m ipsum@^1.0.0[0m
327+
[0m\`-- [email protected] [32m[40mextraneous[49m[39m[0m
328328

329329
`
330330

@@ -336,6 +336,14 @@ [email protected] {CWD}/ls-ls-cycle-deps
336336
337337
`
338338

339+
exports[`test/lib/ls.js TAP ls cycle deps with filter args > should print tree output containing deduped ref 1`] = `
340+
[[email protected] {CWD}/ls-ls-cycle-deps-with-filter-args
341+
\`-- [[email protected]
342+
 \`-- [email protected]
343+
 \`-- [[email protected] deduped
344+

345+
`
346+
339347
exports[`test/lib/ls.js TAP ls deduped missing dep > should output parseable signaling missing peer dep in problems 1`] = `
340348
[email protected] {CWD}/ls-ls-deduped-missing-dep
341349
@@ -379,6 +387,14 @@ exports[`test/lib/ls.js TAP ls global > should print tree and not mark top-level
379387
380388
`
381389

390+
exports[`test/lib/ls.js TAP ls invalid deduped dep > should output tree signaling mismatching peer dep in problems 1`] = `
391+
[[email protected] {CWD}/ls-ls-invalid-deduped-dep
392+
+-- [email protected]
393+
| \`-- [email protected] deduped invalid
394+
\`-- [email protected] invalid
395+

396+
`
397+
382398
exports[`test/lib/ls.js TAP ls invalid peer dep > should output tree signaling mismatching peer dep in problems 1`] = `
383399
[email protected] {CWD}/ls-ls-invalid-peer-dep
384400
@@ -430,6 +446,14 @@ [email protected] {CWD}/ls-ls-no-args
430446
431447
`
432448

449+
exports[`test/lib/ls.js TAP ls print deduped symlinks > should output tree containing linked deps 1`] = `
450+
[email protected] {CWD}/ls-ls-print-deduped-symlinks
451+
452+
| \`-- [email protected] deduped -> {CWD}/ls-ls-print-deduped-symlinks/b
453+
\`-- [email protected] -> {CWD}/ls-ls-print-deduped-symlinks/b
454+
455+
`
456+
433457
exports[`test/lib/ls.js TAP ls resolved points to git ref > should output tree containing git refs 1`] = `
434458
[email protected] {CWD}/ls-ls-resolved-points-to-git-ref
435459
\`-- [email protected] (git+ssh://[email protected]/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c)
@@ -442,8 +466,8 @@ exports[`test/lib/ls.js TAP ls unmet optional dep > should output tree with empt
442466
| \`-- [email protected]
443467
| \`-- [email protected]
444468
+-- [email protected]
445-
[0m+-- [33m[40mUNMET OPTIONAL DEPENDENCY [49m[39mmissing-optional-dep@^1.0.0[0m
446-
[0m+-- [email protected][31m[40m invalid[49m[39m[0m
469+
[0m+-- [33m[40mUNMET OPTIONAL DEPENDENCY[49m[39m missing-optional-dep@^1.0.0[0m
470+
[0m+-- [email protected] [31m[40minvalid[49m[39m[0m
447471
+-- [email protected]
448472
\`-- [email protected]
449473
 \`-- [email protected]
@@ -465,10 +489,10 @@ [email protected] {CWD}/ls-ls-using-aliases
465489
exports[`test/lib/ls.js TAP ls with args and dedupe entries > should print tree output containing deduped ref 1`] = `
466490
[[email protected] {CWD}/ls-ls-with-args-and-dedupe-entries
467491
+-- @npmcli/[email protected]
468-
[0m| \`-- [33m[40m@npmcli/[email protected][49m[39m[90m deduped[39m[0m
492+
[0m| \`-- [33m[40m@npmcli/[email protected][49m[39m [90mdeduped[39m[0m
469493
+-- @npmcli/[email protected]
470494
\`-- @npmcli/[email protected]
471-
[0m \`-- [33m[40m@npmcli/[email protected][49m[39m[90m deduped[39m[0m
495+
[0m \`-- [33m[40m@npmcli/[email protected][49m[39m [90mdeduped[39m[0m
472496

473497
`
474498

test/lib/ls.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,42 @@ test('ls', (t) => {
552552
})
553553
})
554554

555+
t.test('print deduped symlinks', (t) => {
556+
prefix = t.testdir({
557+
'package.json': JSON.stringify({
558+
name: 'print-deduped-symlinks',
559+
version: '1.0.0',
560+
dependencies: {
561+
'a': '^1.0.0',
562+
'b': '^1.0.0'
563+
}
564+
}),
565+
'b': {
566+
'package.json': JSON.stringify({
567+
name: 'b',
568+
version: '1.0.0'
569+
})
570+
},
571+
node_modules: {
572+
a: {
573+
'package.json': JSON.stringify({
574+
name: 'a',
575+
version: '1.0.0',
576+
dependencies: {
577+
b: '^1.0.0'
578+
}
579+
})
580+
},
581+
'b': t.fixture('symlink', '../b')
582+
}
583+
})
584+
ls([], () => {
585+
t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps')
586+
_flatOptions.link = false
587+
t.end()
588+
})
589+
})
590+
555591
t.test('--production', (t) => {
556592
_flatOptions.production = true
557593
prefix = t.testdir({
@@ -719,6 +755,42 @@ test('ls', (t) => {
719755
})
720756
})
721757

758+
t.test('invalid deduped dep', (t) => {
759+
_flatOptions.color = true
760+
prefix = t.testdir({
761+
'package.json': JSON.stringify({
762+
name: 'invalid-deduped-dep',
763+
version: '1.0.0',
764+
dependencies: {
765+
'a': '^1.0.0',
766+
'b': '^2.0.0'
767+
}
768+
}),
769+
node_modules: {
770+
a: {
771+
'package.json': JSON.stringify({
772+
name: 'a',
773+
version: '1.0.0',
774+
dependencies: {
775+
b: '^2.0.0'
776+
}
777+
})
778+
},
779+
b: {
780+
'package.json': JSON.stringify({
781+
name: 'b',
782+
version: '1.0.0'
783+
})
784+
}
785+
}
786+
})
787+
ls([], () => {
788+
t.matchSnapshot(redactCwd(result), 'should output tree signaling mismatching peer dep in problems')
789+
_flatOptions.color = false
790+
t.end()
791+
})
792+
})
793+
722794
t.test('deduped missing dep', (t) => {
723795
prefix = t.testdir({
724796
'package.json': JSON.stringify({
@@ -836,6 +908,45 @@ test('ls', (t) => {
836908
})
837909
})
838910

911+
t.test('cycle deps with filter args', (t) => {
912+
_flatOptions.color = true
913+
prefix = t.testdir({
914+
'package.json': JSON.stringify({
915+
name: 'test-npm-ls',
916+
version: '1.0.0',
917+
dependencies: {
918+
'a': '^1.0.0'
919+
}
920+
}),
921+
node_modules: {
922+
'a': {
923+
'package.json': JSON.stringify({
924+
name: 'a',
925+
version: '1.0.0',
926+
dependencies: {
927+
b: '^1.0.0'
928+
}
929+
})
930+
},
931+
'b': {
932+
'package.json': JSON.stringify({
933+
name: 'b',
934+
version: '1.0.0',
935+
dependencies: {
936+
a: '^1.0.0'
937+
}
938+
})
939+
}
940+
}
941+
})
942+
ls(['a'], (err) => {
943+
t.ifError(err, 'npm ls')
944+
t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
945+
_flatOptions.color = false
946+
t.end()
947+
})
948+
})
949+
839950
t.test('with no args dedupe entries', (t) => {
840951
prefix = t.testdir({
841952
'package.json': JSON.stringify({

0 commit comments

Comments
 (0)