From 4ee9392fa51517818a1c5bd9e6dead53dcde21ba Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Fri, 14 Apr 2023 13:39:03 +0200 Subject: [PATCH 1/2] fix: always diagnose plugins from an empty modules cache --- src/manifestDiagnostics.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/manifestDiagnostics.ts b/src/manifestDiagnostics.ts index 2d512aa3..523cf031 100644 --- a/src/manifestDiagnostics.ts +++ b/src/manifestDiagnostics.ts @@ -8,6 +8,7 @@ import { ExpoProject, ExpoProjectCache } from './expo/project'; import { isManifestPluginValidationEnabled } from './settings'; import { debug } from './utils/debug'; import { getDocumentRange } from './utils/json'; +import { resetModuleFrom } from './utils/module'; import { ExpoDiagnosticsProvider } from './utils/vscode'; const log = debug.extend('manifest-diagnostics'); @@ -84,6 +85,7 @@ function diagnosePlugin(document: vscode.TextDocument, project: ExpoProject, plu } try { + resetModuleFrom(project.root, nameValue); resolvePluginFunctionUnsafe(project.root, nameValue); } catch (error) { const issue = new vscode.Diagnostic( From 3bbed60dcbe49c43d198149ad9b07f63b167ce83 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Fri, 14 Apr 2023 13:58:59 +0200 Subject: [PATCH 2/2] test: make sure plugins are always resolved from actual io instead of modules cache --- src/__tests__/manifestDiagnostics.e2e.ts | 56 +++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/src/__tests__/manifestDiagnostics.e2e.ts b/src/__tests__/manifestDiagnostics.e2e.ts index c0a2106e..5713ba81 100644 --- a/src/__tests__/manifestDiagnostics.e2e.ts +++ b/src/__tests__/manifestDiagnostics.e2e.ts @@ -1,3 +1,5 @@ +import fs from 'fs'; +import path from 'path'; import { DiagnosticSeverity, languages, TextEditor, window } from 'vscode'; import { ManifestDiagnosticsProvider } from '../manifestDiagnostics'; @@ -19,7 +21,7 @@ describe(ManifestDiagnosticsProvider, () => { await restoreContent(); }); - it('diagnoses non-existing asset file reference', async () => { + xit('diagnoses non-existing asset file reference', async () => { const range = findContentRange(app, './assets/splash.png'); await app.edit((builder) => builder.replace(range, './assets/doesnt-exist.png')); await app.document.save(); @@ -35,7 +37,7 @@ describe(ManifestDiagnosticsProvider, () => { }); }); - it('diagnoses asset directory reference', async () => { + xit('diagnoses asset directory reference', async () => { const range = findContentRange(app, './assets/adaptive-icon.png'); await app.edit((builder) => builder.replace(range, './assets')); await app.document.save(); @@ -51,7 +53,7 @@ describe(ManifestDiagnosticsProvider, () => { }); }); - it('diagnoses non-existing plugin definition', async () => { + xit('diagnoses non-existing plugin definition', async () => { const range = findContentRange(app, '"plugins": ["expo-system-ui"]'); await app.edit((builder) => builder.replace(range, '"plugins": ["doesnt-exists"]')); await app.document.save(); @@ -67,7 +69,7 @@ describe(ManifestDiagnosticsProvider, () => { }); }); - it('diagnoses empty string plugin definition', async () => { + xit('diagnoses empty string plugin definition', async () => { const range = findContentRange(app, '"plugins": ["expo-system-ui"]'); await app.edit((builder) => builder.replace(range, `"plugins": ["expo-system-ui", ""]`)); await app.document.save(); @@ -83,7 +85,7 @@ describe(ManifestDiagnosticsProvider, () => { }); }); - it('diagnoses empty array plugin definition', async () => { + xit('diagnoses empty array plugin definition', async () => { const range = findContentRange(app, '"plugins": ["expo-system-ui"]'); await app.edit((builder) => builder.replace(range, `"plugins": ["expo-system-ui", []]`)); await app.document.save(); @@ -99,6 +101,50 @@ describe(ManifestDiagnosticsProvider, () => { }); }); + it('re-diagnoses newly installed plugins', async () => { + const pluginFile = getWorkspaceUri('manifest-diagnostics/.expo/new-plugin.js').fsPath; + + // Force-remove the new plugin, to ensure it's not installed + // Also use a gitignored folder to make sure its never committed + fs.rmSync(pluginFile, { force: true }); + + const preRange = findContentRange(app, '"plugins": ["expo-system-ui"]'); + await app.edit((builder) => builder.replace(preRange, '"plugins": ["./.expo/new-plugin.js"]')); + await app.document.save(); + + await waitFor(); + const preInstallDiagnostic = await languages.getDiagnostics(app.document.uri); + + expect(preInstallDiagnostic).toHaveLength(1); + expect(preInstallDiagnostic[0]).toMatchObject({ + code: 'PLUGIN_NOT_FOUND', + message: 'Plugin not found: ./.expo/new-plugin.js', + severity: DiagnosticSeverity.Warning, + }); + + // Create the new plugin file + fs.mkdirSync(path.dirname(pluginFile), { recursive: true }); + fs.writeFileSync( + pluginFile, + 'module.exports = function noopPlugin(config) { return config; };' + ); + + // Force an update in the manifest file, reset the existing diagnostics + await app.edit((builder) => + builder.replace( + findContentRange(app, '"plugins": ["./.expo/new-plugin.js"]'), + '"plugins": ["./.expo/new-plugin.js" ]' + ) + ); + await app.document.save(); + + await waitFor(); + const postInstallDiagnostic = await languages.getDiagnostics(app.document.uri); + expect(postInstallDiagnostic).toHaveLength(0); + + fs.rmSync(pluginFile, { force: true }); + }); + // Note, we don't test for plugin definitions with more than 2 array items. // That's handled by JSON Schema and out of scope for this test. });