import db from "debug" ; import execa , { ExecaReturnValue , Options as ExecaOptions } from "execa" ; import { Readable } from "stream" ; export function streamToDebug ( s , d , prefix ? ) { prefix = prefix ? `[${ prefix }] ` : "" ; s . on ( "data" , ( chunk ) => d ( prefix + chunk . toString ( ) ) ) ; s . on ( "error" , ( err ) => d ( prefix , err ) ) ; } export interface DebugExecOptions extends ExecaOptions { printFailure ? : boolean ; } const execDefaults = { printFailure : true , } ; export function debugExec ( cmdDebug , outputDebug ) { let _cmdId = 0 ; const cmdId = ( ) => ++ _cmdId ; const exec = async ( cmd , args , options = { } ) : Promise < ExecaReturnValue > => { const { printFailure , ... opts } = { ... execDefaults , ... options } ; opts . all = true ; const debug = outputDebug . enabled ? outputDebug . extend ( ( cmdId ( ) ) . toString ( ) ) : cmdDebug . enabled ? cmdDebug : null ; if ( debug ) debug ( `Running: ${ cmd } ${ args . join ( " " ) }` ) ; try { const ret = execa ( cmd , args , opts ) ; if ( outputDebug . enabled && debug ) { streamToDebug ( ret . stdout , debug ) ; streamToDebug ( ret . stderr , debug ) ; } return await ret ; } catch ( e ) { if ( e . all ) e . message = `${ e . shortMessage }\n${ e . all }` ; if ( debug && printFailure ) debug ( `FAILED: ${ cmd } ${ args . join ( " " ) }: ${ e . shortMessage || e . message }` ) ; throw e ; } } ; return exec ; }