Skip to content

Commit

Permalink
refactor(versioning/distro): added functionality for debian (#15051)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
Gabriel-Ladzaretti and viceice committed Apr 14, 2022
1 parent 4e83d3c commit 5304734
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 10 deletions.
146 changes: 146 additions & 0 deletions lib/modules/versioning/distro.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { DistroInfo } from './distro';

describe('modules/versioning/distro', () => {
const di = new DistroInfo('data/ubuntu-distro-info.json');

it.each`
version | expected
${'jammy'} | ${true}
${'impish'} | ${true}
${'hirsute'} | ${true}
${'groovy'} | ${true}
${'focal'} | ${true}
${'eoan'} | ${true}
${'Wily Werewolf'} | ${false}
${'asdf'} | ${false}
${'Yakkety'} | ${false}
`('isCodename("$version") === $expected', ({ version, expected }) => {
expect(di.isCodename(version)).toBe(expected);
});

it.each`
version | expected
${'jammy'} | ${'22.04'}
${'impish'} | ${'21.10'}
${'hirsute'} | ${'21.04'}
${'groovy'} | ${'20.10'}
${'focal'} | ${'20.04'}
${'eoan'} | ${'19.10'}
${'asd'} | ${'asd'}
${'16.06'} | ${'16.06'}
`(
'getVersionByCodename("$version") === $expected',
({ version, expected }) => {
expect(di.getVersionByCodename(version)).toBe(expected);
}
);

it.each`
version | expected
${'22.04'} | ${'jammy'}
${'21.10'} | ${'impish'}
${'21.04'} | ${'hirsute'}
${'20.10'} | ${'groovy'}
${'20.04'} | ${'focal'}
${'19.10'} | ${'eoan'}
${'asd'} | ${'asd'}
${'16.06'} | ${'16.06'}
`(
'getCodenameByVersion("$version") === $expected',
({ version, expected }) => {
expect(di.getCodenameByVersion(version)).toBe(expected);
}
);

it.each`
version | expected
${'jammy'} | ${true}
${'impish'} | ${true}
${'hirsute'} | ${true}
${'groovy'} | ${true}
${'focal'} | ${true}
${'Wily Werewolf'} | ${false}
${'22.04'} | ${true}
${'21.10'} | ${true}
${'21.04'} | ${true}
${'20.10'} | ${true}
${'Wily Werewolf'} | ${false}
${'asdf'} | ${false}
${'Jellyfish'} | ${false}
`('exists("$version") === $expected', ({ version, expected }) => {
expect(di.exists(version)).toBe(expected);
});

it.each`
version | expected
${'focal'} | ${false}
${'groovy'} | ${true}
${'hirsute'} | ${true}
${'impish'} | ${false}
${'jammy'} | ${false}
${'20.04'} | ${false}
${'20.10'} | ${true}
${'21.04'} | ${true}
${'21.10'} | ${false}
${'22.04'} | ${false}
`('isEolLts("$version") === $expected', ({ version, expected }) => {
expect(di.isEolLts(version)).toBe(expected);
});

it('retrieves most recent release schedule with version', () => {
expect(di.getNLatest(0)).toEqual({
codename: 'Jammy Jellyfish',
created: '2021-10-14',
eol: '2027-04-21',
eol_esm: '2032-04-21',
eol_server: '2027-04-21',
release: '2022-04-21',
series: 'jammy',
version: '22.04',
});
});

it('sends an out of bound argument', () => {
expect(di.getNLatest(-1)).toBeNull();
});

it('sends a float as an argument', () => {
expect(di.getNLatest(0.1)).toEqual({
codename: 'Jammy Jellyfish',
created: '2021-10-14',
eol: '2027-04-21',
eol_esm: '2032-04-21',
eol_server: '2027-04-21',
release: '2022-04-21',
series: 'jammy',
version: '22.04',
});
});

it('retrieves before most recent release schedule with version', () => {
expect(di.getNLatest(1)).toEqual({
codename: 'Impish Indri',
series: 'impish',
created: '2021-04-22',
release: '2021-10-14',
eol: '2022-07-14',
version: '21.10',
});
});

it('retrieves focal release schedule', () => {
expect(di.getSchedule('20.04')).toEqual({
codename: 'Focal Fossa',
created: '2019-10-17',
eol: '2025-04-23',
eol_esm: '2030-04-23',
eol_server: '2025-04-23',
release: '2020-04-23',
series: 'focal',
});
});

it('retrieves non-existent release schedule', () => {
expect(di.getSchedule('20.06')).toBeNull();
});
});
99 changes: 96 additions & 3 deletions lib/modules/versioning/distro.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DateTime } from 'luxon';
import dataFiles, { DataFile } from '../../data-files.generated';

