Add extension uninstall (#1524)

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
This commit is contained in:
Panu Horsmalahti authored and GitHub committed 2020-11-26 10:45:47 +02:00
1 parent 95d7ff847e
commit ccd38b5cbe
8 files changed
+106 -42

No files matched your search

@@ -18,6 +18,7 @@ jest.mock(
name: "TestExtension",
version: "1.0.0",
},
absolutePath: "/test/1",
manifestPath,
isBundled: false,
isEnabled: true,
@@ -30,6 +31,7 @@ jest.mock(
name: "TestExtension2",
version: "2.0.0",
},
absolutePath: "/test/2",
manifestPath: manifestPath2,
isBundled: false,
isEnabled: true,
@@ -52,6 +54,7 @@ jest.mock(
name: "TestExtension",
version: "1.0.0",
},
absolutePath: "/test/1",
manifestPath,
isBundled: false,
isEnabled: true,
@@ -64,7 +67,8 @@ jest.mock(
name: "TestExtension3",
version: "3.0.0",
},
manifestPath3,
absolutePath: "/test/3",
manifestPath: manifestPath3,
isBundled: false,
isEnabled: true,
},
@@ -94,6 +98,7 @@ describe("ExtensionLoader", () => {
expect(extensionLoader.userExtensions).toMatchInlineSnapshot(`
Map {
"manifest/path" => Object {
"absolutePath": "/test/1",
"isBundled": false,
"isEnabled": true,
"manifest": Object {
@@ -103,13 +108,14 @@ describe("ExtensionLoader", () => {
"manifestPath": "manifest/path",
},
"manifest/path3" => Object {
"absolutePath": "/test/3",
"isBundled": false,
"isEnabled": true,
"manifest": Object {
"name": "TestExtension3",
"version": "3.0.0",
},
"manifestPath3": "manifest/path3",
"manifestPath": "manifest/path3",
},
}
`);
@@ -9,6 +9,7 @@ describe("lens extension", () => {
name: "foo-bar",
version: "0.1.1"
},
absolutePath: "/absolute/fake/",
manifestPath: "/this/is/fake/package.json",
isBundled: false,
isEnabled: true
+25
View File
@@ -11,6 +11,12 @@ import type { LensExtensionId, LensExtensionManifest } from "./lens-extension";
export interface InstalledExtension {
readonly manifest: LensExtensionManifest;
// Absolute path to the non-symlinked source folder,
// e.g. "/Users/user/.k8slens/extensions/helloworld"
readonly absolutePath: string;
// Absolute to the symlinked package.json file
readonly manifestPath: string;
readonly isBundled: boolean; // defined in project root's package.json
isEnabled: boolean;
@@ -174,6 +180,24 @@ export class ExtensionDiscovery {
}
};
/**
* Uninstalls extension by path.
* The application will detect the folder unlink and remove the extension from the UI automatically.
* @param absolutePath Path to the non-symlinked folder of the extension
*/
async uninstallExtension(absolutePath: string) {
logger.info(`${logModule} Uninstalling ${absolutePath}`);
const exists = await fs.pathExists(absolutePath);
if (!exists) {
throw new Error(`Extension path ${absolutePath} doesn't exist`);
}
// fs.remove does nothing if the path doesn't exist anymore
await fs.remove(absolutePath);
}
async load(): Promise<Map<LensExtensionId, InstalledExtension>> {
if (this.loadStarted) {
// The class is simplified by only supporting .load() to be called once
@@ -230,6 +254,7 @@ export class ExtensionDiscovery {
const isEnabled = isBundled || extensionsStore.isEnabled(installedManifestPath);
return {
absolutePath: path.dirname(manifestPath),
manifestPath: installedManifestPath,
manifest: manifestJson,
isBundled,
+11 -9
View File
@@ -68,15 +68,18 @@ export class ExtensionLoader {
logger.info(`${logModule} deleting extension instance ${lensExtensionId}`);
const instance = this.instances.get(lensExtensionId);
if (instance) {
try {
instance.disable();
this.events.emit("remove", instance);
this.instances.delete(lensExtensionId);
} catch (error) {
logger.error(`${logModule}: deactivation extension error`, { lensExtensionId, error });
}
if (!instance) {
return;
}
try {
instance.disable();
this.events.emit("remove", instance);
this.instances.delete(lensExtensionId);
} catch (error) {
logger.error(`${logModule}: deactivation extension error`, { lensExtensionId, error });
}
}
removeExtension(lensExtensionId: LensExtensionId) {
@@ -85,7 +88,6 @@ export class ExtensionLoader {
if (!this.extensions.delete(lensExtensionId)) {
throw new Error(`Can't remove extension ${lensExtensionId}, doesn't exist.`);
}
}
protected async initMain() {
+4
View File
@@ -114,3 +114,7 @@ export class LensExtension {
export function sanitizeExtensionName(name: string) {
return name.replace("@", "").replace("/", "--");
}
export function extensionDisplayName(name: string, version: string) {
return `${name}@${version}`;
}
@@ -11,6 +11,7 @@ describe("getPageUrl", () => {
name: "foo-bar",
version: "0.1.1"
},
absolutePath: "/absolute/fake/",
manifestPath: "/this/is/fake/package.json",
isBundled: false,
isEnabled: true
@@ -41,6 +42,7 @@ describe("globalPageRegistry", () => {
name: "@acme/foo-bar",
version: "0.1.1"
},
absolutePath: "/absolute/fake/",
manifestPath: "/this/is/fake/package.json",
isBundled: false,
isEnabled: true