From 23df96d3394ba0b69a37f416d7f0c26bb9354975 Mon Sep 17 00:00:00 2001 From: nlf Date: Wed, 13 Jan 2021 09:12:42 -0800 Subject: [PATCH] fix(link): already linked packages w/ global prefix correctly identify already linked packages when global prefix is a symlink PR-URL: https://github.com/npm/cli/pull/2486 Credit: @nlf Close: #2486 Reviewed-by: @wraithgar --- lib/link.js | 3 ++ tap-snapshots/test-lib-link.js-TAP.test.js | 5 ++ test/lib/link.js | 58 ++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/lib/link.js b/lib/link.js index f7e13369c86a2..84f36ada66201 100644 --- a/lib/link.js +++ b/lib/link.js @@ -45,6 +45,9 @@ const link = async args => { // Returns a list of items that can't be fulfilled by // things found in the current arborist inventory const missingArgsFromTree = (tree, args) => { + if (tree.isLink) + return missingArgsFromTree(tree.target, args) + const foundNodes = [] const missing = args.filter(a => { const arg = npa(a) diff --git a/tap-snapshots/test-lib-link.js-TAP.test.js b/tap-snapshots/test-lib-link.js-TAP.test.js index de7f483b60de8..ab1d5c6b830fb 100644 --- a/tap-snapshots/test-lib-link.js-TAP.test.js +++ b/tap-snapshots/test-lib-link.js-TAP.test.js @@ -19,6 +19,11 @@ exports[`test/lib/link.js TAP link pkg already in global space > should create a ` +exports[`test/lib/link.js TAP link pkg already in global space when prefix is a symlink > should create a local symlink to global pkg 1`] = ` +{CWD}/test/lib/link-link-pkg-already-in-global-space-when-prefix-is-a-symlink/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/link-link-pkg-already-in-global-space-when-prefix-is-a-symlink/scoped-linked + +` + exports[`test/lib/link.js TAP link to globalDir when in current working dir of pkg and no args > should create a global link to current pkg 1`] = ` {CWD}/test/lib/link-link-to-globalDir-when-in-current-working-dir-of-pkg-and-no-args/global-prefix/lib/node_modules/test-pkg-link -> {CWD}/test/lib/link-link-to-globalDir-when-in-current-working-dir-of-pkg-and-no-args/test-pkg-link diff --git a/test/lib/link.js b/test/lib/link.js index a478259f7b409..c39026a49163f 100644 --- a/test/lib/link.js +++ b/test/lib/link.js @@ -259,6 +259,64 @@ t.test('link pkg already in global space', (t) => { }) }) +t.test('link pkg already in global space when prefix is a symlink', (t) => { + t.plan(3) + + const testdir = t.testdir({ + 'global-prefix': t.fixture('symlink', './real-global-prefix'), + 'real-global-prefix': { + lib: { + node_modules: { + '@myscope': { + linked: t.fixture('symlink', '../../../../scoped-linked'), + }, + }, + }, + }, + 'scoped-linked': { + 'package.json': JSON.stringify({ + name: '@myscope/linked', + version: '1.0.0', + }), + }, + 'my-project': { + 'package.json': JSON.stringify({ + name: 'my-project', + version: '1.0.0', + }), + }, + }) + npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') + npm.prefix = resolve(testdir, 'my-project') + + npm.config.find = () => 'default' + + const _cwd = process.cwd() + process.chdir(npm.prefix) + + reifyOutput = async () => { + reifyOutput = undefined + process.chdir(_cwd) + npm.config.find = () => null + + const links = await printLinks({ + path: npm.prefix, + }) + + t.equal( + require(resolve(testdir, 'my-project', 'package.json')).dependencies, + undefined, + 'should not save to package.json upon linking' + ) + + t.matchSnapshot(links, 'should create a local symlink to global pkg') + } + + link(['@myscope/linked'], (err) => { + t.ifError(err, 'should not error out') + }) +}) + t.test('completion', (t) => { const testdir = t.testdir({ 'global-prefix': {