Refactor headless start function
Summary: Refactors the headless to have a list of closures instead of the `if` conditions. This will make addition of new arguments easy as it will be just adding a new closure to the list. One can change the order of the execution of the closures by inserting it at whatever index the user wants. Reviewed By: passy Differential Revision: D15965142 fbshipit-source-id: e9f348fe9d9011adcd47d140713d6187eab3b3d3
This commit is contained in:
committed by
Facebook Github Bot
parent
4aafc49aaf
commit
cad26c9319
@@ -23,6 +23,9 @@ import setup from '../static/setup.js';
|
|||||||
import type {Store} from '../src/reducers';
|
import type {Store} from '../src/reducers';
|
||||||
import {getActivePluginNames} from '../src/utils/pluginUtils.js';
|
import {getActivePluginNames} from '../src/utils/pluginUtils.js';
|
||||||
import {serialize} from '../src/utils/serialization';
|
import {serialize} from '../src/utils/serialization';
|
||||||
|
import type BaseDevice from '../src/devices/BaseDevice';
|
||||||
|
|
||||||
|
type Action = {|exit: boolean, exitMessage?: string|};
|
||||||
|
|
||||||
type UserArguments = {|
|
type UserArguments = {|
|
||||||
securePort: string,
|
securePort: string,
|
||||||
@@ -116,37 +119,33 @@ function errorAndExit(error: string): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function earlyExitActions(
|
async function earlyExitActions(
|
||||||
|
exitClosures: Array<(userArguments: UserArguments) => Promise<Action>>,
|
||||||
userArguments: UserArguments,
|
userArguments: UserArguments,
|
||||||
originalConsole: typeof global.console,
|
originalConsole: typeof global.console,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (userArguments.listDevices) {
|
for (const exitAction of exitClosures) {
|
||||||
const devices = await listDevices();
|
const {exit, exitMessage} = await exitAction(userArguments);
|
||||||
outputAndExit(devices.toString());
|
if (exit) {
|
||||||
|
outputAndExit(exitMessage || 'Exited through the earlyExit action');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function exitActions(
|
async function exitActions(
|
||||||
|
exitClosures: Array<
|
||||||
|
(userArguments: UserArguments, store: Store) => Promise<Action>,
|
||||||
|
>,
|
||||||
userArguments: UserArguments,
|
userArguments: UserArguments,
|
||||||
originalConsole: typeof global.console,
|
|
||||||
store: Store,
|
store: Store,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (userArguments.listPlugins) {
|
const {metrics, exit} = userArguments;
|
||||||
outputAndExit(serialize(getActivePluginNames(store.getState().plugins)));
|
for (var exitAction of exitClosures) {
|
||||||
|
const {exit, exitMessage} = await exitAction(userArguments, store);
|
||||||
|
if (exit) {
|
||||||
|
outputAndExit(exitMessage || 'Exited through the exitActions function');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const {metrics, exit} = userArguments;
|
|
||||||
if (shouldExportMetric(metrics) && metrics && metrics.length > 0) {
|
|
||||||
try {
|
|
||||||
const payload = await exportMetricsFromTrace(
|
|
||||||
metrics,
|
|
||||||
pluginsClassMap(store.getState().plugins),
|
|
||||||
);
|
|
||||||
outputAndExit(payload.toString());
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (exit == 'sigint') {
|
if (exit == 'sigint') {
|
||||||
process.on('SIGINT', async () => {
|
process.on('SIGINT', async () => {
|
||||||
try {
|
try {
|
||||||
@@ -170,33 +169,16 @@ async function exitActions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function storeModifyingActions(
|
async function storeModifyingActions(
|
||||||
|
storeModifyingClosures: Array<
|
||||||
|
(userArguments: UserArguments, store: Store) => Promise<Action>,
|
||||||
|
>,
|
||||||
userArguments: UserArguments,
|
userArguments: UserArguments,
|
||||||
originalConsole: typeof global.console,
|
|
||||||
store: Store,
|
store: Store,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const {device: selectedDeviceID} = userArguments;
|
for (const closure of storeModifyingClosures) {
|
||||||
if (selectedDeviceID) {
|
const {exit, exitMessage} = await closure(userArguments, store);
|
||||||
//$FlowFixMe: Checked the class name before calling reverse.
|
if (exit) {
|
||||||
const devices = await listDevices();
|
outputAndExit(exitMessage || 'Exited through the earlyExit action');
|
||||||
const matchedDevice = devices.find(
|
|
||||||
device => device.serial === selectedDeviceID,
|
|
||||||
);
|
|
||||||
if (matchedDevice) {
|
|
||||||
if (matchedDevice.constructor.name === 'AndroidDevice') {
|
|
||||||
const ports = store.getState().application.serverPorts;
|
|
||||||
matchedDevice.reverse([ports.secure, ports.insecure]);
|
|
||||||
}
|
|
||||||
store.dispatch({
|
|
||||||
type: 'REGISTER_DEVICE',
|
|
||||||
payload: matchedDevice,
|
|
||||||
});
|
|
||||||
store.dispatch({
|
|
||||||
type: 'SELECT_DEVICE',
|
|
||||||
payload: matchedDevice,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(`No device matching the serial ${selectedDeviceID}`);
|
|
||||||
process.exit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,13 +252,107 @@ async function startFlipper(userArguments: UserArguments) {
|
|||||||
);
|
);
|
||||||
const logger = initLogger(store, {isHeadless: true});
|
const logger = initLogger(store, {isHeadless: true});
|
||||||
|
|
||||||
await earlyExitActions(userArguments, originalConsole);
|
const earlyExitClosures: Array<
|
||||||
|
(userArguments: UserArguments) => Promise<Action>,
|
||||||
|
> = [
|
||||||
|
(userArguments: UserArguments) => {
|
||||||
|
if (userArguments.listDevices) {
|
||||||
|
return listDevices().then((devices: Array<BaseDevice>) => {
|
||||||
|
const mapped = devices.map(device => {
|
||||||
|
return {
|
||||||
|
os: device.os,
|
||||||
|
title: device.title,
|
||||||
|
deviceType: device.deviceType,
|
||||||
|
serial: device.serial,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return {exit: true, exitMessage: serialize(mapped)};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({exit: false});
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
await earlyExitActions(earlyExitClosures, userArguments);
|
||||||
|
|
||||||
const cleanupDispatchers = dispatcher(store, logger);
|
const cleanupDispatchers = dispatcher(store, logger);
|
||||||
|
|
||||||
await storeModifyingActions(userArguments, originalConsole, store);
|
const storeModifyingClosures: Array<
|
||||||
|
(userArguments: UserArguments, store: Store) => Promise<Action>,
|
||||||
|
> = [
|
||||||
|
(userArguments: UserArguments, store: Store) => {
|
||||||
|
const {device: selectedDeviceID} = userArguments;
|
||||||
|
if (selectedDeviceID) {
|
||||||
|
return listDevices().then(devices => {
|
||||||
|
const matchedDevice = devices.find(
|
||||||
|
device => device.serial === selectedDeviceID,
|
||||||
|
);
|
||||||
|
if (matchedDevice) {
|
||||||
|
if (matchedDevice.constructor.name === 'AndroidDevice') {
|
||||||
|
const ports = store.getState().application.serverPorts;
|
||||||
|
//$FlowFixMe: Checked the class name before calling reverse.
|
||||||
|
matchedDevice.reverse([ports.secure, ports.insecure]);
|
||||||
|
}
|
||||||
|
store.dispatch({
|
||||||
|
type: 'REGISTER_DEVICE',
|
||||||
|
payload: matchedDevice,
|
||||||
|
});
|
||||||
|
store.dispatch({
|
||||||
|
type: 'SELECT_DEVICE',
|
||||||
|
payload: matchedDevice,
|
||||||
|
});
|
||||||
|
return {exit: false};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
exit: true,
|
||||||
|
exitMessage: `No device matching the serial ${selectedDeviceID}`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
exit: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
await exitActions(userArguments, originalConsole, store);
|
const exitActionClosures: Array<
|
||||||
|
(userArguments: UserArguments, store: Store) => Promise<Action>,
|
||||||
|
> = [
|
||||||
|
(userArguments: UserArguments, store: Store) => {
|
||||||
|
const {listPlugins} = userArguments;
|
||||||
|
if (listPlugins) {
|
||||||
|
return Promise.resolve({
|
||||||
|
exit: true,
|
||||||
|
exitMessage: serialize(
|
||||||
|
getActivePluginNames(store.getState().plugins),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
exit: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(userArguments: UserArguments, store: Store) => {
|
||||||
|
const {metrics} = userArguments;
|
||||||
|
if (shouldExportMetric(metrics) && metrics && metrics.length > 0) {
|
||||||
|
return exportMetricsFromTrace(
|
||||||
|
metrics,
|
||||||
|
pluginsClassMap(store.getState().plugins),
|
||||||
|
)
|
||||||
|
.then(payload => {
|
||||||
|
return {exit: true, exitMessage: payload ? payload.toString() : ''};
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
return {exit: true, exitMessage: error};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({exit: false});
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
await storeModifyingActions(storeModifyingClosures, userArguments, store);
|
||||||
|
|
||||||
|
await exitActions(exitActionClosures, userArguments, store);
|
||||||
|
|
||||||
await cleanupDispatchers();
|
await cleanupDispatchers();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ function parseJSON(str: string): ?any {
|
|||||||
export async function exportMetricsFromTrace(
|
export async function exportMetricsFromTrace(
|
||||||
trace: string,
|
trace: string,
|
||||||
pluginsMap: Map<string, Class<FlipperDevicePlugin<> | FlipperPlugin<>>>,
|
pluginsMap: Map<string, Class<FlipperDevicePlugin<> | FlipperPlugin<>>>,
|
||||||
): Promise<?string> {
|
): Promise<string> {
|
||||||
const data = fs.readFileSync(trace, 'utf8');
|
const data = fs.readFileSync(trace, 'utf8');
|
||||||
const parsedJSONData = parseJSON(data);
|
const parsedJSONData = parseJSON(data);
|
||||||
if (!parsedJSONData) {
|
if (!parsedJSONData) {
|
||||||
|
|||||||
Reference in New Issue
Block a user