[Scoop] Add scoop badge service (#5081)
* [Scoop] Add scoop badge service * Rename scoop.service.js into scoop-version.service.js Also rename scoop.tester.js into scoop-version.tester.js * Cache buckets file * Fix test * Improve regex to handle trailing slash * Switch to static fields Co-authored-by: PyvesB <PyvesDev@gmail.com>
This commit is contained in:
93
services/scoop/scoop-version.service.js
Normal file
93
services/scoop/scoop-version.service.js
Normal file
@@ -0,0 +1,93 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('@hapi/joi')
|
||||
const { NotFound } = require('..')
|
||||
const {
|
||||
ConditionalGithubAuthV3Service,
|
||||
} = require('../github/github-auth-service')
|
||||
const { fetchJsonFromRepo } = require('../github/github-common-fetch')
|
||||
const { renderVersionBadge } = require('../version')
|
||||
|
||||
const gitHubRepoRegExp = new RegExp(
|
||||
'https://github.com/(?<user>.*?)/(?<repo>.*?)(/|$)'
|
||||
)
|
||||
const bucketsSchema = Joi.object()
|
||||
.pattern(/.+/, Joi.string().pattern(gitHubRepoRegExp).required())
|
||||
.required()
|
||||
const scoopSchema = Joi.object({
|
||||
version: Joi.string().required(),
|
||||
}).required()
|
||||
const queryParamSchema = Joi.object({
|
||||
bucket: Joi.string(),
|
||||
})
|
||||
|
||||
module.exports = class ScoopVersion extends ConditionalGithubAuthV3Service {
|
||||
// The buckets file (https://github.com/lukesampson/scoop/blob/master/buckets.json) changes very rarely.
|
||||
// Cache it for the lifetime of the current Node.js process.
|
||||
buckets = null
|
||||
|
||||
static category = 'version'
|
||||
|
||||
static route = {
|
||||
base: 'scoop/v',
|
||||
pattern: ':app',
|
||||
queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'Scoop Version',
|
||||
namedParams: { app: 'ngrok' },
|
||||
staticPreview: this.render({ version: '2.3.35' }),
|
||||
},
|
||||
{
|
||||
title: 'Scoop Version (extras bucket)',
|
||||
namedParams: { app: 'dnspy' },
|
||||
queryParams: { bucket: 'extras' },
|
||||
staticPreview: this.render({ version: '6.1.4' }),
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'scoop' }
|
||||
|
||||
static render({ version }) {
|
||||
return renderVersionBadge({ version })
|
||||
}
|
||||
|
||||
async handle({ app }, queryParams) {
|
||||
if (!this.buckets) {
|
||||
this.buckets = await fetchJsonFromRepo(this, {
|
||||
schema: bucketsSchema,
|
||||
user: 'lukesampson',
|
||||
repo: 'scoop',
|
||||
branch: 'master',
|
||||
filename: 'buckets.json',
|
||||
})
|
||||
}
|
||||
const bucket = queryParams.bucket || 'main'
|
||||
const bucketUrl = this.buckets[bucket]
|
||||
if (!bucketUrl) {
|
||||
throw new NotFound({ prettyMessage: `bucket "${bucket}" not found` })
|
||||
}
|
||||
const {
|
||||
groups: { user, repo },
|
||||
} = gitHubRepoRegExp.exec(bucketUrl)
|
||||
try {
|
||||
const { version } = await fetchJsonFromRepo(this, {
|
||||
schema: scoopSchema,
|
||||
user,
|
||||
repo,
|
||||
branch: 'master',
|
||||
filename: `bucket/${app}.json`,
|
||||
})
|
||||
return this.constructor.render({ version })
|
||||
} catch (error) {
|
||||
if (error instanceof NotFound) {
|
||||
throw new NotFound({
|
||||
prettyMessage: `${app} not found in bucket "${bucket}"`,
|
||||
})
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
44
services/scoop/scoop-version.tester.js
Normal file
44
services/scoop/scoop-version.tester.js
Normal file
@@ -0,0 +1,44 @@
|
||||
'use strict'
|
||||
|
||||
const { ServiceTester } = require('../tester')
|
||||
const { isVPlusDottedVersionNClauses } = require('../test-validators')
|
||||
|
||||
const t = (module.exports = new ServiceTester({
|
||||
id: 'scoop',
|
||||
title: 'Scoop',
|
||||
}))
|
||||
|
||||
// version
|
||||
|
||||
t.create('version (valid)').get('/v/apache.json').expectBadge({
|
||||
label: 'scoop',
|
||||
message: isVPlusDottedVersionNClauses,
|
||||
})
|
||||
|
||||
t.create('version (not found)').get('/v/not-a-real-app.json').expectBadge({
|
||||
label: 'scoop',
|
||||
message: 'not-a-real-app not found in bucket "main"',
|
||||
})
|
||||
|
||||
// version (custom bucket)
|
||||
|
||||
t.create('version (valid custom bucket)')
|
||||
.get('/v/dnspy.json?bucket=extras')
|
||||
.expectBadge({
|
||||
label: 'scoop',
|
||||
message: isVPlusDottedVersionNClauses,
|
||||
})
|
||||
|
||||
t.create('version (not found in custom bucket)')
|
||||
.get('/v/not-a-real-app.json?bucket=extras')
|
||||
.expectBadge({
|
||||
label: 'scoop',
|
||||
message: 'not-a-real-app not found in bucket "extras"',
|
||||
})
|
||||
|
||||
t.create('version (wrong bucket)')
|
||||
.get('/v/not-a-real-app.json?bucket=not-a-real-bucket')
|
||||
.expectBadge({
|
||||
label: 'scoop',
|
||||
message: 'bucket "not-a-real-bucket" not found',
|
||||
})
|
||||
Reference in New Issue
Block a user