microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
d55f3c22ee18a37c605867c8bf588451292bd24e

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/node/childProcess.ts

128lines · 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 { ErrorHelper } from "../error/errorHelper";
6import { InternalErrorCode } from "../error/internalErrorCode";
7
8// Uncomment the following lines to record all spawned processes executions
9// import {Recorder} from "../../../test/resources/processExecution/recorder";
10// Recorder.installGlobalRecorder();
11
12export interface IExecResult {
13 process: nodeChildProcess.ChildProcess;
14 outcome: Promise<string>;
15}
16
17export interface ISpawnResult {
18 spawnedProcess: nodeChildProcess.ChildProcess;
19 stdin: NodeJS.WritableStream;
20 stdout: NodeJS.ReadableStream;
21 stderr: NodeJS.ReadableStream;
22 outcome: Promise<void>;
23}
24
25interface IExecOptions {
26 cwd?: string;
27 stdio?: any;
28 env?: any;
29 encoding?: string;
30 timeout?: number;
31 maxBuffer?: number;
32 killSignal?: string;
33}
34
35interface ISpawnOptions {
36 cwd?: string;
37 stdio?: any;
38 env?: any;
39 detached?: boolean;
40}
41
42export class ChildProcess {
43 public static ERROR_TIMEOUT_MILLISECONDS = 300;
44 private childProcess: typeof nodeChildProcess;
45
46 constructor({ childProcess = nodeChildProcess } = {}) {
47 this.childProcess = childProcess;
48 }
49
50 public exec(command: string, options: IExecOptions = {}): Promise<IExecResult> {
51 let outcome: Promise<string>;
52 let process: nodeChildProcess.ChildProcess;
53 return new Promise<IExecResult>((resolveRes) => {
54 outcome = new Promise<string>((resolve, reject) => {
55 process = this.childProcess.exec(command, options, (error: Error, stdout: string, stderr: string) => {
56 if (error) {
57 reject(ErrorHelper.getNestedError(error, InternalErrorCode.CommandFailed, command));
58 } else {
59 resolve(stdout);
60 }
61 });
62 });
63 resolveRes({process: process, outcome: outcome});
64 });
65
66 }
67
68 public execToString(command: string, options: IExecOptions = {}): Promise<string> {
69 return this.exec(command, options).then(result => result.outcome.then(stdout => stdout.toString()));
70 }
71
72 public execFileSync(command: string, args: string[] = [], options: IExecOptions = {}): Buffer | string {
73 return this.childProcess.execFileSync(command, args, options);
74 }
75
76 public spawn(command: string, args: string[] = [], options: ISpawnOptions = {}, showStdOutputsOnError: boolean = false): ISpawnResult {
77 const spawnedProcess = this.childProcess.spawn(command, args, options);
78 let outcome: Promise<void> = new Promise((resolve, reject) => {
79
80 spawnedProcess.once("error", (error: any) => {
81 reject(error);
82 });
83
84 const stderrChunks: string[] = [];
85 const stdoutChunks: string[] = [];
86
87 spawnedProcess.stderr.on("data", (data) => {
88 stderrChunks.push(data.toString());
89 });
90
91 spawnedProcess.stdout.on("data", (data) => {
92 stdoutChunks.push(data.toString());
93 });
94
95 spawnedProcess.once("exit", (code: number) => {
96 if (code === 0) {
97 resolve();
98 } else {
99 const commandWithArgs = command + " " + args.join(" ");
100 if (showStdOutputsOnError) {
101 let details = "";
102 if (stdoutChunks.length > 0) {
103 details = details.concat(`\n\tSTDOUT: ${stdoutChunks[stdoutChunks.length-1]}`);
104 }
105 if (stderrChunks.length > 0) {
106 details = details.concat(`\n\tSTDERR: ${stderrChunks.join("\n\t")}`);
107 }
108 if (details === "") {
109 details = "STDOUT and STDERR are empty!";
110 }
111 reject(ErrorHelper.getInternalError(InternalErrorCode.CommandFailedWithDetails, commandWithArgs, details));
112 }
113 else {
114 reject(ErrorHelper.getInternalError(InternalErrorCode.CommandFailed, commandWithArgs, code));
115 }
116 }
117 });
118 });
119 return {
120 spawnedProcess: spawnedProcess,
121 stdin: spawnedProcess.stdin,
122 stdout: spawnedProcess.stdout,
123 stderr: spawnedProcess.stderr,
124 outcome: outcome,
125 };
126
127 }
128}
129