Skip to content

Commit

Permalink
Fix extension engine range not working for some ^ ranges (#4554)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nokel81 authored and jim-docker committed Jan 19, 2022
1 parent d22178b commit 40b45a8
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 25 deletions.
44 changes: 25 additions & 19 deletions src/extensions/__tests__/extension-compatibility.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,24 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { isCompatibleExtension } from "../extension-compatibility";
import { rawIsCompatibleExtension } from "../extension-compatibility";
import { Console } from "console";
import { stdout, stderr } from "process";
import type { LensExtensionManifest } from "../lens-extension";
import { appSemVer } from "../../common/vars";
import { SemVer } from "semver";

console = new Console(stdout, stderr);

describe("extension compatibility", () => {
describe("appSemVer with no prerelease tag", () => {
beforeAll(() => {
appSemVer.major = 5;
appSemVer.minor = 0;
appSemVer.patch = 3;
appSemVer.prerelease = [];
});
const isCompatibleExtension = rawIsCompatibleExtension(new SemVer("5.0.3"));

it("has no extension comparator", () => {
const manifest = { name: "extensionName", version: "0.0.1" };

expect(isCompatibleExtension(manifest)).toBe(false);
});

it.each([
{
comparator: "",
Expand Down Expand Up @@ -83,19 +78,32 @@ describe("extension compatibility", () => {
});

describe("appSemVer with prerelease tag", () => {
beforeAll(() => {
appSemVer.major = 5;
appSemVer.minor = 0;
appSemVer.patch = 3;
appSemVer.prerelease = ["beta", 3];
const isCompatibleExtension = rawIsCompatibleExtension(new SemVer("5.0.3-beta.3"));

it("^5.1.0 should work when lens' version is 5.1.0-latest.123456789", () => {
const comparer = rawIsCompatibleExtension(new SemVer("5.1.0-latest.123456789"));

expect(comparer({ name: "extensionName", version: "0.0.1", engines: { lens: "^5.1.0" }})).toBe(true);
});


it("^5.1.0 should not when lens' version is 5.1.0-beta.1.123456789", () => {
const comparer = rawIsCompatibleExtension(new SemVer("5.1.0-beta.123456789"));

expect(comparer({ name: "extensionName", version: "0.0.1", engines: { lens: "^5.1.0" }})).toBe(false);
});

it("^5.1.0 should not when lens' version is 5.1.0-alpha.1.123456789", () => {
const comparer = rawIsCompatibleExtension(new SemVer("5.1.0-alpha.123456789"));

expect(comparer({ name: "extensionName", version: "0.0.1", engines: { lens: "^5.1.0" }})).toBe(false);
});

it("has no extension comparator", () => {
const manifest = { name: "extensionName", version: "0.0.1" };

expect(isCompatibleExtension(manifest)).toBe(false);
});

it.each([
{
comparator: "",
Expand Down Expand Up @@ -130,9 +138,7 @@ describe("extension compatibility", () => {
expected: false,
},
])("extension comparator test: %p", ({ comparator, expected }) => {
const manifest: LensExtensionManifest = { name: "extensionName", version: "0.0.1", engines: { lens: comparator }};

expect(isCompatibleExtension(manifest)).toBe(expected);
expect(isCompatibleExtension({ name: "extensionName", version: "0.0.1", engines: { lens: comparator }})).toBe(expected);
});
});
});
40 changes: 34 additions & 6 deletions src/extensions/extension-compatibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,47 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import semver from "semver";
import semver, { SemVer } from "semver";
import { appSemVer, isProduction } from "../common/vars";
import type { LensExtensionManifest } from "./lens-extension";

export function isCompatibleExtension(manifest: LensExtensionManifest): boolean {
if (manifest.engines?.lens) {
/* include Lens's prerelease tag in the matching so the extension's compatibility is not limited by it */
return semver.satisfies(appSemVer, manifest.engines.lens, { includePrerelease: true });
export function rawIsCompatibleExtension(version: SemVer): (manifest: LensExtensionManifest) => boolean {
const { major, minor, patch, prerelease: oldPrelease } = version;
let prerelease = "";

if (oldPrelease.length > 0) {
const [first] = oldPrelease;

if (first === "alpha" || first === "beta" || first === "rc") {
/**
* Strip the build IDs and "latest" prerelease tag as that is not really
* a part of API version
*/
prerelease = `-${oldPrelease.slice(0, 2).join(".")}`;
}
}

return false;
/**
* We unfortunately have to format as string because the constructor only
* takes an instance or a string.
*/
const strippedVersion = new SemVer(`${major}.${minor}.${patch}${prerelease}`, { includePrerelease: true });

return (manifest: LensExtensionManifest): boolean => {
if (manifest.engines?.lens) {
/**
* include Lens's prerelease tag in the matching so the extension's
* compatibility is not limited by it
*/
return semver.satisfies(strippedVersion, manifest.engines.lens, { includePrerelease: true });
}

return false;
};
}

export const isCompatibleExtension = rawIsCompatibleExtension(appSemVer);

export function isCompatibleBundledExtension(manifest: LensExtensionManifest): boolean {
return !isProduction || manifest.version === appSemVer.raw;
}

0 comments on commit 40b45a8

Please sign in to comment.