mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Clean up versioning and packageJson uses (#6196)
This commit is contained in:
1 parent
cfe35ded90
commit
67ac1692b2
116 files changed
+1154
-644
No files matched your search
@@ -3,65 +3,53 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import assert from "assert";
|
||||
import semver from "semver";
|
||||
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", () => {
|
||||
expect(isCompatible({ extLensEngineVersion: "5.5.0", appVersion: "5.5.0" })).toBeTruthy();
|
||||
expect(isCompatible({ extLensEngineVersion: "5.5.0", extensionApiVersion: "5.5.0" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("is compatible with upper %PATCH versions of base app", () => {
|
||||
expect(isCompatible({ extLensEngineVersion: "5.5.0", appVersion: "5.5.5" })).toBeTruthy();
|
||||
expect(isCompatible({ extLensEngineVersion: "5.5.0", extensionApiVersion: "5.5.5" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("is compatible with higher %MINOR version of base app", () => {
|
||||
expect(isCompatible({ extLensEngineVersion: "5.5.0", appVersion: "5.6.0" })).toBeTruthy();
|
||||
expect(isCompatible({ extLensEngineVersion: "5.5.0", extensionApiVersion: "5.6.0" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("is not compatible with higher %MAJOR version of base app", () => {
|
||||
expect(isCompatible({ extLensEngineVersion: "5.6.0", appVersion: "6.0.0" })).toBeFalsy(); // extension for lens@5 not compatible with lens@6
|
||||
expect(isCompatible({ extLensEngineVersion: "6.0.0", appVersion: "5.6.0" })).toBeFalsy();
|
||||
});
|
||||
|
||||
it("is compatible with lensEngine with prerelease", () => {
|
||||
expect(isCompatible({
|
||||
extLensEngineVersion: "^5.4.0-alpha.0",
|
||||
appVersion: "5.5.0-alpha.0",
|
||||
})).toBeTruthy();
|
||||
expect(isCompatible({ extLensEngineVersion: "5.6.0", extensionApiVersion: "6.0.0" })).toBeFalsy(); // extension for lens@5 not compatible with lens@6
|
||||
expect(isCompatible({ extLensEngineVersion: "6.0.0", extensionApiVersion: "5.6.0" })).toBeFalsy();
|
||||
});
|
||||
|
||||
it("supports short version format for manifest.engines.lens", () => {
|
||||
expect(isCompatible({ extLensEngineVersion: "5.5", appVersion: "5.5.1" })).toBeTruthy();
|
||||
expect(isCompatible({ extLensEngineVersion: "5.5", extensionApiVersion: "5.5.1" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("throws for incorrect or not supported version format", () => {
|
||||
expect(() => isCompatible({
|
||||
extLensEngineVersion: ">=2.0",
|
||||
appVersion: "2.0",
|
||||
extensionApiVersion: "2.0",
|
||||
})).toThrow(/Invalid format/i);
|
||||
|
||||
expect(() => isCompatible({
|
||||
extLensEngineVersion: "~2.0",
|
||||
appVersion: "2.0",
|
||||
extensionApiVersion: "2.0",
|
||||
})).toThrow(/Invalid format/i);
|
||||
|
||||
expect(() => isCompatible({
|
||||
extLensEngineVersion: "*",
|
||||
appVersion: "1.0",
|
||||
extensionApiVersion: "1.0",
|
||||
})).toThrow(/Invalid format/i);
|
||||
});
|
||||
});
|
||||
|
||||
function isCompatible({ extLensEngineVersion = "^1.0", appVersion = "1.0" } = {}): boolean {
|
||||
const appSemVer = semver.coerce(appVersion);
|
||||
function isCompatible({ extLensEngineVersion = "^1.0", extensionApiVersion = "1.0" } = {}): boolean {
|
||||
const extensionManifestMock = getExtensionManifestMock(extLensEngineVersion);
|
||||
|
||||
assert(appSemVer);
|
||||
|
||||
return isCompatibleExtension({ appSemVer })(extensionManifestMock);
|
||||
return isCompatibleExtension({ extensionApiVersion })(extensionManifestMock);
|
||||
}
|
||||
|
||||
function getExtensionManifestMock(lensEngine = "1.0"): LensExtensionManifest {
|
||||
|
||||
@@ -3,14 +3,65 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { getAppVersion } from "../../common/utils";
|
||||
import appNameInjectable from "../../common/vars/app-name.injectable";
|
||||
import isLinuxInjectable from "../../common/vars/is-linux.injectable";
|
||||
import isMacInjectable from "../../common/vars/is-mac.injectable";
|
||||
import isSnapPackageInjectable from "../../common/vars/is-snap-package.injectable";
|
||||
import isWindowsInjectable from "../../common/vars/is-windows.injectable";
|
||||
import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
|
||||
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import getEnabledExtensionsInjectable from "./get-enabled-extensions/get-enabled-extensions.injectable";
|
||||
import * as Preferences from "./user-preferences";
|
||||
import type { UserPreferenceExtensionItems } from "./user-preferences";
|
||||
import { Preferences } from "./user-preferences";
|
||||
import { slackUrl, issuesTrackerUrl } from "../../common/vars";
|
||||
import { buildVersionInjectionToken } from "../../common/vars/build-semantic-version.injectable";
|
||||
|
||||
export const version = getAppVersion();
|
||||
export { isSnap, isWindows, isMac, isLinux, appName, slackUrl, issuesTrackerUrl } from "../../common/vars";
|
||||
export interface AppExtensionItems {
|
||||
readonly Preferences: UserPreferenceExtensionItems;
|
||||
readonly version: string;
|
||||
readonly appName: string;
|
||||
readonly slackUrl: string;
|
||||
readonly issuesTrackerUrl: string;
|
||||
readonly isSnap: boolean;
|
||||
readonly isWindows: boolean;
|
||||
readonly isMac: boolean;
|
||||
readonly isLinux: boolean;
|
||||
getEnabledExtensions: () => string[];
|
||||
}
|
||||
|
||||
export const getEnabledExtensions = asLegacyGlobalFunctionForExtensionApi(getEnabledExtensionsInjectable);
|
||||
export const App: AppExtensionItems = {
|
||||
Preferences,
|
||||
getEnabledExtensions: asLegacyGlobalFunctionForExtensionApi(getEnabledExtensionsInjectable),
|
||||
get version() {
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
|
||||
export { Preferences };
|
||||
return di.inject(buildVersionInjectionToken).get();
|
||||
},
|
||||
get appName() {
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
|
||||
return di.inject(appNameInjectable);
|
||||
},
|
||||
get isSnap() {
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
|
||||
return di.inject(isSnapPackageInjectable);
|
||||
},
|
||||
get isWindows() {
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
|
||||
return di.inject(isWindowsInjectable);
|
||||
},
|
||||
get isMac() {
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
|
||||
return di.inject(isMacInjectable);
|
||||
},
|
||||
get isLinux() {
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
|
||||
return di.inject(isLinuxInjectable);
|
||||
},
|
||||
slackUrl,
|
||||
issuesTrackerUrl,
|
||||
};
|
||||
@@ -4,10 +4,10 @@
|
||||
*/
|
||||
|
||||
// APIs
|
||||
import * as App from "./app";
|
||||
import { App } from "./app";
|
||||
import * as EventBus from "./event-bus";
|
||||
import * as Store from "./stores";
|
||||
import * as Util from "./utils";
|
||||
import { Util } from "./utils";
|
||||
import * as Catalog from "./catalog";
|
||||
import * as Types from "./types";
|
||||
import * as Proxy from "./proxy";
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
*/
|
||||
|
||||
import { UserStore } from "../../common/user-store";
|
||||
|
||||
/**
|
||||
* Get the configured kubectl binaries path.
|
||||
*/
|
||||
export function getKubectlPath(): string | undefined {
|
||||
return UserStore.getInstance().kubectlBinariesPath;
|
||||
export interface UserPreferenceExtensionItems {
|
||||
/**
|
||||
* Get the configured kubectl binaries path.
|
||||
*/
|
||||
getKubectlPath: () => string | undefined;
|
||||
}
|
||||
|
||||
export const Preferences: UserPreferenceExtensionItems = {
|
||||
getKubectlPath: () => UserStore.getInstance().kubectlBinariesPath,
|
||||
};
|
||||
@@ -4,14 +4,34 @@
|
||||
*/
|
||||
|
||||
import openLinkInBrowserInjectable from "../../common/utils/open-link-in-browser.injectable";
|
||||
import buildVersionInjectable from "../../main/vars/build-version/build-version.injectable";
|
||||
import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
|
||||
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import { Singleton } from "../../common/utils";
|
||||
import { prevDefault, stopPropagation } from "../../renderer/utils/prevDefault";
|
||||
import type { IClassName } from "../../renderer/utils/cssNames";
|
||||
import { cssNames } from "../../renderer/utils/cssNames";
|
||||
|
||||
export { Singleton, getAppVersion } from "../../common/utils";
|
||||
export { prevDefault, stopPropagation } from "../../renderer/utils/prevDefault";
|
||||
export { cssNames } from "../../renderer/utils/cssNames";
|
||||
export interface UtilsExtensionItems {
|
||||
Singleton: Singleton;
|
||||
prevDefault: <E extends React.SyntheticEvent | Event, R>(callback: (evt: E) => R) => (evt: E) => R;
|
||||
stopPropagation: (evt: Event | React.SyntheticEvent) => void;
|
||||
cssNames: (...classNames: IClassName[]) => string;
|
||||
openExternal: (url: string) => Promise<void>;
|
||||
openBrowser: (url: string) => Promise<void>;
|
||||
getAppVersion: () => string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link openBrowser} instead
|
||||
*/
|
||||
export const openExternal = asLegacyGlobalFunctionForExtensionApi(openLinkInBrowserInjectable);
|
||||
export const openBrowser = asLegacyGlobalFunctionForExtensionApi(openLinkInBrowserInjectable);
|
||||
export const Util: UtilsExtensionItems = {
|
||||
Singleton,
|
||||
prevDefault,
|
||||
stopPropagation,
|
||||
cssNames,
|
||||
openExternal: asLegacyGlobalFunctionForExtensionApi(openLinkInBrowserInjectable),
|
||||
openBrowser: asLegacyGlobalFunctionForExtensionApi(openLinkInBrowserInjectable),
|
||||
getAppVersion: () => {
|
||||
const di = getLegacyGlobalDiForExtensionApi();
|
||||
|
||||
return di.inject(buildVersionInjectable).get();
|
||||
},
|
||||
};
|
||||
@@ -20,21 +20,20 @@ import watchInjectable from "../../common/fs/watch/watch.injectable";
|
||||
const extensionDiscoveryInjectable = getInjectable({
|
||||
id: "extension-discovery",
|
||||
|
||||
instantiate: (di) =>
|
||||
new ExtensionDiscovery({
|
||||
extensionLoader: di.inject(extensionLoaderInjectable),
|
||||
extensionsStore: di.inject(extensionsStoreInjectable),
|
||||
extensionInstallationStateStore: di.inject(extensionInstallationStateStoreInjectable),
|
||||
isCompatibleExtension: di.inject(isCompatibleExtensionInjectable),
|
||||
installExtension: di.inject(installExtensionInjectable),
|
||||
installExtensions: di.inject(installExtensionsInjectable),
|
||||
extensionPackageRootDirectory: di.inject(extensionPackageRootDirectoryInjectable),
|
||||
staticFilesDirectory: di.inject(staticFilesDirectoryInjectable),
|
||||
readJsonFile: di.inject(readJsonFileInjectable),
|
||||
pathExists: di.inject(pathExistsInjectable),
|
||||
watch: di.inject(watchInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
}),
|
||||
instantiate: (di) => new ExtensionDiscovery({
|
||||
extensionLoader: di.inject(extensionLoaderInjectable),
|
||||
extensionsStore: di.inject(extensionsStoreInjectable),
|
||||
extensionInstallationStateStore: di.inject(extensionInstallationStateStoreInjectable),
|
||||
isCompatibleExtension: di.inject(isCompatibleExtensionInjectable),
|
||||
installExtension: di.inject(installExtensionInjectable),
|
||||
installExtensions: di.inject(installExtensionsInjectable),
|
||||
extensionPackageRootDirectory: di.inject(extensionPackageRootDirectoryInjectable),
|
||||
staticFilesDirectory: di.inject(staticFilesDirectoryInjectable),
|
||||
readJsonFile: di.inject(readJsonFileInjectable),
|
||||
pathExists: di.inject(pathExistsInjectable),
|
||||
watch: di.inject(watchInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
export default extensionDiscoveryInjectable;
|
||||
@@ -15,10 +15,10 @@ import directoryForUserDataInjectable from "../../common/app-paths/directory-for
|
||||
import mockFs from "mock-fs";
|
||||
import { delay } from "../../renderer/utils";
|
||||
import { observable, when } from "mobx";
|
||||
import appVersionInjectable from "../../common/vars/app-version.injectable";
|
||||
import readJsonFileInjectable from "../../common/fs/read-json-file.injectable";
|
||||
import pathExistsInjectable from "../../common/fs/path-exists.injectable";
|
||||
import watchInjectable from "../../common/fs/watch/watch.injectable";
|
||||
import extensionApiVersionInjectable from "../../common/vars/extension-api-version.injectable";
|
||||
|
||||
console = new Console(process.stdout, process.stderr); // fix mockFS
|
||||
|
||||
@@ -33,7 +33,7 @@ describe("ExtensionDiscovery", () => {
|
||||
|
||||
di.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
|
||||
di.override(installExtensionInjectable, () => () => Promise.resolve());
|
||||
di.override(appVersionInjectable, () => "5.0.0");
|
||||
di.override(extensionApiVersionInjectable, () => "5.0.0");
|
||||
|
||||
readJsonFileMock = jest.fn();
|
||||
di.override(readJsonFileInjectable, () => readJsonFileMock);
|
||||
|
||||
+2
-2
@@ -3,13 +3,13 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import appSemanticVersionInjectable from "../../../common/vars/app-semantic-version.injectable";
|
||||
import extensionApiVersionInjectable from "../../../common/vars/extension-api-version.injectable";
|
||||
import { isCompatibleExtension } from "./is-compatible-extension";
|
||||
|
||||
const isCompatibleExtensionInjectable = getInjectable({
|
||||
id: "is-compatible-extension",
|
||||
instantiate: (di) => isCompatibleExtension({
|
||||
appSemVer: di.inject(appSemanticVersionInjectable),
|
||||
extensionApiVersion: di.inject(extensionApiVersionInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
+4
-5
@@ -2,16 +2,15 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import semver, { type SemVer } from "semver";
|
||||
import semver from "semver";
|
||||
import type { LensExtensionManifest } from "../../lens-extension";
|
||||
|
||||
interface Dependencies {
|
||||
appSemVer: SemVer;
|
||||
extensionApiVersion: string;
|
||||
}
|
||||
|
||||
export const isCompatibleExtension = ({ appSemVer }: Dependencies): ((manifest: LensExtensionManifest) => boolean) => {
|
||||
export const isCompatibleExtension = ({ extensionApiVersion }: Dependencies): ((manifest: LensExtensionManifest) => boolean) => {
|
||||
return (manifest: LensExtensionManifest): boolean => {
|
||||
const appVersion = appSemVer.raw.split("-")[0]; // drop prerelease version if any, e.g. "-alpha.0"
|
||||
const manifestLensEngine = manifest.engines.lens;
|
||||
const validVersion = manifestLensEngine.match(/^[\^0-9]\d*\.\d+\b/); // must start from ^ or number
|
||||
|
||||
@@ -30,7 +29,7 @@ export const isCompatibleExtension = ({ appSemVer }: Dependencies): ((manifest:
|
||||
}) as semver.SemVer;
|
||||
const supportedVersionsByExtension = semver.validRange(`^${extMajor}.${extMinor}`) as string;
|
||||
|
||||
return semver.satisfies(appVersion, supportedVersionsByExtension, {
|
||||
return semver.satisfies(extensionApiVersion, supportedVersionsByExtension, {
|
||||
loose: true,
|
||||
includePrerelease: false,
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user