Skip to content

Commit

Permalink
feat: add run-script workspaces
Browse files Browse the repository at this point in the history
Add workspaces support to `npm run-script`

Related to: npm/rfcs#117
Fixes: npm/statusboard#276
  • Loading branch information
ruyadorno committed Mar 12, 2021
1 parent 8a06134 commit 4666f7e
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 11 deletions.
9 changes: 9 additions & 0 deletions lib/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,18 @@ const npm = module.exports = new class extends EventEmitter {
})
}

const workspacesEnabled = this.config.get('workspaces')
const workspacesFilters = this.config.get('workspace')
const filterByWorkspaces = workspacesEnabled || workspacesFilters.length > 0

if (this.config.get('usage')) {
console.log(impl.usage)
cb()
} if (filterByWorkspaces) {
impl.execWorkspaces(args, this.config.get('workspace'), er => {
process.emit('timeEnd', `command:${cmd}`)
cb(er)
})
} else {
impl.exec(args, er => {
process.emit('timeEnd', `command:${cmd}`)
Expand Down
86 changes: 75 additions & 11 deletions lib/run-script.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const runScript = require('@npmcli/run-script')
const mapWorkspaces = require('@npmcli/map-workspaces')
const { isServerPackage } = runScript
const readJson = require('read-package-json-fast')
const rpj = require('read-package-json-fast')
const { resolve } = require('path')
const log = require('npmlog')
const didYouMean = require('./utils/did-you-mean.js')
Expand Down Expand Up @@ -34,7 +35,7 @@ class RunScript extends BaseCommand {
if (argv.length === 2) {
// find the script name
const json = resolve(this.npm.localPrefix, 'package.json')
const { scripts = {} } = await readJson(json).catch(er => ({}))
const { scripts = {} } = await rpj(json).catch(er => ({}))
return Object.keys(scripts)
}
}
Expand All @@ -46,12 +47,18 @@ class RunScript extends BaseCommand {
this.list(args).then(() => cb()).catch(cb)
}

async run (args) {
const path = this.npm.localPrefix
const event = args.shift()
execWorkspaces (args, filters, cb) {
if (args.length)
this.runWorkspaces(args, filters).then(() => cb()).catch(cb)
else
this.listWorkspaces(args, filters).then(() => cb()).catch(cb)
}

async run (_args, { path = this.npm.localPrefix, pkg } = {}) {
const [event, ...args] = _args
const { scriptShell } = this.npm.flatOptions

const pkg = await readJson(`${path}/package.json`)
pkg = pkg || (await rpj(`${path}/package.json`))
const { scripts = {} } = pkg

if (event === 'restart' && !scripts.restart)
Expand Down Expand Up @@ -102,9 +109,10 @@ class RunScript extends BaseCommand {
}
}

async list () {
const path = this.npm.localPrefix
const { scripts, name } = await readJson(`${path}/package.json`)
async list (args, path) {
path = path || this.npm.localPrefix
const { scripts, name, _id } = await rpj(`${path}/package.json`)
const pkgid = _id || name

if (!scripts)
return []
Expand Down Expand Up @@ -135,13 +143,13 @@ class RunScript extends BaseCommand {
}

if (cmds.length)
this.npm.output(`Lifecycle scripts included in ${name}:`)
this.npm.output(`Lifecycle scripts included in ${pkgid}:`)

for (const script of cmds)
this.npm.output(prefix + script + indent + scripts[script])

if (!cmds.length && runScripts.length)
this.npm.output(`Scripts available in ${name} via \`npm run-script\`:`)
this.npm.output(`Scripts available in ${pkgid} via \`npm run-script\`:`)
else if (runScripts.length)
this.npm.output('\navailable via `npm run-script`:')

Expand All @@ -150,5 +158,61 @@ class RunScript extends BaseCommand {

return allScripts
}

async workspaces (filters) {
const cwd = this.npm.localPrefix
const pkg = await rpj(resolve(cwd, 'package.json'))
const workspaces = await mapWorkspaces({ cwd, pkg })

for (const w of filters) {
for (const [key, path] of workspaces.entries()) {
if (w !== key && resolve(cwd, w) !== path)
workspaces.delete(key)
}
}

return workspaces
}

async runWorkspaces (args, filters) {
const workspaces = await this.workspaces(filters)

for (const workspacePath of workspaces.values()) {
const pkg = await rpj(`${workspacePath}/package.json`)
await this.run(args, {
path: workspacePath,
pkg,
})
}
}

async listWorkspaces (args, filters) {
const workspaces = await this.workspaces(filters)

if (this.npm.flatOptions.json) {
const res = {}
for (const w of workspaces.values()) {
const { scripts, name, _id } = await rpj(`${w}/package.json`)
const pkgid = _id || name
res[pkgid] = { ...scripts }
}
this.npm.output(JSON.stringify(res, null, 2))
return
}

if (this.npm.flatOptions.parseable) {
for (const w of workspaces.values()) {
const { scripts, name, _id } = await rpj(`${w}/package.json`)
const pkgid = _id || name
for (const [script, cmd] of Object.entries(scripts))
this.npm.output(`${pkgid}:${script}:${cmd}`)
}
return
}

for (const w of workspaces.values())
await this.list(args, w)
}
}

module.exports = RunScript
4 changes: 4 additions & 0 deletions lib/utils/lifecycle-cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ class LifecycleCmd extends BaseCommand {
exec (args, cb) {
this.npm.commands['run-script']([this.constructor.name, ...args], cb)
}

execWorkspaces (args, filters, cb) {
this.npm.commands['run-script']([this.constructor.name, ...args], cb)
}
}
module.exports = LifecycleCmd

0 comments on commit 4666f7e

Please sign in to comment.