[crates] MSRV Badge (#9871)

Crates.io MSRV: `/crates/msrv/:crate`
Crates.io MSRV (version): `/crates/msrv/:crate/:version`
This commit is contained in:
Sky
2024-01-07 15:54:27 -05:00
committed by GitHub
parent 16d0ebbe7b
commit 57aaaad7fe
3 changed files with 91 additions and 0 deletions

View File

@@ -13,6 +13,7 @@ const crateSchema = Joi.object({
Joi.object({
downloads: nonNegativeInteger,
license: Joi.string().required().allow(null),
rust_version: Joi.string().allow(null),
}),
)
.min(1)
@@ -24,6 +25,7 @@ const versionSchema = Joi.object({
downloads: nonNegativeInteger,
num: Joi.string().required(),
license: Joi.string().required().allow(null),
rust_version: Joi.string().allow(null),
}).required(),
}).required()

View File

@@ -0,0 +1,74 @@
import { NotFound, pathParams } from '../index.js'
import {
BaseCratesService,
description as cratesIoDescription,
} from './crates-base.js'
const description = `
${cratesIoDescription}
MSRV is a crate's minimum suppported rust version,
the oldest version of Rust supported by the crate.
See the [Cargo Book](https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field)
for more info.
`
export default class CratesMSRV extends BaseCratesService {
static category = 'platform-support'
static route = {
base: 'crates/msrv',
pattern: ':crate/:version?',
}
static openApi = {
'/crates/msrv/{crate}': {
get: {
summary: 'Crates.io MSRV',
description,
parameters: pathParams({
name: 'crate',
example: 'serde',
}),
},
},
'/crates/msrv/{crate}/{version}': {
get: {
summary: 'Crates.io MSRV (version)',
description,
parameters: pathParams(
{
name: 'crate',
example: 'serde',
},
{
name: 'version',
example: '1.0.194',
},
),
},
},
}
static defaultBadgeData = { label: 'msrv', color: 'blue' }
static transform({ errors, version, versions }) {
// crates.io returns a 200 response with an errors object in
// error scenarios, e.g. https://crates.io/api/v1/crates/libc/0.1
if (errors) {
throw new NotFound({ prettyMessage: errors[0].detail })
}
const msrv = version ? version.rust_version : versions[0].rust_version
if (!msrv) {
throw new NotFound({ prettyMessage: 'unknown' })
}
return { msrv }
}
async handle({ crate, version }) {
const json = await this.fetch({ crate, version })
const { msrv } = this.constructor.transform(json)
return { message: msrv }
}
}

View File

@@ -0,0 +1,15 @@
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
// dummy crate i created specifically for this test case
t.create('msrv')
.get('/shields-test-dummy-crate-msrv-3452398210.json')
.expectBadge({ label: 'msrv', message: '1.69' })
t.create('msrv (with version)')
.get('/shields-test-dummy-crate-msrv-3452398210/0.69.0.json')
.expectBadge({ label: 'msrv', message: '1.69' })
t.create('msrv (not found)')
.get('/not-a-real-package.json')
.expectBadge({ label: 'msrv', message: 'not found' })