From 845c9b67f554fd0769ed19284cf8aa62977747a4 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Wed, 1 Jul 2020 08:58:40 -0700 Subject: [PATCH] Read flipper-plugin from peer deps Summary: To know whether plugins should be mounted with the old setup or new setup (with a Provided / context based api), we need to be able to recognize whether a plugin is written with the old or new setup. We do this by checking if the flipper-plugin dependency is declared as peer dependency. This we can to check for SDK compatibility as well. Reviewed By: jknoxville Differential Revision: D22043085 fbshipit-source-id: 21afabb6e58d86253a464470f4690c51cced87ab --- desktop/plugin-lib/src/PluginDetails.ts | 1 + .../src/__tests__/getPluginDetails.node.ts | 44 +++++++++++++++++++ desktop/plugin-lib/src/getPluginDetails.ts | 2 + desktop/static/getPlugins.ts | 14 +++++- desktop/static/package.json | 1 + 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/desktop/plugin-lib/src/PluginDetails.ts b/desktop/plugin-lib/src/PluginDetails.ts index d513dce45..285a00a37 100644 --- a/desktop/plugin-lib/src/PluginDetails.ts +++ b/desktop/plugin-lib/src/PluginDetails.ts @@ -26,4 +26,5 @@ export default interface PluginDetails { email?: string; url?: string; }; + flipperSDKVersion?: string; } diff --git a/desktop/plugin-lib/src/__tests__/getPluginDetails.node.ts b/desktop/plugin-lib/src/__tests__/getPluginDetails.node.ts index 82353b4f2..a2f18dc20 100644 --- a/desktop/plugin-lib/src/__tests__/getPluginDetails.node.ts +++ b/desktop/plugin-lib/src/__tests__/getPluginDetails.node.ts @@ -41,6 +41,7 @@ test('getPluginDetailsV1', async () => { "description": "Description of Test Plugin", "dir": "/Users/mock/.flipper/thirdparty/flipper-plugin-test", "entry": "/Users/mock/.flipper/plugins/flipper-plugin-test@2.0.0.js", + "flipperSDKVersion": undefined, "gatekeeper": "GK_flipper_plugin_test", "icon": undefined, "id": "flipper-plugin-test", @@ -78,6 +79,7 @@ test('getPluginDetailsV2', async () => { "description": "Description of Test Plugin", "dir": "/Users/mock/.flipper/thirdparty/flipper-plugin-test", "entry": "/Users/mock/.flipper/thirdparty/flipper-plugin-test/dist/bundle.js", + "flipperSDKVersion": undefined, "gatekeeper": "GK_flipper_plugin_test", "icon": undefined, "id": "flipper-plugin-test", @@ -115,6 +117,7 @@ test('id used as title if the latter omited', async () => { "description": "Description of Test Plugin", "dir": "/Users/mock/.flipper/thirdparty/flipper-plugin-test", "entry": "/Users/mock/.flipper/thirdparty/flipper-plugin-test/dist/bundle.js", + "flipperSDKVersion": undefined, "gatekeeper": "GK_flipper_plugin_test", "icon": undefined, "id": "test", @@ -151,6 +154,47 @@ test('name without "flipper-plugin-" prefix is used as title if the latter omite "description": "Description of Test Plugin", "dir": "/Users/mock/.flipper/thirdparty/flipper-plugin-test", "entry": "/Users/mock/.flipper/thirdparty/flipper-plugin-test/dist/bundle.js", + "flipperSDKVersion": undefined, + "gatekeeper": "GK_flipper_plugin_test", + "icon": undefined, + "id": "flipper-plugin-test", + "isDefault": false, + "main": "dist/bundle.js", + "name": "flipper-plugin-test", + "source": "src/index.tsx", + "specVersion": 2, + "title": "test", + "version": "3.0.1", + } + `); +}); + +test('flipper-plugin-version is parsed', async () => { + const pluginV2 = { + $schema: 'https://fbflipper.com/schemas/plugin-package/v2.json', + name: 'flipper-plugin-test', + version: '3.0.1', + main: 'dist/bundle.js', + flipperBundlerEntry: 'src/index.tsx', + description: 'Description of Test Plugin', + gatekeeper: 'GK_flipper_plugin_test', + peerDependencies: { + 'flipper-plugin': '^0.45', + }, + }; + jest.mock('fs-extra', () => jest.fn()); + fs.readJson = jest.fn().mockImplementation(() => pluginV2); + const details = await getPluginDetails(pluginPath); + details.dir = normalizePath(details.dir); + details.entry = normalizePath(details.entry); + expect(details).toMatchInlineSnapshot(` + Object { + "bugs": undefined, + "category": undefined, + "description": "Description of Test Plugin", + "dir": "/Users/mock/.flipper/thirdparty/flipper-plugin-test", + "entry": "/Users/mock/.flipper/thirdparty/flipper-plugin-test/dist/bundle.js", + "flipperSDKVersion": "^0.45", "gatekeeper": "GK_flipper_plugin_test", "icon": undefined, "id": "flipper-plugin-test", diff --git a/desktop/plugin-lib/src/getPluginDetails.ts b/desktop/plugin-lib/src/getPluginDetails.ts index d36a3d79a..f91859411 100644 --- a/desktop/plugin-lib/src/getPluginDetails.ts +++ b/desktop/plugin-lib/src/getPluginDetails.ts @@ -58,6 +58,7 @@ async function getPluginDetailsV1( description: packageJson.description, category: packageJson.category, bugs: packageJson.bugs, + flipperSDKVersion: packageJson?.peerDependencies?.['flipper-plugin'], }; } @@ -83,6 +84,7 @@ async function getPluginDetailsV2( description: packageJson.description, category: packageJson.category, bugs: packageJson.bugs, + flipperSDKVersion: packageJson?.peerDependencies?.['flipper-plugin'], }; } diff --git a/desktop/static/getPlugins.ts b/desktop/static/getPlugins.ts index 1a51188bc..c6fe9e7b6 100644 --- a/desktop/static/getPlugins.ts +++ b/desktop/static/getPlugins.ts @@ -17,6 +17,9 @@ import { import {PluginDetails, getPluginDetails} from 'flipper-plugin-lib'; import pmap from 'p-map'; import pfilter from 'p-filter'; +import {satisfies} from 'semver'; + +const flipperVersion = require('./package.json').version; export async function getSourcePlugins(): Promise { return await getPluginsFromFolders(await getPluginSourceFolders()); @@ -89,7 +92,16 @@ async function entryPointForPluginFolder( .then((packages) => pmap(packages, async ({manifest, dir}) => { try { - return await getPluginDetails(dir, manifest); + const details = await getPluginDetails(dir, manifest); + if ( + details.flipperSDKVersion && + !satisfies(flipperVersion, details.flipperSDKVersion) + ) { + console.warn( + `⚠️ The current Flipper version (${flipperVersion}) doesn't look compatible with the plugin '${manifest.name}', which expects 'flipper-plugin: ${details.flipperSDKVersion}'`, + ); + } + return details; } catch (e) { console.error( `Could not load plugin from "${dir}", because package.json is invalid.`, diff --git a/desktop/static/package.json b/desktop/static/package.json index 3aa33327a..213090f67 100644 --- a/desktop/static/package.json +++ b/desktop/static/package.json @@ -19,6 +19,7 @@ "p-filter": "^2.1.0", "p-map": "^4.0.0", "recursive-readdir": "^2.2.2", + "semver": "^7.3.2", "uuid": "^8.1.0", "ws": "^7.3.0", "xdg-basedir": "^4.0.0",