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

@@ -7,16 +7,168 @@
* @format
*/
import {initializeElectron} from './electron/initializeElectron';
import {enableMapSet} from 'immer';
initializeElectron();
import {
_NuxManagerContext,
_createNuxManager,
_setGlobalInteractionReporter,
_LoggerContext,
} from 'flipper-plugin';
// eslint-disable-next-line no-restricted-imports,flipper/no-electron-remote-imports
import {remote} from 'electron';
import type {RenderHost} from 'flipper-ui-core';
import os from 'os';
import {
FlipperServerImpl,
getGatekeepers,
loadLauncherSettings,
loadProcessConfig,
loadSettings,
setupPrefetcher,
} from 'flipper-server-core';
import {getLogger, Logger, setLoggerInstance} from 'flipper-common';
import constants from './fb-stubs/constants';
import {initializeElectron} from './electron/initializeElectron';
import path from 'path';
import fs from 'fs';
enableMapSet();
// By turning this in a require, we force the JS that the body of this module (init) has completed (initializeElectron),
// before starting the rest of the Flipper process.
// This prevent issues where the render host is referred at module initialisation level,
// but not set yet, which might happen when using normal imports.
// eslint-disable-next-line import/no-commonjs
require('flipper-ui-core').startFlipperDesktop();
declare global {
interface Window {
// We store this as a global, to make sure the renderHost is available
// before flipper-ui-core is loaded and needs those during module initialisation
FlipperRenderHostInstance: RenderHost;
}
}
if (process.env.NODE_ENV === 'development' && os.platform() === 'darwin') {
// By default Node.JS has its internal certificate storage and doesn't use
// the system store. Because of this, it's impossible to access ondemand / devserver
// which are signed using some internal self-issued FB certificates. These certificates
// are automatically installed to MacOS system store on FB machines, so here we're using
// this "mac-ca" library to load them into Node.JS.
global.electronRequire('mac-ca');
}
async function start() {
const app = remote.app;
const execPath = process.execPath || remote.process.execPath;
const isProduction = !/node_modules[\\/]electron[\\/]/.test(execPath);
const env = process.env;
const logger = createDelegatedLogger();
setLoggerInstance(logger);
const flipperServer = new FlipperServerImpl(
{
env,
gatekeepers: getGatekeepers(),
isProduction,
paths: {
appPath: app.getAppPath(),
homePath: app.getPath('home'),
execPath,
staticPath: getStaticDir(),
tempPath: app.getPath('temp'),
desktopPath: app.getPath('desktop'),
},
launcherSettings: await loadLauncherSettings(),
processConfig: loadProcessConfig(env),
settings: await loadSettings(),
validWebSocketOrigins: constants.VALID_WEB_SOCKET_REQUEST_ORIGIN_PREFIXES,
},
logger,
);
await flipperServer.connect();
const flipperServerConfig = await flipperServer.exec('get-config');
initializeElectron(flipperServerConfig);
// By turning this in a require, we force the JS that the body of this module (init) has completed (initializeElectron),
// before starting the rest of the Flipper process.
// This prevent issues where the render host is referred at module initialisation level,
// but not set yet, which might happen when using normal imports.
// eslint-disable-next-line import/no-commonjs
require('flipper-ui-core').startFlipperDesktop(flipperServer);
// Initialize launcher
setupPrefetcher(flipperServerConfig.settings);
}
start().catch((e) => {
console.error('Failed to start Flipper desktop', e);
document.getElementById('root')!.textContent =
'Failed to start Flipper desktop: ' + e;
});
function getStaticDir() {
let _staticPath = path.resolve(__dirname, '..', '..', 'static');
// fs.existSync used here, as fs-extra doesn't resovle properly in the app.asar
/* eslint-disable node/no-sync*/
if (fs.existsSync(_staticPath)) {
// True in unit tests
return _staticPath;
}
if (remote && fs.existsSync(remote.app.getAppPath())) {
_staticPath = path.join(remote.app.getAppPath());
}
if (!fs.existsSync(_staticPath)) {
throw new Error('Static path does not exist: ' + _staticPath);
}
/* eslint-enable node/no-sync*/
return _staticPath;
}
// getLogger() is not yet created when the electron app starts.
// we can't create it here yet, as the real logger is wired up to
// the redux store and the rest of the world. So we create a delegating logger
// that uses a simple implementation until the real one comes available
function createDelegatedLogger(): Logger {
const naiveLogger: Logger = {
track(...args: [any, any, any?, any?]) {
console.warn('(skipper track)', args);
},
trackTimeSince(...args: [any, any, any?]) {
console.warn('(skipped trackTimeSince)', args);
},
debug(...args: any[]) {
console.debug(...args);
},
error(...args: any[]) {
console.error(...args);
console.warn('(skipped error reporting)');
},
warn(...args: any[]) {
console.warn(...args);
console.warn('(skipped error reporting)');
},
info(...args: any[]) {
console.info(...args);
},
};
// will be overwrittingen later
setLoggerInstance(naiveLogger);
return {
track() {
// noop
},
trackTimeSince() {
// noop
},
debug(...args: any[]) {
getLogger().debug(...args);
},
error(...args: any[]) {
getLogger().error(...args);
},
warn(...args: any[]) {
getLogger().warn(...args);
},
info(...args: any[]) {
getLogger().info(...args);
},
};
}