-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
lib/modules/datasource/bazel/__fixtures__/metadata-no-yanked-versions.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"versions": [ | ||
"0.14.8", | ||
"0.14.9", | ||
"0.15.0", | ||
"0.16.0" | ||
], | ||
"yanked_versions": {} | ||
} |
11 changes: 11 additions & 0 deletions
11
lib/modules/datasource/bazel/__fixtures__/metadata-with-yanked-versions.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"versions": [ | ||
"0.14.8", | ||
"0.14.9", | ||
"0.15.0", | ||
"0.16.0" | ||
], | ||
"yanked_versions": { | ||
"0.15.0": "Very bad bug." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { getPkgReleases } from '..'; | ||
import { Fixtures } from '../../../../test/fixtures'; | ||
import * as httpMock from '../../../../test/http-mock'; | ||
import { EXTERNAL_HOST_ERROR } from '../../../constants/error-messages'; | ||
import { BazelDatasource } from '.'; | ||
|
||
const datasource = BazelDatasource.id; | ||
const defaultRegistryUrl = BazelDatasource.bazelCentralRepoUrl; | ||
const packageName = 'rules_foo'; | ||
const path = BazelDatasource.packageMetadataPath(packageName); | ||
|
||
describe('modules/datasource/bazel/index', () => { | ||
describe('getReleases', () => { | ||
it('throws for error', async () => { | ||
httpMock.scope(defaultRegistryUrl).get(path).replyWithError('error'); | ||
await expect(getPkgReleases({ datasource, packageName })).rejects.toThrow( | ||
EXTERNAL_HOST_ERROR | ||
); | ||
}); | ||
|
||
it('returns null for 404', async () => { | ||
httpMock.scope(defaultRegistryUrl).get(path).reply(404); | ||
expect(await getPkgReleases({ datasource, packageName })).toBeNull(); | ||
}); | ||
|
||
it('returns null for empty result', async () => { | ||
httpMock.scope(defaultRegistryUrl).get(path).reply(200, {}); | ||
expect(await getPkgReleases({ datasource, packageName })).toBeNull(); | ||
}); | ||
|
||
it('returns null for empty 200 OK', async () => { | ||
httpMock | ||
.scope(defaultRegistryUrl) | ||
.get(path) | ||
.reply(200, '{ "versions": [], "yanked_versions": {} }'); | ||
expect(await getPkgReleases({ datasource, packageName })).toBeNull(); | ||
}); | ||
|
||
it('throws for 5xx', async () => { | ||
httpMock.scope(defaultRegistryUrl).get(path).reply(502); | ||
await expect(getPkgReleases({ datasource, packageName })).rejects.toThrow( | ||
EXTERNAL_HOST_ERROR | ||
); | ||
}); | ||
|
||
it('metadata without yanked versions', async () => { | ||
httpMock | ||
.scope(defaultRegistryUrl) | ||
.get(path) | ||
.reply(200, Fixtures.get('metadata-no-yanked-versions.json')); | ||
const res = await getPkgReleases({ datasource, packageName }); | ||
expect(res).toEqual({ | ||
registryUrl: | ||
'https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main', | ||
releases: [ | ||
{ version: '0.14.8' }, | ||
{ version: '0.14.9' }, | ||
{ version: '0.15.0' }, | ||
{ version: '0.16.0' }, | ||
], | ||
}); | ||
}); | ||
|
||
it('metadata with yanked versions', async () => { | ||
httpMock | ||
.scope(defaultRegistryUrl) | ||
.get(path) | ||
.reply(200, Fixtures.get('metadata-with-yanked-versions.json')); | ||
const res = await getPkgReleases({ datasource, packageName }); | ||
expect(res).toEqual({ | ||
registryUrl: | ||
'https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main', | ||
releases: [ | ||
{ version: '0.14.8' }, | ||
{ version: '0.14.9' }, | ||
{ version: '0.15.0', isDeprecated: true }, | ||
{ version: '0.16.0' }, | ||
], | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import is from '@sindresorhus/is'; | ||
import { ExternalHostError } from '../../../types/errors/external-host-error'; | ||
import { cache } from '../../../util/cache/package/decorator'; | ||
import { HttpError } from '../../../util/http'; | ||
import { joinUrlParts } from '../../../util/url'; | ||
import { BzlmodVersion } from '../../versioning/bazel-module/bzlmod-version'; | ||
import { Datasource } from '../datasource'; | ||
import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; | ||
import { BazelModuleMetadata } from './schema'; | ||
|
||
export class BazelDatasource extends Datasource { | ||
static readonly id = 'bazel'; | ||
|
||
static readonly bazelCentralRepoUrl = | ||
'https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main'; | ||
|
||
override readonly defaultRegistryUrls = [BazelDatasource.bazelCentralRepoUrl]; | ||
override readonly customRegistrySupport = true; | ||
override readonly caching = true; | ||
|
||
static packageMetadataPath(packageName: string): string { | ||
return `/modules/${packageName}/metadata.json`; | ||
} | ||
|
||
constructor() { | ||
super(BazelDatasource.id); | ||
} | ||
|
||
@cache({ | ||
namespace: `datasource-${BazelDatasource.id}`, | ||
key: ({ registryUrl, packageName }: GetReleasesConfig) => | ||
`${registryUrl!}:${packageName}`, | ||
}) | ||
async getReleases({ | ||
registryUrl, | ||
packageName, | ||
}: GetReleasesConfig): Promise<ReleaseResult | null> { | ||
const path = BazelDatasource.packageMetadataPath(packageName); | ||
const url = joinUrlParts(registryUrl!, path); | ||
|
||
const result: ReleaseResult = { releases: [] }; | ||
try { | ||
const { body: metadata } = await this.http.getJson( | ||
url, | ||
BazelModuleMetadata | ||
); | ||
result.releases = metadata.versions | ||
.map((v) => new BzlmodVersion(v)) | ||
.sort(BzlmodVersion.defaultCompare) | ||
.map((bv) => { | ||
const release: Release = { version: bv.original }; | ||
if (is.truthy(metadata.yanked_versions[bv.original])) { | ||
release.isDeprecated = true; | ||
} | ||
return release; | ||
}); | ||
} catch (err) { | ||
// istanbul ignore else: not testable with nock | ||
if (err instanceof HttpError) { | ||
if (err.response?.statusCode === 404) { | ||
return null; | ||
} | ||
throw new ExternalHostError(err); | ||
} | ||
this.handleGenericErrors(err); | ||
} | ||
|
||
return result.releases.length ? result : null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The `bazel` datasource is designed to query one or more [Bazel registries](https://bazel.build/external/registry) using the first successful result. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Fixtures } from '../../../../test/fixtures'; | ||
import { BazelModuleMetadata } from './schema'; | ||
|
||
describe('modules/datasource/bazel/schema', () => { | ||
describe('BazelModuleMetadata', () => { | ||
it('parses metadata', () => { | ||
const metadataJson = Fixtures.get('metadata-with-yanked-versions.json'); | ||
const metadata = BazelModuleMetadata.parse(JSON.parse(metadataJson)); | ||
expect(metadata.versions).toHaveLength(4); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { z } from 'zod'; | ||
|
||
export const BazelModuleMetadata = z.object({ | ||
versions: z.array(z.string()), | ||
yanked_versions: z.record(z.string(), z.string()), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters