Make plugin updates work

Summary:
Effectively just removes and re-installs but that way we know
we have everything we need.

Reviewed By: jknoxville

Differential Revision: D18479831

fbshipit-source-id: 5d47abfc660288e1137f393534512997e8b3f83e
This commit is contained in:
Pascal Hartig
2019-11-14 08:51:33 -08:00
committed by Facebook Github Bot
parent 144338e74a
commit 24097ea9b2

View File

@@ -42,7 +42,7 @@ import {
readInstalledPlugins, readInstalledPlugins,
providePluginManager, providePluginManager,
provideSearchIndex, provideSearchIndex,
findPluginUpdates, findPluginUpdates as _findPluginUpdates,
UpdateResult, UpdateResult,
} from '../utils/pluginManager'; } from '../utils/pluginManager';
import {State as AppState} from '../reducers'; import {State as AppState} from '../reducers';
@@ -50,7 +50,6 @@ import {connect} from 'react-redux';
import {Dispatch, Action} from 'redux'; import {Dispatch, Action} from 'redux';
const TAG = 'PluginInstaller'; const TAG = 'PluginInstaller';
const ENABLE_PLUGIN_UPDATES = false;
const EllipsisText = styled(Text)({ const EllipsisText = styled(Text)({
overflow: 'hidden', overflow: 'hidden',
@@ -108,6 +107,9 @@ type DispatchFromProps = {
type OwnProps = { type OwnProps = {
searchIndexFactory: () => algoliasearch.Index; searchIndexFactory: () => algoliasearch.Index;
autoHeight: boolean; autoHeight: boolean;
findPluginUpdates: (
currentPlugins: PluginMap,
) => Promise<[string, UpdateResult][]>;
}; };
type Props = OwnProps & PropsFromState & DispatchFromProps; type Props = OwnProps & PropsFromState & DispatchFromProps;
@@ -115,6 +117,7 @@ type Props = OwnProps & PropsFromState & DispatchFromProps;
const defaultProps: OwnProps = { const defaultProps: OwnProps = {
searchIndexFactory: provideSearchIndex, searchIndexFactory: provideSearchIndex,
autoHeight: false, autoHeight: false,
findPluginUpdates: _findPluginUpdates,
}; };
type UpdatablePlugin = { type UpdatablePlugin = {
@@ -147,6 +150,7 @@ const PluginInstaller = function props(props: Props) {
props.searchIndexFactory, props.searchIndexFactory,
props.installedPlugins, props.installedPlugins,
props.refreshInstalledPlugins, props.refreshInstalledPlugins,
props.findPluginUpdates,
); );
const restartApp = useCallback(() => { const restartApp = useCallback(() => {
restartFlipper(); restartFlipper();
@@ -218,24 +222,32 @@ function InstallButton(props: {
| {kind: 'Update'; error?: string}; | {kind: 'Update'; error?: string};
const catchError = ( const catchError = (
actionKind: 'Install' | 'Remove', actionKind: 'Install' | 'Remove' | 'Update',
fn: () => Promise<void>, fn: () => Promise<void>,
) => async () => { ) => async () => {
try { try {
await fn(); await fn();
} catch (err) { } catch (err) {
console.error(err);
setAction({kind: actionKind, error: err.toString()}); setAction({kind: actionKind, error: err.toString()});
} }
}; };
const performInstall = useCallback( const mkInstallCallback = (action: 'Install' | 'Update') =>
catchError('Install', async () => { catchError(action, async () => {
reportUsage(`${TAG}:install`, undefined, props.name); reportUsage(
action === 'Install' ? `${TAG}:install` : `${TAG}:update`,
undefined,
props.name,
);
setAction({kind: 'Waiting'}); setAction({kind: 'Waiting'});
await fs.ensureDir(PLUGIN_DIR); await fs.ensureDir(PLUGIN_DIR);
// 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'), '{}');
// Clean up existing destination files.
await fs.remove(path.join(PLUGIN_DIR, props.name));
const pluginManager = providePluginManager(); 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(
@@ -261,9 +273,17 @@ function InstallButton(props: {
props.onInstall(); props.onInstall();
setAction({kind: 'Remove'}); setAction({kind: 'Remove'});
}), });
[props.name, props.version],
); const performInstall = useCallback(mkInstallCallback('Install'), [
props.name,
props.version,
]);
const performUpdate = useCallback(mkInstallCallback('Update'), [
props.name,
props.version,
]);
const performRemove = useCallback( const performRemove = useCallback(
catchError('Remove', async () => { catchError('Remove', async () => {
@@ -302,7 +322,7 @@ function InstallButton(props: {
reportPlatformFailures(performRemove(), `${TAG}:remove`); reportPlatformFailures(performRemove(), `${TAG}:remove`);
break; break;
case 'Update': case 'Update':
alert('Not implemented yet.'); reportPlatformFailures(performUpdate(), `${TAG}:update`);
break; break;
} }
}}> }}>
@@ -336,6 +356,9 @@ function useNPMSearch(
searchClientFactory: () => algoliasearch.Index, searchClientFactory: () => algoliasearch.Index,
installedPlugins: Map<string, PluginDefinition>, installedPlugins: Map<string, PluginDefinition>,
refreshInstalledPlugins: () => void, refreshInstalledPlugins: () => void,
findPluginUpdates: (
currentPlugins: PluginMap,
) => Promise<[string, UpdateResult][]>,
): TableRows_immutable { ): TableRows_immutable {
const index = useMemo(searchClientFactory, []); const index = useMemo(searchClientFactory, []);
@@ -413,9 +436,7 @@ function useNPMSearch(
useEffect(() => { useEffect(() => {
(async () => { (async () => {
const updates = ENABLE_PLUGIN_UPDATES const updates = new Map(await findPluginUpdates(installedPlugins));
? new Map(await findPluginUpdates(installedPlugins))
: new Map();
setUpdateAnnotatedInstalledPlugins( setUpdateAnnotatedInstalledPlugins(
annotatePluginsWithUpdates(installedPlugins, updates), annotatePluginsWithUpdates(installedPlugins, updates),
); );