From 95a54e8d357a4937d81d26492d70e75ec9992995 Mon Sep 17 00:00:00 2001 From: Matan Kushner Date: Tue, 14 Jan 2020 23:33:09 -0500 Subject: [PATCH] Add [Repology] repositories badge (#4529) * Add [Repology] repositories badge Partly addresses #929 * Replace JSON API with SVG scrape * Fix failing tests * Replace Joi.number with nonNegativeInteger * Replace integer with string in failing test * Update title to specify that the badge is for num of repositories * Remove repology-repositories.spec.js * Remove keywords * Use the metric text formatter * Remove mocked svg test * Remove the "in" preposition --- .../repology/repology-repositories.service.js | 55 +++++++++++++++++++ .../repology/repology-repositories.tester.js | 18 ++++++ 2 files changed, 73 insertions(+) create mode 100644 services/repology/repology-repositories.service.js create mode 100644 services/repology/repology-repositories.tester.js diff --git a/services/repology/repology-repositories.service.js b/services/repology/repology-repositories.service.js new file mode 100644 index 0000000000..5a1ceb6633 --- /dev/null +++ b/services/repology/repology-repositories.service.js @@ -0,0 +1,55 @@ +'use strict' + +const Joi = require('@hapi/joi') +const { metric } = require('../text-formatters') +const { nonNegativeInteger } = require('../validators') +const { BaseSvgScrapingService } = require('..') + +const schema = Joi.object({ + message: nonNegativeInteger, +}).required() + +module.exports = class RepologyRepositories extends BaseSvgScrapingService { + static get category() { + return 'platform-support' + } + + static get route() { + return { + base: 'repology/repositories', + pattern: ':projectName', + } + } + + static get examples() { + return [ + { + title: 'Repology - Repositories', + namedParams: { projectName: 'starship' }, + staticPreview: this.render({ repositoryCount: '18' }), + }, + ] + } + + static get defaultBadgeData() { + return { + label: 'repositories', + color: 'blue', + } + } + + static render({ repositoryCount }) { + return { + message: metric(repositoryCount), + } + } + + async handle({ projectName }) { + const { message: repositoryCount } = await this._requestSvg({ + schema, + url: `https://repology.org/badge/tiny-repos/${projectName}.svg`, + }) + + return this.constructor.render({ repositoryCount }) + } +} diff --git a/services/repology/repology-repositories.tester.js b/services/repology/repology-repositories.tester.js new file mode 100644 index 0000000000..69a0a09ed3 --- /dev/null +++ b/services/repology/repology-repositories.tester.js @@ -0,0 +1,18 @@ +'use strict' + +const t = (module.exports = require('../tester').createServiceTester()) +const { nonNegativeInteger } = require('../validators') + +t.create('Existing project') + .get('/starship.json') + .expectBadge({ + label: 'repositories', + message: nonNegativeInteger, + }) + +t.create('Non-existent project') + .get('/invalidprojectthatshouldnotexist.json') + .expectBadge({ + label: 'repositories', + message: '0', + })