microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
75c7d921c8412f73630c6d1964c571077e286014

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/common/node/childProcess.ts

100lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as nodeChildProcess from "child_process";
5import Q = require("q");
6import {ErrorHelper} from "../error/errorHelper";
7import {InternalErrorCode} from "../error/internalErrorCode";
8
9export interface IExecResult {
10 process: nodeChildProcess.ChildProcess;
11 outcome: Q.Promise<Buffer>;
12}
13
14export interface ISpawnResult {
15 spawnedProcess: nodeChildProcess.ChildProcess;
16 stdin: NodeJS.WritableStream;
17 stdout: NodeJS.ReadableStream;
18 stderr: NodeJS.ReadableStream;
19 startup: Q.Promise<void>; // The app started succesfully
20 outcome: Q.Promise<void>; // The app finished succesfully
21}
22
23interface IExecOptions {
24 cwd?: string;
25 stdio?: any;
26 env?: any;
27 encoding?: string;
28 timeout?: number;
29 maxBuffer?: number;
30 killSignal?: string;
31}
32
33interface ISpawnOptions {
34 cwd?: string;
35 stdio?: any;
36 env?: any;
37 detached?: boolean;
38}
39
40export class ChildProcess {
41 public static ERROR_TIMEOUT_MILLISECONDS = 300;
42 private childProcess: typeof nodeChildProcess;
43
44 constructor({childProcess = nodeChildProcess} = {}) {
45 this.childProcess = childProcess;
46 }
47
48 public exec(command: string, options: IExecOptions = {}): IExecResult {
49 let outcome = Q.defer<Buffer>();
50
51 let execProcess = this.childProcess.exec(command, options, (error: Error, stdout: Buffer, stderr: Buffer) => {
52 if (error) {
53 outcome.reject(ErrorHelper.getNestedError(error, InternalErrorCode.CommandFailed, command));
54 } else {
55 outcome.resolve(stdout);
56 }
57 });
58
59 return { process: execProcess, outcome: outcome.promise };
60 }
61
62 public execToString(command: string, options: IExecOptions = {}): Q.Promise<string> {
63 return this.exec(command, options).outcome.then(stdout => stdout.toString());
64 }
65
66 public spawn(command: string, args: string[] = [], options: ISpawnOptions = {}): ISpawnResult {
67 const startup = Q.defer<void>();
68 const outcome = Q.defer<void>();
69
70 const spawnedProcess = this.childProcess.spawn(command, args, options);
71
72 spawnedProcess.once("error", (error: any) => {
73 startup.reject(error);
74 outcome.reject(error);
75 });
76
77 Q.delay(ChildProcess.ERROR_TIMEOUT_MILLISECONDS).done(() =>
78 startup.resolve(void 0));
79
80 startup.promise.done(() => {}, () => {}); // Most callers don't use startup, and Q prints a warning if we don't attach any .done()
81
82 spawnedProcess.once("exit", (code: number) => {
83 if (code === 0) {
84 outcome.resolve(void 0);
85 } else {
86 const commandWithArgs = command + " " + args.join(" ");
87 outcome.reject(ErrorHelper.getInternalError(InternalErrorCode.CommandFailed, commandWithArgs, code));
88 }
89 });
90
91 return {
92 spawnedProcess: spawnedProcess,
93 stdin: spawnedProcess.stdin,
94 stdout: spawnedProcess.stdout,
95 stderr: spawnedProcess.stderr,
96 startup: startup.promise,
97 outcome: outcome.promise,
98 };
99 }
100}
101