From ea5079ff9c2cab2e98e4b719f237964166ecf577 Mon Sep 17 00:00:00 2001 From: John Knox Date: Thu, 10 Oct 2019 09:21:35 -0700 Subject: [PATCH] Enable / Disable iOS support depending on xcode-select Summary: Queries xcode-select on ios dispatcher startup, to see if it's installed. If it is, carry on with the ios device tracking, if not, don't bother. This should stop it from emitting errors trying to track devices when things aren't installed. I think it should also stop those install prompts from popping up. Sets it in app state so we can tell the user about it, and maybe gate some other things too. Reviewed By: passy Differential Revision: D17830696 fbshipit-source-id: 960d09a9c5267afabf5e5e222379a0a7ed2cc444 --- src/dispatcher/iOSDevice.tsx | 18 ++++++++++++++++-- src/reducers/application.tsx | 15 +++++++++++++++ src/utils/listDevices.tsx | 12 +++++++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/dispatcher/iOSDevice.tsx b/src/dispatcher/iOSDevice.tsx index 9f5f16a37..9dc0b37bf 100644 --- a/src/dispatcher/iOSDevice.tsx +++ b/src/dispatcher/iOSDevice.tsx @@ -7,6 +7,7 @@ import {ChildProcess} from 'child_process'; import {Store} from '../reducers/index'; +import {setXcodeDetected} from '../reducers/application'; import {Logger} from '../fb-interfaces/Logger'; import {DeviceType} from '../devices/BaseDevice'; import {promisify} from 'util'; @@ -150,7 +151,7 @@ function getActiveDevices(): Promise> { } function queryDevicesForever(store: Store, logger: Logger) { - queryDevices(store, logger) + return queryDevices(store, logger) .then(() => { // It's important to schedule the next check AFTER the current one has completed // to avoid simultaneous queries which can cause multiple user input prompts. @@ -189,6 +190,12 @@ async function checkXcodeVersionMismatch() { } } +async function isXcodeDetected(): Promise { + return promisify(child_process.exec)('xcode-select -p') + .then(_ => true) + .catch(_ => false); +} + export async function getActiveDevicesAndSimulators(): Promise< Array > { @@ -208,5 +215,12 @@ export default (store: Store, logger: Logger) => { if (process.platform !== 'darwin') { return; } - queryDevicesForever(store, logger); + isXcodeDetected() + .then(isDetected => { + store.dispatch(setXcodeDetected(isDetected)); + return isDetected; + }) + .then(isDetected => + isDetected ? queryDevicesForever(store, logger) : Promise.resolve(), + ); }; diff --git a/src/reducers/application.tsx b/src/reducers/application.tsx index 99c81465c..141eab865 100644 --- a/src/reducers/application.tsx +++ b/src/reducers/application.tsx @@ -76,6 +76,7 @@ export type State = { launcherMsg: LauncherMsg; flipperRating: number | null; statusMessages: Array; + xcodeCommandLineToolsDetected: boolean; }; type BooleanActionType = @@ -140,6 +141,12 @@ export type Action = | { type: 'REMOVE_STATUS_MSG'; payload: {msg: string; sender: string}; + } + | { + type: 'SET_XCODE_DETECTED'; + payload: { + isDetected: boolean; + }; }; export const initialState: () => State = () => ({ @@ -161,6 +168,7 @@ export const initialState: () => State = () => ({ }, flipperRating: null, statusMessages: [], + xcodeCommandLineToolsDetected: false, }); function statusMessage(sender: string, msg: string): string { @@ -268,6 +276,8 @@ export default function reducer( return {...state, statusMessages}; } return state; + } else if (action.type === 'SET_XCODE_DETECTED') { + return {...state, xcodeCommandLineToolsDetected: action.payload.isDetected}; } else { return state; } @@ -345,3 +355,8 @@ export const removeStatusMessage = (payload: StatusMessageType): Action => ({ type: 'REMOVE_STATUS_MSG', payload, }); + +export const setXcodeDetected = (isDetected: boolean): Action => ({ + type: 'SET_XCODE_DETECTED', + payload: {isDetected}, +}); diff --git a/src/utils/listDevices.tsx b/src/utils/listDevices.tsx index 66d94e704..03e8dbed4 100644 --- a/src/utils/listDevices.tsx +++ b/src/utils/listDevices.tsx @@ -10,7 +10,13 @@ import BaseDevice from '../devices/BaseDevice'; import {Store} from '../reducers/index'; export async function listDevices(store: Store): Promise> { - const androidDevices = await getActiveAndroidDevices(store); - const iOSDevices: BaseDevice[] = await getActiveDevicesAndSimulators(); - return iOSDevices.concat(androidDevices); + const state = store.getState(); + const androidDevices = state.settingsState.enableAndroid + ? await getActiveAndroidDevices(store) + : []; + const iOSDevices: BaseDevice[] = state.application + .xcodeCommandLineToolsDetected + ? await getActiveDevicesAndSimulators() + : []; + return [...androidDevices, ...iOSDevices]; }