Skip to content

Commit

Permalink
refactor(dotnet-version): Refactor schemas (#21426)
Browse files Browse the repository at this point in the history
  • Loading branch information
zharinov authored Apr 12, 2023
1 parent 1fc7a05 commit 3ded278
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 111 deletions.
89 changes: 22 additions & 67 deletions lib/modules/datasource/dotnet-version/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import is from '@sindresorhus/is';
import { cache } from '../../../util/cache/package/decorator';
import type { HttpResponse } from '../../../util/http/types';
import * as p from '../../../util/promises';
import { Datasource } from '../datasource';
import type { GetReleasesConfig, Release, ReleaseResult } from '../types';
import {
DotnetRelease,
DotnetReleases,
DotnetReleasesIndex,
DotnetReleasesIndexSchema,
DotnetReleasesSchema,
DotnetRuntimeReleases,
DotnetSdkReleases,
ReleasesIndex,
} from './schema';

export class DotnetVersionDatasource extends Datasource {
Expand Down Expand Up @@ -38,42 +35,29 @@ export class DotnetVersionDatasource extends Datasource {
return null;
}

let result: ReleaseResult | null = null;

let raw: HttpResponse<DotnetReleasesIndex> | null = null;
try {
raw = await this.http.getJson(
this.defaultRegistryUrls[0],
DotnetReleasesIndexSchema
const registryUrl = this.defaultRegistryUrls[0];
const { body: urls } = await this.http.getJson(
registryUrl,
ReleasesIndex
);
} catch (err) {
this.handleGenericErrors(err);
}

const body = raw?.body;
if (body) {
const releases: Release[] = [];
const { 'releases-index': releasesIndex } = body;

for (const { 'releases.json': releasesUrl } of releasesIndex) {
const channelReleases = await this.getChannelReleases(
releasesUrl,
packageName
);
if (channelReleases) {
releases.push(...channelReleases);
}
}
const channelReleases = await p.map(
urls,
(url) => this.getChannelReleases(url, packageName),
{ concurrency: 1, stopOnError: true }
);
const releases = channelReleases.flat();

const sourceUrl =
packageName === 'dotnet-sdk'
? 'https://github.com/dotnet/sdk'
: 'https://github.com/dotnet/runtime';

result = { releases, sourceUrl };
return { releases, sourceUrl };
} catch (err) {
this.handleGenericErrors(err);
}

return result;
}

@cache({
Expand All @@ -85,43 +69,14 @@ export class DotnetVersionDatasource extends Datasource {
async getChannelReleases(
releaseUrl: string,
packageName: string
): Promise<Release[] | null> {
let result: Release[] = [];

let raw: HttpResponse<DotnetReleases> | null = null;
): Promise<Release[]> {
const schema =
packageName === 'dotnet-sdk' ? DotnetSdkReleases : DotnetRuntimeReleases;
try {
raw = await this.http.getJson(releaseUrl, DotnetReleasesSchema);
const { body } = await this.http.getJson(releaseUrl, schema);
return body;
} catch (err) {
this.handleGenericErrors(err);
}

const body = raw?.body;
if (body) {
const type = DotnetVersionDatasource.getType(packageName);
const { releases: releases } = body;
result = releases
.filter(
(
release
): release is {
[P in keyof DotnetRelease]: NonNullable<DotnetRelease[P]>;
} => {
return !is.nullOrUndefined(release[type]);
}
)
.map((release) => {
return {
version: release[type].version,
releaseTimestamp: release['release-date'],
changelogUrl: release['release-notes'],
};
});
}

return result;
}

private static getType(packageName: string): 'sdk' | 'runtime' {
return packageName === 'dotnet-sdk' ? 'sdk' : 'runtime';
}
}
95 changes: 51 additions & 44 deletions lib/modules/datasource/dotnet-version/schema.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,59 @@
import { z } from 'zod';
import { looseArray } from '../../../util/schema-utils';
import type { Release } from '../types';

const Product = z.union([z.literal('.NET Core'), z.literal('.NET')]);
const SupportPhase = z.union([
z.literal('current'),
z.literal('eol'),
z.literal('lts'),
z.literal('maintenance'),
z.literal('preview'),
z.literal('rc'),
]);
const ReleaseIndex = z.object({
'channel-version': z.string(),
'latest-release': z.string(),
'latest-release-date': z.string(),
security: z.boolean(),
'latest-runtime': z.string(),
'latest-sdk': z.string(),
product: Product,
'support-phase': SupportPhase,
'eol-date': z.string().nullable(),
'releases.json': z.string(),
});
export const DotnetReleasesIndexSchema = z.object({
'releases-index': z.array(ReleaseIndex),
});
export const ReleasesIndex = z
.object({
'releases-index': looseArray(
z
.object({
'releases.json': z.string(),
})
.transform(({ 'releases.json': releasesUrl }) => releasesUrl)
),
})
.transform(({ 'releases-index': releasesIndex }) => releasesIndex);

const ReleaseDetails = z.object({
version: z.string(),
'version-display': z.string(),
});
const ReleaseSchema = z.object({
const ReleaseBase = z.object({
'release-date': z.string(),
'release-version': z.string(),
security: z.boolean(),
'release-notes': z.string(),
runtime: z.nullable(ReleaseDetails),
sdk: z.nullable(ReleaseDetails),
});
export const DotnetReleasesSchema = z.object({
'channel-version': z.string(),
'latest-release': z.string(),
'latest-release-date': z.string(),
'latest-runtime': z.string(),
'latest-sdk': z.string(),
'support-phase': SupportPhase,
releases: z.array(ReleaseSchema),
const ReleaseDetails = z.object({
version: z.string(),
});

export type DotnetReleasesIndex = z.infer<typeof DotnetReleasesIndexSchema>;
export type DotnetReleases = z.infer<typeof DotnetReleasesSchema>;
export type DotnetRelease = z.infer<typeof ReleaseSchema>;
export const DotnetSdkReleases = z
.object({
releases: looseArray(
ReleaseBase.extend({
sdk: ReleaseDetails,
})
),
})
.transform(({ releases }): Release[] =>
releases.map(
({
sdk: { version },
'release-date': releaseTimestamp,
'release-notes': changelogUrl,
}) => ({ version, releaseTimestamp, changelogUrl })
)
);

export const DotnetRuntimeReleases = z
.object({
releases: looseArray(
ReleaseBase.extend({
runtime: ReleaseDetails,
})
),
})
.transform(({ releases }): Release[] =>
releases.map(
({
runtime: { version },
'release-date': releaseTimestamp,
'release-notes': changelogUrl,
}) => ({ version, releaseTimestamp, changelogUrl })
)
);

0 comments on commit 3ded278

Please sign in to comment.