Fix bundled extensions not being loaded (#7359)

* Fix bundled extensions not being loaded

- Also show that this fixes it by added an example bundled
  extension to 'open-lens'

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix build

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Add explanatory comment for inline require

Signed-off-by: Sebastian Malton <sebastian@malton.name>

---------

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton authored and GitHub committed 2023-03-15 18:16:09 +02:00
1 parent ae9a8c3c41
commit 2c3c88be04
51 files changed
+521 -159

No files matched your search

-7
View File
@@ -1,7 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
// @experimental
export { bundledExtensionInjectionToken } from "../extensions/extension-discovery/bundled-extension-token";
@@ -3,8 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionManifest } from "@k8slens/legacy-extensions";
import { isCompatibleExtension } from "../extension-discovery/is-compatible-extension/is-compatible-extension";
import type { LensExtensionManifest } from "../lens-extension";
describe("Extension/App versions compatibility checks", () => {
it("is compatible with exact version matching", () => {
@@ -16,8 +16,8 @@ export * as Types from "./types";
export * as Proxy from "./proxy";
export type { Logger } from "../../common/logger";
export type { LensExtension, LensExtensionManifest } from "../lens-extension";
export type { InstalledExtension } from "../extension-discovery/extension-discovery";
export type { LensExtension } from "../lens-extension";
export type { PackageJson } from "type-fest";
export type { LensExtensionManifest, InstalledExtension } from "@k8slens/legacy-extensions";
export const logger = asLegacyGlobalForExtensionApi(loggerInjectable);
@@ -1,17 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectionToken } from "@ogre-tools/injectable";
import type { LensExtensionConstructor, LensExtensionManifest } from "../lens-extension";
export interface BundledExtension {
readonly manifest: LensExtensionManifest;
main: () => LensExtensionConstructor | null;
renderer: () => LensExtensionConstructor | null;
}
export const bundledExtensionInjectionToken = getInjectionToken<BundledExtension>({
id: "bundled-extension-path",
});
@@ -11,7 +11,7 @@ import { toJS } from "../../common/utils";
import { isErrnoException } from "@k8slens/utilities";
import type { ExtensionsStore } from "../extensions-store/extensions-store";
import type { ExtensionLoader } from "../extension-loader";
import type { LensExtensionId, LensExtensionManifest } from "../lens-extension";
import type { InstalledExtension, LensExtensionId, LensExtensionManifest } from "@k8slens/legacy-extensions";
import type { ExtensionInstallationStateStore } from "../extension-installation-state-store/extension-installation-state-store";
import { extensionDiscoveryStateChannel } from "../../common/ipc/extension-handling";
import { requestInitialExtensionDiscovery } from "../../renderer/ipc";
@@ -59,22 +59,6 @@ interface Dependencies {
getRelativePath: GetRelativePath;
}
export interface InstalledExtension {
id: LensExtensionId;
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
readonly isCompatible: boolean;
isEnabled: boolean;
}
const logModule = "[EXTENSION-DISCOVERY]";
export const manifestFilename = "package.json";
@@ -2,8 +2,8 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionManifest } from "@k8slens/legacy-extensions";
import semver from "semver";
import type { LensExtensionManifest } from "../../lens-extension";
interface Dependencies {
extensionApiVersion: string;
@@ -3,9 +3,9 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionConstructor, InstalledExtension } from "@k8slens/legacy-extensions";
import { getInjectionToken } from "@ogre-tools/injectable";
import type { InstalledExtension } from "../extension-discovery/extension-discovery";
import type { LensExtension, LensExtensionConstructor } from "../lens-extension";
import type { LensExtension } from "../lens-extension";
export type CreateExtensionInstance = (ExtensionClass: LensExtensionConstructor, extension: InstalledExtension) => LensExtension;
@@ -2,9 +2,10 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId } from "@k8slens/legacy-extensions";
import { getInjectable } from "@ogre-tools/injectable";
import { observable } from "mobx";
import type { LensExtensionId, LensExtension } from "../lens-extension";
import type { LensExtension } from "../lens-extension";
const extensionInstancesInjectable = getInjectable({
id: "extension-instances",
@@ -12,7 +12,7 @@ import extensionInjectable from "./extension/extension.injectable";
import loggerInjectable from "../../common/logger.injectable";
import joinPathsInjectable from "../../common/path/join-paths.injectable";
import getDirnameOfPathInjectable from "../../common/path/get-dirname.injectable";
import { bundledExtensionInjectionToken } from "../extension-discovery/bundled-extension-token";
import { bundledExtensionInjectionToken } from "@k8slens/legacy-extensions";
import { extensionEntryPointNameInjectionToken } from "./entry-point-name";
const extensionLoaderInjectable = getInjectable({
@@ -9,8 +9,7 @@ import type { ObservableMap } from "mobx";
import { action, computed, makeObservable, toJS, observable, observe, reaction, when } from "mobx";
import { broadcastMessage, ipcMainOn, ipcRendererOn, ipcMainHandle } from "../../common/ipc";
import { isDefined } from "@k8slens/utilities";
import type { InstalledExtension } from "../extension-discovery/extension-discovery";
import type { LensExtension, LensExtensionConstructor, LensExtensionId } from "../lens-extension";
import type { LensExtension } from "../lens-extension";
import type { LensExtensionState } from "../extensions-store/extensions-store";
import { extensionLoaderFromMainChannel, extensionLoaderFromRendererChannel } from "../../common/ipc/extension-handling";
import { requestExtensionLoaderInitialState } from "../../renderer/ipc";
@@ -21,7 +20,7 @@ import type { Extension } from "./extension/extension.injectable";
import type { Logger } from "../../common/logger";
import type { JoinPaths } from "../../common/path/join-paths.injectable";
import type { GetDirnameOfPath } from "../../common/path/get-dirname.injectable";
import type { BundledExtension } from "../extension-discovery/bundled-extension-token";
import type { LensExtensionId, BundledExtension, InstalledExtension, LensExtensionConstructor } from "@k8slens/legacy-extensions";
const logModule = "[EXTENSIONS-LOADER]";
@@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId } from "@k8slens/legacy-extensions";
import type { ObservableMap } from "mobx";
import { action, makeObservable } from "mobx";
import type { BaseStoreDependencies } from "../../../common/base-store/base-store";
import { BaseStore } from "../../../common/base-store/base-store";
import type { LensExtensionId } from "../../lens-extension";
import type { EnsureHashedDirectoryForExtension } from "./ensure-hashed-directory-for-extension.injectable";
interface FSProvisionModel {
@@ -2,9 +2,9 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId } from "@k8slens/legacy-extensions";
import { getInjectable } from "@ogre-tools/injectable";
import { observable } from "mobx";
import type { LensExtensionId } from "../../lens-extension";
export const registeredExtensionsInjectable = getInjectable({
id: "registered-extensions",
@@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId } from "../lens-extension";
import type { LensExtensionId } from "@k8slens/legacy-extensions";
import { action, computed, makeObservable, observable } from "mobx";
import type { BaseStoreDependencies } from "../../common/base-store/base-store";
import { BaseStore } from "../../common/base-store/base-store";
+2 -25
View File
@@ -3,35 +3,12 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { InstalledExtension } from "./extension-discovery/extension-discovery";
import { action, computed, makeObservable, observable } from "mobx";
import type { PackageJson } from "type-fest";
import { disposer } from "@k8slens/utilities";
import type { LensExtensionDependencies } from "./lens-extension-set-dependencies";
import type { ProtocolHandlerRegistration } from "../common/protocol-handler/registration";
import type { InstalledExtension, LegacyLensExtension, LensExtensionId, LensExtensionManifest } from "@k8slens/legacy-extensions";
export type LensExtensionId = string; // path to manifest (package.json)
export type LensExtensionConstructor = new (...args: ConstructorParameters<typeof LensExtension>) => LensExtension;
export interface LensExtensionManifest extends PackageJson {
name: string;
version: string;
main?: string; // path to %ext/dist/main.js
renderer?: string; // path to %ext/dist/renderer.js
/**
* Supported Lens version engine by extension could be defined in `manifest.engines.lens`
* Only MAJOR.MINOR version is taken in consideration.
*/
engines: {
lens: string; // "semver"-package format
npm?: string;
node?: string;
};
// Specify extension name used for persisting data.
// Useful if extension is renamed but the data should not be lost.
storeName?: string;
}
export const lensExtensionDependencies = Symbol("lens-extension-dependencies");
export const Disposers = Symbol("disposers");
@@ -41,7 +18,7 @@ export class LensExtension<
* @ignore
*/
Dependencies extends LensExtensionDependencies = LensExtensionDependencies,
> {
> implements LegacyLensExtension {
readonly id: LensExtensionId;
readonly manifest: LensExtensionManifest;
readonly manifestPath: string;
@@ -4,7 +4,7 @@
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { bundledExtensionInjectionToken } from "../../../../../../common/library";
import { bundledExtensionInjectionToken } from "@k8slens/legacy-extensions";
import { object } from "@k8slens/utilities";
import buildSemanticVersionInjectable from "../../../../../../common/vars/build-semantic-version.injectable";
@@ -14,7 +14,6 @@ import lensProtocolRouterMainInjectable from "../lens-protocol-router-main/lens-
import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable";
import getConfigurationFileModelInjectable from "../../../common/get-configuration-file-model/get-configuration-file-model.injectable";
import { LensExtension } from "../../../extensions/lens-extension";
import type { LensExtensionId } from "../../../extensions/lens-extension";
import type { ObservableMap } from "mobx";
import extensionInstancesInjectable from "../../../extensions/extension-loader/extension-instances.injectable";
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
@@ -23,6 +22,7 @@ import pathExistsSyncInjectable from "../../../common/fs/path-exists-sync.inject
import pathExistsInjectable from "../../../common/fs/path-exists.injectable";
import readJsonSyncInjectable from "../../../common/fs/read-json-sync.injectable";
import writeJsonSyncInjectable from "../../../common/fs/write-json-sync.injectable";
import type { LensExtensionId } from "@k8slens/legacy-extensions";
function throwIfDefined(val: any): void {
if (val != null) {
@@ -3,8 +3,6 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { InstalledExtension } from "../../../extensions/extension-discovery/extension-discovery";
import type { LensExtensionId } from "../../../extensions/lens-extension";
import loggerInjectable from "../../../common/logger.injectable";
import extensionDiscoveryInjectable from "../../../extensions/extension-discovery/extension-discovery.injectable";
import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable";
@@ -35,10 +33,10 @@ const initializeExtensionsInjectable = getInjectable({
// Subscribe to extensions that are copied or deleted to/from the extensions folder
extensionDiscovery.events
.on("add", (extension: InstalledExtension) => {
.on("add", (extension) => {
extensionLoader.addExtension(extension);
})
.on("remove", (lensExtensionId: LensExtensionId) => {
.on("remove", (lensExtensionId) => {
extensionLoader.removeExtension(lensExtensionId);
});
@@ -17,7 +17,6 @@ import { disposer } from "@k8slens/utilities";
import type { ShowNotification } from "../../notifications";
import { Button } from "../../button";
import type { ExtensionLoader } from "../../../../extensions/extension-loader";
import type { LensExtensionId } from "../../../../extensions/lens-extension";
import React from "react";
import { remove as removeDir } from "fs-extra";
import { shell } from "electron";
@@ -25,6 +24,7 @@ import type { ExtensionInstallationStateStore } from "../../../../extensions/ext
import { ExtensionInstallationState } from "../../../../extensions/extension-installation-state-store/extension-installation-state-store";
import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable";
import showInfoNotificationInjectable from "../../notifications/show-info-notification.injectable";
import type { LensExtensionId } from "@k8slens/legacy-extensions";
export interface InstallRequest {
fileName: string;
@@ -7,13 +7,13 @@ import extensionDiscoveryInjectable from "../../../../extensions/extension-disco
import { validatePackage } from "./validate-package";
import { getMessageFromError } from "../get-message-from-error/get-message-from-error";
import React from "react";
import type { LensExtensionId, LensExtensionManifest } from "../../../../extensions/lens-extension";
import type { InstallRequest } from "./attempt-install.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
import writeFileInjectable from "../../../../common/fs/write-file.injectable";
import joinPathsInjectable from "../../../../common/path/join-paths.injectable";
import tempDirectoryPathInjectable from "../../../../common/os/temp-directory-path.injectable";
import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable";
import type { LensExtensionId, LensExtensionManifest } from "@k8slens/legacy-extensions";
export interface InstallRequestValidated {
fileName: string;
@@ -2,10 +2,10 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionManifest } from "../../../../extensions/lens-extension";
import { hasTypedProperty, isObject, isString, listTarEntries, readFileFromTar } from "@k8slens/utilities";
import { manifestFilename } from "../../../../extensions/extension-discovery/extension-discovery";
import path from "path";
import type { LensExtensionManifest } from "@k8slens/legacy-extensions";
export async function validatePackage(filePath: string): Promise<LensExtensionManifest> {
const tarFiles = await listTarEntries(filePath);
@@ -2,10 +2,9 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId, InstalledExtension } from "@k8slens/legacy-extensions";
import { getInjectable } from "@ogre-tools/injectable";
import React from "react";
import type { InstalledExtension } from "../../../extensions/extension-discovery/extension-discovery";
import type { LensExtensionId } from "../../../extensions/lens-extension";
import { extensionDisplayName } from "../../../extensions/lens-extension";
import type { Confirm } from "../confirm-dialog/confirm.injectable";
import confirmInjectable from "../confirm-dialog/confirm.injectable";
@@ -2,7 +2,7 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId } from "../../../../extensions/lens-extension";
import type { LensExtensionId } from "@k8slens/legacy-extensions";
import type { ExtensionLoader } from "../../../../extensions/extension-loader";
interface Dependencies {
@@ -2,7 +2,7 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { LensExtensionId } from "../../../../extensions/lens-extension";
import type { LensExtensionId } from "@k8slens/legacy-extensions";
import type { ExtensionLoader } from "../../../../extensions/extension-loader";
interface Dependencies {
@@ -4,8 +4,7 @@
*/
import styles from "./extensions.module.scss";
import type {
IComputedValue } from "mobx";
import type { IComputedValue } from "mobx";
import {
makeObservable,
observable,
@@ -14,7 +13,6 @@ import {
} from "mobx";
import { disposeOnUnmount, observer } from "mobx-react";
import React from "react";
import type { InstalledExtension } from "../../../extensions/extension-discovery/extension-discovery";
import { DropFileInput } from "../input";
import { Install } from "./install";
import { InstalledExtensions } from "./installed-extensions";
@@ -31,13 +29,13 @@ import confirmUninstallExtensionInjectable from "./confirm-uninstall-extension.i
import type { InstallExtensionFromInput } from "./install-extension-from-input.injectable";
import installExtensionFromInputInjectable from "./install-extension-from-input.injectable";
import installFromSelectFileDialogInjectable from "./install-from-select-file-dialog.injectable";
import type { LensExtensionId } from "../../../extensions/lens-extension";
import type { InstallOnDrop } from "./install-on-drop.injectable";
import installOnDropInjectable from "./install-on-drop.injectable";
import { supportedExtensionFormats } from "./supported-extension-formats";
import extensionInstallationStateStoreInjectable from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable";
import type { ExtensionInstallationStateStore } from "../../../extensions/extension-installation-state-store/extension-installation-state-store";
import Gutter from "../gutter/gutter";
import type { InstalledExtension, LensExtensionId } from "@k8slens/legacy-extensions";
interface Dependencies {
userExtensions: IComputedValue<InstalledExtension[]>;
@@ -5,10 +5,7 @@
import styles from "./installed-extensions.module.scss";
import React, { useMemo } from "react";
import type {
ExtensionDiscovery,
InstalledExtension,
} from "../../../extensions/extension-discovery/extension-discovery";
import type { ExtensionDiscovery } from "../../../extensions/extension-discovery/extension-discovery";
import { Icon } from "../icon";
import { List } from "../list/list";
import { MenuActions, MenuItem } from "../menu";
@@ -16,14 +13,11 @@ import { Spinner } from "../spinner";
import { cssNames } from "@k8slens/utilities";
import { observer } from "mobx-react";
import type { Row } from "react-table";
import type { LensExtensionId } from "../../../extensions/lens-extension";
import extensionDiscoveryInjectable
from "../../../extensions/extension-discovery/extension-discovery.injectable";
import extensionDiscoveryInjectable from "../../../extensions/extension-discovery/extension-discovery.injectable";
import { withInjectables } from "@ogre-tools/injectable-react";
import extensionInstallationStateStoreInjectable
from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable";
import extensionInstallationStateStoreInjectable from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable";
import type { ExtensionInstallationStateStore } from "../../../extensions/extension-installation-state-store/extension-installation-state-store";
import type { InstalledExtension, LensExtensionId } from "@k8slens/legacy-extensions";
export interface InstalledExtensionsProps {
extensions: InstalledExtension[];
@@ -7,7 +7,7 @@ import extensionLoaderInjectable from "../../../extensions/extension-loader/exte
import extensionInstallationStateStoreInjectable from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable";
import extensionDiscoveryInjectable from "../../../extensions/extension-discovery/extension-discovery.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import type { LensExtensionId } from "../../../extensions/lens-extension";
import type { LensExtensionId } from "@k8slens/legacy-extensions";
import { extensionDisplayName } from "../../../extensions/lens-extension";
import React from "react";
import { when } from "mobx";
+1 -2
View File
@@ -7,8 +7,7 @@ import { clusterSetFrameIdHandler, clusterStates } from "../../common/ipc/cluste
import type { ClusterId, ClusterState } from "../../common/cluster-types";
import { windowActionHandleChannel, windowLocationChangedChannel, windowOpenAppMenuAsContextMenuChannel, type WindowAction } from "../../common/ipc/window";
import { extensionDiscoveryStateChannel, extensionLoaderFromMainChannel } from "../../common/ipc/extension-handling";
import type { InstalledExtension } from "../../extensions/extension-discovery/extension-discovery";
import type { LensExtensionId } from "../../extensions/lens-extension";
import type { InstalledExtension, LensExtensionId } from "@k8slens/legacy-extensions";
import type { Location } from "history";
import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import ipcRendererInjectable from "../utils/channel/ipc-renderer.injectable";