microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0fc1f1ded677de3d424c138ff2b42948ec8d4f08

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/commandPaletteHandler.ts

118lines · 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 {Log} from "../common/log/log";
9import {Packager} from "../common/packager";
10import {AndroidPlatform} from "../common/android/androidPlatform";
11import {PackagerStatus, PackagerStatusIndicator} from "./packagerStatusIndicator";
12import {ReactNativeProjectHelper} from "../common/reactNativeProjectHelper";
13import {TargetPlatformHelper} from "../common/targetPlatformHelper";
14import {TelemetryHelper} from "../common/telemetryHelper";
15import {IOSDebugModeManager} from "../common/ios/iOSDebugModeManager";
16
17export class CommandPaletteHandler {
18 private reactNativePackager: Packager;
19 private reactNativePackageStatusIndicator: PackagerStatusIndicator;
20 private workspaceRoot: string;
21
22 constructor(workspaceRoot: string, reactNativePackager: Packager, packagerStatusIndicator: PackagerStatusIndicator) {
23 this.workspaceRoot = workspaceRoot;
24 this.reactNativePackager = reactNativePackager;
25 this.reactNativePackageStatusIndicator = packagerStatusIndicator;
26 }
27
28 /**
29 * Starts the React Native packager
30 */
31 public startPackager(): Q.Promise<void> {
32 return this.executeCommandInContext("startPackager", () =>
33 this.runStartPackagerCommandAndUpdateStatus());
34 }
35
36 /**
37 * Kills the React Native packager invoked by the extension's packager
38 */
39 public stopPackager(): Q.Promise<void> {
40 return this.executeCommandInContext("stopPackager", () => this.reactNativePackager.stop())
41 .then(() => this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STOPPED));
42 }
43
44 /**
45 * Executes the 'react-native run-android' command
46 */
47 public runAndroid(): Q.Promise<void> {
48 TargetPlatformHelper.checkTargetPlatformSupport("android");
49 return this.executeCommandInContext("runAndroid", () => this.executeWithPackagerRunning(() => {
50 const packagerPort = SettingsHelper.getPackagerPort();
51 return new AndroidPlatform({ projectRoot: this.workspaceRoot, packagerPort: packagerPort }).runApp(/*shouldLaunchInAllDevices*/true);
52 }));
53 }
54
55
56 /**
57 * Executes the 'react-native run-ios' command
58 */
59 public runIos(): Q.Promise<void> {
60 TargetPlatformHelper.checkTargetPlatformSupport("ios");
61 return this.executeCommandInContext("runIos", () => {
62 // Set the Debugging setting to disabled, because in iOS it's persisted across runs of the app
63 return new IOSDebugModeManager(this.workspaceRoot).setSimulatorJSDebuggingModeSetting(/*enable=*/ false)
64 .catch(() => { }) // If setting the debugging mode fails, we ignore the error and we run the run ios command anyways
65 .then(() => this.executeReactNativeRunCommand("run-ios"));
66 });
67 }
68
69 private runStartPackagerCommandAndUpdateStatus(): Q.Promise<void> {
70 return this.reactNativePackager.start(SettingsHelper.getPackagerPort())
71 .then(() => this.reactNativePackageStatusIndicator.updatePackagerStatus(PackagerStatus.PACKAGER_STARTED));
72 }
73
74 /**
75 * Executes a react-native command passed after starting the packager
76 * {command} The command to be executed
77 * {args} The arguments to be passed to the command
78 */
79 private executeReactNativeRunCommand(command: string, args?: string[]): Q.Promise<void> {
80 return this.executeWithPackagerRunning(() => {
81 return new CommandExecutor(this.workspaceRoot).spawnReactCommand(command, args).outcome;
82 });
83 }
84
85 /**
86 * Executes a lambda function after starting the packager
87 * {lambda} The lambda function to be executed
88 */
89 private executeWithPackagerRunning(lambda: () => Q.Promise<void>): Q.Promise<void> {
90 // Start the packager before executing the React-Native command
91 Log.logMessage("Attempting to start the React Native packager");
92 return this.runStartPackagerCommandAndUpdateStatus().then(lambda);
93 }
94
95 /**
96 * Ensures that we are in a React Native project and then executes the operation
97 * Otherwise, displays an error message banner
98 * {operation} - a function that performs the expected operation
99 */
100 private executeCommandInContext(rnCommand: string, operation: () => Q.Promise<void> | void): Q.Promise<void> {
101 let reactNativeProjectHelper = new ReactNativeProjectHelper(vscode.workspace.rootPath);
102 return TelemetryHelper.generate("RNCommand", (generator) => {
103 generator.add("command", rnCommand, false);
104 return reactNativeProjectHelper.isReactNativeProject().then(isRNProject => {
105 generator.add("isRNProject", isRNProject, false);
106 if (isRNProject) {
107 // Bring the log channel to focus
108 Log.setFocusOnLogChannel();
109
110 // Execute the operation
111 return operation();
112 } else {
113 vscode.window.showErrorMessage("Current workspace is not a React Native project.");
114 }
115 });
116 });
117 }
118}
119