1import chalk from 'chalk'; 2 3import logger from '../Logger'; 4import { Package } from '../Packages'; 5import { spawnAsync } from '../Utils'; 6 7const { cyan, gray, red, reset } = chalk; 8 9/** 10 * Executes the specified script (defined in package.json under "scripts") on the given package. 11 */ 12export default async function runPackageScriptAsync( 13 pkg: Package, 14 scriptName: string, 15 args: string[] = [] 16): Promise<void> { 17 if (!pkg.scripts[scriptName]) { 18 // Package doesn't have such script. 19 logger.debug(`♂️ ${cyan(scriptName)} script not found`); 20 return; 21 } 22 const spawnArgs = [scriptName, ...args]; 23 24 logger.log(`♀️ Running ${cyan.italic(`yarn ${spawnArgs.join(' ')}`)}`); 25 26 try { 27 await spawnAsync('yarn', spawnArgs, { 28 stdio: 'pipe', 29 cwd: pkg.path, 30 }); 31 } catch (error) { 32 logger.error(`${cyan(scriptName)} script failed, see process output:`); 33 consoleErrorOutput(error.stdout, 'stdout >', reset); 34 consoleErrorOutput(error.stderr, 'stderr >', red); 35 36 // Rethrow error so we can count how many checks failed 37 throw error; 38 } 39} 40 41function consoleErrorOutput(output: string, label: string, color: (string) => string): void { 42 const lines = output.trim().split(/\r\n?|\n/g); 43 logger.log(lines.map((line) => `${gray(label)} ${color(line)}`).join('\n')); 44} 45