Skip to content

Commit

Permalink
Added Run Windows and Run macOS commands to Command Palette (#1576)
Browse files Browse the repository at this point in the history
* Added Run Windows command

* Added Run Macos command

* Changed visibility of Run Windows and Run MacOS commans

* Moved all react native packages to export constant

* Changed native module used for reloading app

* Implemented Reload app command for React Native Windows app

* Minor fix

Co-authored-by: RedMickey <33267199+RedMickey@users.noreply.github.com>
  • Loading branch information
etatanova and RedMickey authored Jun 7, 2021
1 parent 1f5927e commit cfbe5cc
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 48 deletions.
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@
"category": "React Native",
"enablement": "!config.security.workspace.trust.enabled || isWorkspaceTrusted"
},
{
"command": "reactNative.runWindows",
"title": "%reactNative.command.runWindows.title%",
"category": "React Native",
"enablement": "!config.security.workspace.trust.enabled && isRNWindowsProject || isWorkspaceTrusted && isRNWindowsProject"
},
{
"command": "reactNative.runMacOS",
"title": "%reactNative.command.runMacOS.title%",
"category": "React Native",
"enablement": "!config.security.workspace.trust.enabled && isRNMacOSProject || isWorkspaceTrusted && isRNMacOSProject"
},
{
"command": "reactNative.startPackager",
"title": "%reactNative.command.startPackager.title%",
Expand Down
2 changes: 2 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"reactNative.command.runIosSimulator.title": "Run iOS on Simulator",
"reactNative.command.runIosDevice.title": "Run iOS on Device",
"reactNative.command.runExponent.title": "Run Expo",
"reactNative.command.runWindows.title": "Run Windows",
"reactNative.command.runMacOS.title": "Run MacOS",
"reactNative.command.startPackager.title": "Start Packager",
"reactNative.command.stopPackager.title": "Stop Packager",
"reactNative.command.restartPackager.title": "Restart Packager",
Expand Down
2 changes: 2 additions & 0 deletions src/common/error/internalErrorCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export enum InternalErrorCode {
FailedToPublishToExpHost = 111,
UnsupportedCommandStatus = 112,
CommandFailedWithDetails = 113,
FailedToRunOnWindows = 114,
FailedToRunOnMacOS = 115,

// Device Deployer errors
IOSDeployNotFound = 201,
Expand Down
2 changes: 1 addition & 1 deletion src/common/extensionHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function generateRandomPortNumber(): number {
return Math.round(Math.random() * 40000 + 3000);
}

export function getNodeModulesInFolderHierarhy(projectRoot: string): string | null {
export function getNodeModulesInFolderHierarchy(projectRoot: string): string | null {
const NODE_MODULES_FOLDER: string = "node_modules";
const REACT_NATIVE_MODULE: string = "react-native";
const pathToReactNativeModule: string = path.join(NODE_MODULES_FOLDER, REACT_NATIVE_MODULE);
Expand Down
46 changes: 26 additions & 20 deletions src/common/projectVersionHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ export interface RNPackageVersions {
reactNativeMacOSVersion: string;
}

export const REACT_NATIVE_PACKAGES: Record<string, ParsedPackage> = {
REACT_NATIVE: {
packageName: "react-native",
useSemverCoerce: true,
},
REACT_NATIVE_WINDOWS: {
packageName: "react-native-windows",
useSemverCoerce: false,
},
REACT_NATIVE_MACOS: {
packageName: "react-native-macos",
useSemverCoerce: false,
},
};

export class ProjectVersionHelper {
private static SEMVER_INVALID = "SemverInvalid";

Expand Down Expand Up @@ -78,32 +93,28 @@ export class ProjectVersionHelper {
public static generateAdditionalPackagesToCheckByPlatform(args: ILaunchArgs): ParsedPackage[] {
let additionalPackages: ParsedPackage[] = [];
if (args.platform === PlatformType.Windows) {
additionalPackages.push({
packageName: "react-native-windows",
useSemverCoerce: false,
});
additionalPackages.push(REACT_NATIVE_PACKAGES.REACT_NATIVE_WINDOWS);
}

if (args.platform === PlatformType.macOS) {
additionalPackages.push({
packageName: "react-native-macos",
useSemverCoerce: false,
});
additionalPackages.push(REACT_NATIVE_PACKAGES.REACT_NATIVE_MACOS);
}

return additionalPackages;
}

public static generateAllAdditionalPackages(): ParsedPackage[] {
return [
REACT_NATIVE_PACKAGES.REACT_NATIVE_WINDOWS,
REACT_NATIVE_PACKAGES.REACT_NATIVE_MACOS,
];
}

public static getReactNativePackageVersionsFromNodeModules(
nodeModulesRoot: string,
additionalPackagesToCheck?: ParsedPackage[],
): Promise<RNPackageVersions> {
let parsedPackages: ParsedPackage[] = [
{
packageName: "react-native",
useSemverCoerce: true,
},
];
let parsedPackages: ParsedPackage[] = [REACT_NATIVE_PACKAGES.REACT_NATIVE];

if (additionalPackagesToCheck) {
parsedPackages.push(...additionalPackagesToCheck);
Expand Down Expand Up @@ -148,12 +159,7 @@ export class ProjectVersionHelper {
cwd: string,
additionalPackagesToCheck?: ParsedPackage[],
): Promise<RNPackageVersions> {
let parsedPackages: ParsedPackage[] = [
{
packageName: "react-native",
useSemverCoerce: true,
},
];
let parsedPackages: ParsedPackage[] = [REACT_NATIVE_PACKAGES.REACT_NATIVE];

if (additionalPackagesToCheck) {
parsedPackages.push(...additionalPackagesToCheck);
Expand Down
4 changes: 2 additions & 2 deletions src/debugger/appWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ function getNativeModules() {
var vscodeHandlers = {
'vscode_reloadApp': function () {
var NativeModules = getNativeModules();
if (NativeModules && NativeModules.DevMenu) {
NativeModules.DevMenu.reload();
if (NativeModules && NativeModules.DevSettings) {
NativeModules.DevSettings.reload();
}
},
'vscode_showDevMenu': function () {
Expand Down
4 changes: 2 additions & 2 deletions src/extension/appLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { TelemetryHelper } from "../common/telemetryHelper";
import { ErrorHelper } from "../common/error/errorHelper";
import { InternalErrorCode } from "../common/error/internalErrorCode";
import { TargetPlatformHelper } from "../common/targetPlatformHelper";
import { getNodeModulesInFolderHierarhy } from "../common/extensionHelper";
import { getNodeModulesInFolderHierarchy } from "../common/extensionHelper";
import { ProjectsStorage } from "./projectsStorage";
import { ReactNativeCDPProxy } from "../cdp-proxy/reactNativeCDPProxy";
import { generateRandomPortNumber } from "../common/extensionHelper";
Expand Down Expand Up @@ -174,7 +174,7 @@ export class AppLauncher {

public getOrUpdateNodeModulesRoot(forceUpdate: boolean = false): string {
if (!this.nodeModulesRoot || forceUpdate) {
const nodeModulesRootPath: string | null = getNodeModulesInFolderHierarhy(
const nodeModulesRootPath: string | null = getNodeModulesInFolderHierarchy(
this.packager.getProjectPath(),
);

Expand Down
117 changes: 109 additions & 8 deletions src/extension/commandPaletteHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ import { OutputChannelLogger } from "./log/OutputChannelLogger";
import { TargetType, GeneralMobilePlatform } from "./generalMobilePlatform";
import { AndroidPlatform } from "./android/androidPlatform";
import { IOSPlatform } from "./ios/iOSPlatform";
import { ProjectVersionHelper } from "../common/projectVersionHelper";
import { ReactNativeProjectHelper } from "../common/reactNativeProjectHelper";
import { ProjectVersionHelper, REACT_NATIVE_PACKAGES } from "../common/projectVersionHelper";
import { ParsedPackage, ReactNativeProjectHelper } from "../common/reactNativeProjectHelper";
import { TargetPlatformHelper } from "../common/targetPlatformHelper";
import { TelemetryHelper } from "../common/telemetryHelper";
import { ProjectsStorage } from "./projectsStorage";
import { IAndroidRunOptions, IIOSRunOptions, PlatformType } from "./launchArgs";
import {
IAndroidRunOptions,
IIOSRunOptions,
ImacOSRunOptions,
IWindowsRunOptions,
PlatformType,
} from "./launchArgs";
import { ExponentPlatform } from "./exponent/exponentPlatform";
import { spawn, ChildProcess } from "child_process";
import { HostPlatform } from "../common/hostPlatform";
Expand All @@ -33,6 +39,8 @@ import { LogCatMonitor } from "./android/logCatMonitor";
import { LogCatMonitorManager } from "./android/logCatMonitorManager";
import { NetworkInspectorServer } from "./networkInspector/networkInspectorServer";
import { InspectorViewFactory } from "./networkInspector/views/inspectorViewFactory";
import { WindowsPlatform } from "./windows/windowsPlatform";
import { MacOSPlatform } from "./macos/macOSPlatform";
nls.config({
messageFormat: nls.MessageFormat.bundle,
bundleFormat: nls.BundleFormat.standalone,
Expand Down Expand Up @@ -301,6 +309,70 @@ export class CommandPaletteHandler {
});
}

public static runWindows(): Promise<void> {
const additionalPackagesToCheck: ParsedPackage[] = [
REACT_NATIVE_PACKAGES.REACT_NATIVE_WINDOWS,
];
return this.selectProject().then((appLauncher: AppLauncher) => {
TargetPlatformHelper.checkTargetPlatformSupport(PlatformType.Windows);
return ProjectVersionHelper.getReactNativePackageVersionsFromNodeModules(
appLauncher.getOrUpdateNodeModulesRoot(),
additionalPackagesToCheck,
).then(versions => {
appLauncher.setReactNativeVersions(versions);
return this.executeCommandInContext(
"runWindows",
appLauncher.getWorkspaceFolder(),
() => {
const platform = <WindowsPlatform>(
this.createPlatform(appLauncher, PlatformType.Windows, WindowsPlatform)
);
return platform
.beforeStartPackager()
.then(() => {
return platform.startPackager();
})
.then(() => {
return platform.runApp(false);
});
},
);
});
});
}

public static runMacOS(): Promise<void> {
const additionalPackagesToCheck: ParsedPackage[] = [
REACT_NATIVE_PACKAGES.REACT_NATIVE_MACOS,
];
return this.selectProject().then((appLauncher: AppLauncher) => {
TargetPlatformHelper.checkTargetPlatformSupport(PlatformType.macOS);
return ProjectVersionHelper.getReactNativePackageVersionsFromNodeModules(
appLauncher.getOrUpdateNodeModulesRoot(),
additionalPackagesToCheck,
).then(versions => {
appLauncher.setReactNativeVersions(versions);
return this.executeCommandInContext(
"runMacOS",
appLauncher.getWorkspaceFolder(),
() => {
const platform = <MacOSPlatform>(
this.createPlatform(appLauncher, PlatformType.macOS, MacOSPlatform)
);
return platform
.beforeStartPackager()
.then(() => {
return platform.startPackager();
})
.then(() => {
return platform.runApp();
});
},
);
});
});
}

public static showDevMenu(): Promise<void> {
return this.selectProject().then((appLauncher: AppLauncher) => {
const androidPlatform = <AndroidPlatform>(
Expand All @@ -320,6 +392,11 @@ export class CommandPaletteHandler {
// eslint-disable-next-line @typescript-eslint/no-empty-function
.catch(() => {}); // Ignore any errors
}

if (process.platform === "win32") {
// TODO: implement Show DevMenu command for RNW
}

return Promise.resolve();
});
}
Expand All @@ -334,6 +411,27 @@ export class CommandPaletteHandler {
// eslint-disable-next-line @typescript-eslint/no-empty-function
.catch(() => {}); // Ignore any errors

if (process.platform === "win32") {
const nodeModulesRoot = appLauncher.getOrUpdateNodeModulesRoot();
ProjectVersionHelper.getReactNativePackageVersionsFromNodeModules(nodeModulesRoot, [
REACT_NATIVE_PACKAGES.REACT_NATIVE_WINDOWS,
]).then(RNPackageVersions => {
const isRNWProject = !ProjectVersionHelper.isVersionError(
RNPackageVersions.reactNativeWindowsVersion,
);

if (isRNWProject) {
const windowsPlatform = <WindowsPlatform>(
this.createPlatform(appLauncher, PlatformType.Windows, WindowsPlatform)
);
windowsPlatform
.reloadApp(appLauncher)
// eslint-disable-next-line @typescript-eslint/no-empty-function
.catch(() => {}); // Ignore any errors
}
});
}

if (process.platform === "darwin") {
const iosPlatform = <IOSPlatform>(
this.createPlatform(appLauncher, PlatformType.iOS, IOSPlatform)
Expand Down Expand Up @@ -569,7 +667,7 @@ export class CommandPaletteHandler {

private static createPlatform(
appLauncher: AppLauncher,
platform: PlatformType.iOS | PlatformType.Android | PlatformType.Exponent,
platform: PlatformType,
platformClass: typeof GeneralMobilePlatform,
target?: TargetType,
): GeneralMobilePlatform {
Expand Down Expand Up @@ -741,9 +839,9 @@ export class CommandPaletteHandler {

private static getRunOptions(
appLauncher: AppLauncher,
platform: PlatformType.iOS | PlatformType.Android | PlatformType.Exponent,
platform: PlatformType,
target: TargetType = "simulator",
): IAndroidRunOptions | IIOSRunOptions {
): IAndroidRunOptions | IIOSRunOptions | IWindowsRunOptions | ImacOSRunOptions {
const packagerPort = SettingsHelper.getPackagerPort(
appLauncher.getWorkspaceFolderUri().fsPath,
);
Expand All @@ -765,9 +863,12 @@ export class CommandPaletteHandler {
const projectRoot = SettingsHelper.getReactNativeProjectRoot(
appLauncher.getWorkspaceFolderUri().fsPath,
);

const nodeModulesRoot: string = appLauncher.getOrUpdateNodeModulesRoot();
const runOptions: IAndroidRunOptions | IIOSRunOptions = {
const runOptions:
| IAndroidRunOptions
| IIOSRunOptions
| IWindowsRunOptions
| ImacOSRunOptions = {
platform: platform,
workspaceRoot: appLauncher.getWorkspaceFolderUri().fsPath,
projectRoot: projectRoot,
Expand Down
26 changes: 24 additions & 2 deletions src/extension/rn-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { ErrorHelper } from "../common/error/errorHelper";
import { InternalError } from "../common/error/internalError";
import { InternalErrorCode } from "../common/error/internalErrorCode";
import { SettingsHelper } from "./settingsHelper";
import { ProjectVersionHelper } from "../common/projectVersionHelper";
import { ProjectVersionHelper, RNPackageVersions } from "../common/projectVersionHelper";
import { ReactDirManager } from "./reactDirManager";
import { Telemetry } from "../common/telemetry";
import { TelemetryHelper, ICommandTelemetryProperties } from "../common/telemetryHelper";
Expand Down Expand Up @@ -256,7 +256,7 @@ export function onFolderAdded(folder: vscode.WorkspaceFolder): Promise<void> {
outputChannelLogger.debug(`Add project: ${projectRootPath}`);
return ProjectVersionHelper.tryToGetRNSemverValidVersionsFromProjectPackage(
projectRootPath,
undefined,
ProjectVersionHelper.generateAllAdditionalPackages(),
projectRootPath,
).then(versions => {
outputChannelLogger.debug(`React Native version: ${versions.reactNativeVersion}`);
Expand All @@ -271,6 +271,8 @@ export function onFolderAdded(folder: vscode.WorkspaceFolder): Promise<void> {
versions.reactNativeVersion,
);
} else if (isSupportedVersion(versions.reactNativeVersion)) {
activateCommands(versions);

promises.push(
entryPointHandler.runFunction(
"debugger.setupLauncherStub",
Expand Down Expand Up @@ -299,6 +301,16 @@ export function onFolderAdded(folder: vscode.WorkspaceFolder): Promise<void> {
});
}

function activateCommands(versions: RNPackageVersions): void {
if (!ProjectVersionHelper.isVersionError(versions.reactNativeWindowsVersion)) {
vscode.commands.executeCommand("setContext", "isRNWindowsProject", true);
}

if (!ProjectVersionHelper.isVersionError(versions.reactNativeMacOSVersion)) {
vscode.commands.executeCommand("setContext", "isRNMacOSProject", true);
}
}

function onFolderRemoved(folder: vscode.WorkspaceFolder): void {
let appLauncher = ProjectsStorage.getFolder(folder);
Object.keys(appLauncher).forEach(key => {
Expand Down Expand Up @@ -375,6 +387,16 @@ function registerReactNativeCommands(): void {
ErrorHelper.getInternalError(InternalErrorCode.FailedToRunExponent),
() => CommandPaletteHandler.runExponent(),
);
registerVSCodeCommand(
"runWindows",
ErrorHelper.getInternalError(InternalErrorCode.FailedToRunOnWindows),
() => CommandPaletteHandler.runWindows(),
);
registerVSCodeCommand(
"runMacOS",
ErrorHelper.getInternalError(InternalErrorCode.FailedToRunOnMacOS),
() => CommandPaletteHandler.runMacOS(),
);
registerVSCodeCommand(
"startPackager",
ErrorHelper.getInternalError(InternalErrorCode.FailedToStartPackager),
Expand Down
Loading

0 comments on commit cfbe5cc

Please sign in to comment.