microsoft/vscode-react-native
Publicmirrored from https://github.com/microsoft/vscode-react-nativeAvailable
src/common/node/childProcess.ts
128lines · modeblame
a31b007cunknown10 years ago | 1 | // Copyright (c) Microsoft Corporation. All rights reserved. |
| 2 | // Licensed under the MIT license. See LICENSE file in the project root for details. | |
| 3 | | |
6f8b71fedigeff10 years ago | 4 | import * as nodeChildProcess from "child_process"; |
ce5e88eeYuri Skorokhodov5 years ago | 5 | import { ErrorHelper } from "../error/errorHelper"; |
| 6 | import { InternalErrorCode } from "../error/internalErrorCode"; | |
3fb37ad5unknown10 years ago | 7 | |
c7f1165cdigeff10 years ago | 8 | // Uncomment the following lines to record all spawned processes executions |
3c172a05Artem Egorov8 years ago | 9 | // import {Recorder} from "../../../test/resources/processExecution/recorder"; |
c7f1165cdigeff10 years ago | 10 | // Recorder.installGlobalRecorder(); |
| 11 | | |
3fb37ad5unknown10 years ago | 12 | export interface IExecResult { |
6f8b71fedigeff10 years ago | 13 | process: nodeChildProcess.ChildProcess; |
ce5e88eeYuri Skorokhodov5 years ago | 14 | outcome: Promise<string>; |
3fb37ad5unknown10 years ago | 15 | } |
| 16 | | |
45944d15Meena Kunnathur Balakrishnan10 years ago | 17 | export interface ISpawnResult { |
6f8b71fedigeff10 years ago | 18 | spawnedProcess: nodeChildProcess.ChildProcess; |
5b0582f3digeff10 years ago | 19 | stdin: NodeJS.WritableStream; |
| 20 | stdout: NodeJS.ReadableStream; | |
| 21 | stderr: NodeJS.ReadableStream; | |
ce5e88eeYuri Skorokhodov5 years ago | 22 | outcome: Promise<void>; |
45944d15Meena Kunnathur Balakrishnan10 years ago | 23 | } |
| 24 | | |
3fb37ad5unknown10 years ago | 25 | interface IExecOptions { |
| 26 | cwd?: string; | |
| 27 | stdio?: any; | |
| 28 | env?: any; | |
| 29 | encoding?: string; | |
| 30 | timeout?: number; | |
| 31 | maxBuffer?: number; | |
| 32 | killSignal?: string; | |
| 33 | } | |
| 34 | | |
| 35 | interface ISpawnOptions { | |
| 36 | cwd?: string; | |
| 37 | stdio?: any; | |
| 38 | env?: any; | |
| 39 | detached?: boolean; | |
| 40 | } | |
| 41 | | |
| 42 | export class ChildProcess { | |
88246fe9Meena Kunnathur Balakrishnan10 years ago | 43 | public static ERROR_TIMEOUT_MILLISECONDS = 300; |
6f8b71fedigeff10 years ago | 44 | private childProcess: typeof nodeChildProcess; |
aab2095edigeff10 years ago | 45 | |
ce5e88eeYuri Skorokhodov5 years ago | 46 | constructor({ childProcess = nodeChildProcess } = {}) { |
aab2095edigeff10 years ago | 47 | this.childProcess = childProcess; |
| 48 | } | |
| 49 | | |
ce5e88eeYuri Skorokhodov5 years ago | 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}); | |
3fb37ad5unknown10 years ago | 64 | }); |
| 65 | | |
| 66 | } | |
| 67 | | |
ce5e88eeYuri Skorokhodov5 years ago | 68 | public execToString(command: string, options: IExecOptions = {}): Promise<string> { |
| 69 | return this.exec(command, options).then(result => result.outcome.then(stdout => stdout.toString())); | |
3fb37ad5unknown10 years ago | 70 | } |
| 71 | | |
b3753d4eRedMickey6 years ago | 72 | public execFileSync(command: string, args: string[] = [], options: IExecOptions = {}): Buffer | string { |
| 73 | return this.childProcess.execFileSync(command, args, options); | |
| 74 | } | |
| 75 | | |
dd8375caJiglioNero5 years ago | 76 | public spawn(command: string, args: string[] = [], options: ISpawnOptions = {}, showStdOutputsOnError: boolean = false): ISpawnResult { |
9596aa53digeff10 years ago | 77 | const spawnedProcess = this.childProcess.spawn(command, args, options); |
ce5e88eeYuri Skorokhodov5 years ago | 78 | let outcome: Promise<void> = new Promise((resolve, reject) => { |
dd8375caJiglioNero5 years ago | 79 | |
ce5e88eeYuri Skorokhodov5 years ago | 80 | spawnedProcess.once("error", (error: any) => { |
| 81 | reject(error); | |
| 82 | }); | |
| 83 | | |
dd8375caJiglioNero5 years ago | 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 | | |
ce5e88eeYuri Skorokhodov5 years ago | 95 | spawnedProcess.once("exit", (code: number) => { |
| 96 | if (code === 0) { | |
| 97 | resolve(); | |
| 98 | } else { | |
| 99 | const commandWithArgs = command + " " + args.join(" "); | |
dd8375caJiglioNero5 years ago | 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 | } | |
ce5e88eeYuri Skorokhodov5 years ago | 116 | } |
| 117 | }); | |
3fb37ad5unknown10 years ago | 118 | }); |
c3a987a7Meena Kunnathur Balakrishnan10 years ago | 119 | return { |
ce5e88eeYuri Skorokhodov5 years ago | 120 | spawnedProcess: spawnedProcess, |
| 121 | stdin: spawnedProcess.stdin, | |
| 122 | stdout: spawnedProcess.stdout, | |
| 123 | stderr: spawnedProcess.stderr, | |
| 124 | outcome: outcome, | |
| 125 | }; | |
| 126 | | |
c3a987a7Meena Kunnathur Balakrishnan10 years ago | 127 | } |
3fb37ad5unknown10 years ago | 128 | } |