diff options
-rw-r--r-- | lib/modules/versioning/api.ts | 2 | ||||
-rw-r--r-- | lib/modules/versioning/devbox/index.spec.ts | 103 | ||||
-rw-r--r-- | lib/modules/versioning/devbox/index.ts | 74 | ||||
-rw-r--r-- | lib/modules/versioning/devbox/readme.md | 2 |
4 files changed, 181 insertions, 0 deletions
diff --git a/lib/modules/versioning/api.ts b/lib/modules/versioning/api.ts index 211c3f8740f..454d0f631ad 100644 --- a/lib/modules/versioning/api.ts +++ b/lib/modules/versioning/api.ts @@ -6,6 +6,7 @@ import * as composer from './composer'; import * as conan from './conan'; import * as deb from './deb'; import * as debian from './debian'; +import * as devbox from './devbox'; import * as docker from './docker'; import * as git from './git'; import * as glasskube from './glasskube'; @@ -52,6 +53,7 @@ api.set(composer.id, composer.api); api.set(conan.id, conan.api); api.set(deb.id, deb.api); api.set(debian.id, debian.api); +api.set(devbox.id, devbox.api); api.set(docker.id, docker.api); api.set(git.id, git.api); api.set(glasskube.id, glasskube.api); diff --git a/lib/modules/versioning/devbox/index.spec.ts b/lib/modules/versioning/devbox/index.spec.ts new file mode 100644 index 00000000000..542a28eeed6 --- /dev/null +++ b/lib/modules/versioning/devbox/index.spec.ts @@ -0,0 +1,103 @@ +import devbox from '.'; + +describe('modules/versioning/devbox/index', () => { + it.each` + version | expected + ${'1'} | ${false} + ${'01'} | ${false} + ${'1.01'} | ${false} + ${'1.1'} | ${false} + ${'1.3.0'} | ${true} + ${'2.1.20'} | ${true} + ${'v1.4'} | ${false} + ${'V0.5'} | ${false} + ${'3.5.0'} | ${true} + ${'4.2.21.Final'} | ${false} + ${'1234'} | ${false} + ${'foo'} | ${false} + ${'latest'} | ${false} + ${''} | ${false} + ${'3.5.0-beta.3'} | ${false} + ${'*'} | ${false} + ${'x'} | ${false} + ${'X'} | ${false} + ${'~1.2.3'} | ${false} + ${'>1.2.3'} | ${false} + ${'^1.2.3'} | ${false} + ${'1.2.3-foo'} | ${false} + ${'1.2.3foo'} | ${false} + `('isVersion("$version") === $expected', ({ version, expected }) => { + expect(!!devbox.isVersion(version)).toBe(expected); + }); + + it.each` + version | isValid + ${'1'} | ${true} + ${'01'} | ${false} + ${'1.01'} | ${false} + ${'1.1'} | ${true} + ${'1.3.0'} | ${true} + ${'2.1.20'} | ${true} + ${'v1.4'} | ${false} + ${'V0.5'} | ${false} + ${'3.5.0'} | ${true} + ${'4.2.21.Final'} | ${false} + ${'1234'} | ${true} + ${'foo'} | ${false} + ${'latest'} | ${true} + ${''} | ${false} + ${'3.5.0-beta.3'} | ${false} + ${'*'} | ${false} + ${'x'} | ${false} + ${'X'} | ${false} + ${'~1.2.3'} | ${false} + ${'>1.2.3'} | ${false} + ${'^1.2.3'} | ${false} + ${'1.2.3-foo'} | ${false} + ${'1.2.3foo'} | ${false} + `('isValid("$version") === $isValid', ({ version, isValid }) => { + expect(!!devbox.isValid(version)).toBe(isValid); + }); + + it.each` + version | range | expected + ${'1'} | ${'1'} | ${false} + ${'1'} | ${'0'} | ${false} + ${'1.2.3'} | ${'1'} | ${true} + ${'1.2'} | ${'1'} | ${false} + ${'1.0.0'} | ${'1'} | ${true} + ${'1.2.0'} | ${'1.2'} | ${true} + ${'1.2.3'} | ${'1.2'} | ${true} + ${'0'} | ${'latest'} | ${false} + ${'1.2.3'} | ${'latest'} | ${true} + ${'1.2.3.5'} | ${'1.2.3.5'} | ${false} + ${'1.2'} | ${'1.2.3'} | ${false} + `( + 'matches("$version", "$range") === $expected', + ({ version, range, expected }) => { + expect(devbox.matches(version, range)).toBe(expected); + }, + ); + + it.each` + version | range | expected + ${'1'} | ${'1'} | ${true} + ${'1'} | ${'0'} | ${false} + ${'1.2.3'} | ${'1'} | ${true} + ${'1.2'} | ${'1'} | ${true} + ${'1.0.0'} | ${'1'} | ${true} + ${'1.2.0'} | ${'1.2'} | ${true} + ${'1.2.3'} | ${'1.2'} | ${true} + ${'0'} | ${'latest'} | ${true} + ${'1.2.3'} | ${'latest'} | ${true} + ${'1.2.3.5'} | ${'1.2.3.5'} | ${false} + ${'latest'} | ${'latest'} | ${false} + ${'latest'} | ${'1.2.3'} | ${false} + ${'1.2'} | ${'1.2.3'} | ${true} + `( + 'equals("$version", "$range") === $expected', + ({ version, range, expected }) => { + expect(devbox.equals(version, range)).toBe(expected); + }, + ); +}); diff --git a/lib/modules/versioning/devbox/index.ts b/lib/modules/versioning/devbox/index.ts new file mode 100644 index 00000000000..153f01f4f4d --- /dev/null +++ b/lib/modules/versioning/devbox/index.ts @@ -0,0 +1,74 @@ +import { regEx } from '../../../util/regex'; +import type { GenericVersion } from '../generic'; +import { GenericVersioningApi } from '../generic'; +import type { VersioningApi } from '../types'; + +export const id = 'devbox'; +export const displayName = 'devbox'; +export const urls = []; +export const supportsRanges = false; + +const validPattern = regEx(/^((\d|[1-9]\d*)(\.(\d|[1-9]\d*)){0,2})$/); +const versionPattern = regEx(/^((\d|[1-9]\d*)(\.(\d|[1-9]\d*)){2})$/); + +class DevboxVersioningApi extends GenericVersioningApi { + protected _parse(version: string): GenericVersion | null { + const matches = validPattern.exec(version); + if (!matches) { + return null; + } + const release = matches[0].split('.').map(Number); + return { release }; + } + + override isValid(version: string): boolean { + if (version === 'latest') { + return true; + } + return this._parse(version) !== null; + } + + override isVersion(version: string): boolean { + if (version === 'latest') { + return false; + } + const matches = versionPattern.exec(version); + return !!matches; + } + + override matches(version: string, range: string): boolean { + return this.isVersion(version) && this.equals(version, range); + } + + protected override _compare(version: string, other: string): number { + const parsed1 = this._parse(version); + const parsed2 = this._parse(other); + + // Treat "latest" as * and always return equal + if (other === 'latest' && parsed1) { + return 0; + } + + // If either version is invalid, return unequal + if (!(parsed1 && parsed2)) { + return 1; + } + // support variable length compare + const length = Math.max(parsed1.release.length, parsed2.release.length); + for (let i = 0; i < length; i += 1) { + // 2.1 and 2.1.0 are equivalent + const part1 = parsed1.release[i]; + const part2 = parsed2.release[i]; + // if part1 or part2 is undefined, we should treat them as equal + // e.g. 1.0.0 === 1.0 + if (part1 !== undefined && part2 !== undefined && part1 !== part2) { + return part1 - part2; + } + } + return 0; + } +} + +export const api: VersioningApi = new DevboxVersioningApi(); + +export default api; diff --git a/lib/modules/versioning/devbox/readme.md b/lib/modules/versioning/devbox/readme.md new file mode 100644 index 00000000000..e7eff534d5c --- /dev/null +++ b/lib/modules/versioning/devbox/readme.md @@ -0,0 +1,2 @@ +Devbox's Nixhub uses fairly strict versioning, characters such as ~, ^ and >= are not allowed. +The semver values must not include "\*" or "x". "1.2.3" "1.2" and "1" are the only valid formats. |