From bdf84f9f9466923efc439a014b483fd30d8f3289 Mon Sep 17 00:00:00 2001 From: Joey Li <joey@joeyli.dev> Date: Sun, 4 Aug 2024 14:35:28 +0200 Subject: [PATCH] [Crates] Added crate size badge (#10421) * add some basic tests for size badge * add crate size to crates fetch * add crate size service * change test to reflect base-10 counting instead * fix downloads tests to work with new crate_size scheme addition * move handling of unknown size to handle --- services/crates/crates-base.js | 2 + services/crates/crates-downloads.tester.js | 7 ++- services/crates/crates-size.service.js | 59 ++++++++++++++++++++++ services/crates/crates-size.tester.js | 19 +++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 services/crates/crates-size.service.js create mode 100644 services/crates/crates-size.tester.js diff --git a/services/crates/crates-base.js b/services/crates/crates-base.js index 079f519de5..7b7571c55d 100644 --- a/services/crates/crates-base.js +++ b/services/crates/crates-base.js @@ -4,6 +4,8 @@ import { BaseJsonService, InvalidResponse } from '../index.js' const versionSchema = Joi.object({ downloads: nonNegativeInteger, + // Crate size is not available for all versions. + crate_size: nonNegativeInteger.allow(null), num: Joi.string().required(), license: Joi.string().required().allow(null), rust_version: Joi.string().allow(null), diff --git a/services/crates/crates-downloads.tester.js b/services/crates/crates-downloads.tester.js index 8bc169570e..1f2986e722 100644 --- a/services/crates/crates-downloads.tester.js +++ b/services/crates/crates-downloads.tester.js @@ -42,7 +42,12 @@ t.create('recent downloads (null)') max_version: '0.2.71', }, versions: [ - { downloads: 42, license: 'MIT OR Apache-2.0', num: '0.2.71' }, + { + downloads: 42, + license: 'MIT OR Apache-2.0', + num: '0.2.71', + crate_size: 42, + }, ], }), ) diff --git a/services/crates/crates-size.service.js b/services/crates/crates-size.service.js new file mode 100644 index 0000000000..ab819c46ac --- /dev/null +++ b/services/crates/crates-size.service.js @@ -0,0 +1,59 @@ +import prettyBytes from 'pretty-bytes' +import { InvalidResponse, pathParams } from '../index.js' +import { BaseCratesService, description } from './crates-base.js' + +export default class CratesSize extends BaseCratesService { + static category = 'size' + static route = { + base: 'crates/size', + pattern: ':crate/:version?', + } + + static openApi = { + '/crates/size/{crate}': { + get: { + summary: 'Crates.io Size', + description, + parameters: pathParams({ + name: 'crate', + example: 'rustc-serialize', + }), + }, + }, + '/crates/size/{crate}/{version}': { + get: { + summary: 'Crates.io Size (version)', + description, + parameters: pathParams( + { + name: 'crate', + example: 'rustc-serialize', + }, + { + name: 'version', + example: '0.3.24', + }, + ), + }, + }, + } + + render({ size }) { + return { + label: 'size', + message: prettyBytes(size), + color: 'blue', + } + } + + async handle({ crate, version }) { + const json = await this.fetch({ crate, version }) + const size = this.constructor.getVersionObj(json).crate_size + + if (size == null) { + throw new InvalidResponse({ prettyMessage: 'unknown' }) + } + + return this.render({ size }) + } +} diff --git a/services/crates/crates-size.tester.js b/services/crates/crates-size.tester.js new file mode 100644 index 0000000000..6aea268ced --- /dev/null +++ b/services/crates/crates-size.tester.js @@ -0,0 +1,19 @@ +import { createServiceTester } from '../tester.js' +import { isFileSize } from '../test-validators.js' +export const t = await createServiceTester() + +t.create('size') + .get('/tokio.json') + .expectBadge({ label: 'size', message: isFileSize }) + +t.create('size (with version)') + .get('/tokio/1.32.0.json') + .expectBadge({ label: 'size', message: '725 kB' }) + +t.create('size (with version where version doesnt have size)') + .get('/tokio/0.1.6.json') + .expectBadge({ label: 'crates.io', message: 'unknown' }) + +t.create('size (not found)') + .get('/not-a-crate.json') + .expectBadge({ label: 'crates.io', message: 'not found' }) -- GitLab