import * as path from 'path' ; import glob from 'glob' ; import ServiceElectron from '../service.electron' ; import Logger from '../../tools/env.logger' ; import { CLIAction , TAction } from './cli.action' ; import { exist } from '../../tools/fs' ; import { IPCMessages } from '../service.electron' ; import { sequences } from '../../tools/sequences' ; export class ConcatFiles extends CLIAction { static KEYS : string [ ] = [ '-c' , '--concat' ] ; private _logger : Logger = new Logger ( 'CLIAction:: ConcatFiles' ) ; public getTask ( pwd , args ) { const self = this ; function verify ( files ) { return new Promise ( ( res , reject ) => { const patterns = [ ] ; files = files . filter ( ( file ) => { if ( file . search ( /[\?\^\!\+@]/gi ) === 0 || file . indexOf ( '*' ) !== - 1 ) { patterns . push ( file ) ; return false ; } else { return true ; } } ) ; Promise . all ( patterns . map ( ( pattern ) => { return new Promise ( ( resolvePattern ) => { glob ( pattern , { cwd : pwd } , ( err , matches ) => { if ( err ) { self . _logger . warn ( `Fail apply pattern "${ pattern }" due error: ${ err . message }` ) ; } else if ( matches . length > 0 ) { files = files . concat ( matches ) ; } resolvePattern ( undefined ) ; } ) ; } ) ; } ) ) . then ( ( ) => { Promise . all ( files . map ( ( file ) => { return exist ( file ) ; } ) ) . then ( ( results ) => { const confirmed = results . map ( ( v , index ) => { return v ? files [ index ] : '' ; } ) . filter ( f => f . trim ( ) !== '' ) ; res ( confirmed ) ; } ) . catch ( reject ) ; } ) ; } ) ; } return new Promise ( ( resolve , reject ) => { let groups = [ ] ; this . _filter ( args , true ) . forEach ( ( arg , i , arr ) => { if ( ConcatFiles . KEYS . indexOf ( arg ) !== - 1 ) { groups . push ( [ ] ) ; } else { groups [ groups . length - 1 ] . push ( path . resolve ( pwd , arg ) ) ; } } ) ; groups = groups . filter ( g => g . length > 0 ) ; const confirmed = [ ] ; Promise . all ( groups . map ( ( g ) => { return verify ( g ) . then ( ( files ) => { if ( files . length > 0 ) { confirmed . push ( files ) ; } } ) . catch ( ( err ) => { this . _logger . debug ( `Fail to verify file list due error: ${ err . message }` ) ; } ) ; } ) ) . then ( ( ) => { if ( confirmed . length === 0 ) { return resolve ( undefined ) ; } this . _logger . debug ( `Confirmed groups: ${ JSON . stringify ( confirmed ) }` ) ; resolve ( this . action . bind ( this , confirmed ) ) ; } ) . catch ( reject ) ; } ) ; } public clear ( args ) { return this . _filter ( args , false ) ; } private action ( groups ) { return new Promise ( ( resolve ) => { sequences ( groups . map ( ( files ) => { return ( ) => { return new Promise ( ( done ) => { ServiceElectron . IPC . request ( new IPCMessages . CLIActionConcatFilesRequest ( { files : files , } ) , IPCMessages . CLIActionConcatFilesResponse ) . then ( ( response ) => { if ( typeof response . error === 'string' && response . error . trim ( ) !== '' ) { this . _logger . warn ( `Fail to merge files due error: ${ response . error }` ) ; } } ) . catch ( ( err ) => { this . _logger . error ( err . message ) ; } ) . finally ( ( ) => { done ( undefined ) ; } ) ; } ) ; } ; } ) , false ) . catch ( ( err ) => { this . _logger . warn ( `Error during applying actions: ${ err . message }` ) ; } ) . finally ( resolve ) ; } ) ; } private _filter ( args , merge ) { let open = false ; return args . filter ( ( arg ) => { if ( ConcatFiles . KEYS . indexOf ( arg ) !== - 1 ) { open = true ; return merge ; } if ( ! open ) { return ! merge ; } if ( arg . indexOf ( '-' ) === 0 ) { open = false ; return ! merge ; } else { return merge ; } } ) ; } }