Use configurable idb installation path

Summary:
Part of https://github.com/facebook/flipper/issues/262

Use the user-configured idb install location instead of a hardcoded one.

Reviewed By: passy

Differential Revision: D21860236

fbshipit-source-id: 5c604d7b6361e7c93ab49d8a03a437dfce880ac1
This commit is contained in:
John Knox
2020-06-04 03:01:18 -07:00
committed by Facebook GitHub Bot
parent 17763809dd
commit ec6310dc3b
3 changed files with 45 additions and 40 deletions

View File

@@ -171,7 +171,7 @@ const INITAL_STATE: State = {
staticView: WelcomeScreen,
};
const reducer = (state: State = INITAL_STATE, action: Actions): State => {
export default (state: State = INITAL_STATE, action: Actions): State => {
switch (action.type) {
case 'SET_STATIC_VIEW': {
const {payload} = action;
@@ -444,33 +444,6 @@ const reducer = (state: State = INITAL_STATE, action: Actions): State => {
}
};
export default (state: State = INITAL_STATE, action: Actions): State => {
const nextState = reducer(state, action);
if (nextState.selectedDevice) {
const {selectedDevice} = nextState;
const deviceNotSupportedErrorMessage = 'iOS Devices are not yet supported';
const error =
selectedDevice.os === 'iOS' &&
selectedDevice.deviceType === 'physical' &&
!iosUtil.isAvailable()
? deviceNotSupportedErrorMessage
: null;
if (error) {
const deviceNotSupportedError = nextState.errors.find(
(error) => error.message === deviceNotSupportedErrorMessage,
);
if (deviceNotSupportedError) {
deviceNotSupportedError.message = error;
} else {
nextState.errors.push({message: error});
}
}
}
return nextState;
};
function mergeError(
errors: FlipperError[],
newError: FlipperError,

View File

@@ -78,6 +78,7 @@ export default class CertificateProvider {
logger: Logger;
adb: Promise<ADBClient>;
certificateSetup: Promise<void>;
store: Store;
server: Server;
constructor(server: Server, logger: Logger, store: Store) {
@@ -87,6 +88,7 @@ export default class CertificateProvider {
this.ensureServerCertExists(),
'ensureServerCertExists',
);
this.store = store;
this.server = server;
}
@@ -261,7 +263,13 @@ export default class CertificateProvider {
return tmpDir({unsafeCleanup: true}).then((dir) => {
const filePath = path.resolve(dir, filename);
promisify(fs.writeFile)(filePath, contents).then(() =>
iosUtil.push(udid, filePath, bundleId, destination),
iosUtil.push(
udid,
filePath,
bundleId,
destination,
this.store.getState().settingsState.idbPath,
),
);
});
}
@@ -386,7 +394,13 @@ export default class CertificateProvider {
return tmpDir({unsafeCleanup: true})
.then((dir) => {
return iosUtil
.pull(deviceId, originalFile, bundleId, path.join(dir, csrFileName))
.pull(
deviceId,
originalFile,
bundleId,
path.join(dir, csrFileName),
this.store.getState().settingsState.idbPath,
)
.then(() => dir);
})
.then((dir) => {

View File

@@ -14,9 +14,8 @@ import {notNull} from './typeUtils';
const unsafeExec = promisify(child_process.exec);
import {killOrphanedInstrumentsProcesses} from './processCleanup';
import {reportPlatformFailures} from './metrics';
import config from '../fb-stubs/config';
import {promises, constants} from 'fs';
const idbPath = '/usr/local/bin/idb';
// Use debug to get helpful logs when idb fails
const idbLogLevel = 'DEBUG';
const operationPrefix = 'iosContainerUtility';
@@ -29,8 +28,14 @@ export type DeviceTarget = {
name: string;
};
function isAvailable(): boolean {
return config.isFBBuild;
function isAvailable(idbPath: string): Promise<boolean> {
if (!idbPath) {
return Promise.resolve(false);
}
return promises
.access(idbPath, constants.X_OK)
.then((_) => true)
.catch((_) => false);
}
function safeExec(command: string): Promise<{stdout: string; stderr: string}> {
@@ -61,12 +66,14 @@ async function targets(): Promise<Array<DeviceTarget>> {
);
}
function push(
async function push(
udid: string,
src: string,
bundleId: string,
dst: string,
idbPath: string,
): Promise<void> {
await checkIdbIsInstalled(idbPath);
return wrapWithErrorMessage(
reportPlatformFailures(
safeExec(
@@ -75,18 +82,20 @@ function push(
.then(() => {
return;
})
.catch(handleMissingIdb),
.catch((e) => handleMissingIdb(e, idbPath)),
`${operationPrefix}:push`,
),
);
}
function pull(
async function pull(
udid: string,
src: string,
bundleId: string,
dst: string,
idbPath: string,
): Promise<void> {
await checkIdbIsInstalled(idbPath);
return wrapWithErrorMessage(
reportPlatformFailures(
safeExec(
@@ -95,15 +104,24 @@ function pull(
.then(() => {
return;
})
.catch(handleMissingIdb),
.catch((e) => handleMissingIdb(e, idbPath)),
`${operationPrefix}:pull`,
),
);
}
// The idb binary is a shim that downloads the proper one on first run. It requires sudo to do so.
async function checkIdbIsInstalled(idbPath: string): Promise<void> {
const isInstalled = await isAvailable(idbPath);
if (!isInstalled) {
throw new Error(
`idb is required to use iOS devices. Install it with instructions from https://github.com/facebook/idb and set the installation path in Flipper settings.`,
);
}
}
// The fb-internal idb binary is a shim that downloads the proper one on first run. It requires sudo to do so.
// If we detect this, Tell the user how to fix it.
function handleMissingIdb(e: Error): void {
function handleMissingIdb(e: Error, idbPath: string): void {
if (
e.message &&
e.message.includes('sudo: no tty present and no askpass program specified')