microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
a875cef475b9a3dbed5f54480837fd4956013416

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/commandExecutor.ts

160lines · 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 Q from "q";
5import {ChildProcess} from "child_process";
6import {Log} from "./log/log";
7import {Node} from "./node/node";
8import {ISpawnResult} from "./node/childProcess";
9import {HostPlatformResolver} from "../common/hostPlatform";
10import {ErrorHelper} from "./error/errorHelper";
11import {InternalErrorCode} from "./error/internalErrorCode";
12
13interface EnvironmentOptions {
14 REACT_DEBUGGER?: string;
15}
16
17interface Options {
18 env?: EnvironmentOptions;
19}
20
21export enum CommandStatus {
22 Start = 0,
23 End = 1
24}
25
26export class CommandExecutor {
27 private currentWorkingDirectory: string;
28
29 constructor(currentWorkingDirectory?: string) {
30 this.currentWorkingDirectory = currentWorkingDirectory;
31 }
32
33 public execute(command: string, options: Options = {}): Q.Promise<void> {
34 Log.logCommandStatus(command, CommandStatus.Start);
35 return new Node.ChildProcess().execToString(command, { cwd: this.currentWorkingDirectory, env: options.env })
36 .then(stdout => {
37 Log.logMessage(stdout);
38 Log.logCommandStatus(command, CommandStatus.End);
39 },
40 (reason: Error) =>
41 this.generateRejectionForCommand(command, reason));
42 }
43
44 /**
45 * Spawns a child process with the params passed and returns promise of the spawned ChildProcess
46 * This method does not wait for the spawned process to finish execution
47 * {command} - The command to be invoked in the child process
48 * {args} - Arguments to be passed to the command
49 * {options} - additional options with which the child process needs to be spawned
50 */
51 public spawn(command: string, args: string[], options: Options = {}): ChildProcess {
52 return this.spawnChildProcess(command, args, options).spawnedProcess;
53 }
54
55 /**
56 * Spawns a child process with the params passed
57 * This method waits until the spawned process finishes execution
58 * {command} - The command to be invoked in the child process
59 * {args} - Arguments to be passed to the command
60 * {options} - additional options with which the child process needs to be spawned
61 */
62 public spawnAndWaitForCompletion(command: string, args: string[], options: Options = {}): Q.Promise<void> {
63 return this.spawnChildProcess(command, args, options).outcome;
64 }
65
66 /**
67 * Spawns the React Native packager in a child process.
68 */
69 public spawnReactPackager(args?: string[], options: Options = {}): Q.Promise<ChildProcess> {
70 let deferred = Q.defer<ChildProcess>();
71 let command = HostPlatformResolver.getHostPlatform().getReactNativeCommand();
72 let runArguments = ["start"];
73
74 if (args) {
75 runArguments = runArguments.concat(args);
76 }
77
78 let spawnOptions = Object.assign({}, { cwd: this.currentWorkingDirectory }, options);
79
80 let result = new Node.ChildProcess().spawn(command, runArguments, spawnOptions);
81 result.spawnedProcess.once("error", (error: any) => {
82 deferred.reject(ErrorHelper.getNestedError(error, InternalErrorCode.PackagerStartFailed));
83 });
84
85 result.stderr.on("data", (data: Buffer) => {
86 Log.logMessage(data.toString(), /*formatMessage*/false);
87 });
88
89 result.stdout.on("data", (data: Buffer) => {
90 Log.logMessage(data.toString(), /*formatMessage*/false);
91 });
92
93 // TODO #83 - PROMISE: We need to consume result.outcome here
94 Q.delay(300).done(() => deferred.resolve(result.spawnedProcess));
95 return deferred.promise;
96 }
97
98 /**
99 * Kills the React Native packager in a child process.
100 */
101 public killReactPackager(packagerProcess: ChildProcess): Q.Promise<void> {
102 Log.logMessage("Stopping Packager");
103 if (packagerProcess) {
104 return HostPlatformResolver.getHostPlatform().killProcess(packagerProcess)
105 .then(() => {
106 Log.logMessage("Packager stopped");
107 });
108 } else {
109 Log.logMessage("Packager not found");
110 return Q.resolve<void>(void 0);
111 }
112 }
113
114
115
116 /**
117 * Executes a react native command and waits for its completion.
118 */
119 public spawnAndWaitReactCommand(command: string, args?: string[], options: Options = {}): Q.Promise<void> {
120 return this.spawnChildReactCommandProcess(command, args, options).outcome;
121 }
122
123 public spawnChildReactCommandProcess(command: string, args?: string[], options: Options = {}): ISpawnResult {
124 let runArguments = [command];
125 if (args) {
126 runArguments = runArguments.concat(args);
127 }
128
129 let reactCommand = HostPlatformResolver.getHostPlatform().getReactNativeCommand();
130 return this.spawnChildProcess(reactCommand, runArguments, options);
131 }
132
133 private spawnChildProcess(command: string, args: string[], options: Options = {}): ISpawnResult {
134 let spawnOptions = Object.assign({}, { cwd: this.currentWorkingDirectory }, options);
135 let commandWithArgs = command + " " + args.join(" ");
136
137 Log.logCommandStatus(commandWithArgs, CommandStatus.Start);
138 let result = new Node.ChildProcess().spawnWithExitHandler(command, args, spawnOptions);
139
140 result.stderr.on("data", (data: Buffer) => {
141 Log.logMessage(data.toString(), /*formatMessage*/ false);
142 });
143
144 result.stdout.on("data", (data: Buffer) => {
145 Log.logMessage(data.toString(), /*formatMessage*/ false);
146 });
147
148 result.outcome = result.outcome.then(
149 () =>
150 Log.logCommandStatus(commandWithArgs, CommandStatus.End),
151 reason =>
152 this.generateRejectionForCommand(command, reason));
153
154 return result;
155 }
156
157 private generateRejectionForCommand(command: string, reason: any): Q.Promise<void> {
158 return Q.reject<void>(ErrorHelper.getInternalError(InternalErrorCode.CommandFailed, command, reason));
159 }
160}
161