UNPKG

@coat/cli

Version:

TODO: See #3

107 lines (102 loc) 3.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.runMultipleScripts = runMultipleScripts; var _chalk = _interopRequireDefault(require("chalk")); var _execa = _interopRequireDefault(require("execa")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Returns a listener function that prefixes * all lines with a certain label and writes * the result to the passed stream. * * The stream should not be asynchrounous, and this * function is currently only able to handle process.stdout * and process.stdin safely. * * The implementation of this function is leaned heavily * on concurrently's prefixing mechanism. * See: https://github.com/kimmobrunfeldt/concurrently/blob/master/src/logger.js#L85 * * @param stream The write stream, typically process.stdout or process.stderr * @param prefix The label that will be prepended to each line */ function createStreamPrefixHandler(stream, prefix) { // The first line of a data chunk should // only be prefixed, if the last character // of the previous chunk ended with a new line. // // To prefix the first chunk correctly, lastChar // is initially set to a new line let lastChar = "\n"; return data => { // replace some ANSI code that would impact clearing lines // See concurrently issue #70: // https://github.com/kimmobrunfeldt/concurrently/pull/70 const text = data.toString().replace(/\u2026/g, "..."); const lines = text // Split the current chunk by new lines to // modify each line individually .split("\n").map((line, index, array) => { if ( // Prefix all lines except the first and the // last line - which is an empty line for // each chunk index > 0 && index < array.length - 1 || // The first line should only be prefixed // if the last character of the previous chunk // was a new line index === 0 && lastChar === "\n") { // Color the prefix label using chalk return (0, _chalk.default)`{dim ${prefix} - }${line}`; } // If no prefix is added, the line is returned // unmodified return line; }); // Set the saved lastChar value to the last // character of the current text chunk to determine // whether the next chunk's first line needs to be prefixed lastChar = text[text.length - 1]; // Write all lines to the stream. // // Although stream.write is an asynchrounous method, // using it with process.stdout and process.stderr is // synchrounous and does not need to be awaited. stream.write(lines.join("\n")); }; } async function runMultipleScripts(cwd, scripts, args) { // Promise.all is used here to create a // fail fast behavior that exits once the first // script run fails await Promise.all(scripts.map(async script => { var _task$stdout, _task$stderr; // Run scripts in silent mode to surpress // any npm specific output const npmArgs = ["run", "--silent", script]; if (args !== null && args !== void 0 && args.length) { // Add two dashes ("--") in order for npm run // to pick up the arguments npmArgs.push("--", ...args); } const task = (0, _execa.default)("npm", npmArgs, { cwd, // Setting FORCE_COLOR to true // helps to preserve colored // output in a lot of scenarios, // even though stdio are piped // for these tasks env: { FORCE_COLOR: "true" } }); // Attach stream handlers that prefix // the outputs to stdout and stderr with // the script's name (_task$stdout = task.stdout) === null || _task$stdout === void 0 ? void 0 : _task$stdout.on("data", createStreamPrefixHandler(process.stdout, script)); (_task$stderr = task.stderr) === null || _task$stderr === void 0 ? void 0 : _task$stderr.on("data", createStreamPrefixHandler(process.stderr, script)); await task; })); }