Skip to content

Commit 83590d4

Browse files
isaacswraithgar
authored andcommitted
fix(ls): show relative paths from root
Change the output in `npm ls` for symlink dependencies (including workspaces) to show the relative path from the project root, rather than the absolute path of the link target. This makes the output much less noisy and more ergonomic when many workspaces and link dependencies are in use, especially when paths are long. It is arguable that this output might be slightly misleading, since the _actual_ workspace symlink from `${root}/node_modules/b` to `${root}/packages/b` has a link value of `../packages/b`, not just `packages/b`. (Or on Windows, always the full absolute path, because junctions.) Thus, `npm ls b` will not show the same output as `ls -l node_modules/b`. However, `npm ls` shows the logical tree, not the physical tree, so presenting the user with a path that they can use and interpret is more important than presenting them with the strictly accurate details of their filesystem. PR-URL: #3272 Credit: @isaacs Close: #3272 Reviewed-by: @darcyclarke
1 parent 46a9bcb commit 83590d4

File tree

3 files changed

+39
-26
lines changed

3 files changed

+39
-26
lines changed

lib/ls.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const { resolve } = require('path')
1+
const { resolve, relative, sep } = require('path')
2+
const relativePrefix = `.${sep}`
23
const { EOL } = require('os')
34

45
const archy = require('archy')
@@ -298,6 +299,9 @@ const getHumanOutputItem = (node, { args, color, global, long }) => {
298299
? chalk.yellow.bgBlack
299300
: chalk.red.bgBlack
300301
const missingMsg = `UNMET ${isOptional(node) ? 'OPTIONAL ' : ''}DEPENDENCY`
302+
const targetLocation = node.root
303+
? relative(node.root.realpath, node.realpath)
304+
: node.targetLocation
301305
const label =
302306
(
303307
node[_missing]
@@ -321,7 +325,7 @@ const getHumanOutputItem = (node, { args, color, global, long }) => {
321325
: ''
322326
) +
323327
(isGitNode(node) ? ` (${node.resolved})` : '') +
324-
(node.isLink ? ` -> ${node.realpath}` : '') +
328+
(node.isLink ? ` -> ${relativePrefix}${targetLocation}` : '') +
325329
(long ? `${EOL}${node.package.description || ''}` : '')
326330

327331
return augmentItemWithIncludeMetadata(node, { label, nodes: [] })
@@ -445,6 +449,9 @@ const augmentNodesWithMetadata = ({
445449
// revisit that node in tree traversal logic, so we make it so that
446450
// we have a diff obj for deduped nodes:
447451
if (seenNodes.has(node.path)) {
452+
const { realpath, root } = node
453+
const targetLocation = root ? relative(root.realpath, realpath)
454+
: node.targetLocation
448455
node = {
449456
name: node.name,
450457
version: node.version,
@@ -453,6 +460,7 @@ const augmentNodesWithMetadata = ({
453460
path: node.path,
454461
isLink: node.isLink,
455462
realpath: node.realpath,
463+
targetLocation,
456464
[_type]: node[_type],
457465
[_invalid]: node[_invalid],
458466
[_missing]: node[_missing],

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

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ [email protected] {CWD}/tap-testdir-ls-ls---dev
7070

7171
exports[`test/lib/ls.js TAP ls --link > should output tree containing linked deps 1`] = `
7272
[email protected] {CWD}/tap-testdir-ls-ls---link
73-
\`-- [email protected] -> {CWD}/tap-testdir-ls-ls---link/linked-dep
73+
\`-- [email protected] -> ./linked-dep
7474
7575
`
7676

@@ -480,59 +480,59 @@ exports[`test/lib/ls.js TAP ls json read problems > should print empty result 1`
480480

481481
exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should filter by parent folder workspace config 1`] = `
482482
[email protected] {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
483-
+-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/group/e
484-
\`-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/group/f
483+
+-- [email protected] -> ./group/e
484+
\`-- [email protected] -> ./group/f
485485
486486
`
487487

488488
exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should filter single workspace 1`] = `
489489
[email protected] {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
490-
+-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/a
491-
| \`-- [email protected] deduped -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/d
492-
\`-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/d
490+
491+
| \`-- [email protected] deduped -> ./d
492+
\`-- [email protected] -> ./d
493493
494494
`
495495

496496
exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should filter using workspace config 1`] = `
497497
[email protected] {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
498-
\`-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/a
498+
\`-- [email protected] -> ./a
499499
500-
\`-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/d
500+
\`-- [email protected] -> ./d
501501
502502
503503
504504
`
505505

506506
exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should list --all workspaces properly 1`] = `
507507
[email protected] {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
508-
+-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/a
508+
509509
510-
| \`-- [email protected] deduped -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/d
511-
+-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/b
512-
+-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/d
510+
| \`-- [email protected] deduped -> ./d
511+
512+
513513
514514
515-
+-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/group/e
516-
\`-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/group/f
515+
+-- [email protected] -> ./group/e
516+
\`-- [email protected] -> ./group/f
517517
518518
`
519519

520520
exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should list workspaces properly with default configs 1`] = `
521521
[[email protected] {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
522-
[0m+-- [[email protected][39m -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/a[0m
522+
[0m+-- [[email protected][39m -> ./a[0m
523523
| +-- [email protected]
524-
[0m| \`-- [email protected] [90mdeduped[39m -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/d[0m
525-
[0m+-- [[email protected][39m -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/b[0m
526-
[0m+-- [[email protected][39m -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/d[0m
524+
[0m| \`-- [email protected] [90mdeduped[39m -> ./d[0m
525+
[0m+-- [[email protected][39m -> ./b[0m
526+
[0m+-- [[email protected][39m -> ./d[0m
527527
| \`-- [email protected]
528-
[0m+-- [[email protected][39m -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/group/e[0m
529-
[0m\`-- [[email protected][39m -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/group/f[0m
528+
[0m+-- [[email protected][39m -> ./group/e[0m
529+
[0m\`-- [[email protected][39m -> ./group/f[0m
530530

531531
`
532532

533533
exports[`test/lib/ls.js TAP ls loading a tree containing workspaces > should print all tree and filter by dep within only the ws subtree 1`] = `
534534
[email protected] {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
535-
\`-- [email protected] -> {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces/d
535+
\`-- [email protected] -> ./d
536536
537537
538538
@@ -567,8 +567,8 @@ [email protected] {CWD}/tap-testdir-ls-ls-no-args
567567
exports[`test/lib/ls.js TAP ls print deduped symlinks > should output tree containing linked deps 1`] = `
568568
[email protected] {CWD}/tap-testdir-ls-ls-print-deduped-symlinks
569569
570-
| \`-- [email protected] deduped -> {CWD}/tap-testdir-ls-ls-print-deduped-symlinks/b
571-
\`-- [email protected] -> {CWD}/tap-testdir-ls-ls-print-deduped-symlinks/b
570+
| \`-- [email protected] deduped -> ./b
571+
\`-- [email protected] -> ./b
572572
573573
`
574574

test/lib/ls.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,12 @@ const diffDepTypesNmFixture = {
9090
}
9191

9292
let result = ''
93-
const LS = require('../../lib/ls.js')
93+
const LS = t.mock('../../lib/ls.js', {
94+
path: {
95+
...require('path'),
96+
sep: '/',
97+
},
98+
})
9499
const config = {
95100
all: true,
96101
color: false,

0 commit comments

Comments
 (0)