-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.ts
70 lines (64 loc) · 1.63 KB
/
run.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
* Configuration for a sub-process.
*/
export type Run = {
/**
* The arguments for the process.
*/
cmd: string[];
/**
* The directory in which the process should run.
*/
cwd?: string;
/**
* A map of environment variables for the process.
*/
env?: Record<string, string>;
/**
* An optional input string or buffer that will be written to `stdin`.
*/
input?: string | Uint8Array;
};
/**
* Runs a sub-process and retrieves the output.
*
* @param opts is the configuration for the sub-process.
* @returns a buffer that contains the data read from `stdin`.
* @throws if the sub-process terminates with an error. The message is the contents of `stderr`.
*/
export async function run(opts: Run): Promise<Uint8Array> {
const process = Deno.run({
cwd: opts.cwd,
cmd: opts.cmd,
env: opts.env,
stdin: "piped",
stdout: "piped",
stderr: "piped",
});
try {
// Write data to stdin.
let input = opts.input || "";
if (typeof input === "string") {
input = new TextEncoder().encode(input);
}
await process.stdin.write(input);
process.stdin.close();
// Read streams to close them.
// For info see: https://github.com/denoland/deno/issues/4568#issuecomment-772463496
const [stderr, stdout, status] = await Promise.all([
process.stderrOutput(),
process.output(),
process.status(),
]);
// Return stdout, or throw error.
if (status.success) {
return stdout;
} else {
const error = new TextDecoder().decode(stderr);
throw new Error(error);
}
} finally {
// Avoid leaking resources.
process.close();
}
}