diff --git a/lib/commands/link.js b/lib/commands/link.js index 7bce73ed2bb6f..c9169edc9e5c3 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -51,6 +51,8 @@ class Link extends ArboristWorkspaceCmd { { code: 'ELINKGLOBAL' } ) } + // install-links is implicitely false when running `npm link` + this.npm.config.set('install-links', false) // link with no args: symlink the folder to the global location // link with package arg: symlink the global to the local diff --git a/tap-snapshots/test/lib/commands/link.js.test.cjs b/tap-snapshots/test/lib/commands/link.js.test.cjs index e01409e4ce196..0c34bd972dcf9 100644 --- a/tap-snapshots/test/lib/commands/link.js.test.cjs +++ b/tap-snapshots/test/lib/commands/link.js.test.cjs @@ -48,3 +48,8 @@ exports[`test/lib/commands/link.js TAP link ws to globalDir when workspace speci {CWD}/test/lib/commands/tap-testdir-link-link-ws-to-globalDir-when-workspace-specified-and-no-args/global-prefix/lib/node_modules/a -> {CWD}/test/lib/commands/tap-testdir-link-link-ws-to-globalDir-when-workspace-specified-and-no-args/test-pkg-link/packages/a ` + +exports[`test/lib/commands/link.js TAP test linked installed as symlinks > linked package should not be installed 1`] = ` +{CWD}/test/lib/commands/tap-testdir-link-test-linked-installed-as-symlinks/prefix/node_modules/mylink -> {CWD}/test/lib/commands/tap-testdir-link-test-linked-installed-as-symlinks/other/mylink + +` diff --git a/test/lib/commands/link.js b/test/lib/commands/link.js index 5bd7a3f1480ae..d908fa025fbde 100644 --- a/test/lib/commands/link.js +++ b/test/lib/commands/link.js @@ -1,9 +1,9 @@ const t = require('tap') -const { resolve } = require('path') +const { resolve, join } = require('path') const fs = require('fs') const Arborist = require('@npmcli/arborist') -const { fake: mockNpm } = require('../../fixtures/mock-npm') +const { fake: mockNpm, load: fullMockNpm } = require('../../fixtures/mock-npm') const redactCwd = (path) => { const normalizePath = p => p @@ -72,7 +72,6 @@ t.test('link to globalDir when in current working dir of pkg and no args', async path: resolve(npm.globalDir, '..'), global: true, }) - t.matchSnapshot(links, 'should create a global link to current pkg') }) @@ -550,3 +549,34 @@ t.test('hash character in working directory path', async t => { t.matchSnapshot(links, 'should create a global link to current pkg, even within path with hash') }) + +t.test('test linked installed as symlinks', async t => { + // fakeMock is insufficient due to lack of flatOptions + const { npm } = await fullMockNpm(t, { + otherDirs: { + mylink: { + 'package.json': JSON.stringify({ + name: 'mylink', + version: '1.0.0', + }), + }, + }, + }) + + const _cwd = process.cwd() + process.chdir(npm.prefix) + + await npm.exec('link', [ + join('file:../other/mylink'), + ]) + process.chdir(_cwd) + const links = await printLinks({ + path: npm.prefix, + }) + + t.ok(fs.lstatSync(join(npm.prefix, 'node_modules', 'mylink')).isSymbolicLink(), + 'linked path should by symbolic link' + ) + + t.matchSnapshot(links, 'linked package should not be installed') +})