UNPKG

monorepo-run-workspace

Version:

Run scripts in monorepo with colors, streaming and separated panes

121 lines (107 loc) 2.85 kB
const path = require('path') const consola = require('consola') const chalk = require('chalk') const { resolvePatterns } = require('./patterns') const { resolveScriptFolders } = require('./resolve') const { runScripts } = require('./run') /** * @typedef MonorepoRunOptions * @prop {string} script * @prop {string[]} patterns * @prop {string} cwd * @prop {number | 'auto'} concurrency * @prop {boolean} streaming * @prop {number} throttle * @prop {string} ui */ /** * @param {MonorepoRunOptions} options */ exports.monorepoRun = async ({ script, patterns, cwd, concurrency = null, streaming = false, throttle = 0, ui = null, }) => { if (!cwd) { cwd = process.cwd() } if (!patterns) { patterns = resolvePatterns(cwd) } if (!patterns.length) { consola.error(`'patterns' is empty.`) return { folders: [], } } const folders = resolveScriptFolders(script, patterns) if (concurrency === null) { concurrency = folders.length } else if (concurrency === 'auto') { const os = require('os') concurrency = os.cpus().length consola.log(`Concurrency automatically set to ${chalk.bold(concurrency)}`) } concurrency = Math.min(folders.length, concurrency) if (ui) { const { startUI } = require('./ui') await startUI({ script, folders, layout: ui, concurrency }) } else { // Simple progress UI let spinner, spinnerLabels if (!streaming) { const Multispinner = require('multispinner') // One task per folder spinnerLabels = {} for (const folder of folders) { const label = path.relative(process.cwd(), folder) spinnerLabels[folder] = label } spinner = new Multispinner(spinnerLabels, { clear: true, frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'], }) spinner.stop = function () { if (this.clear) this.update.clear() this.update.done() }.bind(spinner) } await runScripts({ script, folders, streaming, throttle, concurrency, }, (folder, status, result) => { if (status === 'running' && spinner) { spinner.spinners[folder].text = spinnerLabels[folder] } else if (status === 'error') { if (spinner) { spinner.stop() } consola.error(result) exports.killAll() process.exit(1) } else if (status === 'completed' && spinner) { spinner.success(folder) } else if (status === 'pending' && spinner) { spinner.spinners[folder].text = `${spinnerLabels[folder]} (💤️ Pending)` } }) if (spinner) { spinner.stop() } } return { folders, } } Object.assign(module.exports, { ...require('./patterns'), ...require('./resolve'), ...require('./run'), })