microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
bb77358c8dc7ea46fae9d6aa601a11fde8eed0fd

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/commandPaletteHandler.ts

135lines · 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 vscode from "vscode";
5import * as Q from "q";
6import {CommandExecutor} from "../common/commandExecutor";
7import {SettingsHelper} from "./settingsHelper";
8import {DeviceHelper, IDevice} from "../common/android/deviceHelper";
9import {Log} from "../common/log/log";
10import {Packager} from "../common/packager";
11import {Package} from "../common/node/package";
12import {PackageNameResolver} from "../common/android/packageNameResolver";
13import {PackagerStatus, PackagerStatusIndicator} from "./packagerStatusIndicator";
14import {ReactNativeProjectHelper} from "../common/reactNativeProjectHelper";
15import {TargetPlatformHelper} from "../common/targetPlatformHelper";
16import {TelemetryHelper} from "../common/telemetryHelper";
17import {IOSDebugModeManager} from "../common/ios/iOSDebugModeManager";
18
19export class CommandPaletteHandler {
20 private reactNativePackager: Packager;
21 private reactNativePackageStatusIndicator: PackagerStatusIndicator;
22 private workspaceRoot: string;
23
24 constructor(workspaceRoot: string, reactNativePackager: Packager, packagerStatusIndicator: PackagerStatusIndicator) {
25 this.workspaceRoot = workspaceRoot;
26 this.reactNativePackager = reactNativePackager;
27 this.reactNativePackageStatusIndicator = packagerStatusIndicator;
28 }
29
30 /**
31 * Starts the React Native packager
32 */
33 public startPackager(): Q.Promise<void> {
34 return this.executeCommandInContext("startPackager", () =>
35 this.runStartPackagerCommandAndUpdateStatus());
36 }
37
38 /**
39 * Kills the React Native packager invoked by the extension's packager
40 */
41 public stopPackager(): Q.Promise<void> {
42 return this.executeCommandInContext("stopPackager", () => this.reactNativePackager.stop())
43 .then(() => this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STOPPED));
44 }
45
46 /**
47 * Executes the 'react-native run-android' command
48 */
49 public runAndroid(): Q.Promise<void> {
50 /* If there are multiple devices available, the run-android command will install the application on each and then print a warning.
51 The command will succeed but the application will not be launched on any device.
52 We fix this behavior by checking if there are more than one devices available and running the application on each. */
53 TargetPlatformHelper.checkTargetPlatformSupport("android");
54 return this.executeCommandInContext("runAndroid", () => this.executeReactNativeRunCommand("run-android"))
55 .then(() => {
56 let deviceHelper = new DeviceHelper();
57 let pkg = new Package(this.workspaceRoot);
58
59 return Q.all<any>([
60 pkg.name().then((appName) => new PackageNameResolver(appName).resolvePackageName(this.workspaceRoot)),
61 deviceHelper.getConnectedDevices(),
62 ]).spread<any>((packagName: string, devices: IDevice[]) => {
63 if (devices.length > 1) {
64 let result = Q<void>(void 0);
65 /* if we have more than one device, launch the application on each */
66 devices.forEach((device: IDevice) => {
67 if (device.isOnline) {
68 result = result.then(() => deviceHelper.launchApp(this.workspaceRoot, packagName, device.id));
69 }
70 });
71 return result;
72 } else {
73 return Q.resolve(void 0);
74 }
75 });
76 });
77 }
78
79 /**
80 * Executes the 'react-native run-ios' command
81 */
82 public runIos(): Q.Promise<void> {
83 TargetPlatformHelper.checkTargetPlatformSupport("ios");
84 return this.executeCommandInContext("runIos", () => {
85 // Set the Debugging setting to disabled, because in iOS it's persisted across runs of the app
86 return new IOSDebugModeManager(this.workspaceRoot).setSimulatorJSDebuggingModeSetting(/*enable=*/ false)
87 .catch(() => { }) // If setting the debugging mode fails, we ignore the error and we run the run ios command anyways
88 .then(() => this.executeReactNativeRunCommand("run-ios"));
89 });
90 }
91
92 private runStartPackagerCommandAndUpdateStatus(): Q.Promise<void> {
93 return this.reactNativePackager.start(SettingsHelper.getPackagerPort())
94 .then(() => this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STARTED));
95 }
96
97 /**
98 * Executes a react-native command passed after starting the packager
99 * {command} The command to be executed
100 * {args} The arguments to be passed to the command
101 */
102 private executeReactNativeRunCommand(command: string, args?: string[]): Q.Promise<void> {
103 // Start the packager before executing the React-Native command
104 Log.logMessage("Attempting to start the React Native packager");
105
106 return this.runStartPackagerCommandAndUpdateStatus()
107 .then(() => {
108 return new CommandExecutor(this.workspaceRoot).spawnReactCommand(command, args).outcome;
109 });
110 }
111
112 /**
113 * Ensures that we are in a React Native project and then executes the operation
114 * Otherwise, displays an error message banner
115 * {operation} - a function that performs the expected operation
116 */
117 private executeCommandInContext(rnCommand: string, operation: () => Q.Promise<void> | void): Q.Promise<void> {
118 let reactNativeProjectHelper = new ReactNativeProjectHelper(vscode.workspace.rootPath);
119 return TelemetryHelper.generate("RNCommand", (generator) => {
120 generator.add("command", rnCommand, false);
121 return reactNativeProjectHelper.isReactNativeProject().then(isRNProject => {
122 generator.add("isRNProject", isRNProject, false);
123 if (isRNProject) {
124 // Bring the log channel to focus
125 Log.setFocusOnLogChannel();
126
127 // Execute the operation
128 return operation();
129 } else {
130 vscode.window.showErrorMessage("Current workspace is not a React Native project.");
131 }
132 });
133 });
134 }
135}
136