From a9c4b158c46dd0d0c8d8744a97750ffd0c30cc09 Mon Sep 17 00:00:00 2001 From: nlf Date: Mon, 14 Dec 2020 07:35:18 -0800 Subject: [PATCH] allow for rebuilding by path PR-URL: https://github.com/npm/cli/pull/2342 Credit: @nlf Close: #2342 Reviewed-by: @ruyadorno --- lib/rebuild.js | 13 +++++++++++-- test/lib/rebuild.js | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/lib/rebuild.js b/lib/rebuild.js index e02c89bd79f2..ab34b7f3dfb5 100644 --- a/lib/rebuild.js +++ b/lib/rebuild.js @@ -39,16 +39,25 @@ const getFilterFn = args => { const spec = npa(arg) if (spec.type === 'tag' && spec.rawSpec === '') return spec - if (spec.type !== 'range' && spec.type !== 'version') + + if (spec.type !== 'range' && spec.type !== 'version' && spec.type !== 'directory') throw new Error('`npm rebuild` only supports SemVer version/range specifiers') + return spec }) + return node => specs.some(spec => { - const { version } = node.package + if (spec.type === 'directory') + return node.path === spec.fetchSpec + if (spec.name !== node.name) return false + if (spec.rawSpec === '' || spec.rawSpec === '*') return true + + const { version } = node.package + // TODO: add tests for a package with missing version return semver.satisfies(version, spec.fetchSpec) }) } diff --git a/test/lib/rebuild.js b/test/lib/rebuild.js index dbc37d57af56..d9df048d9057 100644 --- a/test/lib/rebuild.js +++ b/test/lib/rebuild.js @@ -174,8 +174,48 @@ t.test('filter by pkg@', t => { }) }) -t.test('filter must be a semver version/range', t => { - rebuild(['b:git+ssh://github.com/npm/arborist'], err => { +t.test('filter by directory', t => { + const path = t.testdir({ + node_modules: { + a: { + 'index.js': '', + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + bin: 'index.js', + }), + }, + b: { + 'index.js': '', + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + bin: 'index.js', + }), + }, + }, + }) + + npm.prefix = path + + const aBinFile = resolve(path, 'node_modules/.bin/a') + const bBinFile = resolve(path, 'node_modules/.bin/b') + t.throws(() => fs.statSync(aBinFile)) + t.throws(() => fs.statSync(bBinFile)) + + rebuild(['file:node_modules/b'], err => { + if (err) + throw err + + t.throws(() => fs.statSync(aBinFile), 'should not link a bin') + t.ok(() => fs.statSync(bBinFile), 'should link filtered pkg bin') + + t.end() + }) +}) + +t.test('filter must be a semver version/range, or directory', t => { + rebuild(['git+ssh://github.com/npm/arborist'], err => { t.match( err, /Error: `npm rebuild` only supports SemVer version\/range specifiers/,