microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
fix-ts-error1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/ios/iOSContainerUtility.ts

258lines · modeblame

4bb0956eRedMickey5 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
09f6024fHeniker4 years ago4/* eslint-disable */
5/* eslint-enable prettier/prettier*/
6
7import * as fs from "fs";
8import * as path from "path";
623be8a6Ezio Li2 years ago9import { logger } from "@vscode/debugadapter/lib/logger";
4bb0956eRedMickey5 years ago10import { ChildProcess } from "../../common/node/childProcess";
11import { PromiseUtil } from "../../common/node/promise";
12import { OutputChannelLogger } from "../log/OutputChannelLogger";
4cd25962JiglioNero4 years ago13import { IDebuggableMobileTarget } from "../mobileTarget";
4bb0956eRedMickey5 years ago14
15/**
16* @preserve
4cd25962JiglioNero4 years ago17* Start region: the code is borrowed from https://github.com/facebook/flipper/blob/c2848df7f210c363113797c0f2e3db8c5d4fd49f/desktop/app/src/server/devices/ios/iOSContainerUtility.tsx
4bb0956eRedMickey5 years ago18*
19* Copyright (c) Facebook, Inc. and its affiliates.
20*
21* This source code is licensed under the MIT license found in the
22* LICENSE file in the root directory of this source tree.
23*
24* @format
25*/
26
27export const idbPath = "/usr/local/bin/idb";
28// Use debug to get helpful logs when idb fails
29const idbLogLevel = "DEBUG";
30
31type IdbTarget = {
32name: string;
33udid: string;
34state: string;
35type: string;
4cd25962JiglioNero4 years ago36target_type?: string;
4bb0956eRedMickey5 years ago37os_version: string;
38architecture: string;
39};
40
4cd25962JiglioNero4 years ago41export type DeviceTarget = IDebuggableMobileTarget;
4bb0956eRedMickey5 years ago42
4cd25962JiglioNero4 years ago43export const isIdbAvailable = PromiseUtil.promiseCacheDecorator<boolean>(isAvailable);
4bb0956eRedMickey5 years ago44
45function isAvailable(): Promise<boolean> {
46if (!idbPath) {
47return Promise.resolve(false);
48}
4cd25962JiglioNero4 years ago49return fs.promises
50.access(idbPath, fs.constants.X_OK)
4bb0956eRedMickey5 years ago51.then(() => true)
52.catch(() => false);
53}
54
4cd25962JiglioNero4 years ago55export async function isXcodeDetected(): Promise<boolean> {
56return new ChildProcess()
57.execToString("xcode-select -p")
58.then(stdout => {
59return fs.existsSync(stdout.trim());
60})
61.catch(_ => false);
62}
63
64async function queryTargetsWithoutXcodeDependency(
65idbCompanionPath: string,
66isAvailableFunc: (idbPath: string) => Promise<boolean>,
67): Promise<Array<DeviceTarget>> {
68if (await isAvailableFunc(idbCompanionPath)) {
69return new ChildProcess()
70.execToString(`${idbCompanionPath} --list 1 --only device`)
71.then(stdout => parseIdbTargets(stdout))
72.catch((e: Error) => {
73logger.warn(
74`Failed to query idb_companion --list 1 --only device for physical targets: ${e}`,
75);
76return [];
77});
78} else {
79logger.warn(
80`Unable to locate idb_companion in ${idbCompanionPath}. Try running sudo yum install -y fb-idb`,
81);
82return [];
83}
84}
85
86function parseIdbTargets(lines: string): Array<DeviceTarget> {
87return lines
88.trim()
89.split("\n")
90.map(line => line.trim())
91.filter(Boolean)
92.map(line => JSON.parse(line))
93.filter(({ state }: IdbTarget) => state.toLocaleLowerCase() === "booted")
94.map<IdbTarget>(({ type, target_type, ...rest }: IdbTarget) => ({
95type: (type || target_type) === "simulator" ? "emulator" : "physical",
96...rest,
97}))
98.map<DeviceTarget>((target: IdbTarget) => ({
99id: target.udid,
100isVirtualTarget: target.type === "emulator",
101name: target.name,
102isOnline: true,
103}));
104}
105
106export async function idbListTargets(idbPath: string): Promise<Array<DeviceTarget>> {
107return new ChildProcess()
108.execToString(`${idbPath} list-targets --json`)
109.then(stdout =>
110// See above.
111parseIdbTargets(stdout),
112)
113.catch((e: Error) => {
114logger.warn(`Failed to query idb for targets: ${e}`);
115return [];
116});
117}
118
4bb0956eRedMickey5 years ago119async function targets(): Promise<Array<DeviceTarget>> {
120if (process.platform !== "darwin") {
121return [];
122}
4cd25962JiglioNero4 years ago123const isXcodeInstalled = await isXcodeDetected();
124if (!isXcodeInstalled) {
125const idbCompanionPath = path.dirname(idbPath) + "/idb_companion";
126return queryTargetsWithoutXcodeDependency(idbCompanionPath, isAvailable);
127}
4bb0956eRedMickey5 years ago128
129// Not all users have idb installed because you can still use
130// Flipper with Simulators without it.
4cd25962JiglioNero4 years ago131// But idb is MUCH more CPU efficient than xcrun, so
132// when installed, use it. This still holds true
133// with the move from instruments to xcrun.
134// TODO: Move idb availability check up.
09f6024fHeniker4 years ago135return (await isIdbAvailable())
136? await idbListTargets(idbPath)
137: new ChildProcess()
138.execToString("xcrun xctrace list devices")
139.then(stdout => {
140const targets: DeviceTarget[] = [];
141const lines = stdout
142.split("\n")
143.map(line => line.trim())
144.filter(line => !!line);
145const firstDevicesIndex = lines.indexOf("== Devices ==") + 1;
146const lastDevicesIndex = lines.indexOf("== Simulators ==") - 1;
147for (let i = firstDevicesIndex; i <= lastDevicesIndex; i++) {
148const line = lines[i];
149const params = line
150.split(" ")
151.map(el => el.trim())
152.filter(el => !!el);
153// Add only devices with system version
154if (
155params[params.length - 1].match(/\(.+\)/) &&
156params[params.length - 2].match(/\(.+\)/)
157) {
158targets.push({
159id: params[params.length - 1].replace(/\(|\)/g, "").trim(),
160name: params.slice(0, params.length - 2).join(" "),
161isVirtualTarget: false,
162isOnline: true,
163});
164}
165}
166return targets;
167})
168.catch(e => {
169logger.warn(`Failed to query for devices using xctrace: ${e}`);
170return [];
171});
4bb0956eRedMickey5 years ago172}
173
174async function push(
175udid: string,
176src: string,
177bundleId: string,
178dst: string,
179logger?: OutputChannelLogger,
180): Promise<void> {
181const cp = new ChildProcess();
182await checkIdbIsInstalled();
183return wrapWithErrorMessage(
184cp
185.execToString(
186`${idbPath} --log ${idbLogLevel} file push --udid ${udid} --bundle-id ${bundleId} '${src}' '${dst}'`,
187)
188.then(() => {
189return;
190})
191.catch(e => handleMissingIdb(e)),
192logger,
193);
194}
195
196async function pull(
197udid: string,
198src: string,
199bundleId: string,
200dst: string,
201logger?: OutputChannelLogger,
202): Promise<void> {
203const cp = new ChildProcess();
204await checkIdbIsInstalled();
205return wrapWithErrorMessage(
206cp
207.execToString(
208`${idbPath} --log ${idbLogLevel} file pull --udid ${udid} --bundle-id ${bundleId} '${src}' '${dst}'`,
209)
210.then(() => {
211return;
212})
213.catch(e => handleMissingIdb(e)),
214logger,
215);
216}
217
218export async function checkIdbIsInstalled(): Promise<void> {
219const isInstalled = await isIdbAvailable();
220if (!isInstalled) {
221throw new Error(
222`idb is required to use iOS devices. Please install it with instructions from https://github.com/facebook/idb.`,
223);
224}
225}
226
227// The fb-internal idb binary is a shim that downloads the proper one on first run. It requires sudo to do so.
228// If we detect this, Tell the user how to fix it.
229function handleMissingIdb(e: Error): void {
230if (e.message && e.message.includes("sudo: no tty present and no askpass program specified")) {
231throw new Error(
232`idb doesn't appear to be installed. Run "${idbPath} list-targets" to fix this.`,
233);
234}
235throw e;
236}
237
238function wrapWithErrorMessage<T>(p: Promise<T>, logger?: OutputChannelLogger): Promise<T> {
239return p.catch((e: Error) => {
240logger?.error(e.message);
241// Give the user instructions. Don't embed the error because it's unique per invocation so won't be deduped.
242throw new Error(
243"A problem with idb has ocurred. Please run `sudo rm -rf /tmp/idb*` and `sudo yum install -y fb-idb` to update it, if that doesn't fix it, post in https://github.com/microsoft/vscode-react-native.",
244);
245});
246}
247
248export default {
249isAvailable,
250targets,
251push,
252pull,
253};
254
255/**
256* @preserve
4cd25962JiglioNero4 years ago257* End region: https://github.com/facebook/flipper/blob/c2848df7f210c363113797c0f2e3db8c5d4fd49f/desktop/app/src/server/devices/ios/iOSContainerUtility.tsx
4bb0956eRedMickey5 years ago258*/