interface DistroSchedule {
Expand All @@ -12,7 +13,7 @@ interface DistroSchedule {
eol_elts?: string;
}

type DistroDataFile = 'data/ubuntu-distro-info.json';
export type DistroDataFile = 'data/ubuntu-distro-info.json';

export type DistroInfoRecord = Record<string, DistroSchedule>;

Expand All @@ -23,6 +24,9 @@ export class DistroInfo {
string,
DistroInfoRecordWithVersion
>();

private readonly _sortedInfo: DistroInfoRecordWithVersion[] = [];

private readonly _distroInfo: DistroInfoRecord;

constructor(distroJsonKey: DistroDataFile) {
Expand All @@ -35,12 +39,45 @@ export class DistroInfo {
const schedule = this._distroInfo[version];
this._codenameToVersion.set(schedule.series, { version, ...schedule });
}

const arr = Object.keys(this._distroInfo).sort(
(a, b) => parseFloat(a) - parseFloat(b)
);

for (const v of arr) {
const obj = { version: v, ...this._distroInfo[v.toString()] };
if (!obj.eol) {
// istanbul ignore next
continue;
}
this._sortedInfo.push(obj);
}
}

/**
* Check if input is a valid release codename
* @param input A codename
* @returns true if input is a codename, false otherwise
*/
public isCodename(input: string): boolean {
return this._codenameToVersion.has(input);
}

/**
* Checks if given input string is a valid release version
* @param input A codename/semVer
* @returns true if release exists, false otherwise
*/
public exists(input: string): boolean {
const ver = this.getVersionByCodename(input);
return !!this._distroInfo[ver];
}

/**
* Get semVer representation of a given codename
* @param input A codename
* @returns A semVer if exists, otherwise input string is returned
*/
public getVersionByCodename(input: string): string {
const schedule = this._codenameToVersion.get(input);
if (schedule) {
Expand All @@ -49,6 +86,11 @@ export class DistroInfo {
return input;
}

/**
* Get codename representation of a given semVer
* @param input A semVer
* @returns A codename if exists, otherwise input string is returned
*/
public getCodenameByVersion(input: string): string {
const di = this._distroInfo[input];
if (di) {
Expand All @@ -58,7 +100,58 @@ export class DistroInfo {
return input;
}

public getSchedule(input: string): DistroSchedule {
return this._distroInfo[input];
/**
* Get schedule of a given release
* @param input A codename/semVer
* @returns A schedule if available, otherwise undefined
*/
public getSchedule(input: string): DistroSchedule | null {
const ver = this.getVersionByCodename(input);
return this._distroInfo[ver] ?? null;
}

/**
* Check if a given release has passed its EOL
* @param input A codename/semVer
* @returns false if still supported, true otherwise
*/
public isEolLts(input: string): boolean {
const ver = this.getVersionByCodename(input);
const schedule = this.getSchedule(ver);
const endLts = schedule?.eol ?? null;
let end = schedule?.eol_lts ?? null;

// ubuntu: does not have eol_lts
// debian: only "Stable" has no eol_lts, old and oldold has both
if (!end) {
end = endLts;
}

if (end) {
const now = DateTime.now();
const eol = DateTime.fromISO(end);
return eol < now;
}

// istanbul ignore next
return true;
}

/**
* Get distro info for the release that has N other newer releases.
* Example: n=0 corresponds to the latest available release, n=1 the release before, etc.
* In Debian terms: N = 0 -> stable, N = 1 -> oldstable, N = 2 -> oldoldstalbe
* @param n
* @returns Distro info of the Nth latest release
*/
public getNLatest(n: number): DistroInfoRecordWithVersion | null {
const len = this._sortedInfo.length - 1;
const i = len - Math.floor(n);

if (len >= i && i >= 0) {
return this._sortedInfo[i];
}

return null;
}
}
12 changes: 5 additions & 7 deletions lib/modules/versioning/ubuntu/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ describe('modules/versioning/ubuntu/index', () => {
${'impish'} | ${true}
${'jammy'} | ${true}
`('isValid("$version") === $expected', ({ version, expected }) => {
expect(!!ubuntu.isValid(version)).toBe(expected);
expect(ubuntu.isValid(version)).toBe(expected);
});

test.each`
Expand All @@ -94,8 +94,7 @@ describe('modules/versioning/ubuntu/index', () => {
`(
'isCompatible("$version") === $expected',
({ version, range, expected }) => {
const res = ubuntu.isCompatible(version, range);
expect(!!res).toBe(expected);
expect(ubuntu.isCompatible(version, range)).toBe(expected);
}
);

Expand All @@ -107,7 +106,7 @@ describe('modules/versioning/ubuntu/index', () => {
${'20.04'} | ${true}
${'>=20.04'} | ${false}
`('isSingleVersion("$version") === $expected', ({ version, expected }) => {
expect(!!ubuntu.isSingleVersion(version)).toBe(expected);
expect(ubuntu.isSingleVersion(version)).toBe(expected);
});

test.each`
Expand Down Expand Up @@ -198,8 +197,7 @@ describe('modules/versioning/ubuntu/index', () => {
${'impish'} | ${false}
${'jammy'} | ${false}
`('isStable("$version") === $expected', ({ version, expected }) => {
const res = !!ubuntu.isStable(version);
expect(res).toBe(expected);
expect(ubuntu.isStable(version)).toBe(expected);
});

test.each`
Expand Down Expand Up @@ -252,7 +250,7 @@ describe('modules/versioning/ubuntu/index', () => {
${'impish-'} | ${false}
${'JAMMY'} | ${false}
`('isVersion("$version") === $expected', ({ version, expected }) => {
expect(!!ubuntu.isVersion(version)).toBe(expected);
expect(ubuntu.isVersion(version)).toBe(expected);
});

test.each`
Expand Down

0 comments on commit 5304734

Please sign in to comment.