mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-14 16:46:25 +00:00
feat: add dart version datasource (#19277)
This commit is contained in:
parent
943efc50ae
commit
aab79f15d1
7 changed files with 202 additions and 0 deletions
|
@ -11,6 +11,7 @@ import { CondaDatasource } from './conda';
|
|||
import { CpanDatasource } from './cpan';
|
||||
import { CrateDatasource } from './crate';
|
||||
import { DartDatasource } from './dart';
|
||||
import { DartVersionDatasource } from './dart-version';
|
||||
import { DenoDatasource } from './deno';
|
||||
import { DockerDatasource } from './docker';
|
||||
import { DotnetDatasource } from './dotnet';
|
||||
|
@ -67,6 +68,7 @@ api.set(CondaDatasource.id, new CondaDatasource());
|
|||
api.set(CpanDatasource.id, new CpanDatasource());
|
||||
api.set(CrateDatasource.id, new CrateDatasource());
|
||||
api.set(DartDatasource.id, new DartDatasource());
|
||||
api.set(DartVersionDatasource.id, new DartVersionDatasource());
|
||||
api.set(DenoDatasource.id, new DenoDatasource());
|
||||
api.set(DockerDatasource.id, new DockerDatasource());
|
||||
api.set(DotnetDatasource.id, new DotnetDatasource());
|
||||
|
|
15
lib/modules/datasource/dart-version/__fixtures__/beta.json
Normal file
15
lib/modules/datasource/dart-version/__fixtures__/beta.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"kind": "storage#objects",
|
||||
"prefixes": [
|
||||
"channels/beta/release/2.17.0-69.2.beta/",
|
||||
"channels/beta/release/2.17.0/",
|
||||
"channels/beta/release/2.17.1/",
|
||||
"channels/beta/release/2.18.0-271.8.beta/",
|
||||
"channels/beta/release/2.18.0-44.1.beta/",
|
||||
"channels/beta/release/2.18.0/",
|
||||
"channels/beta/release/2.19.0-255.2.beta/",
|
||||
"channels/beta/release/2.19.0-374.1.beta/",
|
||||
"channels/beta/release/2.19.0-374.2.beta/",
|
||||
"channels/beta/release/latest/"
|
||||
]
|
||||
}
|
15
lib/modules/datasource/dart-version/__fixtures__/dev.json
Normal file
15
lib/modules/datasource/dart-version/__fixtures__/dev.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"kind": "storage#objects",
|
||||
"prefixes": [
|
||||
"channels/dev/release/2.17.0-7.0.dev/",
|
||||
"channels/dev/release/2.17.0-85.0.dev/",
|
||||
"channels/dev/release/2.17.0-91.0.dev/",
|
||||
"channels/dev/release/2.18.0-82.0.dev/",
|
||||
"channels/dev/release/2.18.0-9.0.dev/",
|
||||
"channels/dev/release/2.18.0-99.0.dev/",
|
||||
"channels/dev/release/2.19.0-59.0.dev/",
|
||||
"channels/dev/release/2.19.0-70.0.dev/",
|
||||
"channels/dev/release/2.19.0-81.0.dev/",
|
||||
"channels/dev/release/latest/"
|
||||
]
|
||||
}
|
12
lib/modules/datasource/dart-version/__fixtures__/stable.json
Normal file
12
lib/modules/datasource/dart-version/__fixtures__/stable.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"kind": "storage#objects",
|
||||
"prefixes": [
|
||||
"channels/stable/release/2.17.5/",
|
||||
"channels/stable/release/2.17.6/",
|
||||
"channels/stable/release/2.17.7/",
|
||||
"channels/stable/release/2.18.0/",
|
||||
"channels/stable/release/2.18.4/",
|
||||
"channels/stable/release/2.18.5/",
|
||||
"channels/stable/release/latest/"
|
||||
]
|
||||
}
|
74
lib/modules/datasource/dart-version/index.spec.ts
Normal file
74
lib/modules/datasource/dart-version/index.spec.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
import { getPkgReleases } from '..';
|
||||
import { Fixtures } from '../../../../test/fixtures';
|
||||
import * as httpMock from '../../../../test/http-mock';
|
||||
import { EXTERNAL_HOST_ERROR } from '../../../constants/error-messages';
|
||||
import { DartVersionDatasource } from '.';
|
||||
|
||||
const baseUrl = 'https://storage.googleapis.com';
|
||||
const urlPath =
|
||||
'/storage/v1/b/dart-archive/o?delimiter=%2F&prefix=channels%2Fstable%2Frelease%2F&alt=json';
|
||||
const datasource = DartVersionDatasource.id;
|
||||
const depName = 'dart';
|
||||
const channels = ['stable', 'beta', 'dev'];
|
||||
|
||||
describe('modules/datasource/dart-version/index', () => {
|
||||
describe('getReleases', () => {
|
||||
it('throws for 500', async () => {
|
||||
httpMock.scope(baseUrl).get(urlPath).reply(500);
|
||||
await expect(
|
||||
getPkgReleases({
|
||||
datasource,
|
||||
depName,
|
||||
})
|
||||
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||
});
|
||||
|
||||
it('returns null for error', async () => {
|
||||
httpMock.scope(baseUrl).get(urlPath).replyWithError('error');
|
||||
expect(
|
||||
await getPkgReleases({
|
||||
datasource,
|
||||
depName,
|
||||
})
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it('returns null for empty 200 OK', async () => {
|
||||
httpMock.scope(baseUrl).get(urlPath).reply(200, []);
|
||||
expect(
|
||||
await getPkgReleases({
|
||||
datasource,
|
||||
depName,
|
||||
})
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it('processes real data', async () => {
|
||||
for (const channel of channels) {
|
||||
httpMock
|
||||
.scope(baseUrl)
|
||||
.get(
|
||||
`/storage/v1/b/dart-archive/o?delimiter=%2F&prefix=channels%2F${channel}%2Frelease%2F&alt=json`
|
||||
)
|
||||
.reply(200, Fixtures.get(`${channel}.json`));
|
||||
}
|
||||
|
||||
const res = await getPkgReleases({
|
||||
datasource,
|
||||
depName,
|
||||
});
|
||||
|
||||
expect(res).toBeDefined();
|
||||
expect(res?.sourceUrl).toBe('https://github.com/dart-lang/sdk');
|
||||
expect(res?.releases).toHaveLength(21);
|
||||
expect(res?.releases).toIncludeAllPartialMembers([
|
||||
{ version: '2.18.0', isStable: true },
|
||||
{ version: '2.17.7', isStable: true },
|
||||
{ version: '2.19.0-374.2.beta', isStable: false },
|
||||
{ version: '2.18.0-44.1.beta', isStable: false },
|
||||
{ version: '2.19.0-81.0.dev', isStable: false },
|
||||
{ version: '2.18.0-99.0.dev', isStable: false },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
80
lib/modules/datasource/dart-version/index.ts
Normal file
80
lib/modules/datasource/dart-version/index.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import is from '@sindresorhus/is';
|
||||
import { regEx } from '../../../util/regex';
|
||||
import { Datasource } from '../datasource';
|
||||
import type { GetReleasesConfig, Release, ReleaseResult } from '../types';
|
||||
import type { DartResponse } from './types';
|
||||
|
||||
export const stableVersionRegex = regEx(/^\d+\.\d+\.\d+$/);
|
||||
|
||||
export class DartVersionDatasource extends Datasource {
|
||||
static readonly id = 'dart-version';
|
||||
|
||||
constructor() {
|
||||
super(DartVersionDatasource.id);
|
||||
}
|
||||
|
||||
override readonly customRegistrySupport = false;
|
||||
|
||||
override readonly defaultRegistryUrls = ['https://storage.googleapis.com'];
|
||||
|
||||
override readonly caching = true;
|
||||
|
||||
private readonly channels = ['stable', 'beta', 'dev'];
|
||||
|
||||
async getReleases({
|
||||
registryUrl,
|
||||
}: GetReleasesConfig): Promise<ReleaseResult | null> {
|
||||
// istanbul ignore if
|
||||
if (!registryUrl) {
|
||||
return null;
|
||||
}
|
||||
const result: ReleaseResult = {
|
||||
homepage: 'https://dart.dev/',
|
||||
sourceUrl: 'https://github.com/dart-lang/sdk',
|
||||
registryUrl,
|
||||
releases: [],
|
||||
};
|
||||
try {
|
||||
for (const channel of this.channels) {
|
||||
const resp = (
|
||||
await this.http.getJson<DartResponse>(
|
||||
`${registryUrl}/storage/v1/b/dart-archive/o?delimiter=%2F&prefix=channels%2F${channel}%2Frelease%2F&alt=json`
|
||||
)
|
||||
).body;
|
||||
const releases = this.getReleasesFromResponse(channel, resp.prefixes);
|
||||
result.releases.push(...releases);
|
||||
}
|
||||
} catch (err) {
|
||||
this.handleGenericErrors(err);
|
||||
}
|
||||
|
||||
return result.releases.length ? result : null;
|
||||
}
|
||||
|
||||
private getReleasesFromResponse(
|
||||
channel: string,
|
||||
prefixes: string[]
|
||||
): Release[] {
|
||||
return prefixes
|
||||
.map((prefix) => this.getVersionFromPrefix(prefix))
|
||||
.filter(is.string)
|
||||
.filter((version) => {
|
||||
if (
|
||||
version === 'latest' ||
|
||||
// The API response contains a stable version being released as a non-stable
|
||||
// release. So we filter out these releases here.
|
||||
(channel !== 'stable' && stableVersionRegex.test(version))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((version) => ({ version, isStable: channel === 'stable' }));
|
||||
}
|
||||
|
||||
// Prefix should have a format of "channels/stable/release/2.9.3/"
|
||||
private getVersionFromPrefix(prefix: string): string | undefined {
|
||||
const parts = prefix.split('/');
|
||||
return parts[parts.length - 2];
|
||||
}
|
||||
}
|
4
lib/modules/datasource/dart-version/types.ts
Normal file
4
lib/modules/datasource/dart-version/types.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export interface DartResponse {
|
||||
kind: string;
|
||||
prefixes: string[];
|
||||
}
|
Loading…
Reference in a new issue