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:
committed by
Facebook GitHub Bot
parent
17763809dd
commit
ec6310dc3b
@@ -171,7 +171,7 @@ const INITAL_STATE: State = {
|
|||||||
staticView: WelcomeScreen,
|
staticView: WelcomeScreen,
|
||||||
};
|
};
|
||||||
|
|
||||||
const reducer = (state: State = INITAL_STATE, action: Actions): State => {
|
export default (state: State = INITAL_STATE, action: Actions): State => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'SET_STATIC_VIEW': {
|
case 'SET_STATIC_VIEW': {
|
||||||
const {payload} = action;
|
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(
|
function mergeError(
|
||||||
errors: FlipperError[],
|
errors: FlipperError[],
|
||||||
newError: FlipperError,
|
newError: FlipperError,
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export default class CertificateProvider {
|
|||||||
logger: Logger;
|
logger: Logger;
|
||||||
adb: Promise<ADBClient>;
|
adb: Promise<ADBClient>;
|
||||||
certificateSetup: Promise<void>;
|
certificateSetup: Promise<void>;
|
||||||
|
store: Store;
|
||||||
server: Server;
|
server: Server;
|
||||||
|
|
||||||
constructor(server: Server, logger: Logger, store: Store) {
|
constructor(server: Server, logger: Logger, store: Store) {
|
||||||
@@ -87,6 +88,7 @@ export default class CertificateProvider {
|
|||||||
this.ensureServerCertExists(),
|
this.ensureServerCertExists(),
|
||||||
'ensureServerCertExists',
|
'ensureServerCertExists',
|
||||||
);
|
);
|
||||||
|
this.store = store;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +263,13 @@ export default class CertificateProvider {
|
|||||||
return tmpDir({unsafeCleanup: true}).then((dir) => {
|
return tmpDir({unsafeCleanup: true}).then((dir) => {
|
||||||
const filePath = path.resolve(dir, filename);
|
const filePath = path.resolve(dir, filename);
|
||||||
promisify(fs.writeFile)(filePath, contents).then(() =>
|
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})
|
return tmpDir({unsafeCleanup: true})
|
||||||
.then((dir) => {
|
.then((dir) => {
|
||||||
return iosUtil
|
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);
|
||||||
})
|
})
|
||||||
.then((dir) => {
|
.then((dir) => {
|
||||||
|
|||||||
@@ -14,9 +14,8 @@ import {notNull} from './typeUtils';
|
|||||||
const unsafeExec = promisify(child_process.exec);
|
const unsafeExec = promisify(child_process.exec);
|
||||||
import {killOrphanedInstrumentsProcesses} from './processCleanup';
|
import {killOrphanedInstrumentsProcesses} from './processCleanup';
|
||||||
import {reportPlatformFailures} from './metrics';
|
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
|
// Use debug to get helpful logs when idb fails
|
||||||
const idbLogLevel = 'DEBUG';
|
const idbLogLevel = 'DEBUG';
|
||||||
const operationPrefix = 'iosContainerUtility';
|
const operationPrefix = 'iosContainerUtility';
|
||||||
@@ -29,8 +28,14 @@ export type DeviceTarget = {
|
|||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function isAvailable(): boolean {
|
function isAvailable(idbPath: string): Promise<boolean> {
|
||||||
return config.isFBBuild;
|
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}> {
|
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,
|
udid: string,
|
||||||
src: string,
|
src: string,
|
||||||
bundleId: string,
|
bundleId: string,
|
||||||
dst: string,
|
dst: string,
|
||||||
|
idbPath: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
await checkIdbIsInstalled(idbPath);
|
||||||
return wrapWithErrorMessage(
|
return wrapWithErrorMessage(
|
||||||
reportPlatformFailures(
|
reportPlatformFailures(
|
||||||
safeExec(
|
safeExec(
|
||||||
@@ -75,18 +82,20 @@ function push(
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
return;
|
return;
|
||||||
})
|
})
|
||||||
.catch(handleMissingIdb),
|
.catch((e) => handleMissingIdb(e, idbPath)),
|
||||||
`${operationPrefix}:push`,
|
`${operationPrefix}:push`,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pull(
|
async function pull(
|
||||||
udid: string,
|
udid: string,
|
||||||
src: string,
|
src: string,
|
||||||
bundleId: string,
|
bundleId: string,
|
||||||
dst: string,
|
dst: string,
|
||||||
|
idbPath: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
await checkIdbIsInstalled(idbPath);
|
||||||
return wrapWithErrorMessage(
|
return wrapWithErrorMessage(
|
||||||
reportPlatformFailures(
|
reportPlatformFailures(
|
||||||
safeExec(
|
safeExec(
|
||||||
@@ -95,15 +104,24 @@ function pull(
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
return;
|
return;
|
||||||
})
|
})
|
||||||
.catch(handleMissingIdb),
|
.catch((e) => handleMissingIdb(e, idbPath)),
|
||||||
`${operationPrefix}:pull`,
|
`${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.
|
// If we detect this, Tell the user how to fix it.
|
||||||
function handleMissingIdb(e: Error): void {
|
function handleMissingIdb(e: Error, idbPath: string): void {
|
||||||
if (
|
if (
|
||||||
e.message &&
|
e.message &&
|
||||||
e.message.includes('sudo: no tty present and no askpass program specified')
|
e.message.includes('sudo: no tty present and no askpass program specified')
|
||||||
|
|||||||
Reference in New Issue
Block a user