diff --git a/src/core/exec.ts b/src/core/exec.ts index 916e6a1..2ba6daa 100644 --- a/src/core/exec.ts +++ b/src/core/exec.ts @@ -1,6 +1,7 @@ -import manage from 'manage-path'; import { IOfType } from '~/types'; import _exec from '~/utils/exec'; +import manage from 'manage-path'; +import manager from '~/utils/ps-manager'; export default async function exec( command: string, @@ -17,5 +18,7 @@ export default async function exec( const alter = manage(opts.env); alter.unshift(bin); - return _exec(command, args, fork, opts); + const { ps, promise } = _exec(command, args, fork, opts); + manager.add(ps.pid, promise); + return promise; } diff --git a/src/utils/exec.ts b/src/utils/exec.ts index 8310100..eabe98b 100644 --- a/src/utils/exec.ts +++ b/src/utils/exec.ts @@ -1,19 +1,24 @@ -import { SpawnOptions } from 'child_process'; -import { DEFAULT_STDIO, NODE_PATH } from '~/constants'; +import { + spawn, + fork as _fork, + SpawnOptions, + ChildProcess, + ForkOptions +} from 'child_process'; +import { DEFAULT_STDIO } from '~/constants'; import logger from '~/utils/logger'; import join from 'command-join'; import { IExecOptions } from '~/types'; -import { spawn } from 'exits'; -import errors from './errors'; +import { rejects } from 'errorish'; -export default async function exec( +export default function exec( cmd: string, args: string[], fork: boolean, options: IExecOptions = {} -): Promise { - const opts: SpawnOptions = { - shell: !fork, +): { ps: ChildProcess; promise: Promise } { + const opts: SpawnOptions | ForkOptions = { + shell: fork ? undefined : true, cwd: options.cwd, env: options.env || process.env, stdio: options.stdio || DEFAULT_STDIO @@ -21,11 +26,16 @@ export default async function exec( logger.debug('Executing: ' + join([cmd].concat(args))); - const { promise } = fork - ? spawn(NODE_PATH, [cmd].concat(args), opts) - : spawn(cmd, args, opts); + const ps = fork ? _fork(cmd, args, opts) : spawn(cmd, args, opts); - await promise.catch(async (err) => { - throw new errors.CustomError(`Process failed: ${join([cmd])}`, null, err); - }); + const promise = new Promise((resolve: (arg: void) => void, reject) => { + ps.on('error', (err: any) => reject(err)); + ps.on('close', (code: number) => { + return code + ? reject(Error(`Process failed with code ${code}: ${join([cmd])}`)) + : resolve(); + }); + }).catch(rejects); + + return { ps, promise }; }