clean up dynamic plugin loading

Summary:
There are 3 sources where plugins can be loaded from:
* `src/plugins`
* `src/fb/plugins`
* any path specified in `~/.sonar/config.json`

Plugins found in the first two directories are bundled with the app when building.

Reviewed By: jknoxville

Differential Revision: D8636061

fbshipit-source-id: 2064090d43d11695ffd99df195e5b594559fe087
This commit is contained in:
Daniel Büchele
2018-06-26 07:10:57 -07:00
committed by Facebook Github Bot
parent 70e11e8269
commit 5edb8bd770
9 changed files with 31 additions and 91 deletions

View File

@@ -26,7 +26,6 @@ function launchElectron({bundleURL, electronURL}) {
const args = [
path.join(STATIC_DIR, 'index.js'),
'--remote-debugging-port=9222',
'--dynamicPlugins=~/fbsource/xplat/sonar/src/plugins,~/fbsource/xplat/sonar/src/fb/plugins',
];
const proc = child.spawn(electronBinary, args, {

View File

@@ -8,11 +8,6 @@
import type {SonarBasePlugin} from './plugin.js';
import {devicePlugins} from './device-plugins/index.js';
import {
isProduction,
loadsDynamicPlugins,
toggleDynamicPluginLoading,
} from './utils/dynamicPluginLoading.js';
import plugins from './plugins/index.js';
import electron from 'electron';
@@ -332,15 +327,6 @@ function getTemplate(app: Object, shell: Object): Array<MenuItem> {
{
type: 'separator',
},
{
label: `Restart in ${
loadsDynamicPlugins() ? 'Production' : 'Development'
} Mode`,
enabled: isProduction(),
click: function() {
toggleDynamicPluginLoading();
},
},
{
label: 'Quit',
accelerator: 'Command+Q',

View File

@@ -7,7 +7,7 @@
import {FlexRow, Text, colors, LoadingIndicator, Glyph, Component} from 'sonar';
import {remote} from 'electron';
import {isProduction} from '../utils/dynamicPluginLoading';
import isProduction from '../utils/isProduction.js';
import config from '../fb-stubs/config.js';
const version = remote.app.getVersion();

View File

@@ -10,16 +10,10 @@ import {
Button,
ButtonGroup,
FlexRow,
FlexBox,
Component,
Spacer,
Glyph,
GK,
} from 'sonar';
import {
loadsDynamicPlugins,
dynamicPluginPath,
} from '../utils/dynamicPluginLoading.js';
import {connect} from 'react-redux';
import {
toggleBugDialogVisible,
@@ -60,10 +54,6 @@ const TitleBar = FlexRow.extends(
},
);
const Icon = FlexBox.extends({
marginRight: 3,
});
type Props = {|
windowIsFocused: boolean,
leftSidebarVisible: boolean,
@@ -82,13 +72,6 @@ class SonarTitleBar extends Component<Props> {
<TitleBar focused={this.props.windowIsFocused} className="toolbar">
<DevicesButton />
<Spacer />
{loadsDynamicPlugins() && (
<Icon
title={`Plugins are loaded dynamically from ${dynamicPluginPath() ||
''}`}>
<Glyph color={colors.light30} name="flash-default" size={16} />
</Icon>
)}
{process.platform === 'darwin' ? <AutoUpdateVersion /> : null}
{config.bugReportButtonVisible && (
<Button

View File

@@ -15,7 +15,7 @@ import {
colors,
brandColors,
} from 'sonar';
import {isProduction} from '../utils/dynamicPluginLoading';
import isProduction from '../utils/isProduction.js';
import {shell, remote} from 'electron';
const Container = FlexColumn.extends({

View File

@@ -1,47 +0,0 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import electron from 'electron';
const DP_ARG = '--dynamicPlugins=';
/* Sometimes remote objects are missing intermittently. To reduce the chance of
* this being a problem while in use. Only read it once at startup.
* https://github.com/electron/electron/issues/8205 */
const _argv = electron.remote.process.argv;
const _loadsDynamicPlugins =
_argv.findIndex(arg => arg.startsWith(DP_ARG)) > -1;
const _isProduction = !/node_modules[\\/]electron[\\/]/.test(
electron.remote.process.execPath,
);
export function isProduction(): boolean {
return _isProduction;
}
export function loadsDynamicPlugins(): boolean {
return _loadsDynamicPlugins;
}
export function toggleDynamicPluginLoading() {
const args = _argv.filter(arg => !arg.startsWith(DP_ARG));
if (!loadsDynamicPlugins()) {
args.push(DP_ARG + '~/fbsource/xplat/sonar/src/plugins');
}
const {app} = electron.remote;
app.relaunch({args: args.slice(1).concat(['--relaunch'])});
app.exit(0);
}
export function dynamicPluginPath(): ?string {
const index = _argv.findIndex(arg => arg.startsWith(DP_ARG));
if (index > -1) {
return _argv[index].replace(DP_ARG, '');
} else {
null;
}
}

16
src/utils/isProduction.js Normal file
View File

@@ -0,0 +1,16 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import electron from 'electron';
const _isProduction = !/node_modules[\\/]electron[\\/]/.test(
electron.remote.process.execPath,
);
export default function isProduction(): boolean {
return _isProduction;
}

View File

@@ -8,7 +8,6 @@
const path = require('path');
const fs = require('fs');
const metro = require('metro');
const yargs = require('yargs');
const HOME_DIR = require('os').homedir();
module.exports = (reloadCallback, pluginPaths, pluginCache) => {
@@ -16,10 +15,7 @@ module.exports = (reloadCallback, pluginPaths, pluginCache) => {
if (!fs.existsSync(pluginCache)) {
fs.mkdirSync(pluginCache);
}
if (yargs.argv.dynamicPlugins) {
// watch for changes on plugins if we are loading plugins dynamically
watchChanges(plugins, reloadCallback, pluginCache);
}
watchChanges(plugins, reloadCallback, pluginCache);
return Promise.all(
Object.values(plugins).map(plugin =>
compilePlugin(plugin, false, pluginCache),
@@ -178,7 +174,12 @@ function compilePlugin(
changeExport(out);
resolve(result);
})
.catch(console.error);
.catch(err => {
console.error(
`❌ Plugin ${name} is ignored, because it could not be compiled.`,
);
console.error(err);
});
}
});
}

View File

@@ -8,7 +8,6 @@ const {app, BrowserWindow} = require('electron');
const path = require('path');
const url = require('url');
const fs = require('fs');
const yargs = require('yargs');
const compilePlugins = require('./compilePlugins.js');
// ensure .sonar folder and config exist
@@ -29,9 +28,12 @@ try {
fs.writeFileSync(configPath, JSON.stringify(config));
}
const pluginPaths = config.pluginPaths.concat(
(yargs.argv.dynamicPlugins || '').split(',').filter(Boolean),
);
const pluginPaths = config.pluginPaths
.concat(
path.join(__dirname, '..', 'src', 'plugins'),
path.join(__dirname, '..', 'src', 'fb', 'plugins'),
)
.filter(fs.existsSync);
process.env.CONFIG = JSON.stringify({
...config,