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