Move plugin manager logic out of UI component
Summary: Moving some things around for the upcoming update support. Reviewed By: jknoxville Differential Revision: D18347572 fbshipit-source-id: b614fe3a87f8e7fdc0c11c0d3bfe4787c0914d17
This commit is contained in:
committed by
Facebook Github Bot
parent
4c0c212258
commit
05c007be16
@@ -30,7 +30,6 @@ import {List} from 'immutable';
|
|||||||
import algoliasearch from 'algoliasearch';
|
import algoliasearch from 'algoliasearch';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {PluginManager as PM} from 'live-plugin-manager';
|
|
||||||
import {reportPlatformFailures, reportUsage} from '../utils/metrics';
|
import {reportPlatformFailures, reportUsage} from '../utils/metrics';
|
||||||
import restartFlipper from '../utils/restartFlipper';
|
import restartFlipper from '../utils/restartFlipper';
|
||||||
import {
|
import {
|
||||||
@@ -38,17 +37,17 @@ import {
|
|||||||
PluginDefinition,
|
PluginDefinition,
|
||||||
registerInstalledPlugins,
|
registerInstalledPlugins,
|
||||||
} from '../reducers/pluginManager';
|
} from '../reducers/pluginManager';
|
||||||
import {PLUGIN_DIR, readInstalledPlugins} from '../dispatcher/pluginManager';
|
import {
|
||||||
import {State as AppState, Store} from '../reducers';
|
PLUGIN_DIR,
|
||||||
|
readInstalledPlugins,
|
||||||
|
providePluginManager,
|
||||||
|
provideSearchIndex,
|
||||||
|
} from '../utils/pluginManager';
|
||||||
|
import {State as AppState} from '../reducers';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {Dispatch, Action} from 'redux';
|
import {Dispatch, Action} from 'redux';
|
||||||
|
|
||||||
const ALGOLIA_APPLICATION_ID = 'OFCNCOG2CU';
|
|
||||||
const ALGOLIA_API_KEY = 'f54e21fa3a2a0160595bb058179bfb1e';
|
|
||||||
const TAG = 'PluginInstaller';
|
const TAG = 'PluginInstaller';
|
||||||
const PluginManager = new PM({
|
|
||||||
ignoredDependencies: ['flipper', 'react', 'react-dom', '@types/*'],
|
|
||||||
});
|
|
||||||
|
|
||||||
const EllipsisText = styled(Text)({
|
const EllipsisText = styled(Text)({
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
@@ -111,10 +110,7 @@ type OwnProps = {
|
|||||||
type Props = OwnProps & PropsFromState & DispatchFromProps;
|
type Props = OwnProps & PropsFromState & DispatchFromProps;
|
||||||
|
|
||||||
const defaultProps: OwnProps = {
|
const defaultProps: OwnProps = {
|
||||||
searchIndexFactory: () => {
|
searchIndexFactory: provideSearchIndex,
|
||||||
const client = algoliasearch(ALGOLIA_APPLICATION_ID, ALGOLIA_API_KEY);
|
|
||||||
return client.initIndex('npm-search');
|
|
||||||
},
|
|
||||||
autoHeight: false,
|
autoHeight: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -208,13 +204,14 @@ function InstallButton(props: {
|
|||||||
// create empty watchman config (required by metro's file watcher)
|
// create empty watchman config (required by metro's file watcher)
|
||||||
await fs.writeFile(path.join(PLUGIN_DIR, '.watchmanconfig'), '{}');
|
await fs.writeFile(path.join(PLUGIN_DIR, '.watchmanconfig'), '{}');
|
||||||
|
|
||||||
|
const pluginManager = providePluginManager();
|
||||||
// install the plugin and all it's dependencies into node_modules
|
// install the plugin and all it's dependencies into node_modules
|
||||||
PluginManager.options.pluginsPath = path.join(
|
pluginManager.options.pluginsPath = path.join(
|
||||||
PLUGIN_DIR,
|
PLUGIN_DIR,
|
||||||
props.name,
|
props.name,
|
||||||
'node_modules',
|
'node_modules',
|
||||||
);
|
);
|
||||||
await PluginManager.install(props.name);
|
await pluginManager.install(props.name);
|
||||||
|
|
||||||
// move the plugin itself out of the node_modules folder
|
// move the plugin itself out of the node_modules folder
|
||||||
const pluginDir = path.join(
|
const pluginDir = path.join(
|
||||||
|
|||||||
@@ -9,46 +9,8 @@
|
|||||||
|
|
||||||
import {Store} from '../reducers/index';
|
import {Store} from '../reducers/index';
|
||||||
import {Logger} from '../fb-interfaces/Logger';
|
import {Logger} from '../fb-interfaces/Logger';
|
||||||
import path from 'path';
|
import {registerInstalledPlugins} from '../reducers/pluginManager';
|
||||||
import fs from 'fs-extra';
|
import {readInstalledPlugins} from '../utils/pluginManager';
|
||||||
import {homedir} from 'os';
|
|
||||||
import {
|
|
||||||
registerInstalledPlugins,
|
|
||||||
PluginMap,
|
|
||||||
PluginDefinition,
|
|
||||||
} from '../reducers/pluginManager';
|
|
||||||
|
|
||||||
export const PLUGIN_DIR = path.join(homedir(), '.flipper', 'thirdparty');
|
|
||||||
|
|
||||||
export async function readInstalledPlugins(): Promise<PluginMap> {
|
|
||||||
const pluginDirExists = await fs.pathExists(PLUGIN_DIR);
|
|
||||||
|
|
||||||
if (!pluginDirExists) {
|
|
||||||
return new Map();
|
|
||||||
}
|
|
||||||
const dirs = await fs.readdir(PLUGIN_DIR);
|
|
||||||
const plugins = await Promise.all<[string, PluginDefinition]>(
|
|
||||||
dirs.map(
|
|
||||||
name =>
|
|
||||||
new Promise(async (resolve, reject) => {
|
|
||||||
if (!(await fs.lstat(path.join(PLUGIN_DIR, name))).isDirectory()) {
|
|
||||||
return resolve(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
const packageJSON = await fs.readFile(
|
|
||||||
path.join(PLUGIN_DIR, name, 'package.json'),
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
resolve([name, JSON.parse(packageJSON.toString())]);
|
|
||||||
} catch (e) {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return new Map(plugins.filter(Boolean));
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshInstalledPlugins(store: Store) {
|
function refreshInstalledPlugins(store: Store) {
|
||||||
readInstalledPlugins().then(plugins =>
|
readInstalledPlugins().then(plugins =>
|
||||||
|
|||||||
63
src/utils/pluginManager.tsx
Normal file
63
src/utils/pluginManager.tsx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* 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 path from 'path';
|
||||||
|
import fs from 'fs-extra';
|
||||||
|
import {homedir} from 'os';
|
||||||
|
import {PluginMap, PluginDefinition} from '../reducers/pluginManager';
|
||||||
|
import {PluginManager as PM} from 'live-plugin-manager';
|
||||||
|
import algoliasearch from 'algoliasearch';
|
||||||
|
|
||||||
|
const ALGOLIA_APPLICATION_ID = 'OFCNCOG2CU';
|
||||||
|
const ALGOLIA_API_KEY = 'f54e21fa3a2a0160595bb058179bfb1e';
|
||||||
|
|
||||||
|
// TODO(T57014856): The use should be constrained to just this module when the
|
||||||
|
// refactor is done.
|
||||||
|
export function providePluginManager(): PM {
|
||||||
|
return new PM({
|
||||||
|
ignoredDependencies: ['flipper', 'react', 'react-dom', '@types/*'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(T57014856): This should be private, too.
|
||||||
|
export function provideSearchIndex(): algoliasearch.Index {
|
||||||
|
const client = algoliasearch(ALGOLIA_APPLICATION_ID, ALGOLIA_API_KEY);
|
||||||
|
return client.initIndex('npm-search');
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PLUGIN_DIR = path.join(homedir(), '.flipper', 'thirdparty');
|
||||||
|
export async function readInstalledPlugins(): Promise<PluginMap> {
|
||||||
|
const pluginDirExists = await fs.pathExists(PLUGIN_DIR);
|
||||||
|
|
||||||
|
if (!pluginDirExists) {
|
||||||
|
return new Map();
|
||||||
|
}
|
||||||
|
const dirs = await fs.readdir(PLUGIN_DIR);
|
||||||
|
const plugins = await Promise.all<[string, PluginDefinition]>(
|
||||||
|
dirs.map(
|
||||||
|
name =>
|
||||||
|
new Promise(async (resolve, reject) => {
|
||||||
|
if (!(await fs.lstat(path.join(PLUGIN_DIR, name))).isDirectory()) {
|
||||||
|
return resolve(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
const packageJSON = await fs.readFile(
|
||||||
|
path.join(PLUGIN_DIR, name, 'package.json'),
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
resolve([name, JSON.parse(packageJSON.toString())]);
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return new Map(plugins.filter(Boolean));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user