Use the single type representing plugins
Summary: Use interface PluginDetails everywhere where plugins are handled and removed PluginDefinition type which was effectively a subset of PluginDetails Reviewed By: mweststrate Differential Revision: D21927456 fbshipit-source-id: 434ebeef955b922cc11757e78fbba8dec05f1060
This commit is contained in:
committed by
Facebook GitHub Bot
parent
907cb9e3cc
commit
db3f04a2d7
@@ -10,13 +10,13 @@
|
||||
jest.mock('../../defaultPlugins');
|
||||
|
||||
import dispatcher, {
|
||||
PluginDefinition,
|
||||
getDynamicPlugins,
|
||||
checkDisabled,
|
||||
checkGK,
|
||||
requirePlugin,
|
||||
filterNewestVersionOfEachPlugin,
|
||||
} from '../plugins';
|
||||
import {PluginDetails} from 'flipper-plugin-lib';
|
||||
import path from 'path';
|
||||
import {ipcRenderer, remote} from 'electron';
|
||||
import {FlipperPlugin} from 'flipper';
|
||||
@@ -32,6 +32,19 @@ const mockStore = configureStore<State, {}>([])(
|
||||
);
|
||||
const logger = initLogger(mockStore);
|
||||
|
||||
const samplePluginDetails: PluginDetails = {
|
||||
name: 'other Name',
|
||||
entry: './test/index.js',
|
||||
version: '1.0.0',
|
||||
specVersion: 2,
|
||||
main: 'dist/bundle.js',
|
||||
dir: '/Users/mock/.flipper/thirdparty/flipper-plugin-sample',
|
||||
source: 'src/index.js',
|
||||
id: 'Sample',
|
||||
title: 'Sample',
|
||||
isDefault: false,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
resetConfigForTesting();
|
||||
});
|
||||
@@ -69,6 +82,7 @@ test('checkDisabled', () => {
|
||||
|
||||
expect(
|
||||
disabled({
|
||||
...samplePluginDetails,
|
||||
name: 'other Name',
|
||||
entry: './test/index.js',
|
||||
version: '1.0.0',
|
||||
@@ -77,6 +91,7 @@ test('checkDisabled', () => {
|
||||
|
||||
expect(
|
||||
disabled({
|
||||
...samplePluginDetails,
|
||||
name: disabledPlugin,
|
||||
entry: './test/index.js',
|
||||
version: '1.0.0',
|
||||
@@ -87,6 +102,7 @@ test('checkDisabled', () => {
|
||||
test('checkGK for plugin without GK', () => {
|
||||
expect(
|
||||
checkGK([])({
|
||||
...samplePluginDetails,
|
||||
name: 'pluginID',
|
||||
entry: './test/index.js',
|
||||
version: '1.0.0',
|
||||
@@ -97,6 +113,7 @@ test('checkGK for plugin without GK', () => {
|
||||
test('checkGK for passing plugin', () => {
|
||||
expect(
|
||||
checkGK([])({
|
||||
...samplePluginDetails,
|
||||
name: 'pluginID',
|
||||
gatekeeper: TEST_PASSING_GK,
|
||||
entry: './test/index.js',
|
||||
@@ -106,9 +123,10 @@ test('checkGK for passing plugin', () => {
|
||||
});
|
||||
|
||||
test('checkGK for failing plugin', () => {
|
||||
const gatekeepedPlugins: PluginDefinition[] = [];
|
||||
const gatekeepedPlugins: PluginDetails[] = [];
|
||||
const name = 'pluginID';
|
||||
const plugins = checkGK(gatekeepedPlugins)({
|
||||
...samplePluginDetails,
|
||||
name,
|
||||
gatekeeper: TEST_FAILING_GK,
|
||||
entry: './test/index.js',
|
||||
@@ -122,6 +140,7 @@ test('checkGK for failing plugin', () => {
|
||||
test('requirePlugin returns null for invalid requires', () => {
|
||||
const requireFn = requirePlugin([], {}, require);
|
||||
const plugin = requireFn({
|
||||
...samplePluginDetails,
|
||||
name: 'pluginID',
|
||||
entry: 'this/path/does not/exist',
|
||||
version: '1.0.0',
|
||||
@@ -134,6 +153,7 @@ test('requirePlugin loads plugin', () => {
|
||||
const name = 'pluginID';
|
||||
const requireFn = requirePlugin([], {}, require);
|
||||
const plugin = requireFn({
|
||||
...samplePluginDetails,
|
||||
name,
|
||||
entry: path.join(__dirname, 'TestPlugin'),
|
||||
version: '1.0.0',
|
||||
@@ -143,19 +163,29 @@ test('requirePlugin loads plugin', () => {
|
||||
});
|
||||
|
||||
test('newest version of each plugin is taken', () => {
|
||||
const plugins: PluginDefinition[] = [
|
||||
{name: 'flipper-plugin-test1', version: '0.1.0'},
|
||||
{name: 'flipper-plugin-test2', version: '0.1.0-alpha.201'},
|
||||
{name: 'flipper-plugin-test2', version: '0.1.0-alpha.21'},
|
||||
{name: 'flipper-plugin-test1', version: '0.10.0'},
|
||||
const plugins: PluginDetails[] = [
|
||||
{...samplePluginDetails, name: 'flipper-plugin-test1', version: '0.1.0'},
|
||||
{
|
||||
...samplePluginDetails,
|
||||
name: 'flipper-plugin-test2',
|
||||
version: '0.1.0-alpha.201',
|
||||
},
|
||||
{
|
||||
...samplePluginDetails,
|
||||
name: 'flipper-plugin-test2',
|
||||
version: '0.1.0-alpha.21',
|
||||
},
|
||||
{...samplePluginDetails, name: 'flipper-plugin-test1', version: '0.10.0'},
|
||||
];
|
||||
const filteredPlugins = filterNewestVersionOfEachPlugin(plugins);
|
||||
expect(filteredPlugins).toHaveLength(2);
|
||||
expect(filteredPlugins).toContainEqual({
|
||||
...samplePluginDetails,
|
||||
name: 'flipper-plugin-test1',
|
||||
version: '0.10.0',
|
||||
});
|
||||
expect(filteredPlugins).toContainEqual({
|
||||
...samplePluginDetails,
|
||||
name: 'flipper-plugin-test2',
|
||||
version: '0.1.0-alpha.201',
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import {Store} from '../reducers/index';
|
||||
import {Logger} from '../fb-interfaces/Logger';
|
||||
import {registerInstalledPlugins} from '../reducers/pluginManager';
|
||||
import {readInstalledPlugins} from '../utils/pluginManager';
|
||||
import {readInstalledPlugins} from 'flipper-plugin-lib';
|
||||
|
||||
function refreshInstalledPlugins(store: Store) {
|
||||
readInstalledPlugins().then((plugins) =>
|
||||
|
||||
@@ -30,19 +30,11 @@ import isProduction from '../utils/isProduction';
|
||||
import {notNull} from '../utils/typeUtils';
|
||||
import {sideEffect} from '../utils/sideEffect';
|
||||
import semver from 'semver';
|
||||
import {PluginDetails} from 'flipper-plugin-lib';
|
||||
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import getPluginIndex from '../utils/getDefaultPluginsIndex';
|
||||
|
||||
export type PluginDefinition = {
|
||||
id?: string;
|
||||
name: string;
|
||||
out?: string;
|
||||
gatekeeper?: string;
|
||||
entry?: string;
|
||||
version: string;
|
||||
};
|
||||
|
||||
export default (store: Store, logger: Logger) => {
|
||||
// expose Flipper and exact globally for dynamically loaded plugins
|
||||
const globalObject: any = typeof window === 'undefined' ? global : window;
|
||||
@@ -51,9 +43,9 @@ export default (store: Store, logger: Logger) => {
|
||||
globalObject.Flipper = Flipper;
|
||||
globalObject.adbkit = adbkit;
|
||||
|
||||
const gatekeepedPlugins: Array<PluginDefinition> = [];
|
||||
const disabledPlugins: Array<PluginDefinition> = [];
|
||||
const failedPlugins: Array<[PluginDefinition, string]> = [];
|
||||
const gatekeepedPlugins: Array<PluginDetails> = [];
|
||||
const disabledPlugins: Array<PluginDetails> = [];
|
||||
const failedPlugins: Array<[PluginDetails, string]> = [];
|
||||
|
||||
const defaultPluginsIndex = getPluginIndex();
|
||||
|
||||
@@ -88,9 +80,9 @@ export default (store: Store, logger: Logger) => {
|
||||
};
|
||||
|
||||
export function filterNewestVersionOfEachPlugin(
|
||||
plugins: PluginDefinition[],
|
||||
): PluginDefinition[] {
|
||||
const pluginByName: {[key: string]: PluginDefinition} = {};
|
||||
plugins: PluginDetails[],
|
||||
): PluginDetails[] {
|
||||
const pluginByName: {[key: string]: PluginDetails} = {};
|
||||
for (const plugin of plugins) {
|
||||
if (
|
||||
!pluginByName[plugin.name] ||
|
||||
@@ -102,7 +94,7 @@ export function filterNewestVersionOfEachPlugin(
|
||||
return Object.values(pluginByName);
|
||||
}
|
||||
|
||||
function getBundledPlugins(): Array<PluginDefinition> {
|
||||
function getBundledPlugins(): Array<PluginDetails> {
|
||||
// DefaultPlugins that are included in the bundle.
|
||||
// List of defaultPlugins is written at build time
|
||||
const pluginPath =
|
||||
@@ -111,27 +103,18 @@ function getBundledPlugins(): Array<PluginDefinition> {
|
||||
? path.join(__dirname, 'defaultPlugins')
|
||||
: './defaultPlugins/index.json');
|
||||
|
||||
let bundledPlugins: Array<PluginDefinition> = [];
|
||||
let bundledPlugins: Array<PluginDetails> = [];
|
||||
try {
|
||||
bundledPlugins = global.electronRequire(pluginPath);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
return bundledPlugins
|
||||
.filter((plugin) => notNull(plugin.entry))
|
||||
.map(
|
||||
(plugin) =>
|
||||
({
|
||||
...plugin,
|
||||
entry: path.resolve(pluginPath, plugin.entry!),
|
||||
} as PluginDefinition),
|
||||
)
|
||||
.concat(bundledPlugins.filter((plugin) => !plugin.entry));
|
||||
return bundledPlugins;
|
||||
}
|
||||
|
||||
export function getDynamicPlugins() {
|
||||
let dynamicPlugins: Array<PluginDefinition> = [];
|
||||
let dynamicPlugins: Array<PluginDetails> = [];
|
||||
try {
|
||||
dynamicPlugins = ipcRenderer.sendSync('get-dynamic-plugins');
|
||||
} catch (e) {
|
||||
@@ -140,8 +123,8 @@ export function getDynamicPlugins() {
|
||||
return dynamicPlugins;
|
||||
}
|
||||
|
||||
export const checkGK = (gatekeepedPlugins: Array<PluginDefinition>) => (
|
||||
plugin: PluginDefinition,
|
||||
export const checkGK = (gatekeepedPlugins: Array<PluginDetails>) => (
|
||||
plugin: PluginDetails,
|
||||
): boolean => {
|
||||
if (!plugin.gatekeeper) {
|
||||
return true;
|
||||
@@ -153,8 +136,8 @@ export const checkGK = (gatekeepedPlugins: Array<PluginDefinition>) => (
|
||||
return result;
|
||||
};
|
||||
|
||||
export const checkDisabled = (disabledPlugins: Array<PluginDefinition>) => (
|
||||
plugin: PluginDefinition,
|
||||
export const checkDisabled = (disabledPlugins: Array<PluginDetails>) => (
|
||||
plugin: PluginDetails,
|
||||
): boolean => {
|
||||
let disabledList: Set<string> = new Set();
|
||||
try {
|
||||
@@ -171,17 +154,17 @@ export const checkDisabled = (disabledPlugins: Array<PluginDefinition>) => (
|
||||
};
|
||||
|
||||
export const requirePlugin = (
|
||||
failedPlugins: Array<[PluginDefinition, string]>,
|
||||
failedPlugins: Array<[PluginDetails, string]>,
|
||||
defaultPluginsIndex: any,
|
||||
reqFn: Function = global.electronRequire,
|
||||
) => {
|
||||
return (
|
||||
pluginDefinition: PluginDefinition,
|
||||
pluginDetails: PluginDetails,
|
||||
): typeof FlipperPlugin | typeof FlipperDevicePlugin | null => {
|
||||
try {
|
||||
let plugin = pluginDefinition.entry
|
||||
? reqFn(pluginDefinition.entry)
|
||||
: defaultPluginsIndex[pluginDefinition.name];
|
||||
let plugin = pluginDetails.isDefault
|
||||
? defaultPluginsIndex[pluginDetails.name]
|
||||
: reqFn(pluginDetails.entry);
|
||||
if (plugin.default) {
|
||||
plugin = plugin.default;
|
||||
}
|
||||
@@ -189,21 +172,21 @@ export const requirePlugin = (
|
||||
throw new Error(`Plugin ${plugin.name} is not a FlipperBasePlugin`);
|
||||
}
|
||||
|
||||
plugin.id = plugin.id || pluginDefinition.id;
|
||||
plugin.packageName = pluginDefinition.name;
|
||||
plugin.id = plugin.id || pluginDetails.id;
|
||||
plugin.packageName = pluginDetails.name;
|
||||
|
||||
// set values from package.json as static variables on class
|
||||
Object.keys(pluginDefinition).forEach((key) => {
|
||||
Object.keys(pluginDetails).forEach((key) => {
|
||||
if (key !== 'name' && key !== 'id') {
|
||||
plugin[key] =
|
||||
plugin[key] || pluginDefinition[key as keyof PluginDefinition];
|
||||
plugin[key] || pluginDetails[key as keyof PluginDetails];
|
||||
}
|
||||
});
|
||||
|
||||
return plugin;
|
||||
} catch (e) {
|
||||
failedPlugins.push([pluginDefinition, e.message]);
|
||||
console.error(pluginDefinition, e);
|
||||
failedPlugins.push([pluginDetails, e.message]);
|
||||
console.error(pluginDetails, e);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user