1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Adapt code and unit tests to recent changes in application setup and event handling

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
Janne Savolainen 2022-04-19 13:19:22 +03:00
parent 0d7cbcfaab
commit f18926ab66
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
28 changed files with 259 additions and 155 deletions

View File

@ -83,17 +83,16 @@ describe("cluster-store", () => {
beforeEach(async () => {
mainDi = getDiForUnitTesting({ doGeneralOverrides: true });
await runSetups(mainDi);
mockFs();
mainDi.override(clusterStoreInjectable, (di) => ClusterStore.createInstance({ createCluster: di.inject(createClusterInjectionToken) }));
mainDi.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
mainDi.permitSideEffects(getConfigurationFileModelInjectable);
mainDi.permitSideEffects(appVersionInjectable);
mainDi.permitSideEffects(clusterStoreInjectable);
createCluster = mainDi.inject(createClusterInjectionToken);
// @ts-ignore
mainDi.unoverride(clusterStoreInjectable);
});
afterEach(() => {
@ -108,10 +107,6 @@ describe("cluster-store", () => {
getCustomKubeConfigDirectoryInjectable,
);
// TODO: Remove these by removing Singleton base-class from BaseStore
ClusterStore.getInstance(false)?.unregisterIpcListener();
ClusterStore.resetInstance();
const mockOpts = {
"some-directory-for-user-data": {
"lens-cluster-store.json": JSON.stringify({}),
@ -120,7 +115,13 @@ describe("cluster-store", () => {
mockFs(mockOpts);
await runSetups(mainDi);
createCluster = mainDi.inject(createClusterInjectionToken);
clusterStore = mainDi.inject(clusterStoreInjectable);
clusterStore.unregisterIpcListener();
});
afterEach(() => {
@ -199,9 +200,7 @@ describe("cluster-store", () => {
});
describe("config with existing clusters", () => {
beforeEach(() => {
ClusterStore.resetInstance();
beforeEach(async () => {
const mockOpts = {
"temp-kube-config": kubeconfig,
"some-directory-for-user-data": {
@ -240,6 +239,10 @@ describe("cluster-store", () => {
mockFs(mockOpts);
await runSetups(mainDi);
createCluster = mainDi.inject(createClusterInjectionToken);
clusterStore = mainDi.inject(clusterStoreInjectable);
});
@ -267,7 +270,7 @@ describe("cluster-store", () => {
});
describe("config with invalid cluster kubeconfig", () => {
beforeEach(() => {
beforeEach(async () => {
const invalidKubeconfig = `
apiVersion: v1
clusters:
@ -322,6 +325,10 @@ users:
mockFs(mockOpts);
await runSetups(mainDi);
createCluster = mainDi.inject(createClusterInjectionToken);
clusterStore = mainDi.inject(clusterStoreInjectable);
});
@ -337,7 +344,7 @@ users:
});
describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
beforeEach(() => {
beforeEach(async () => {
ClusterStore.resetInstance();
const mockOpts = {
"some-directory-for-user-data": {
@ -364,6 +371,10 @@ users:
mockFs(mockOpts);
await runSetups(mainDi);
createCluster = mainDi.inject(createClusterInjectionToken);
clusterStore = mainDi.inject(clusterStoreInjectable);
});

View File

@ -15,60 +15,8 @@ import hotbarStoreInjectable from "../hotbar-store.injectable";
import { HotbarStore } from "../hotbar-store";
import catalogCatalogEntityInjectable from "../catalog-entities/general-catalog-entities/implementations/catalog-catalog-entity.injectable";
import { runSetups } from "../setupable-injection-token/run-setups";
import catalogEntityRegistryInjectable from "../../main/catalog/catalog-entity-registry.injectable";
jest.mock("../../main/catalog/catalog-entity-registry", () => ({
catalogEntityRegistry: {
items: [
getMockCatalogEntity({
apiVersion: "v1",
kind: "Cluster",
status: {
phase: "Running",
},
metadata: {
uid: "1dfa26e2ebab15780a3547e9c7fa785c",
name: "mycluster",
source: "local",
labels: {},
},
}),
getMockCatalogEntity({
apiVersion: "v1",
kind: "Cluster",
status: {
phase: "Running",
},
metadata: {
uid: "55b42c3c7ba3b04193416cda405269a5",
name: "my_shiny_cluster",
source: "remote",
labels: {},
},
}),
getMockCatalogEntity({
apiVersion: "v1",
kind: "Cluster",
status: {
phase: "Running",
},
metadata: {
uid: "catalog-entity",
name: "Catalog",
source: "app",
labels: {},
},
}),
],
},
}));
function getMockCatalogEntity(data: Partial<CatalogEntityData> & CatalogEntityKindData): CatalogEntity {
return {
@ -134,6 +82,59 @@ describe("HotbarStore", () => {
di.permitSideEffects(getConfigurationFileModelInjectable);
di.permitSideEffects(appVersionInjectable);
di.override(catalogEntityRegistryInjectable, () => ({
addComputedSource: (id, source) => {},
items: [
getMockCatalogEntity({
apiVersion: "v1",
kind: "Cluster",
status: {
phase: "Running",
},
metadata: {
uid: "1dfa26e2ebab15780a3547e9c7fa785c",
name: "mycluster",
source: "local",
labels: {},
},
}),
getMockCatalogEntity({
apiVersion: "v1",
kind: "Cluster",
status: {
phase: "Running",
},
metadata: {
uid: "55b42c3c7ba3b04193416cda405269a5",
name: "my_shiny_cluster",
source: "remote",
labels: {},
},
}),
getMockCatalogEntity({
apiVersion: "v1",
kind: "Cluster",
status: {
phase: "Running",
},
metadata: {
uid: "catalog-entity",
name: "Catalog",
source: "app",
labels: {},
},
}),
],
}));
di.override(hotbarStoreInjectable, () => {
HotbarStore.resetInstance();

View File

@ -16,8 +16,8 @@ import installExtensionsInjectable from "../extension-installer/install-extensio
const extensionDiscoveryInjectable = getInjectable({
id: "extension-discovery",
instantiate: (di) => {
const extensionDiscovery = new ExtensionDiscovery({
instantiate: (di) =>
new ExtensionDiscovery({
extensionLoader: di.inject(extensionLoaderInjectable),
extensionsStore: di.inject(extensionsStoreInjectable),
@ -37,13 +37,7 @@ const extensionDiscoveryInjectable = getInjectable({
extensionPackageRootDirectory: di.inject(
extensionPackageRootDirectoryInjectable,
),
});
// TODO: Missing await
extensionDiscovery.init();
return extensionDiscovery;
},
}),
});
export default extensionDiscoveryInjectable;

View File

@ -4,17 +4,14 @@
*/
import { LensExtension } from "./lens-extension";
import { catalogEntityRegistry } from "../main/catalog";
import type { CatalogEntity } from "../common/catalog";
import type { IObservableArray } from "mobx";
import type { MenuRegistration } from "../main/menu/menu-registration";
import type { TrayMenuRegistration } from "../main/tray/tray-menu-registration";
import type { ShellEnvModifier } from "../main/shell-session/shell-env-modifier/shell-env-modifier-registration";
import {
Environments,
getEnvironmentSpecificLegacyGlobalDiForExtensionApi,
} from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import windowManagerInjectable from "../main/window-manager.injectable";
import catalogEntityRegistryInjectable from "../main/catalog/catalog-entity-registry.injectable";
export class LensMainExtension extends LensExtension {
appMenus: MenuRegistration[] = [];
@ -44,10 +41,18 @@ export class LensMainExtension extends LensExtension {
}
addCatalogSource(id: string, source: IObservableArray<CatalogEntity>) {
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main);
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
catalogEntityRegistry.addObservableSource(`${this.name}:${id}`, source);
}
removeCatalogSource(id: string) {
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main);
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
catalogEntityRegistry.removeSource(`${this.name}:${id}`);
}
}

View File

@ -4,13 +4,18 @@
*/
import type { CatalogEntity } from "../../common/catalog";
import { catalogEntityRegistry as registry } from "../../main/catalog";
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import catalogEntityRegistryInjectable from "../../main/catalog/catalog-entity-registry.injectable";
export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog/catalog-category-registry";
export class CatalogEntityRegistry {
getItemsForApiKind<T extends CatalogEntity>(apiVersion: string, kind: string): T[] {
return registry.getItemsForApiKind<T>(apiVersion, kind);
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main);
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
return catalogEntityRegistry.getItemsForApiKind<T>(apiVersion, kind);
}
}

View File

@ -48,6 +48,9 @@ describe("kubeconfig-sync.source tests", () => {
ClusterStore.createInstance({ createCluster: () => null }),
);
di.permitSideEffects(getConfigurationFileModelInjectable);
di.permitSideEffects(appVersionInjectable);
await runSetups(di);
computeDiff = computeDiffFor({
@ -56,9 +59,6 @@ describe("kubeconfig-sync.source tests", () => {
clusterManager: di.inject(clusterManagerInjectable),
});
di.permitSideEffects(getConfigurationFileModelInjectable);
di.permitSideEffects(appVersionInjectable);
di.inject(clusterStoreInjectable);
});

View File

@ -7,6 +7,7 @@ import directoryForKubeConfigsInjectable from "../../../common/app-paths/directo
import { KubeconfigSyncManager } from "./kubeconfig-sync-manager";
import { createClusterInjectionToken } from "../../../common/cluster/create-cluster-injection-token";
import clusterManagerInjectable from "../../cluster-manager.injectable";
import catalogEntityRegistryInjectable from "../../catalog/catalog-entity-registry.injectable";
const kubeconfigSyncManagerInjectable = getInjectable({
id: "kubeconfig-sync-manager",
@ -15,6 +16,7 @@ const kubeconfigSyncManagerInjectable = getInjectable({
directoryForKubeConfigs: di.inject(directoryForKubeConfigsInjectable),
createCluster: di.inject(createClusterInjectionToken),
clusterManager: di.inject(clusterManagerInjectable),
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
}),
});

View File

@ -6,7 +6,7 @@
import type { IComputedValue, ObservableMap } from "mobx";
import { action, observable, computed, runInAction, makeObservable, observe } from "mobx";
import type { CatalogEntity } from "../../../common/catalog";
import { catalogEntityRegistry } from "../../catalog";
import type { CatalogEntityRegistry } from "../../catalog";
import type { FSWatcher } from "chokidar";
import { watch } from "chokidar";
import fs from "fs";
@ -50,10 +50,11 @@ const ignoreGlobs = [
const folderSyncMaxAllowedFileReadSize = 2 * 1024 * 1024; // 2 MiB
const fileSyncMaxAllowedFileReadSize = 16 * folderSyncMaxAllowedFileReadSize; // 32 MiB
interface Dependencies {
interface KubeconfigSyncManagerDependencies {
directoryForKubeConfigs: string;
createCluster: (model: ClusterModel) => Cluster;
clusterManager: ClusterManager;
catalogEntityRegistry: CatalogEntityRegistry;
}
const kubeConfigSyncName = "lens:kube-sync";
@ -63,7 +64,7 @@ export class KubeconfigSyncManager {
protected syncing = false;
protected syncListDisposer?: Disposer;
constructor(private dependencies: Dependencies) {
constructor(private dependencies: KubeconfigSyncManagerDependencies) {
makeObservable(this);
}
@ -77,7 +78,7 @@ export class KubeconfigSyncManager {
logger.info(`${logPrefix} starting requested syncs`);
catalogEntityRegistry.addComputedSource(kubeConfigSyncName, computed(() => (
this.dependencies.catalogEntityRegistry.addComputedSource(kubeConfigSyncName, computed(() => (
Array.from(iter.flatMap(
this.sources.values(),
([entities]) => entities.get(),
@ -111,7 +112,7 @@ export class KubeconfigSyncManager {
this.stopOldSync(filePath);
}
catalogEntityRegistry.removeSource(kubeConfigSyncName);
this.dependencies.catalogEntityRegistry.removeSource(kubeConfigSyncName);
this.syncing = false;
}
@ -164,8 +165,14 @@ export function configToModels(rootConfig: KubeConfig, filePath: string): Update
type RootSourceValue = [Cluster, CatalogEntity];
type RootSource = ObservableMap<string, RootSourceValue>;
interface ComputeDiffDependencies {
directoryForKubeConfigs: string;
createCluster: (model: ClusterModel) => Cluster;
clusterManager: ClusterManager;
}
// exported for testing
export const computeDiff = ({ directoryForKubeConfigs, createCluster, clusterManager }: Dependencies) => (contents: string, source: RootSource, filePath: string): void => {
export const computeDiff = ({ directoryForKubeConfigs, createCluster, clusterManager }: ComputeDiffDependencies) => (contents: string, source: RootSource, filePath: string): void => {
runInAction(() => {
try {
const { config, error } = loadConfigFromString(contents);
@ -241,7 +248,7 @@ interface DiffChangedConfigArgs {
maxAllowedFileReadSize: number;
}
const diffChangedConfigFor = (dependencies: Dependencies) => ({ filePath, source, stats, maxAllowedFileReadSize }: DiffChangedConfigArgs): Disposer => {
const diffChangedConfigFor = (dependencies: ComputeDiffDependencies) => ({ filePath, source, stats, maxAllowedFileReadSize }: DiffChangedConfigArgs): Disposer => {
logger.debug(`${logPrefix} file changed`, { filePath });
if (stats.size >= maxAllowedFileReadSize) {
@ -297,7 +304,7 @@ const diffChangedConfigFor = (dependencies: Dependencies) => ({ filePath, source
return cleanup;
};
const watchFileChanges = (filePath: string, dependencies: Dependencies): [IComputedValue<CatalogEntity[]>, Disposer] => {
const watchFileChanges = (filePath: string, dependencies: ComputeDiffDependencies): [IComputedValue<CatalogEntity[]>, Disposer] => {
const rootSource = observable.map<string, ObservableMap<string, RootSourceValue>>();
const derivedSource = computed(() => Array.from(iter.flatMap(rootSource.values(), from => iter.map(from.values(), child => child[1]))));

View File

@ -6,7 +6,7 @@
import { computed, observable, reaction } from "mobx";
import type { WeblinkStore } from "../../common/weblink-store";
import { WebLink } from "../../common/catalog-entities";
import { catalogEntityRegistry } from "../catalog";
import type { CatalogEntityRegistry } from "../catalog";
import got from "got";
import type { Disposer } from "../../common/utils";
import { random } from "lodash";
@ -28,8 +28,12 @@ async function validateLink(link: WebLink) {
}
}
interface Dependencies {
weblinkStore: WeblinkStore;
catalogEntityRegistry: CatalogEntityRegistry;
}
export function syncWeblinks(weblinkStore: WeblinkStore) {
export function syncWeblinks({ weblinkStore, catalogEntityRegistry }: Dependencies) {
const webLinkEntities = observable.map<string, [WebLink, Disposer]>();
function periodicallyCheckLink(link: WebLink): Disposer {

View File

@ -3,12 +3,17 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { catalogEntityRegistry } from "./catalog-entity-registry";
import { CatalogEntityRegistry } from "./catalog-entity-registry";
import catalogCategoryRegistryInjectable from "../../common/catalog/catalog-category-registry.injectable";
const catalogEntityRegistryInjectable = getInjectable({
id: "catalog-entity-registry",
instantiate: () => catalogEntityRegistry,
causesSideEffects: true,
instantiate: (di) => {
const categoryRegistryRegistry = di.inject(catalogCategoryRegistryInjectable);
return new CatalogEntityRegistry(categoryRegistryRegistry);
},
});
export default catalogEntityRegistryInjectable;

View File

@ -5,7 +5,6 @@
import { action, computed, type IComputedValue, type IObservableArray, makeObservable, observable } from "mobx";
import type { CatalogCategoryRegistry, CatalogEntity, CatalogEntityConstructor } from "../../common/catalog";
import { catalogCategoryRegistry } from "../../common/catalog";
import { iter } from "../../common/utils";
export class CatalogEntityRegistry {
@ -48,8 +47,3 @@ export class CatalogEntityRegistry {
return this.items.filter((item) => item instanceof constructor) as T[];
}
}
/**
* @deprecated Switch to using catalogEntityRegistryInjectable
*/
export const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry);

View File

@ -5,6 +5,7 @@
import { getInjectable } from "@ogre-tools/injectable";
import { ClusterManager } from "./cluster-manager";
import clusterStoreInjectable from "../common/cluster-store/cluster-store.injectable";
import catalogEntityRegistryInjectable from "./catalog/catalog-entity-registry.injectable";
const clusterManagerInjectable = getInjectable({
id: "cluster-manager",
@ -12,6 +13,7 @@ const clusterManagerInjectable = getInjectable({
instantiate: (di) => {
const clusterManager = new ClusterManager({
store: di.inject(clusterStoreInjectable),
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
});
clusterManager.init();

View File

@ -10,7 +10,7 @@ import type { Cluster } from "../common/cluster/cluster";
import logger from "./logger";
import { apiKubePrefix } from "../common/vars";
import { getClusterIdFromHost } from "../common/utils";
import { catalogEntityRegistry } from "./catalog";
import type { CatalogEntityRegistry } from "./catalog";
import type { KubernetesClusterPrometheusMetrics } from "../common/catalog-entities/kubernetes-cluster";
import { KubernetesCluster, LensKubernetesClusterStatus } from "../common/catalog-entities/kubernetes-cluster";
import { ipcMainOn } from "../common/ipc";
@ -24,6 +24,7 @@ const lensSpecificClusterStatuses: Set<string> = new Set(Object.values(LensKuber
interface Dependencies {
store: ClusterStore;
catalogEntityRegistry: CatalogEntityRegistry;
}
export class ClusterManager {
@ -51,12 +52,12 @@ export class ClusterManager {
);
reaction(
() => catalogEntityRegistry.getItemsByEntityClass(KubernetesCluster) as KubernetesCluster[],
() => this.dependencies.catalogEntityRegistry.getItemsByEntityClass(KubernetesCluster) as KubernetesCluster[],
entities => this.syncClustersFromCatalog(entities),
);
reaction(() => [
catalogEntityRegistry.getItemsByEntityClass(KubernetesCluster),
this.dependencies.catalogEntityRegistry.getItemsByEntityClass(KubernetesCluster),
this.visibleCluster,
] as const, ([entities, visibleCluster]) => {
for (const entity of entities) {
@ -70,7 +71,7 @@ export class ClusterManager {
observe(this.deleting, change => {
if (change.type === "add") {
this.updateEntityStatus(catalogEntityRegistry.getById(change.newValue));
this.updateEntityStatus(this.dependencies.catalogEntityRegistry.getById(change.newValue));
}
});
@ -88,13 +89,13 @@ export class ClusterManager {
}
protected updateEntityFromCluster(cluster: Cluster) {
const index = catalogEntityRegistry.items.findIndex((entity) => entity.getId() === cluster.id);
const index = this.dependencies.catalogEntityRegistry.items.findIndex((entity) => entity.getId() === cluster.id);
if (index === -1) {
return;
}
const entity = catalogEntityRegistry.items[index] as KubernetesCluster;
const entity = this.dependencies.catalogEntityRegistry.items[index] as KubernetesCluster;
this.updateEntityStatus(entity, cluster);
@ -135,7 +136,7 @@ export class ClusterManager {
cluster.preferences.icon = undefined;
}
catalogEntityRegistry.items.splice(index, 1, entity);
this.dependencies.catalogEntityRegistry.items.splice(index, 1, entity);
}
@action

View File

@ -0,0 +1,18 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import electronAppInjectable from "./electron-app.injectable";
const requestSingleInstanceLockInjectable = getInjectable({
id: "request-single-instance-lock",
instantiate: (di) => {
const app = di.inject(electronAppInjectable);
return () => app.requestSingleInstanceLock();
},
});
export default requestSingleInstanceLockInjectable;

View File

@ -0,0 +1,27 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import electronAppInjectable from "./electron-app.injectable";
import isMacInjectable from "../../common/vars/is-mac.injectable";
import commandLineArgumentsInjectable from "../utils/command-line-arguments.injectable";
const shouldStartHiddenInjectable = getInjectable({
id: "should-start-hidden",
instantiate: (di) => {
const app = di.inject(electronAppInjectable);
const isMac = di.inject(isMacInjectable);
const commandLineArguments = di.inject(commandLineArgumentsInjectable);
// Start the app without showing the main window when auto starting on login
// (On Windows and Linux, we get a flag. On MacOS, we get special API.)
return (
commandLineArguments.includes("--hidden") ||
(isMac && app.getLoginItemSettings().wasOpenedAsHidden)
);
},
});
export default shouldStartHiddenInjectable;

View File

@ -54,12 +54,24 @@ import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.inject
import registerFileProtocolInjectable from "./electron-app/register-file-protocol.injectable";
import environmentVariablesInjectable from "../common/utils/environment-variables.injectable";
import disableHardwareAccelerationInjectable from "./electron-app/disable-hardware-acceleration.injectable";
import catalogEntityRegistryInjectable from "./catalog/catalog-entity-registry.injectable";
import { CatalogCategoryRegistry } from "../common/catalog";
import { CatalogEntityRegistry } from "./catalog";
import catalogCategoryRegistryInjectable from "../common/catalog/catalog-category-registry.injectable";
import setupIpcMainHandlersInjectable from "./start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable";
import setupLensProxyInjectable from "./start-main-application/after-application-is-ready/implementations/setup-lens-proxy.injectable";
import setupListenerForRootFrameRenderingInjectable from "./start-main-application/after-application-is-ready/implementations/setup-listener-for-root-frame-rendering.injectable";
import setupOsThemeUpdatesInjectable from "./start-main-application/after-application-is-ready/implementations/setup-os-theme-updates.injectable";
import setupSentryInjectable from "./start-main-application/after-application-is-ready/implementations/setup-sentry.injectable";
import setupShellInjectable from "./start-main-application/after-application-is-ready/implementations/setup-shell.injectable";
import requestSingleInstanceLockInjectable from "./electron-app/request-single-instance-lock.injectable";
import setupSyncingOfWeblinksInjectable from "./start-main-application/after-application-is-ready/implementations/setup-syncing-of-weblinks.injectable";
import shouldStartHiddenInjectable from "./electron-app/should-start-hidden.injectable";
import stopServicesAndExitAppInjectable from "./stop-services-and-exit-app.injectable";
import trayInjectable from "./tray/tray.injectable";
import applicationMenuInjectable from "./menu/application-menu.injectable";
import windowManagerInjectable from "./window-manager.injectable";
import isDevelopmentInjectable from "../common/vars/is-development.injectable";
import setupSystemCaInjectable
from "./start-main-application/before-application-is-ready/implementations/setup-system-ca.injectable";
export const getDiForUnitTesting = (
{ doGeneralOverrides } = { doGeneralOverrides: false },
@ -84,6 +96,7 @@ export const getDiForUnitTesting = (
di.override(isMacInjectable, () => true);
di.override(isWindowsInjectable, () => false);
di.override(isLinuxInjectable, () => false);
di.override(isDevelopmentInjectable, () => false);
di.override(getAbsolutePathInjectable, () => getAbsolutePathFake);
di.override(joinPathsInjectable, () => joinPathsFake);
@ -98,21 +111,29 @@ export const getDiForUnitTesting = (
di.override(getCommandLineSwitchInjectable, () => () => "irrelevant");
di.override(isAutoUpdateEnabledInjectable, () => () => false);
di.override(registerProtocolClientInjectable, () => () => {});
di.override(initializeExtensionsInjectable, () => ({ run: () => {} }));
di.override(lensResourcesDirInjectable, () => "/irrelevant");
di.override(registerFileProtocolInjectable, () => () => {});
di.override(requestSingleInstanceLockInjectable, () => () => true);
di.override(disableHardwareAccelerationInjectable, () => () => {});
di.override(shouldStartHiddenInjectable, () => true);
di.override(stopServicesAndExitAppInjectable, () => () => {});
di.override(windowManagerInjectable, () => ({ ensureMainWindow: () => Promise.resolve(null) }));
di.override(initializeExtensionsInjectable, () => ({ run: () => {} }));
di.override(setupIpcMainHandlersInjectable, () => ({ run: () => {} }));
di.override(setupLensProxyInjectable, () => ({ run: () => {} }));
di.override(setupListenerForRootFrameRenderingInjectable, () => ({ run: () => {} }));
di.override(setupOsThemeUpdatesInjectable, () => ({ run: () => {} }));
di.override(setupSentryInjectable, () => ({ run: () => {} }));
di.override(setupShellInjectable, () => ({ run: () => {} }));
di.override(setupSyncingOfWeblinksInjectable, () => ({ run: () => {} }));
di.override(setupSystemCaInjectable, () => ({ run: () => {} }));
di.override(trayInjectable, () => ({ start: () => {}, stop: () => {} }));
di.override(applicationMenuInjectable, () => ({ start: () => {}, stop: () => {} }));
di.override(catalogCategoryRegistryInjectable, () => new CatalogCategoryRegistry());
di.override(catalogEntityRegistryInjectable, (diForInstantiate) => {
const catalogCategoryRegistry = diForInstantiate.inject(catalogCategoryRegistryInjectable);
return new CatalogEntityRegistry(catalogCategoryRegistry);
});
di.override(environmentVariablesInjectable, () => ({}));
di.override(commandLineArgumentsInjectable, () => []);
@ -122,13 +143,13 @@ export const getDiForUnitTesting = (
// eslint-disable-next-line unused-imports/no-unused-vars-ts
di.override(extensionsStoreInjectable, () => ({ isEnabled: ({ id, isBundled }) => false }) as ExtensionsStore);
di.override(hotbarStoreInjectable, () => ({}));
di.override(hotbarStoreInjectable, () => ({ load: () => {} }));
di.override(fileSystemProvisionerStoreInjectable, () => ({}) as FileSystemProvisionerStore);
// eslint-disable-next-line unused-imports/no-unused-vars-ts
di.override(clusterStoreInjectable, () => ({ getById: (id): Cluster => ({}) as Cluster }) as ClusterStore);
di.override(userStoreInjectable, () => ({}) as UserStore);
di.override(clusterStoreInjectable, () => ({ provideInitialFromMain: () => {}, getById: (id): Cluster => ({}) as Cluster }) as ClusterStore);
di.override(userStoreInjectable, () => ({ startMainReactions: () => {} }) as UserStore);
di.override(
getElectronAppPathInjectable,

View File

@ -7,13 +7,14 @@ import type { IComputedValue } from "mobx";
import { computed } from "mobx";
import type { ClusterId } from "../../../common/cluster-types";
import type { LensMainExtension } from "../../../extensions/lens-main-extension";
import { catalogEntityRegistry } from "../../catalog";
import type { CatalogEntityRegistry } from "../../catalog";
interface Dependencies {
extensions: IComputedValue<LensMainExtension[]>;
catalogEntityRegistry: CatalogEntityRegistry;
}
export const terminalShellEnvModify = ({ extensions }: Dependencies) =>
export const terminalShellEnvModify = ({ extensions, catalogEntityRegistry }: Dependencies) =>
(clusterId: ClusterId, env: Record<string, string>) => {
const terminalShellEnvModifiers = computed(() => (
extensions.get()

View File

@ -6,6 +6,7 @@
import { getInjectable } from "@ogre-tools/injectable";
import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable";
import { terminalShellEnvModify } from "./terminal-shell-env-modifiers";
import catalogEntityRegistryInjectable from "../../catalog/catalog-entity-registry.injectable";
const terminalShellEnvModifyInjectable = getInjectable({
id: "terminal-shell-env-modify",
@ -13,6 +14,7 @@ const terminalShellEnvModifyInjectable = getInjectable({
instantiate: (di) =>
terminalShellEnvModify({
extensions: di.inject(mainExtensionsInjectable),
catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable),
}),
});

View File

@ -5,18 +5,18 @@
import { getInjectable } from "@ogre-tools/injectable";
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
import exitAppInjectable from "../../../electron-app/exit-app.injectable";
import electronAppInjectable from "../../../electron-app/electron-app.injectable";
import requestSingleInstanceLockInjectable from "../../../electron-app/request-single-instance-lock.injectable";
const setupSingleInstanceLockInjectable = getInjectable({
id: "setup-single-instance-lock",
const enforceSingleApplicationInstanceInjectable = getInjectable({
id: "enforce-single-application-instance",
instantiate: (di) => {
const exitApp = di.inject(exitAppInjectable);
const app = di.inject(electronAppInjectable);
const requestSingleInstanceLock = di.inject(requestSingleInstanceLockInjectable);
return {
run: () => {
if (!app.requestSingleInstanceLock()) {
if (!requestSingleInstanceLock()) {
exitApp();
return;
@ -28,4 +28,4 @@ const setupSingleInstanceLockInjectable = getInjectable({
injectionToken: afterApplicationIsReadyInjectionToken,
});
export default setupSingleInstanceLockInjectable;
export default enforceSingleApplicationInstanceInjectable;

View File

@ -23,6 +23,8 @@ const initializeExtensionsInjectable = getInjectable({
run: async () => {
logger.info("🧩 Initializing extensions");
await extensionDiscovery.init();
await extensionLoader.init();
try {

View File

@ -10,6 +10,7 @@ import clusterManagerInjectable from "../../../../cluster-manager.injectable";
import applicationMenuItemsInjectable from "../../../../menu/application-menu-items.injectable";
import getAbsolutePathInjectable from "../../../../../common/path/get-absolute-path.injectable";
import { afterApplicationIsReadyInjectionToken } from "../../after-application-is-ready-injection-token";
import catalogEntityRegistryInjectable from "../../../../catalog/catalog-entity-registry.injectable";
const setupIpcMainHandlersInjectable = getInjectable({
id: "setup-ipc-main-handlers",
@ -24,6 +25,7 @@ const setupIpcMainHandlersInjectable = getInjectable({
const clusterManager = di.inject(clusterManagerInjectable);
const applicationMenuItems = di.inject(applicationMenuItemsInjectable);
const getAbsolutePath = di.inject(getAbsolutePathInjectable);
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
return {
run: () => {
@ -34,6 +36,7 @@ const setupIpcMainHandlersInjectable = getInjectable({
getAbsolutePath,
directoryForLensLocalStorage,
clusterManager,
catalogEntityRegistry,
});
},
};

View File

@ -10,7 +10,7 @@ import type { ClusterId } from "../../../../../common/cluster-types";
import { ClusterStore } from "../../../../../common/cluster-store/cluster-store";
import { appEventBus } from "../../../../../common/app-event-bus/event-bus";
import { broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../../common/ipc";
import { catalogEntityRegistry } from "../../../../catalog";
import type { CatalogEntityRegistry } from "../../../../catalog";
import { pushCatalogToRenderer } from "../../../../catalog-pusher";
import type { ClusterManager } from "../../../../cluster-manager";
import { ResourceApplier } from "../../../../resource-applier";
@ -30,9 +30,10 @@ interface Dependencies {
getAbsolutePath: GetAbsolutePath;
applicationMenuItems: IComputedValue<MenuItemOpts[]>;
clusterManager: ClusterManager;
catalogEntityRegistry: CatalogEntityRegistry;
}
export const setupIpcMainHandlers = ({ applicationMenuItems, directoryForLensLocalStorage, getAbsolutePath, clusterManager }: Dependencies) => {
export const setupIpcMainHandlers = ({ applicationMenuItems, directoryForLensLocalStorage, getAbsolutePath, clusterManager, catalogEntityRegistry }: Dependencies) => {
ipcMainHandle(clusterActivateHandler, (event, clusterId: ClusterId, force = false) => {
return ClusterStore.getInstance()
.getById(clusterId)

View File

@ -6,16 +6,18 @@ import { getInjectable } from "@ogre-tools/injectable";
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
import { syncWeblinks } from "../../../catalog-sources";
import weblinkStoreInjectable from "../../../../common/weblink-store.injectable";
import catalogEntityRegistryInjectable from "../../../catalog/catalog-entity-registry.injectable";
const setupSyncingOfWeblinksInjectable = getInjectable({
id: "setup-syncing-of-weblinks",
instantiate: (di) => {
const weblinkStore = di.inject(weblinkStoreInjectable);
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
return {
run: () => {
syncWeblinks(weblinkStore);
syncWeblinks({ weblinkStore, catalogEntityRegistry });
},
};
},

View File

@ -4,34 +4,23 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import windowManagerInjectable from "../../../window-manager.injectable";
import electronAppInjectable from "../../../electron-app/electron-app.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
import isMacInjectable from "../../../../common/vars/is-mac.injectable";
import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token";
import commandLineArgumentsInjectable from "../../../utils/command-line-arguments.injectable";
import shouldStartHiddenInjectable from "../../../electron-app/should-start-hidden.injectable";
const startMainWindowInjectable = getInjectable({
id: "start-main-window",
instantiate: (di) => {
const windowManager = di.inject(windowManagerInjectable);
const app = di.inject(electronAppInjectable);
const logger = di.inject(loggerInjectable);
const isMac = di.inject(isMacInjectable);
const commandLineArguments = di.inject(commandLineArgumentsInjectable);
const shouldStartHidden = di.inject(shouldStartHiddenInjectable);
return {
run: async () => {
// Start the app without showing the main window when auto starting on login
// (On Windows and Linux, we get a flag. On MacOS, we get special API.)
const startHidden =
commandLineArguments.includes("--hidden") ||
(isMac && app.getLoginItemSettings().wasOpenedAsHidden);
logger.info("🖥️ Starting WindowManager");
if (!startHidden) {
if (!shouldStartHidden) {
await windowManager.ensureMainWindow();
}
},

View File

@ -15,6 +15,8 @@ const setupSystemCaInjectable = getInjectable({
},
}),
causesSideEffects: true,
injectionToken: beforeApplicationIsReadyInjectionToken,
});

View File

@ -4,8 +4,11 @@
*/
import type { Hotbar } from "../../common/hotbar-types";
import { catalogEntityRegistry } from "../../main/catalog";
import type { MigrationDeclaration } from "../helpers";
import {
getLegacyGlobalDiForExtensionApi,
} from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import catalogEntityRegistryInjectable from "../../main/catalog/catalog-entity-registry.injectable";
export default {
version: "5.0.0-beta.5",
@ -13,6 +16,9 @@ export default {
const rawHotbars = store.get("hotbars");
const hotbars: Hotbar[] = Array.isArray(rawHotbars) ? rawHotbars : [];
const di = getLegacyGlobalDiForExtensionApi();
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
for (const hotbar of hotbars) {
for (let i = 0; i < hotbar.items.length; i += 1) {
const item = hotbar.items[i];

View File

@ -21,10 +21,8 @@ import { renderFor } from "../../test-utils/renderFor";
import extensionDiscoveryInjectable from "../../../../extensions/extension-discovery/extension-discovery.injectable";
import directoryForUserDataInjectable from "../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import directoryForDownloadsInjectable from "../../../../common/app-paths/directory-for-downloads/directory-for-downloads.injectable";
import getConfigurationFileModelInjectable
from "../../../../common/get-configuration-file-model/get-configuration-file-model.injectable";
import appVersionInjectable
from "../../../../common/get-configuration-file-model/app-version/app-version.injectable";
import getConfigurationFileModelInjectable from "../../../../common/get-configuration-file-model/get-configuration-file-model.injectable";
import appVersionInjectable from "../../../../common/get-configuration-file-model/app-version/app-version.injectable";
mockWindow();

View File

@ -76,6 +76,7 @@ export const getApplicationBuilder = () => {
const dis = { rendererDi, mainDi };
const clusterStoreStub = {
provideInitialFromMain: () => {},
getById: (): null => null,
} as unknown as ClusterStore;