Move FlipperServer initialisation out of flipper-core

Summary: This diff makes sure flipper-ui-core no longer depends on flipper-server-core. Currently server config is still transferred from UI to server, which doesn't really make sense in future scenarios where server might start before client, but will address that separately

Reviewed By: timur-valiev, aigoncharov

Differential Revision: D32462835

fbshipit-source-id: 498a944256ba1aabbf963b896953e64d11e27214
This commit is contained in:
Michel Weststrate
2021-12-08 04:25:28 -08:00
committed by Facebook GitHub Bot
parent d48f22b8dc
commit eed19b3a3d
16 changed files with 79 additions and 65 deletions

View File

@@ -26,9 +26,12 @@ import type {RenderHost} from 'flipper-ui-core';
import fs from 'fs'; import fs from 'fs';
import {setupMenuBar} from './setupMenuBar'; import {setupMenuBar} from './setupMenuBar';
import os from 'os'; import os from 'os';
import {FlipperServerImpl} from 'flipper-server-core';
declare global { declare global {
interface Window { 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; FlipperRenderHostInstance: RenderHost;
} }
} }
@@ -46,6 +49,8 @@ export function initializeElectron() {
const app = remote.app; const app = remote.app;
const execPath = process.execPath || remote.process.execPath; const execPath = process.execPath || remote.process.execPath;
const isProduction = !/node_modules[\\/]electron[\\/]/.test(execPath); const isProduction = !/node_modules[\\/]electron[\\/]/.test(execPath);
const staticPath = getStaticDir();
const tempPath = app.getPath('temp');
function restart(update: boolean = false) { function restart(update: boolean = false) {
if (isProduction) { if (isProduction) {
@@ -192,11 +197,21 @@ export function initializeElectron() {
appPath: app.getAppPath(), appPath: app.getAppPath(),
homePath: app.getPath('home'), homePath: app.getPath('home'),
execPath, execPath,
staticPath: getStaticDir(), staticPath,
tempPath: app.getPath('temp'), tempPath,
desktopPath: app.getPath('desktop'), desktopPath: app.getPath('desktop'),
}, },
loadDefaultPlugins: getDefaultPluginsIndex, loadDefaultPlugins: getDefaultPluginsIndex,
startFlipperServer({logger, ...config}) {
return new FlipperServerImpl(
{
...config,
staticPath,
tempPath,
},
logger,
);
},
}; };
setupMenuBar(); setupMenuBar();

View File

@@ -154,6 +154,7 @@ export type FlipperServerCommands = {
}; };
export interface FlipperServer { export interface FlipperServer {
start(): Promise<void>;
on<Event extends keyof FlipperServerEvents>( on<Event extends keyof FlipperServerEvents>(
event: Event, event: Event,
callback: (payload: FlipperServerEvents[Event]) => void, callback: (payload: FlipperServerEvents[Event]) => void,

View File

@@ -74,7 +74,7 @@ async function start(deviceTitle: string, appName: string, pluginId: string) {
enableIOS: true, enableIOS: true,
enablePhysicalIOS: true, enablePhysicalIOS: true,
staticPath: path.resolve(__dirname, '..', '..', 'static'), staticPath: path.resolve(__dirname, '..', '..', 'static'),
tmpPath: os.tmpdir(), tempPath: os.tmpdir(),
validWebSocketOrigins: [], validWebSocketOrigins: [],
}, },
logger, logger,

View File

@@ -40,7 +40,11 @@ import {stubLogger} from '../utils/Logger';
import {Idler} from '../utils/Idler'; import {Idler} from '../utils/Idler';
import {createState} from '../state/atom'; import {createState} from '../state/atom';
import baseMockConsole from 'jest-mock-console'; import baseMockConsole from 'jest-mock-console';
import {DeviceLogEntry} from 'flipper-common'; import {
DeviceLogEntry,
FlipperServer,
FlipperServerCommands,
} from 'flipper-common';
type Renderer = RenderResult<typeof queries>; type Renderer = RenderResult<typeof queries>;
@@ -581,3 +585,26 @@ export function mockConsole() {
} }
export type MockedConsole = ReturnType<typeof mockConsole>; export type MockedConsole = ReturnType<typeof mockConsole>;
export function createFlipperServerMock(
overrides?: Partial<FlipperServerCommands>,
): FlipperServer {
return {
async start() {},
on: jest.fn(),
off: jest.fn(),
exec: jest
.fn()
.mockImplementation(
(cmd: keyof FlipperServerCommands, ...args: any[]) => {
if (overrides?.[cmd]) {
return (overrides[cmd] as any)(...args);
}
return Promise.reject(
new Error(`FlipperServerMock exec not implemented: ${cmd}}`),
);
},
),
close: jest.fn(),
};
}

View File

@@ -18,7 +18,7 @@ export interface FlipperServerConfig {
enablePhysicalIOS: boolean; enablePhysicalIOS: boolean;
validWebSocketOrigins: string[]; validWebSocketOrigins: string[];
staticPath: string; staticPath: string;
tmpPath: string; tempPath: string;
} }
// defaultConfig should be used for testing only, and disables by default all features // defaultConfig should be used for testing only, and disables by default all features
@@ -30,7 +30,7 @@ const testConfig: FlipperServerConfig = {
idbPath: '', idbPath: '',
validWebSocketOrigins: [], validWebSocketOrigins: [],
staticPath: '/static/', staticPath: '/static/',
tmpPath: '/temp/', tempPath: '/temp/',
}; };
let currentConfig: FlipperServerConfig | undefined = undefined; let currentConfig: FlipperServerConfig | undefined = undefined;

View File

@@ -98,7 +98,7 @@ export function xcrunStartLogListener(udid: string, deviceType: DeviceType) {
function makeTempScreenshotFilePath() { function makeTempScreenshotFilePath() {
const imageName = uuid() + '.png'; const imageName = uuid() + '.png';
return path.join(getFlipperServerConfig().tmpPath, imageName); return path.join(getFlipperServerConfig().tempPath, imageName);
} }
async function runScreenshotCommand( async function runScreenshotCommand(

View File

@@ -34,7 +34,6 @@
"flipper-doctor": "0.0.0", "flipper-doctor": "0.0.0",
"flipper-plugin": "0.0.0", "flipper-plugin": "0.0.0",
"flipper-plugin-lib": "0.0.0", "flipper-plugin-lib": "0.0.0",
"flipper-server-core": "0.0.0",
"flipper-ui-core": "0.0.0", "flipper-ui-core": "0.0.0",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"immer": "^9.0.6", "immer": "^9.0.6",

View File

@@ -10,8 +10,9 @@
import type {NotificationEvents} from './dispatcher/notifications'; import type {NotificationEvents} from './dispatcher/notifications';
import type {PluginNotification} from './reducers/notifications'; import type {PluginNotification} from './reducers/notifications';
import type {NotificationConstructorOptions} from 'electron'; import type {NotificationConstructorOptions} from 'electron';
import type {FlipperLib} from 'flipper-plugin'; import {FlipperLib, TestUtils} from 'flipper-plugin';
import path from 'path'; import path from 'path';
import {FlipperServer, Logger} from 'flipper-common';
type ENVIRONMENT_VARIABLES = 'NODE_ENV' | 'DEV_SERVER_URL' | 'CONFIG'; type ENVIRONMENT_VARIABLES = 'NODE_ENV' | 'DEV_SERVER_URL' | 'CONFIG';
type ENVIRONMENT_PATHS = type ENVIRONMENT_PATHS =
@@ -106,6 +107,16 @@ export interface RenderHost {
paths: Record<ENVIRONMENT_PATHS, string>; paths: Record<ENVIRONMENT_PATHS, string>;
openLink(url: string): void; openLink(url: string): void;
loadDefaultPlugins(): Record<string, any>; loadDefaultPlugins(): Record<string, any>;
startFlipperServer(config: {
// TODO: this config is temporarily, settings should be loaded/stored by server, not client
logger: Logger;
enableAndroid: boolean;
androidHome: string;
enableIOS: boolean;
enablePhysicalIOS: boolean;
idbPath: string;
validWebSocketOrigins: string[];
}): FlipperServer;
} }
export function getRenderHostInstance(): RenderHost { export function getRenderHostInstance(): RenderHost {
@@ -154,5 +165,6 @@ if (process.env.NODE_ENV === 'test') {
loadDefaultPlugins() { loadDefaultPlugins() {
return {}; return {};
}, },
startFlipperServer: () => TestUtils.createFlipperServerMock(),
}; };
} }

View File

@@ -40,6 +40,7 @@ Object {
"exec": [MockFunction], "exec": [MockFunction],
"off": [MockFunction], "off": [MockFunction],
"on": [MockFunction], "on": [MockFunction],
"start": [Function],
}, },
"pluginMenuEntries": Array [], "pluginMenuEntries": Array [],
"selectedAppId": "TestApp#Android#MockAndroidDevice#serial", "selectedAppId": "TestApp#Android#MockAndroidDevice#serial",

View File

@@ -26,6 +26,7 @@ export default class ArchivedDevice extends BaseDevice {
}) { }) {
super( super(
{ {
async start() {},
close() {}, close() {},
exec(command, ..._args: any[]) { exec(command, ..._args: any[]) {
throw new Error( throw new Error(

View File

@@ -14,15 +14,12 @@ import {
Logger, Logger,
NoLongerConnectedToClientError, NoLongerConnectedToClientError,
} from 'flipper-common'; } from 'flipper-common';
import {FlipperServerImpl} from 'flipper-server-core';
import {selectClient} from '../reducers/connections';
import Client from '../Client'; import Client from '../Client';
import {notification} from 'antd'; import {notification} from 'antd';
import BaseDevice from '../devices/BaseDevice'; import BaseDevice from '../devices/BaseDevice';
import {ClientDescription, timeout} from 'flipper-common'; import {ClientDescription, timeout} from 'flipper-common';
import {reportPlatformFailures} from 'flipper-common'; import {reportPlatformFailures} from 'flipper-common';
import {sideEffect} from '../utils/sideEffect'; import {sideEffect} from '../utils/sideEffect';
import {getStaticPath} from '../utils/pathUtils';
import constants from '../fb-stubs/constants'; import constants from '../fb-stubs/constants';
import {getRenderHostInstance} from '../RenderHost'; import {getRenderHostInstance} from '../RenderHost';
@@ -30,19 +27,15 @@ export default async (store: Store, logger: Logger) => {
const {enableAndroid, androidHome, idbPath, enableIOS, enablePhysicalIOS} = const {enableAndroid, androidHome, idbPath, enableIOS, enablePhysicalIOS} =
store.getState().settingsState; store.getState().settingsState;
const server = new FlipperServerImpl( const server = getRenderHostInstance().startFlipperServer({
{ logger,
enableAndroid, enableAndroid,
androidHome, androidHome,
idbPath, idbPath,
enableIOS, enableIOS,
enablePhysicalIOS, enablePhysicalIOS,
staticPath: getStaticPath(),
tmpPath: getRenderHostInstance().paths.tempPath,
validWebSocketOrigins: constants.VALID_WEB_SOCKET_REQUEST_ORIGIN_PREFIXES, validWebSocketOrigins: constants.VALID_WEB_SOCKET_REQUEST_ORIGIN_PREFIXES,
}, });
logger,
);
store.dispatch({ store.dispatch({
type: 'SET_FLIPPER_SERVER', type: 'SET_FLIPPER_SERVER',

View File

@@ -14,12 +14,11 @@ import {createStore} from 'redux';
import {LaunchEmulatorDialog} from '../LaunchEmulator'; import {LaunchEmulatorDialog} from '../LaunchEmulator';
import {createRootReducer} from '../../../reducers'; import {createRootReducer} from '../../../reducers';
import {sleep} from 'flipper-plugin'; import {sleep, TestUtils} from 'flipper-plugin';
import {createFlipperServerMock} from '../../../test-utils/createFlipperServerMock';
test('Can render and launch android apps - empty', async () => { test('Can render and launch android apps - empty', async () => {
const store = createStore(createRootReducer()); const store = createStore(createRootReducer());
const mockServer = createFlipperServerMock({ const mockServer = TestUtils.createFlipperServerMock({
'ios-get-simulators': () => Promise.resolve([]), 'ios-get-simulators': () => Promise.resolve([]),
'android-get-emulators': () => Promise.resolve([]), 'android-get-emulators': () => Promise.resolve([]),
}); });
@@ -49,7 +48,7 @@ test('Can render and launch android apps', async () => {
const store = createStore(createRootReducer()); const store = createStore(createRootReducer());
const launch = jest.fn().mockImplementation(() => Promise.resolve()); const launch = jest.fn().mockImplementation(() => Promise.resolve());
const mockServer = createFlipperServerMock({ const mockServer = TestUtils.createFlipperServerMock({
'ios-get-simulators': () => Promise.resolve([]), 'ios-get-simulators': () => Promise.resolve([]),
'android-get-emulators': () => 'android-get-emulators': () =>
(p = Promise.resolve(['emulator1', 'emulator2'])), (p = Promise.resolve(['emulator1', 'emulator2'])),

View File

@@ -27,8 +27,8 @@ import {PluginDetails} from 'flipper-plugin-lib';
import ArchivedDevice from '../devices/ArchivedDevice'; import ArchivedDevice from '../devices/ArchivedDevice';
import {ClientQuery, DeviceOS} from 'flipper-common'; import {ClientQuery, DeviceOS} from 'flipper-common';
import {TestDevice} from './TestDevice'; import {TestDevice} from './TestDevice';
import {createFlipperServerMock} from './createFlipperServerMock';
import {getRenderHostInstance} from '../RenderHost'; import {getRenderHostInstance} from '../RenderHost';
import {TestUtils} from 'flipper-plugin';
export interface AppOptions { export interface AppOptions {
plugins?: PluginDefinition[]; plugins?: PluginDefinition[];
@@ -58,7 +58,7 @@ export default class MockFlipper {
private _clients: Client[] = []; private _clients: Client[] = [];
private _deviceCounter: number = 0; private _deviceCounter: number = 0;
private _clientCounter: number = 0; private _clientCounter: number = 0;
flipperServer: FlipperServer = createFlipperServerMock(); flipperServer: FlipperServer = TestUtils.createFlipperServerMock();
public get store(): Store { public get store(): Store {
return this._store; return this._store;

View File

@@ -21,6 +21,7 @@ export class TestDevice extends BaseDevice {
) { ) {
super( super(
{ {
async start() {},
on: jest.fn(), on: jest.fn(),
off: jest.fn(), off: jest.fn(),
exec: jest.fn(), exec: jest.fn(),

View File

@@ -1,32 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {FlipperServer, FlipperServerCommands} from 'flipper-common';
export function createFlipperServerMock(
overrides?: Partial<FlipperServerCommands>,
): FlipperServer {
return {
on: jest.fn(),
off: jest.fn(),
exec: jest
.fn()
.mockImplementation(
(cmd: keyof FlipperServerCommands, ...args: any[]) => {
if (overrides?.[cmd]) {
return (overrides[cmd] as any)(...args);
}
return Promise.reject(
new Error(`FlipperServerMock exec not implemented: ${cmd}}`),
);
},
),
close: jest.fn(),
};
}

View File

@@ -16,9 +16,6 @@
{ {
"path": "../flipper-plugin" "path": "../flipper-plugin"
}, },
{
"path": "../flipper-server-core"
},
{ {
"path": "../plugin-lib" "path": "../plugin-lib"
}, },