-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Added ELINKGLOBAL error code for when using --global - Added tests for lib/link.js - Do not reify, only load globals when linking a pkg to a local prefix - Fixes: #1777
- Loading branch information
Showing
3 changed files
with
266 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* IMPORTANT | ||
* This snapshot file is auto-generated, but designed for humans. | ||
* It should be checked into source control and tracked carefully. | ||
* Re-generate by setting TAP_SNAPSHOT=1 and running tests. | ||
* Make sure to inspect the output below. Do not ignore changes! | ||
*/ | ||
'use strict' | ||
exports[`test/lib/link.js TAP link global linked pkg to local nm when using args > should create a local symlink to global pkg 1`] = ` | ||
{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/a -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/a | ||
{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/bar -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/@myscope/bar | ||
{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/test-pkg-link -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/test-pkg-link | ||
{CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/link-link-global-linked-pkg-to-local-nm-when-using-args/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 | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
const { resolve } = require('path') | ||
|
||
const Arborist = require('@npmcli/arborist') | ||
const t = require('tap') | ||
const requireInject = require('require-inject') | ||
|
||
const redactCwd = (path) => { | ||
const normalizePath = p => p | ||
.replace(/\\+/g, '/') | ||
.replace(/\r\n/g, '\n') | ||
return normalizePath(path) | ||
.replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}') | ||
} | ||
|
||
t.cleanSnapshot = (str) => redactCwd(str) | ||
|
||
let reifyOutput | ||
const npm = { | ||
globalDir: null, | ||
prefix: null, | ||
flatOptions: {}, | ||
config: { | ||
get () { return false } | ||
} | ||
} | ||
const printLinks = async (opts) => { | ||
let res = '' | ||
const arb = new Arborist(opts) | ||
const tree = await arb.loadActual() | ||
const linkedItems = [...tree.inventory.values()] | ||
for (const item of linkedItems) { | ||
if (item.target) | ||
res += `${item.path} -> ${item.target.path}\n` | ||
} | ||
return res | ||
} | ||
|
||
const mocks = { | ||
'../../lib/npm.js': npm, | ||
'../../lib/utils/reify-output.js': () => reifyOutput() | ||
} | ||
|
||
const link = requireInject('../../lib/link.js', mocks) | ||
|
||
t.test('link to globalDir when in current working dir of pkg and no args', (t) => { | ||
t.plan(2) | ||
|
||
const testdir = t.testdir({ | ||
'global-prefix': { | ||
lib: { | ||
node_modules: { | ||
a: { | ||
'package.json': JSON.stringify({ | ||
name: 'a', | ||
version: '1.0.0' | ||
}) | ||
} | ||
} | ||
} | ||
}, | ||
'test-pkg-link': { | ||
'package.json': JSON.stringify({ | ||
name: 'test-pkg-link', | ||
version: '1.0.0' | ||
}) | ||
} | ||
}) | ||
npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') | ||
npm.prefix = resolve(testdir, 'test-pkg-link') | ||
|
||
reifyOutput = async () => { | ||
reifyOutput = undefined | ||
|
||
const links = await printLinks({ | ||
path: resolve(npm.globalDir, '..'), | ||
global: true | ||
}) | ||
|
||
t.matchSnapshot(links, 'should create a global link to current pkg') | ||
} | ||
|
||
link([], (err) => { | ||
t.ifError(err, 'should not error out') | ||
}) | ||
}) | ||
|
||
t.test('link global linked pkg to local nm when using args', (t) => { | ||
t.plan(2) | ||
|
||
const testdir = t.testdir({ | ||
'global-prefix': { | ||
lib: { | ||
node_modules: { | ||
'@myscope': { | ||
foo: { | ||
'package.json': JSON.stringify({ | ||
name: '@myscope/foo', | ||
version: '1.0.0' | ||
}) | ||
}, | ||
bar: { | ||
'package.json': JSON.stringify({ | ||
name: '@myscope/bar', | ||
version: '1.0.0' | ||
}) | ||
}, | ||
linked: t.fixture('symlink', '../../../../scoped-linked') | ||
}, | ||
a: { | ||
'package.json': JSON.stringify({ | ||
name: 'a', | ||
version: '1.0.0' | ||
}) | ||
}, | ||
b: { | ||
'package.json': JSON.stringify({ | ||
name: 'b', | ||
version: '1.0.0' | ||
}) | ||
}, | ||
'test-pkg-link': t.fixture('symlink', '../../../test-pkg-link') | ||
} | ||
} | ||
}, | ||
'test-pkg-link': { | ||
'package.json': JSON.stringify({ | ||
name: 'test-pkg-link', | ||
version: '1.0.0' | ||
}) | ||
}, | ||
'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', | ||
dependencies: { | ||
foo: '^1.0.0' | ||
} | ||
}), | ||
node_modules: { | ||
foo: { | ||
'package.json': JSON.stringify({ | ||
name: 'foo', | ||
version: '1.0.0' | ||
}) | ||
} | ||
} | ||
} | ||
}) | ||
npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') | ||
npm.prefix = resolve(testdir, 'my-project') | ||
|
||
reifyOutput = async () => { | ||
reifyOutput = undefined | ||
|
||
const links = await printLinks({ | ||
path: npm.prefix | ||
}) | ||
|
||
t.matchSnapshot(links, 'should create a local symlink to global pkg') | ||
} | ||
|
||
// installs examples for: | ||
// - test-pkg-link: pkg linked to globalDir from local fs | ||
// - @myscope/linked: scoped pkg linked to globalDir from local fs | ||
// - @myscope/bar: prev installed scoped package available in globalDir | ||
// - a: prev installed package available in globalDir | ||
link(['test-pkg-link', '@myscope/linked', '@myscope/bar', 'a'], (err) => { | ||
t.ifError(err, 'should not error out') | ||
}) | ||
}) | ||
|
||
t.test('completion', (t) => { | ||
const testdir = t.testdir({ | ||
'global-prefix': { | ||
lib: { | ||
node_modules: { | ||
foo: {}, | ||
bar: {}, | ||
lorem: {}, | ||
ipsum: {} | ||
} | ||
} | ||
} | ||
}) | ||
npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules') | ||
|
||
link.completion({}, (err, words) => { | ||
t.ifError(err, 'should not error out') | ||
t.deepEqual( | ||
words, | ||
['bar', 'foo', 'ipsum', 'lorem'], | ||
'should list all package names available in globalDir' | ||
) | ||
t.end() | ||
}) | ||
}) | ||
|
||
t.test('--global option', (t) => { | ||
const _config = npm.config | ||
npm.config = { get () { return true } } | ||
link([], (err) => { | ||
npm.config = _config | ||
|
||
t.match( | ||
err.message, | ||
/link should never be --global/, | ||
'should throw an useful error' | ||
) | ||
|
||
t.end() | ||
}) | ||
}) |