import path from 'path' ; import { createWriteStream } from 'fs' ; import { readdir , stat , mkdir , rm , copyFile } from 'fs/promises' ; import { series } from 'async' ; import { spawn } from 'child_process' ; import chalk from 'chalk' ; import stripAnsi from 'strip-ansi' ; export interface ILogger { out : ( data : string ) => void ; err : ( data : string ) => void ; } export const defaultLogger = { out : data => process . stdout . write ( data ) , err : data => process . stderr . write ( data ) , } ; export async function copyRecursive ( sourceBasePath , destinationBasePath ) { for ( const filePath of await findRecursive ( sourceBasePath , ( ) => true ) ) { const destinationPath = path . join ( destinationBasePath , path . relative ( sourceBasePath , filePath ) ) ; await mkdir ( path . dirname ( destinationPath ) , { recursive : true } ) ; await copyFile ( filePath , destinationPath ) ; } } export async function findRecursive ( basePath , filter ) { let results = [ ] ; for ( const subPathName of await readdir ( basePath ) ) { const subPath = path . resolve ( `${ basePath }/${ subPathName }` ) ; const fileStat = await stat ( subPath ) ; if ( fileStat . isDirectory ( ) ) { const pathResults = await findRecursive ( subPath , filter ) ; results = results . concat ( pathResults ) ; continue ; } if ( ! fileStat . isFile ( ) ) { continue ; } if ( ! filter ( subPath ) ) { continue ; } results . push ( subPath ) ; } return results ; } export function executeCmd ( logger , verbose , cwd , cmd , args ) { return new Promise ( ( resolve , reject ) => { if ( verbose ) { logOut ( logger , chalk . green ( `Executing: ${ cmd } ${ args . join ( ' ' ) }` ) ) ; } const child = spawn ( cmd , args , { cwd : cwd , windowsHide : true , shell : true , } ) ; child . stdout . on ( 'data' , data => logger . out ( chalk . grey ( data . toString ( ) ) ) ) ; child . stderr . on ( 'data' , data => { const message = data . toString ( ) ; logger . err ( chalk . red ( message ) ) ; if ( message . indexOf ( 'FATAL ERROR' ) > - 1 && message . indexOf ( 'Allocation failed - JavaScript heap out of memory' ) > - 1 ) { reject ( 'Child process has run out of memory' ) ; } } ) ; child . on ( 'error' , err => { reject ( err ) ; } ) ; child . on ( 'exit' , code => { if ( code !== 0 ) { reject ( `Exited with code ${ code }` ) ; } else { resolve ( ) ; } } ) ; } ) ; } export function executeSynchronous < T > ( asyncFunc ) { series ( [ asyncFunc ] , ( error ) => { if ( error ) { throw error ; } } ) ; } export function lowerCaseCompare ( a , b ) { const aLower = a . toLowerCase ( ) ; const bLower = b . toLowerCase ( ) ; if ( aLower === bLower ) { return 0 ; } return aLower < bLower ? - 1 : 1 ; } export function logOut ( logger , line ) { logger . out ( `${ line }\n` ) ; } export function logErr ( logger , line ) { logger . err ( `${ line }\n` ) ; } export async function getLogger ( logFilePath ) { await rm ( logFilePath , { force : true } ) ; const logFileStream = createWriteStream ( logFilePath , { flags : 'a' } ) ; return { out : ( data ) => { process . stdout . write ( data ) ; logFileStream . write ( stripAnsi ( data ) ) ; } , err : ( data ) => { process . stdout . write ( data ) ; logFileStream . write ( stripAnsi ( data ) ) ; } , } ; }