import { exec , SpawnOptions } from 'child_process' ; import * as spawn from 'cross-spawn' ; import * as fs from 'fs' ; import * as path from 'path' ; import * as copy from 'recursive-copy' ; import * as util from 'util' ; const asyncExec = util . promisify ( exec ) ; export default { isEmptyDir ( dir ) { const files = fs . readdirSync ( dir ) ; return files . length === 0 ; } , ensureRequire ( path ) { if ( ! fs . existsSync ( path ) ) { throw Error ( `${ path } cannot be found, please check` ) ; } delete require . cache [ path ] ; return require ( path ) ; } , async asyncExec ( cmd ) { return asyncExec ( cmd ) ; } , async asyncSpawn ( cmd , args = [ ] , options = { } ) { const child = spawn ( cmd , args , { stdio : 'inherit' , ... options , } ) ; return new Promise ( ( resolve , reject ) => { child . on ( 'error' , reject ) ; child . on ( 'exit' , code => { if ( code === 0 ) { resolve ( ) ; } else { const err = new Error ( `child exited with code ${ code }` ) ; reject ( err ) ; } } ) ; } ) ; } , restoreFlags ( flags ) { const list = [ ] ; Object . keys ( flags ) . forEach ( key => { list . push ( `--${ key }` ) ; if ( typeof flags [ key ] !== 'boolean' ) { list . push ( `${ flags [ key ] }` ) ; } } ) ; return list ; } , async copy ( src , dest , mapping ) { let options = { overwrite : true , dot : true , ... mapping . options , rename ( filePath ) { if ( fs . lstatSync ( src ) . isFile ( ) && mapping . options && mapping . options . rename ) { const name = mapping . options . rename ( path . basename ( src ) ) ; return `../${ name }` ; } return filePath ; } , } ; await copy ( src , dest , options ) ; } , } ;