forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproc.ts
More file actions
86 lines (79 loc) · 2.47 KB
/
proc.ts
File metadata and controls
86 lines (79 loc) · 2.47 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import * as cp from 'child_process';
import { sleep } from '../client/common/utils/async';
type OutStream = 'stdout' | 'stderr';
export class ProcOutput {
private readonly output: [OutStream, Buffer][] = [];
public get stdout(): string {
return this.dump('stdout');
}
public get stderr(): string {
return this.dump('stderr');
}
public get combined(): string {
return this.dump();
}
public addStdout(data: Buffer) {
this.output.push(['stdout', data]);
}
public addStderr(data: Buffer) {
this.output.push(['stdout', data]);
}
private dump(which?: OutStream) {
let out = '';
for (const [stream, data] of this.output) {
if (!which || which !== stream) {
continue;
}
out += data.toString();
}
return out;
}
}
export type ProcResult = {
exitCode: number;
stdout: string;
};
interface IRawProc extends cp.ChildProcess {
// Apparently the type declaration doesn't expose exitCode.
// See: https://nodejs.org/api/child_process.html#child_process_subprocess_exitcode
exitCode: number | null;
}
export class Proc {
public readonly raw: IRawProc;
private readonly output: ProcOutput;
private result: ProcResult | undefined;
constructor(raw: cp.ChildProcess, output: ProcOutput) {
this.raw = (raw as unknown) as IRawProc;
this.output = output;
}
public get pid(): number | undefined {
return this.raw.pid;
}
public get exited(): boolean {
return this.raw.exitCode !== null;
}
public async waitUntilDone(): Promise<ProcResult> {
if (this.result) {
return this.result;
}
while (this.raw.exitCode === null) {
await sleep(10); // milliseconds
}
this.result = {
exitCode: this.raw.exitCode,
stdout: this.output.stdout,
};
return this.result;
}
}
export function spawn(executable: string, ...args: string[]) {
// Un-comment this to see the executed command:
//console.log(`|${executable} ${args.join(' ')}|`);
const output = new ProcOutput();
const raw = cp.spawn(executable, args);
raw.stdout.on('data', (data: Buffer) => output.addStdout(data));
raw.stderr.on('data', (data: Buffer) => output.addStderr(data));
return new Proc(raw, output);
}