diff options
Diffstat (limited to 'u/process/exec.ts')
-rw-r--r-- | u/process/exec.ts | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/u/process/exec.ts b/u/process/exec.ts index a2cdbca..7721f61 100644 --- a/u/process/exec.ts +++ b/u/process/exec.ts @@ -7,19 +7,17 @@ import { Metric, TraceUtil, } from '@emprespresso/pengueno'; -import { promisify } from 'node:util'; -import { exec as execCallback } from 'node:child_process'; -const exec = promisify(execCallback); +import { exec } from 'node:child_process'; export type Command = string[] | string; export type StdStreams = { stdout: string; stderr: string }; export const CmdMetric = Metric.fromName('Exec').asResult(); type Environment = Record<string, string>; -type Options = { env?: Environment; clearEnv?: boolean }; +type Options = { streamTraceable?: Array<'stdout' | 'stderr'>; env?: Environment; clearEnv?: boolean }; export const getStdout = ( cmd: ITraceable<Command, LogMetricTraceSupplier>, - options: Options = {}, + options: Options = { streamTraceable: [] }, ): Promise<IEither<Error, string>> => cmd .flatMap(TraceUtil.withFunctionTrace(getStdout)) @@ -28,7 +26,36 @@ export const getStdout = ( const cmd = tCmd.get(); const _exec = typeof cmd === 'string' ? cmd : cmd.join(' '); const env = options.clearEnv ? options.env : { ...process.env, ...options.env }; - return Either.fromFailableAsync<Error, StdStreams>(exec(_exec, { env })); + return Either.fromFailableAsync<Error, StdStreams>( + new Promise<StdStreams>((res, rej) => { + const proc = exec(_exec, { env }); + let stdout = ''; + proc.stdout?.on('data', (d) => { + const s = d.toString(); + stdout += s; + if (options.streamTraceable?.includes('stdout')) { + tCmd.trace.trace(s); + } + }); + let stderr = ''; + proc.stderr?.on('data', (d) => { + const s = d.toString(); + stdout += s; + if (options.streamTraceable?.includes('stderr')) { + tCmd.trace.trace(s); + } + }); + + proc.on('exit', (code) => { + const streams = { stdout, stderr }; + if (code === 0) { + res(streams); + } else { + rej(new Error(`exited with non-zero code: ${code}`)); + } + }); + }), + ); }) .map( TraceUtil.promiseify((tEitherStdStreams) => @@ -43,7 +70,7 @@ export const getStdout = ( export const getStdoutMany = ( cmds: ITraceable<Array<Command>, LogMetricTraceSupplier>, - options: Options = {}, + options: Options = { streamTraceable: [] }, ): Promise<IEither<Error, Array<string>>> => cmds .coExtend((t) => t.get()) |