summaryrefslogtreecommitdiff
path: root/u/process/exec.ts
diff options
context:
space:
mode:
Diffstat (limited to 'u/process/exec.ts')
-rw-r--r--u/process/exec.ts41
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())