import chalk from "chalk" ; import { spawn } from "child_process" ; import * as path from "path" ; import { Logger } from "./logger" ; const isWindows = ( ) => process . platform === "win32" ; const commandAliases = isWindows ( ) ? { git : "git.exe" , npm : "npm.cmd" , yarn : "yarn.cmd" , } : { } ; /**
 * Runs shell commands.
 */ export class Shell { /**
     * Logs on important events.
     */ private readonly logger : Logger ; /**
     * Current working directory.
     */ private cwd = "." ; param logger param pathComponents public constructor ( logger , ... pathComponents ) { this . logger = logger ; if ( pathComponents . length !== 0 ) { this . setCwd ( ... pathComponents ) ; } } param rawPathComponents returns public setCwd ( ... rawPathComponents ) { const pathComponents = rawPathComponents . filter ( ( pathComponent ) => pathComponent !== undefined ) as string [ ] ; const cwd = path . resolve ( path . join ( ... pathComponents ) ) ; this . cwd = cwd ; if ( this . logger . onSetCwd !== undefined ) { this . logger . onSetCwd ( { cwd , pathComponents } ) ; } return this ; } param fullCommand returns public async execute ( fullCommand ) { const [ command , ... args ] = fullCommand . split ( " " ) ; const commandAlias = commandAliases [ command ] !== undefined ? ( commandAliases [ command ] as string ) : command ; this . logger . log ( chalk . grey ( `> ${ commandAlias } ${ args . join ( " " ) }` ) ) ; return new Promise < number > ( ( resolve , reject ) : void => { const childProcess = spawn ( commandAlias , args , { cwd : this . cwd , stdio : "inherit" , } ) ; childProcess . on ( "error" , reject ) ; childProcess . on ( "close" , resolve ) ; } ) ; } }