microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
transitive-dependency-serialize-javascript

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/macos/macOSPlatform.ts

225lines · modeblame

341dba36Yuri Skorokhodov5 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
1c2424f4RedMickey5 years ago4import * as path from "path";
09f6024fHeniker4 years ago5import * as semver from "semver";
4cd25962JiglioNero4 years ago6import { GeneralPlatform, MobilePlatformDeps, TargetType } from "../generalPlatform";
341dba36Yuri Skorokhodov5 years ago7import { ImacOSRunOptions, PlatformType } from "../launchArgs";
8import { OutputVerifier, PatternToFailure } from "../../common/outputVerifier";
9import { TelemetryHelper } from "../../common/telemetryHelper";
10import { CommandExecutor } from "../../common/commandExecutor";
11import { InternalErrorCode } from "../../common/error/internalErrorCode";
0d77292aJiglioNero4 years ago12import { PlistBuddy } from "../ios/plistBuddy";
1c2424f4RedMickey5 years ago13import { ChildProcess } from "../../common/node/childProcess";
47927908RedMickey4 years ago14import { ProjectVersionHelper } from "../../common/projectVersionHelper";
09f6024fHeniker4 years ago15import { MacOSDebugModeManager } from "./macOSDebugModeManager";
341dba36Yuri Skorokhodov5 years ago16
17/**
18* macOS specific platform implementation for debugging RN applications.
19*/
4cd25962JiglioNero4 years ago20export class MacOSPlatform extends GeneralPlatform {
34472878RedMickey5 years ago21private static SUCCESS_PATTERNS = ["Launching app"];
341dba36Yuri Skorokhodov5 years ago22private static FAILURE_PATTERNS: PatternToFailure[] = [
23{
24pattern: "Unrecognized command 'run-macos'",
25errorCode: InternalErrorCode.ReactNativemacOSIsNotInstalled,
26},
27];
28
1c2424f4RedMickey5 years ago29public static DEFAULT_MACOS_PROJECT_RELATIVE_PATH = "macos";
30
31private macosProjectRoot: string;
32private plistBuddy: PlistBuddy;
33private macOSDebugModeManager: MacOSDebugModeManager;
34
341dba36Yuri Skorokhodov5 years ago35constructor(protected runOptions: ImacOSRunOptions, platformDeps: MobilePlatformDeps = {}) {
36super(runOptions, platformDeps);
1c2424f4RedMickey5 years ago37
38const macosProjectFolderPath = MacOSPlatform.getOptFromRunArgs(
39this.runArguments,
40"--project-path",
41false,
42);
43this.macosProjectRoot = path.join(
44this.projectPath,
45macosProjectFolderPath || MacOSPlatform.DEFAULT_MACOS_PROJECT_RELATIVE_PATH,
46);
47this.plistBuddy = new PlistBuddy();
48
49const schemeFromArgs = MacOSPlatform.getOptFromRunArgs(
50this.runArguments,
51"--scheme",
52false,
53);
54this.macOSDebugModeManager = new MacOSDebugModeManager(
55this.macosProjectRoot,
56this.projectPath,
57schemeFromArgs ? schemeFromArgs : this.runOptions.scheme,
58);
341dba36Yuri Skorokhodov5 years ago59}
60
0d77292aJiglioNero4 years ago61public async runApp(): Promise<void> {
008d88e5RedMickey4 years ago62let extProps: any = {
341dba36Yuri Skorokhodov5 years ago63platform: {
64value: PlatformType.macOS,
65isPii: false,
66},
67};
68
e7a2c40dRedMickey4 years ago69this.projectObserver?.updateRNMacosProjectState(true);
008d88e5RedMickey4 years ago70if (this.runOptions.isDirect) {
71extProps.isDirect = {
72value: true,
73isPii: false,
74};
e7a2c40dRedMickey4 years ago75this.projectObserver?.updateRNMacosHermesProjectState(true);
008d88e5RedMickey4 years ago76}
77
34472878RedMickey5 years ago78extProps = TelemetryHelper.addPlatformPropertiesToTelemetryProperties(
79this.runOptions,
80this.runOptions.reactNativeVersions,
81extProps,
82);
341dba36Yuri Skorokhodov5 years ago83
0d77292aJiglioNero4 years ago84await TelemetryHelper.generate("MacOSPlatform.runApp", extProps, async () => {
4cd25962JiglioNero4 years ago85const env = GeneralPlatform.getEnvArgument(
34472878RedMickey5 years ago86process.env,
87this.runOptions.env,
88this.runOptions.envFile,
89);
341dba36Yuri Skorokhodov5 years ago90
34472878RedMickey5 years ago91if (
92!semver.valid(
93this.runOptions.reactNativeVersions.reactNativeVersion,
09f6024fHeniker4 years ago94) /* Custom RN implementations should support this flag*/ ||
34472878RedMickey5 years ago95semver.gte(
96this.runOptions.reactNativeVersions.reactNativeVersion,
97MacOSPlatform.NO_PACKAGER_VERSION,
47927908RedMickey4 years ago98) ||
99ProjectVersionHelper.isCanaryVersion(
100this.runOptions.reactNativeVersions.reactNativeVersion,
34472878RedMickey5 years ago101)
102) {
341dba36Yuri Skorokhodov5 years ago103this.runArguments.push("--no-packager");
104}
105
34472878RedMickey5 years ago106const runmacOSSpawn = new CommandExecutor(
4dfb1c4cetatanova5 years ago107this.runOptions.nodeModulesRoot,
34472878RedMickey5 years ago108this.projectPath,
109this.logger,
110).spawnReactCommand(`run-${this.platformName}`, this.runArguments, { env });
0d77292aJiglioNero4 years ago111await new OutputVerifier(
34472878RedMickey5 years ago112() => Promise.resolve(MacOSPlatform.SUCCESS_PATTERNS),
113() => Promise.resolve(MacOSPlatform.FAILURE_PATTERNS),
114this.platformName,
115).process(runmacOSSpawn);
341dba36Yuri Skorokhodov5 years ago116});
117}
118
0d77292aJiglioNero4 years ago119public async prewarmBundleCache(): Promise<void> {
341dba36Yuri Skorokhodov5 years ago120return this.packager.prewarmBundleCache(PlatformType.macOS);
121}
122
123public getRunArguments(): string[] {
09f6024fHeniker4 years ago124const runArguments: string[] = [];
341dba36Yuri Skorokhodov5 years ago125
126if (this.runOptions.runArguments && this.runOptions.runArguments.length > 0) {
127runArguments.push(...this.runOptions.runArguments);
128} else {
09f6024fHeniker4 years ago129const target =
4cd25962JiglioNero4 years ago130this.runOptions.target === TargetType.Simulator ? "" : this.runOptions.target;
341dba36Yuri Skorokhodov5 years ago131if (target) {
132runArguments.push(`--${target}`);
133}
134}
135
136return runArguments;
137}
1c2424f4RedMickey5 years ago138
0d77292aJiglioNero4 years ago139public async enableJSDebuggingMode(): Promise<void> {
1c2424f4RedMickey5 years ago140// Configure the app for debugging
141// Wait until the configuration file exists, and check to see if debugging is enabled
0d77292aJiglioNero4 years ago142const [debugModeEnabled, appName] = await Promise.all<boolean | string>([
1c2424f4RedMickey5 years ago143this.macOSDebugModeManager.getAppRemoteDebuggingSetting(
144this.runOptions.configuration,
145this.runOptions.productName,
146),
147this.getApplicationName(),
0d77292aJiglioNero4 years ago148]);
149if (debugModeEnabled) {
150return;
151}
1c2424f4RedMickey5 years ago152
0d77292aJiglioNero4 years ago153// Debugging must still be enabled
154// We enable debugging by writing to a plist file that backs a NSUserDefaults object,
155// but that file is written to by the app on occasion. To avoid races, we shut the app
156// down before writing to the file.
157await this.terminateMacOSapp(<string>appName);
158// Write to the settings file while the app is not running to avoid races
159await this.macOSDebugModeManager.setAppRemoteDebuggingSetting(
09f6024fHeniker4 years ago160/* enable=*/ true,
0d77292aJiglioNero4 years ago161this.runOptions.configuration,
162this.runOptions.productName,
163);
164// Relaunch the app
165await this.runApp();
1c2424f4RedMickey5 years ago166}
167
168public disableJSDebuggingMode(): Promise<void> {
169return this.macOSDebugModeManager.setAppRemoteDebuggingSetting(
09f6024fHeniker4 years ago170/* enable=*/ false,
1c2424f4RedMickey5 years ago171this.runOptions.configuration,
172this.runOptions.productName,
173);
174}
175
0d77292aJiglioNero4 years ago176private async getApplicationName(): Promise<string> {
177const iOSBuildLocationData = await this.plistBuddy.getExecutableAndConfigurationFolder(
178this.macosProjectRoot,
179this.projectPath,
180PlatformType.macOS,
181false,
182this.runOptions.configuration,
183this.runOptions.productName,
184this.getSchemeFromDebuggingParameters(),
185);
186return iOSBuildLocationData.executable;
1c2424f4RedMickey5 years ago187}
188
189private getSchemeFromDebuggingParameters(): string | undefined {
190let scheme = this.runOptions.scheme;
191if (!scheme) {
192const schemeFromArgs = MacOSPlatform.getOptFromRunArgs(
193this.runArguments,
194"--scheme",
195false,
196);
197if (schemeFromArgs) {
198scheme = schemeFromArgs;
199}
200}
201return scheme;
202}
203
0d77292aJiglioNero4 years ago204private async terminateMacOSapp(appName: string): Promise<void> {
09f6024fHeniker4 years ago205const childProcess = new ChildProcess();
0d77292aJiglioNero4 years ago206// An example of the output from the command above:
207// 40943 ?? 4:13.97 node /Users/user/Documents/rn_for_mac_proj/node_modules/.bin/react-native start --port 8081
208// 40959 ?? 0:10.36 /Users/user/.nvm/versions/node/v10.19.0/bin/node /Users/user/Documents/rn_for_mac_proj/node_modules/metro/node_modules/jest-worker/build/workers/processChild.js
209// 41004 ?? 0:21.34 /Users/user/Library/Developer/Xcode/DerivedData/rn_for_mac_proj-ghuavabiztosiqfqkrityjoxqfmv/Build/Products/Debug/rn_for_mac_proj.app/Contents/MacOS/rn_for_mac_proj
210// 75514 ttys007 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn rn_for_mac_proj
211const searchResults = await childProcess.execToString(`ps -ax | grep ${appName}`);
212if (searchResults) {
213const processIdRgx = /(^\d*)\s\?\?/g;
214// We are looking for a process whose path contains the "appName.app" part
215const processData = searchResults.split("\n").find(str => str.includes(appName));
216
217if (processData) {
218const match = processIdRgx.exec(processData.trim());
219if (match && match[1]) {
220await childProcess.execToString(`kill ${match[1]}`);
221}
222}
223}
1c2424f4RedMickey5 years ago224}
341dba36Yuri Skorokhodov5 years ago225}