Move settings, launcherSettings, GKs to app / flipper-server-core

Summary:
This diff moves a lot of stuff from the client to the server. This diff is fairly large, as a lot of concept closely relate, although some things have split off to the earlier diffs in the stack, or are still to follow (like making intern requests).

This diff primarily moves reading and storing settings and GKs from client to server (both flipper and launcher settings). This means that settings are no longer persisted by Redux (which only exists on client). Most other changes are fallout from that. For now settings are just one big object, although we might need to separate settings that are only make sense in an Electron context. For example launcher settings.

Reviewed By: passy, aigoncharov

Differential Revision: D32498649

fbshipit-source-id: d842faf7a7f03774b621c7656e53a9127afc6192
This commit is contained in:
Michel Weststrate
2021-12-08 04:25:28 -08:00
committed by Facebook GitHub Bot
parent eed19b3a3d
commit bca169df73
71 changed files with 844 additions and 830 deletions

View File

@@ -21,12 +21,11 @@ import path from 'path';
import {createRootReducer, State} from '../../reducers/index';
import {getLogger} from 'flipper-common';
import configureStore from 'redux-mock-store';
import {TEST_PASSING_GK, TEST_FAILING_GK} from '../../fb-stubs/GK';
import TestPlugin from './TestPlugin';
import {resetConfigForTesting} from '../../utils/processConfig';
import {_SandyPluginDefinition} from 'flipper-plugin';
import {mocked} from 'ts-jest/utils';
import loadDynamicPlugins from '../../utils/loadDynamicPlugins';
import {getRenderHostInstance} from '../../RenderHost';
const loadDynamicPluginsMock = mocked(loadDynamicPlugins);
@@ -57,7 +56,6 @@ const sampleBundledPluginDetails: BundledPluginDetails = {
};
beforeEach(() => {
resetConfigForTesting();
loadDynamicPluginsMock.mockResolvedValue([]);
});
@@ -80,10 +78,13 @@ test('getDynamicPlugins returns empty array on errors', async () => {
test('checkDisabled', () => {
const disabledPlugin = 'pluginName';
const config = {disabledPlugins: [disabledPlugin]};
const orig = process.env.CONFIG;
const hostConfig = getRenderHostInstance().serverConfig;
const orig = hostConfig.processConfig;
try {
process.env.CONFIG = JSON.stringify(config);
hostConfig.processConfig = {
...orig,
disabledPlugins: new Set([disabledPlugin]),
};
const disabled = checkDisabled([]);
expect(
@@ -93,7 +94,6 @@ test('checkDisabled', () => {
version: '1.0.0',
}),
).toBeTruthy();
expect(
disabled({
...sampleBundledPluginDetails,
@@ -102,7 +102,7 @@ test('checkDisabled', () => {
}),
).toBeFalsy();
} finally {
process.env.CONFIG = orig;
hostConfig.processConfig = orig;
}
});
@@ -121,7 +121,7 @@ test('checkGK for passing plugin', () => {
checkGK([])({
...sampleBundledPluginDetails,
name: 'pluginID',
gatekeeper: TEST_PASSING_GK,
gatekeeper: 'TEST_PASSING_GK',
version: '1.0.0',
}),
).toBeTruthy();
@@ -133,7 +133,7 @@ test('checkGK for failing plugin', () => {
const plugins = checkGK(gatekeepedPlugins)({
...sampleBundledPluginDetails,
name,
gatekeeper: TEST_FAILING_GK,
gatekeeper: 'TEST_FAILING_GK',
version: '1.0.0',
});

View File

@@ -13,6 +13,7 @@ import {
FlipperServer,
Logger,
NoLongerConnectedToClientError,
isTest,
} from 'flipper-common';
import Client from '../Client';
import {notification} from 'antd';
@@ -20,23 +21,12 @@ import BaseDevice from '../devices/BaseDevice';
import {ClientDescription, timeout} from 'flipper-common';
import {reportPlatformFailures} from 'flipper-common';
import {sideEffect} from '../utils/sideEffect';
import constants from '../fb-stubs/constants';
import {getRenderHostInstance} from '../RenderHost';
export default async (store: Store, logger: Logger) => {
const {enableAndroid, androidHome, idbPath, enableIOS, enablePhysicalIOS} =
store.getState().settingsState;
const server = getRenderHostInstance().startFlipperServer({
logger,
enableAndroid,
androidHome,
idbPath,
enableIOS,
enablePhysicalIOS,
validWebSocketOrigins: constants.VALID_WEB_SOCKET_REQUEST_ORIGIN_PREFIXES,
});
export function connectFlipperServerToStore(
server: FlipperServer,
store: Store,
logger: Logger,
) {
store.dispatch({
type: 'SET_FLIPPER_SERVER',
payload: server,
@@ -147,25 +137,55 @@ export default async (store: Store, logger: Logger) => {
});
}
server
.start()
.then(() => {
console.log(
'Flipper server started and accepting device / client connections',
);
})
.catch((e) => {
console.error('Failed to start Flipper server', e);
notification.error({
message: 'Failed to start Flipper server',
description: 'error: ' + e,
});
});
let sideEffectDisposer: undefined | (() => void);
if (!isTest()) {
sideEffectDisposer = startSideEffects(store, server);
}
console.log(
'Flipper server started and accepting device / client connections',
);
return () => {
sideEffectDisposer?.();
server.close();
};
};
}
function startSideEffects(store: Store, server: FlipperServer) {
const dispose1 = sideEffect(
store,
{
name: 'settingsPersistor',
throttleMs: 100,
},
(state) => state.settingsState,
(settings) => {
server.exec('persist-settings', settings).catch((e) => {
console.error('Failed to persist Flipper settings', e);
});
},
);
const dispose2 = sideEffect(
store,
{
name: 'launcherSettingsPersistor',
throttleMs: 100,
},
(state) => state.launcherSettingsState,
(settings) => {
server.exec('persist-launcher-settings', settings).catch((e) => {
console.error('Failed to persist launcher settings', e);
});
},
);
return () => {
dispose1();
dispose2();
};
}
export async function handleClientConnected(
server: Pick<FlipperServer, 'exec'>,

View File

@@ -8,7 +8,6 @@
*/
// Used responsibly.
import flipperServer from './flipperServer';
import application from './application';
import tracking from './tracking';
import notifications from './notifications';
@@ -32,7 +31,6 @@ export default function (store: Store, logger: Logger): () => Promise<void> {
const dispatchers: Array<Dispatcher> = [
application,
tracking,
flipperServer,
notifications,
plugins,
user,

View File

@@ -24,11 +24,9 @@ import {
MarketplacePluginDetails,
pluginsInitialized,
} from '../reducers/plugins';
import GK from '../fb-stubs/GK';
import {FlipperBasePlugin} from '../plugin';
import fs from 'fs-extra';
import path from 'path';
import {default as config} from '../utils/processConfig';
import {notNull} from '../utils/typeUtils';
import {
ActivatablePluginDetails,
@@ -151,6 +149,9 @@ export function getLatestCompatibleVersionOfEachPlugin<
}
async function getBundledPlugins(): Promise<Array<BundledPluginDetails>> {
if (process.env.NODE_ENV === 'test') {
return [];
}
// defaultPlugins that are included in the Flipper distributive.
// List of default bundled plugins is written at build time to defaultPlugins/bundled.json.
const pluginPath = getStaticPath(
@@ -183,7 +184,7 @@ export const checkGK =
if (!plugin.gatekeeper) {
return true;
}
const result = GK.get(plugin.gatekeeper);
const result = getRenderHostInstance().GK(plugin.gatekeeper);
if (!result) {
gatekeepedPlugins.push(plugin);
}
@@ -197,15 +198,16 @@ export const checkGK =
export const checkDisabled = (
disabledPlugins: Array<ActivatablePluginDetails>,
) => {
const config = getRenderHostInstance().serverConfig;
let enabledList: Set<string> | null = null;
let disabledList: Set<string> = new Set();
try {
if (process.env.FLIPPER_ENABLED_PLUGINS) {
if (config.env.FLIPPER_ENABLED_PLUGINS) {
enabledList = new Set<string>(
process.env.FLIPPER_ENABLED_PLUGINS.split(','),
config.env.FLIPPER_ENABLED_PLUGINS.split(','),
);
}
disabledList = config().disabledPlugins;
disabledList = config.processConfig.disabledPlugins;
} catch (e) {
console.error('Failed to compute enabled/disabled plugins', e);
}

View File

@@ -21,7 +21,7 @@ export default (store: Store) => {
const settings = store.getState().settingsState.reactNative;
const renderHost = getRenderHostInstance();
if (!settings.shortcuts.enabled) {
if (!settings?.shortcuts.enabled) {
return;
}