import chalk from 'chalk' ; import { ToolingLog } from '@kbn/dev-utils' ; import { isErrorLogged , markErrorLogged } from './errors' ; import { Build } from './build' ; import { Config } from './config' ; interface Options { config : Config ; log : ToolingLog ; } export interface GlobalTask { global : true ; description : string ; run ( config , log , builds ) : Promise < void > ; } export interface Task { global ? : false ; description : string ; run ( config , log , build ) : Promise < void > ; } export function createRunner ( { config , log } ) { async function execTask ( desc , task , lastArg ) { log . info ( desc ) ; log . indent ( 4 ) ; const start = Date . now ( ) ; const time = ( ) => { const sec = ( Date . now ( ) - start ) / 1000 ; const minStr = sec > 60 ? `${ Math . floor ( sec / 60 ) } min ` : '' ; const secStr = `${ Math . round ( sec % 60 ) } sec` ; return chalk . dim ( `${ minStr }${ secStr }` ) ; } ; try { await task . run ( config , log , lastArg ) ; log . success ( chalk . green ( '✓' ) , time ( ) ) ; } catch ( error ) { if ( ! isErrorLogged ( error ) ) { log . error ( `failure ${ time ( ) }` ) ; log . error ( error ) ; markErrorLogged ( error ) ; } throw error ; } finally { log . indent ( - 4 ) ; log . write ( '' ) ; } } const builds = [ ] ; builds . push ( new Build ( config ) ) ; /**
     * Run a task by calling its `run()` method with three arguments:
     *    `config`: an object with methods for determining top-level config values, see `./config.js`
     *    `log`: an instance of the `ToolingLog`, see `../../tooling_log/tooling_log.js`
     *    `builds?`: If task does is not defined as `global: true` then it is called for each build and passed each one here.
     */ return async function run ( task ) { if ( task . global ) { await execTask ( chalk `{dim [  global  ]} ${ task . description }` , task , builds ) ; } else { for ( const build of builds ) { await execTask ( `${ build . getLogTag ( ) } ${ task . description }` , task , build ) ; } } } ; }