-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add workspaces support to `npm exec` - Refactored logic to read and filter workspaces into `lib/workspaces/get-workspaces.js` - Add ability to execute a package in the context of each configured workspace Fixes: npm/statusboard#288
- Loading branch information
Showing
5 changed files
with
330 additions
and
46 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
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,33 @@ | ||
const { resolve } = require('path') | ||
const mapWorkspaces = require('@npmcli/map-workspaces') | ||
const minimatch = require('minimatch') | ||
const rpj = require('read-package-json-fast') | ||
|
||
const getWorkspaces = async (filters, { path }) => { | ||
const pkg = await rpj(resolve(path, 'package.json')) | ||
const workspaces = await mapWorkspaces({ cwd: path, pkg }) | ||
const res = filters.length ? new Map() : workspaces | ||
|
||
for (const filterArg of filters) { | ||
for (const [workspaceName, workspacePath] of workspaces.entries()) { | ||
if (filterArg === workspaceName | ||
|| resolve(path, filterArg) === workspacePath | ||
|| minimatch(workspacePath, `${resolve(path, filterArg)}/*`)) | ||
res.set(workspaceName, workspacePath) | ||
} | ||
} | ||
|
||
if (!res.size) { | ||
let msg = '!' | ||
if (filters.length) { | ||
msg = `:\n ${filters.reduce( | ||
(res, filterArg) => `${res} --workspace=${filterArg}`, '')}` | ||
} | ||
|
||
throw new Error(`No workspaces found${msg}`) | ||
} | ||
|
||
return res | ||
} | ||
|
||
module.exports = getWorkspaces |
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 |
---|---|---|
|
@@ -186,7 +186,7 @@ t.test('npm exec foo, already present locally', t => { | |
if (er) | ||
throw er | ||
t.strictSame(MKDIRPS, [], 'no need to make any dirs') | ||
t.match(ARB_CTOR, [{ package: ['foo'], path }]) | ||
t.match(ARB_CTOR, [{ path }]) | ||
t.strictSame(ARB_REIFY, [], 'no need to reify anything') | ||
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') | ||
t.match(RUN_SCRIPTS, [{ | ||
|
@@ -300,7 +300,7 @@ t.test('npm exec foo, not present locally or in central loc', t => { | |
if (er) | ||
throw er | ||
t.strictSame(MKDIRPS, [installDir], 'need to make install dir') | ||
t.match(ARB_CTOR, [{ package: ['foo'], path }]) | ||
t.match(ARB_CTOR, [{ path }]) | ||
t.match(ARB_REIFY, [{add: ['foo@'], legacyPeerDeps: false}], 'need to install foo@') | ||
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') | ||
const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` | ||
|
@@ -340,7 +340,7 @@ t.test('npm exec foo, not present locally but in central loc', t => { | |
if (er) | ||
throw er | ||
t.strictSame(MKDIRPS, [installDir], 'need to make install dir') | ||
t.match(ARB_CTOR, [{ package: ['foo'], path }]) | ||
t.match(ARB_CTOR, [{ path }]) | ||
t.match(ARB_REIFY, [], 'no need to install again, already there') | ||
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') | ||
const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` | ||
|
@@ -380,7 +380,7 @@ t.test('npm exec foo, present locally but wrong version', t => { | |
if (er) | ||
throw er | ||
t.strictSame(MKDIRPS, [installDir], 'need to make install dir') | ||
t.match(ARB_CTOR, [{ package: ['foo'], path }]) | ||
t.match(ARB_CTOR, [{ path }]) | ||
t.match(ARB_REIFY, [{ add: ['[email protected]'], legacyPeerDeps: false }], 'need to add [email protected]') | ||
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') | ||
const PATH = `${resolve(installDir, 'node_modules', '.bin')}${delimiter}${process.env.PATH}` | ||
|
@@ -417,7 +417,7 @@ t.test('npm exec --package=foo bar', t => { | |
if (er) | ||
throw er | ||
t.strictSame(MKDIRPS, [], 'no need to make any dirs') | ||
t.match(ARB_CTOR, [{ package: ['foo'], path }]) | ||
t.match(ARB_CTOR, [{ path }]) | ||
t.strictSame(ARB_REIFY, [], 'no need to reify anything') | ||
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') | ||
t.match(RUN_SCRIPTS, [{ | ||
|
@@ -459,7 +459,7 @@ t.test('npm exec @foo/bar -- --some=arg, locally installed', t => { | |
if (er) | ||
throw er | ||
t.strictSame(MKDIRPS, [], 'no need to make any dirs') | ||
t.match(ARB_CTOR, [{ package: ['@foo/bar'], path }]) | ||
t.match(ARB_CTOR, [{ path }]) | ||
t.strictSame(ARB_REIFY, [], 'no need to reify anything') | ||
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') | ||
t.match(RUN_SCRIPTS, [{ | ||
|
@@ -502,7 +502,7 @@ t.test('npm exec @foo/bar, with same bin alias and no unscoped named bin, locall | |
if (er) | ||
throw er | ||
t.strictSame(MKDIRPS, [], 'no need to make any dirs') | ||
t.match(ARB_CTOR, [{ package: ['@foo/bar'], path }]) | ||
t.match(ARB_CTOR, [{ path }]) | ||
t.strictSame(ARB_REIFY, [], 'no need to reify anything') | ||
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') | ||
t.match(RUN_SCRIPTS, [{ | ||
|
@@ -666,7 +666,7 @@ t.test('npm exec -p foo -c "ls -laF"', t => { | |
if (er) | ||
throw er | ||
t.strictSame(MKDIRPS, [], 'no need to make any dirs') | ||
t.match(ARB_CTOR, [{ package: ['foo'], path }]) | ||
t.match(ARB_CTOR, [{ path }]) | ||
t.strictSame(ARB_REIFY, [], 'no need to reify anything') | ||
t.equal(PROGRESS_ENABLED, true, 'progress re-enabled') | ||
t.match(RUN_SCRIPTS, [{ | ||
|
@@ -1082,3 +1082,56 @@ t.test('forward legacyPeerDeps opt', t => { | |
t.done() | ||
}) | ||
}) | ||
|
||
t.test('workspaces', t => { | ||
npm.localPrefix = t.testdir({ | ||
node_modules: { | ||
'.bin': { | ||
foo: '', | ||
}, | ||
}, | ||
packages: { | ||
a: { | ||
'package.json': JSON.stringify({ | ||
name: 'a', | ||
version: '1.0.0', | ||
bin: 'cli.js', | ||
}), | ||
'cli.js': '', | ||
}, | ||
b: { | ||
'package.json': JSON.stringify({ | ||
name: 'b', | ||
version: '1.0.0', | ||
}), | ||
}, | ||
}, | ||
'package.json': JSON.stringify({ | ||
name: 'root', | ||
version: '1.0.0', | ||
workspaces: ['packages/*'], | ||
}), | ||
}) | ||
|
||
PROGRESS_IGNORED = true | ||
npm.localBin = resolve(npm.localPrefix, 'node_modules/.bin') | ||
|
||
exec.execWorkspaces(['foo', 'one arg', 'two arg'], ['a', 'b'], er => { | ||
if (er) | ||
throw er | ||
|
||
t.match(RUN_SCRIPTS, [{ | ||
pkg: { scripts: { npx: 'foo' }}, | ||
args: ['one arg', 'two arg'], | ||
banner: false, | ||
path: process.cwd(), | ||
stdioString: true, | ||
event: 'npx', | ||
env: { | ||
PATH: [npm.localBin, ...PATH].join(delimiter), | ||
}, | ||
stdio: 'inherit', | ||
}]) | ||
t.end() | ||
}) | ||
}) |
Oops, something went wrong.