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 11, 2021
1 parent 8a06134 commit 452f092
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 9 deletions.
1 change: 1 addition & 0 deletions lib/base-command.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Base class for npm.commands[cmd]
const usageUtil = require('./utils/usage.js')
const mapWorkspaces = require('@npmcli/map-workspaces')

class BaseCommand {
constructor (npm) {
Expand Down
10 changes: 10 additions & 0 deletions lib/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,19 @@ 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
77 changes: 68 additions & 9 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,20 @@ class RunScript extends BaseCommand {
this.list(args).then(() => cb()).catch(cb)
}

async run (args) {
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, topLevelPath) {
const path = this.npm.localPrefix
topLevelPath = topLevelPath || this.npm.localPrefix
const event = args.shift()
const { scriptShell } = this.npm.flatOptions

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

if (event === 'restart' && !scripts.restart)
Expand Down Expand Up @@ -102,9 +111,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 +145,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 +160,54 @@ 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) {
for (const w of workspaces.values()) {
const pkg = await rpj(`${w}/package.json`)
}
}

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

0 comments on commit 452f092

Please sign in to comment.