2017-10-28 13:23:56 +02:00
|
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
2022-03-02 17:48:26 +01:00
|
|
|
|
'use strict'
|
|
|
|
|
|
|
2017-10-28 13:23:56 +02:00
|
|
|
|
const { delimiter } = require('path')
|
|
|
|
|
|
const { forEach, fromEvent } = require('promise-toolbox')
|
|
|
|
|
|
const { spawn } = require('child_process')
|
2022-11-10 18:08:48 +01:00
|
|
|
|
const getopts = require('getopts')
|
2017-10-28 13:23:56 +02:00
|
|
|
|
|
|
|
|
|
|
const { getPackages } = require('./utils')
|
|
|
|
|
|
|
|
|
|
|
|
const { env } = process
|
|
|
|
|
|
|
2022-11-25 15:45:52 +01:00
|
|
|
|
async function run(command, opts, verbose) {
|
|
|
|
|
|
const child = spawn(command, {
|
|
|
|
|
|
...opts,
|
|
|
|
|
|
shell: true,
|
|
|
|
|
|
stdio: verbose ? 'inherit' : 'pipe',
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const output = []
|
|
|
|
|
|
if (!verbose) {
|
|
|
|
|
|
function onData(chunk) {
|
|
|
|
|
|
output.push(chunk)
|
|
|
|
|
|
}
|
|
|
|
|
|
child.stderr.on('data', onData)
|
|
|
|
|
|
child.stdout.on('data', onData)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const code = await fromEvent(child, 'exit')
|
|
|
|
|
|
if (code !== 0) {
|
|
|
|
|
|
for (const chunk of output) {
|
|
|
|
|
|
process.stderr.write(chunk)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
throw code
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-28 13:23:56 +02:00
|
|
|
|
// run a script for each package (also run pre and post)
|
|
|
|
|
|
//
|
|
|
|
|
|
// TODO: https://docs.npmjs.com/misc/scripts#environment
|
2017-12-27 10:01:56 +01:00
|
|
|
|
require('exec-promise')(args => {
|
2022-11-10 18:08:48 +01:00
|
|
|
|
const {
|
2022-11-25 15:45:08 +01:00
|
|
|
|
bail,
|
2022-11-10 18:08:48 +01:00
|
|
|
|
concurrency,
|
|
|
|
|
|
parallel,
|
2022-11-25 15:45:52 +01:00
|
|
|
|
verbose,
|
2022-11-10 18:08:48 +01:00
|
|
|
|
_: [script],
|
|
|
|
|
|
} = getopts(args, {
|
2022-11-25 15:45:52 +01:00
|
|
|
|
boolean: ['bail', 'parallel', 'verbose'],
|
2022-11-10 18:08:48 +01:00
|
|
|
|
string: ['concurrency'],
|
|
|
|
|
|
})
|
2017-12-27 10:01:56 +01:00
|
|
|
|
|
|
|
|
|
|
let errors = 0
|
2018-02-09 17:56:03 +01:00
|
|
|
|
return getPackages(true)
|
2022-11-10 18:08:48 +01:00
|
|
|
|
[parallel ? 'map' : 'forEach'](
|
|
|
|
|
|
({ dir, name, package: { scripts } }) => {
|
|
|
|
|
|
if (scripts == null) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2017-10-28 13:23:56 +02:00
|
|
|
|
|
2022-11-10 18:08:48 +01:00
|
|
|
|
const spawnOpts = {
|
|
|
|
|
|
cwd: dir,
|
|
|
|
|
|
env: Object.assign({}, env, {
|
|
|
|
|
|
PATH: `${dir}/node_modules/.bin${delimiter}${env.PATH}`,
|
|
|
|
|
|
}),
|
2017-10-28 13:23:56 +02:00
|
|
|
|
}
|
2022-11-10 18:08:48 +01:00
|
|
|
|
return forEach.call([`pre${script}`, script, `post${script}`], script => {
|
|
|
|
|
|
const command = scripts[script]
|
|
|
|
|
|
if (command !== undefined) {
|
|
|
|
|
|
console.log(`* ${name}:${script} −`, command)
|
2022-11-25 15:45:52 +01:00
|
|
|
|
return run(command, spawnOpts, verbose).catch(code => {
|
2022-11-10 18:08:48 +01:00
|
|
|
|
if (code !== 0) {
|
2022-11-25 15:45:08 +01:00
|
|
|
|
if (bail) {
|
|
|
|
|
|
// eslint-disable-next-line no-throw-literal
|
|
|
|
|
|
throw `${name}:${script} − Error: ` + code
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-11-10 18:08:48 +01:00
|
|
|
|
++errors
|
|
|
|
|
|
console.log(`* ${name}:${script} − Error:`, code)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
{ concurrency: concurrency ? Number(concurrency) : undefined }
|
|
|
|
|
|
)
|
2018-02-09 17:56:03 +01:00
|
|
|
|
.then(() => {
|
|
|
|
|
|
if (errors !== 0) {
|
|
|
|
|
|
throw errors
|
2017-10-28 13:23:56 +02:00
|
|
|
|
}
|
2018-02-09 17:56:03 +01:00
|
|
|
|
})
|
2017-12-27 10:01:56 +01:00
|
|
|
|
})
|