Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(versioning/distro): Move date handling into distro.ts #15271

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 55 additions & 40 deletions lib/modules/versioning/distro.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { DateTime, Settings } from 'luxon';
import { DistroInfo } from './distro';

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

beforeAll(() => {
const dt = DateTime.fromISO('2021-03-20');
jest.spyOn(Settings, 'now').mockReturnValue(dt.valueOf());
});

it.each`
version | expected
${'jammy'} | ${true}
Expand Down Expand Up @@ -73,68 +79,77 @@ describe('modules/versioning/distro', () => {

it.each`
version | expected
${'eoan'} | ${true}
${'focal'} | ${false}
${'groovy'} | ${true}
${'hirsute'} | ${true}
${'groovy'} | ${false}
${'hirsute'} | ${false}
${'impish'} | ${false}
${'jammy'} | ${false}
${'19.10'} | ${true}
${'20.04'} | ${false}
${'20.10'} | ${true}
${'21.04'} | ${true}
${'20.10'} | ${false}
${'21.04'} | ${false}
${'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.each`
version | expected
${'focal'} | ${true}
${'groovy'} | ${true}
${'hirsute'} | ${false}
${'impish'} | ${false}
${'jammy'} | ${false}
${'20.04'} | ${true}
${'20.10'} | ${true}
${'21.04'} | ${false}
${'21.10'} | ${false}
${'22.04'} | ${false}
${'24.04'} | ${false}
`('isReleased("$version") === $expected', ({ version, expected }) => {
expect(di.isReleased(version)).toBe(expected);
});
viceice marked this conversation as resolved.
Show resolved Hide resolved

it('retrieves schedule of the previous previous release', () => {
expect(di.getNLatest(2)).toMatchObject({
series: 'eoan',
version: '19.10',
});
});

it('sends an out of bound argument', () => {
expect(di.getNLatest(-1)).toBeNull();
it('retrieves schedule of the previous release', () => {
expect(di.getNLatest(1)).toMatchObject({
series: 'focal',
version: '20.04',
});
});

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 schedule of the most recent release', () => {
expect(di.getNLatest(0)).toMatchObject({
series: 'groovy',
version: '20.10',
});
});

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('sends a float as an argument', () => {
expect(di.getNLatest(0.1)).toMatchObject({
series: 'groovy',
version: '20.10',
});
});

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

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

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',
expect(di.getSchedule('20.04')).toMatchObject({
release: '2020-04-23',
series: 'focal',
});
Expand Down
47 changes: 41 additions & 6 deletions lib/modules/versioning/distro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export type DistroInfoRecord = Record<string, DistroSchedule>;

export type DistroInfoRecordWithVersion = { version: string } & DistroSchedule;

// Days to delay new releases
const delay = 1;

export class DistroInfo {
private readonly _codenameToVersion = new Map<
string,
Expand Down Expand Up @@ -127,15 +130,34 @@ export class DistroInfo {
}

if (end) {
const now = DateTime.now();
const eol = DateTime.fromISO(end);
const now = DateTime.now().toUTC();
const eol = DateTime.fromISO(end, { zone: 'utc' });
return eol < now;
}

// istanbul ignore next
return true;
}

/**
* Check if a given version has been released
* @param input A codename/semVer
* @returns false if unreleased or has no schedule, true otherwise
*/
public isReleased(input: string): boolean {
const ver = this.getVersionByCodename(input);
const schedule = this.getSchedule(ver);

if (!schedule) {
return false;
}

const now = DateTime.now().minus({ day: delay }).toUTC();
const release = DateTime.fromISO(schedule.release, { zone: 'utc' });

return release < now;
}

/**
* 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.
Expand All @@ -145,12 +167,25 @@ export class DistroInfo {
*/
public getNLatest(n: number): DistroInfoRecordWithVersion | null {
const len = this._sortedInfo.length - 1;
const i = len - Math.floor(n);
let idx = -1;

if (n < 0) {
return null;
}

for (let i = len; i >= 0; i--) {
if (this.isReleased(this._sortedInfo[i].version)) {
// 'i' holds the latest released version index
// compensate for the requested 'n'
idx = i - Math.floor(n);
break;
}
}

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

return null;
return this._sortedInfo[idx];
}
}
11 changes: 0 additions & 11 deletions lib/modules/versioning/ubuntu/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,6 @@ describe('modules/versioning/ubuntu/index', () => {
${'20.04'} | ${true}
${'20.10'} | ${false}
${'22.04'} | ${false}
${'42.01'} | ${false}
${'42.02'} | ${false}
${'42.03'} | ${false}
${'42.04'} | ${true}
${'42.05'} | ${false}
${'42.06'} | ${false}
${'42.07'} | ${false}
${'42.08'} | ${false}
${'42.09'} | ${false}
${'42.10'} | ${false}
${'42.11'} | ${false}
${'2020.04'} | ${false}
${'warty'} | ${false}
${'hoary'} | ${false}
Expand Down
10 changes: 3 additions & 7 deletions lib/modules/versioning/ubuntu/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { DateTime } from 'luxon';
import { regEx } from '../../../util/regex';
import { DistroInfo } from '../distro';
import type { NewValueConfig, VersioningApi } from '../types';
Expand Down Expand Up @@ -43,12 +42,9 @@ function isStable(version: string): boolean {
return false;
}

const schedule = di.getSchedule(ver);
if (
schedule &&
DateTime.fromISO(schedule.release).toUTC() >
DateTime.now().minus({ days: 1 }).toUTC()
) {
const match = ver.match(regEx(/^\d+.\d+/));

if (!di.isReleased(match ? match[0] : ver)) {
return false;
}

Expand Down