refactor [docker] service (#2263)
This commit is contained in:
62
services/docker/docker-automated.service.js
Normal file
62
services/docker/docker-automated.service.js
Normal file
@@ -0,0 +1,62 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const BaseJsonService = require('../base-json')
|
||||
const {
|
||||
dockerBlue,
|
||||
buildDockerUrl,
|
||||
getDockerHubUser,
|
||||
} = require('./docker-helpers')
|
||||
|
||||
const automatedBuildSchema = Joi.object({
|
||||
is_automated: Joi.boolean().required(),
|
||||
}).required()
|
||||
|
||||
module.exports = class DockerAutomatedBuild extends BaseJsonService {
|
||||
async fetch({ user, repo }) {
|
||||
return this._requestJson({
|
||||
schema: automatedBuildSchema,
|
||||
url: `https://registry.hub.docker.com/v2/repositories/${getDockerHubUser(
|
||||
user
|
||||
)}/${repo}`,
|
||||
errorMessages: { 404: 'repo not found' },
|
||||
})
|
||||
}
|
||||
|
||||
static render({ isAutomated }) {
|
||||
if (isAutomated) {
|
||||
return { message: 'automated', color: dockerBlue }
|
||||
} else {
|
||||
return { message: 'manual', color: 'yellow' }
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ user, repo }) {
|
||||
const data = await this.fetch({ user, repo })
|
||||
return this.constructor.render({ isAutomated: data.is_automated })
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'build'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return buildDockerUrl('automated')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'docker build' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Docker Automated build',
|
||||
exampleUrl: 'jrottenberg/ffmpeg',
|
||||
urlPattern: ':user/:repo',
|
||||
keywords: ['docker', 'automated', 'build'],
|
||||
staticExample: this.render({ isAutomated: true }),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
84
services/docker/docker-automated.tester.js
Normal file
84
services/docker/docker-automated.tester.js
Normal file
@@ -0,0 +1,84 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const createServiceTester = require('../create-service-tester')
|
||||
const { colorScheme: colorsB } = require('../test-helpers')
|
||||
const { dockerBlue } = require('./docker-helpers')
|
||||
const isAutomatedBuildStatus = Joi.string().valid('automated', 'manual')
|
||||
|
||||
const t = createServiceTester()
|
||||
module.exports = t
|
||||
|
||||
t.create('docker automated build (valid, library)')
|
||||
.get('/_/ubuntu.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isAutomatedBuildStatus,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker automated build (valid, user)')
|
||||
.get('/jrottenberg/ffmpeg.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isAutomatedBuildStatus,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker automated build (not found)')
|
||||
.get('/_/not-a-real-repo.json')
|
||||
.expectJSON({ name: 'docker build', value: 'repo not found' })
|
||||
|
||||
t.create('docker automated build - automated')
|
||||
.get('/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(200, { is_automated: true })
|
||||
)
|
||||
.expectJSON({
|
||||
name: 'docker build',
|
||||
value: 'automated',
|
||||
colorB: `#${dockerBlue}`,
|
||||
})
|
||||
|
||||
t.create('docker automated build - manual')
|
||||
.get('/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(200, { is_automated: false })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'manual', colorB: colorsB.yellow })
|
||||
|
||||
t.create('docker automated build - colorB override in manual')
|
||||
.get('/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(200, { is_automated: false })
|
||||
)
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isAutomatedBuildStatus,
|
||||
colorB: '#fedcba',
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker automated build - colorB override in automated')
|
||||
.get('/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(200, { is_automated: true })
|
||||
)
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isAutomatedBuildStatus,
|
||||
colorB: '#fedcba',
|
||||
})
|
||||
)
|
||||
66
services/docker/docker-build.service.js
Normal file
66
services/docker/docker-build.service.js
Normal file
@@ -0,0 +1,66 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const BaseJsonService = require('../base-json')
|
||||
const { anyInteger } = require('../validators')
|
||||
const {
|
||||
dockerBlue,
|
||||
buildDockerUrl,
|
||||
getDockerHubUser,
|
||||
} = require('./docker-helpers')
|
||||
|
||||
const buildSchema = Joi.object({
|
||||
results: Joi.array()
|
||||
.items(Joi.object({ status: anyInteger }).required())
|
||||
.required(),
|
||||
}).required()
|
||||
|
||||
module.exports = class DockerBuild extends BaseJsonService {
|
||||
async fetch({ user, repo }) {
|
||||
return this._requestJson({
|
||||
schema: buildSchema,
|
||||
url: `https://registry.hub.docker.com/v2/repositories/${getDockerHubUser(
|
||||
user
|
||||
)}/${repo}/buildhistory`,
|
||||
errorMessages: { 404: 'repo not found' },
|
||||
})
|
||||
}
|
||||
|
||||
static render({ status }) {
|
||||
if (status === 10) {
|
||||
return { message: 'passing', color: 'brightgreen' }
|
||||
} else if (status < 0) {
|
||||
return { message: 'failing', color: 'red' }
|
||||
}
|
||||
return { message: 'building', color: dockerBlue }
|
||||
}
|
||||
|
||||
async handle({ user, repo }) {
|
||||
const data = await this.fetch({ user, repo })
|
||||
return this.constructor.render({ status: data.results[0].status })
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'build'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return buildDockerUrl('build')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'docker build' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Docker Build Status',
|
||||
exampleUrl: 'jrottenberg/ffmpeg',
|
||||
urlPattern: ':user/:repo',
|
||||
keywords: ['docker', 'build', 'status'],
|
||||
staticExample: this.render({ status: 10 }),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
85
services/docker/docker-build.tester.js
Normal file
85
services/docker/docker-build.tester.js
Normal file
@@ -0,0 +1,85 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const createServiceTester = require('../create-service-tester')
|
||||
const { colorScheme: colorsB } = require('../test-helpers')
|
||||
const { dockerBlue } = require('./docker-helpers')
|
||||
const { isBuildStatus } = require('../test-validators')
|
||||
|
||||
const t = createServiceTester()
|
||||
module.exports = t
|
||||
|
||||
t.create('docker build status (valid, user)')
|
||||
.get('/jrottenberg/ffmpeg.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isBuildStatus,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker build status (not found)')
|
||||
.get('/_/not-a-real-repo.json')
|
||||
.expectJSON({ name: 'docker build', value: 'repo not found' })
|
||||
|
||||
t.create('docker build status (passing)')
|
||||
.get('/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: 10 }] })
|
||||
)
|
||||
.expectJSON({
|
||||
name: 'docker build',
|
||||
value: 'passing',
|
||||
colorB: colorsB.brightgreen,
|
||||
})
|
||||
|
||||
t.create('docker build status (failing)')
|
||||
.get('/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: -1 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'failing', colorB: colorsB.red })
|
||||
|
||||
t.create('docker build status (building)')
|
||||
.get('/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: 1 }] })
|
||||
)
|
||||
.expectJSON({
|
||||
name: 'docker build',
|
||||
value: 'building',
|
||||
colorB: `#${dockerBlue}`,
|
||||
})
|
||||
|
||||
t.create('docker build status (override colorB for passing)')
|
||||
.get('/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: 10 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'passing', colorB: '#fedcba' })
|
||||
|
||||
t.create('docker build status (override colorB for failing)')
|
||||
.get('/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: -1 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'failing', colorB: '#fedcba' })
|
||||
|
||||
t.create('docker build status (override colorB for building)')
|
||||
.get('/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: 1 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'building', colorB: '#fedcba' })
|
||||
16
services/docker/docker-helpers.js
Normal file
16
services/docker/docker-helpers.js
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict'
|
||||
|
||||
const dockerBlue = '066da5' // see https://github.com/badges/shields/pull/1690
|
||||
|
||||
const buildDockerUrl = function(badgeName) {
|
||||
return {
|
||||
base: `docker/${badgeName}`,
|
||||
pattern: ':user/:repo',
|
||||
}
|
||||
}
|
||||
|
||||
const getDockerHubUser = function(user) {
|
||||
return user === '_' ? 'library' : user
|
||||
}
|
||||
|
||||
module.exports = { dockerBlue, buildDockerUrl, getDockerHubUser }
|
||||
63
services/docker/docker-pulls.service.js
Normal file
63
services/docker/docker-pulls.service.js
Normal file
@@ -0,0 +1,63 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const BaseJsonService = require('../base-json')
|
||||
const { metric } = require('../../lib/text-formatters')
|
||||
const { nonNegativeInteger } = require('../validators')
|
||||
const {
|
||||
dockerBlue,
|
||||
buildDockerUrl,
|
||||
getDockerHubUser,
|
||||
} = require('./docker-helpers')
|
||||
|
||||
const pullsSchema = Joi.object({
|
||||
pull_count: nonNegativeInteger,
|
||||
}).required()
|
||||
|
||||
module.exports = class DockerPulls extends BaseJsonService {
|
||||
async fetch({ user, repo }) {
|
||||
return this._requestJson({
|
||||
schema: pullsSchema,
|
||||
url: `https://hub.docker.com/v2/repositories/${getDockerHubUser(
|
||||
user
|
||||
)}/${repo}`,
|
||||
errorMessages: { 404: 'repo not found' },
|
||||
})
|
||||
}
|
||||
|
||||
static render({ count }) {
|
||||
return {
|
||||
message: metric(count),
|
||||
color: dockerBlue,
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ user, repo }) {
|
||||
const data = await this.fetch({ user, repo })
|
||||
return this.constructor.render({ count: data.pull_count })
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'docker pulls' }
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'downloads'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return buildDockerUrl('pulls')
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Docker Pulls',
|
||||
exampleUrl: '_/ubuntu',
|
||||
keywords: ['docker', 'pulls'],
|
||||
urlPattern: ':user/:repo',
|
||||
staticExample: this.render({ count: 765400000 }),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
42
services/docker/docker-pulls.tester.js
Normal file
42
services/docker/docker-pulls.tester.js
Normal file
@@ -0,0 +1,42 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const createServiceTester = require('../create-service-tester')
|
||||
const { dockerBlue } = require('./docker-helpers')
|
||||
const { isMetric } = require('../test-validators')
|
||||
|
||||
const t = createServiceTester()
|
||||
module.exports = t
|
||||
|
||||
t.create('docker pulls (valid, library)')
|
||||
.get('/_/ubuntu.json?style=_shields_test')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker pulls',
|
||||
value: isMetric,
|
||||
colorB: `#${dockerBlue}`,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker pulls (override colorB)')
|
||||
.get('/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker pulls',
|
||||
value: isMetric,
|
||||
colorB: '#fedcba',
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker pulls (valid, user)')
|
||||
.get('/jrottenberg/ffmpeg.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker pulls',
|
||||
value: isMetric,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker pulls (not found)')
|
||||
.get('/_/not-a-real-repo.json')
|
||||
.expectJSON({ name: 'docker pulls', value: 'repo not found' })
|
||||
59
services/docker/docker-stars.service.js
Normal file
59
services/docker/docker-stars.service.js
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict'
|
||||
|
||||
const BaseService = require('../base')
|
||||
const { metric } = require('../../lib/text-formatters')
|
||||
const {
|
||||
dockerBlue,
|
||||
buildDockerUrl,
|
||||
getDockerHubUser,
|
||||
} = require('./docker-helpers')
|
||||
const { nonNegativeInteger } = require('../validators')
|
||||
|
||||
module.exports = class DockerStars extends BaseService {
|
||||
async fetch({ user, repo }) {
|
||||
const url = `https://hub.docker.com/v2/repositories/${getDockerHubUser(
|
||||
user
|
||||
)}/${repo}/stars/count/`
|
||||
const { buffer } = await this._request({
|
||||
url,
|
||||
errorMessages: { 404: 'repo not found' },
|
||||
})
|
||||
return this.constructor._validate(buffer, nonNegativeInteger)
|
||||
}
|
||||
|
||||
static render({ stars }) {
|
||||
return {
|
||||
message: metric(stars),
|
||||
color: dockerBlue,
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ user, repo }) {
|
||||
const stars = await this.fetch({ user, repo })
|
||||
return this.constructor.render({ stars })
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'docker stars' }
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'rating'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return buildDockerUrl('stars')
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Docker Stars',
|
||||
exampleUrl: '_/ubuntu',
|
||||
urlPattern: ':user/:repo',
|
||||
keywords: ['docker', 'stars'],
|
||||
staticExample: this.render({ stars: 9000 }),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
42
services/docker/docker-stars.tester.js
Normal file
42
services/docker/docker-stars.tester.js
Normal file
@@ -0,0 +1,42 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const createServiceTester = require('../create-service-tester')
|
||||
const { dockerBlue } = require('./docker-helpers')
|
||||
const { isMetric } = require('../test-validators')
|
||||
|
||||
const t = createServiceTester()
|
||||
module.exports = t
|
||||
|
||||
t.create('docker stars (valid, library)')
|
||||
.get('/_/ubuntu.json?style=_shields_test')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker stars',
|
||||
value: isMetric,
|
||||
colorB: `#${dockerBlue}`,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker stars (override colorB)')
|
||||
.get('/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker stars',
|
||||
value: isMetric,
|
||||
colorB: '#fedcba',
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker stars (valid, user)')
|
||||
.get('/jrottenberg/ffmpeg.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker stars',
|
||||
value: isMetric,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker stars (not found)')
|
||||
.get('/_/not-a-real-repo.json')
|
||||
.expectJSON({ name: 'docker stars', value: 'repo not found' })
|
||||
@@ -1,236 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const LegacyService = require('../legacy-service')
|
||||
const {
|
||||
makeBadgeData: getBadgeData,
|
||||
setBadgeColor,
|
||||
} = require('../../lib/badge-data')
|
||||
const { checkErrorResponse } = require('../../lib/error-helper')
|
||||
const { metric } = require('../../lib/text-formatters')
|
||||
|
||||
class DockerStars extends LegacyService {
|
||||
static get category() {
|
||||
return 'rating'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'docker/stars',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Docker Stars',
|
||||
previewUrl: '_/ubuntu',
|
||||
keywords: ['docker', 'stars'],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static registerLegacyRouteHandler({ camp, cache }) {
|
||||
camp.route(
|
||||
/^\/docker\/stars\/([^/]+)\/([^/]+)\.(svg|png|gif|jpg|json)$/,
|
||||
cache((data, match, sendBadge, request) => {
|
||||
let user = match[1] // eg, mashape
|
||||
const repo = match[2] // eg, kong
|
||||
const format = match[3]
|
||||
if (user === '_') {
|
||||
user = 'library'
|
||||
}
|
||||
const path = `${user}/${repo}`
|
||||
const url = `https://hub.docker.com/v2/repositories/${path}/stars/count/`
|
||||
const badgeData = getBadgeData('docker stars', data)
|
||||
request(url, (err, res, buffer) => {
|
||||
if (
|
||||
checkErrorResponse(badgeData, err, res, { 404: 'repo not found' })
|
||||
) {
|
||||
sendBadge(format, badgeData)
|
||||
return
|
||||
}
|
||||
try {
|
||||
const stars = parseInt(buffer, 10)
|
||||
if (Number.isNaN(stars)) {
|
||||
throw Error('Unexpected response.')
|
||||
}
|
||||
badgeData.text[1] = metric(stars)
|
||||
setBadgeColor(badgeData, data.colorB || '066da5')
|
||||
sendBadge(format, badgeData)
|
||||
} catch (e) {
|
||||
badgeData.text[1] = 'invalid'
|
||||
sendBadge(format, badgeData)
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class DockerPulls extends LegacyService {
|
||||
static get category() {
|
||||
return 'downloads'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'docker/pulls',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Docker Pulls',
|
||||
previewUrl: 'mashape/kong',
|
||||
keywords: ['docker', 'pulls'],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static registerLegacyRouteHandler({ camp, cache }) {
|
||||
camp.route(
|
||||
/^\/docker\/pulls\/([^/]+)\/([^/]+)\.(svg|png|gif|jpg|json)$/,
|
||||
cache((data, match, sendBadge, request) => {
|
||||
let user = match[1] // eg, mashape
|
||||
const repo = match[2] // eg, kong
|
||||
const format = match[3]
|
||||
if (user === '_') {
|
||||
user = 'library'
|
||||
}
|
||||
const path = `${user}/${repo}`
|
||||
const url = `https://hub.docker.com/v2/repositories/${path}`
|
||||
const badgeData = getBadgeData('docker pulls', data)
|
||||
request(url, (err, res, buffer) => {
|
||||
if (
|
||||
checkErrorResponse(badgeData, err, res, { 404: 'repo not found' })
|
||||
) {
|
||||
sendBadge(format, badgeData)
|
||||
return
|
||||
}
|
||||
try {
|
||||
const parseData = JSON.parse(buffer)
|
||||
const pulls = parseData.pull_count
|
||||
badgeData.text[1] = metric(pulls)
|
||||
setBadgeColor(badgeData, data.colorB || '066da5')
|
||||
sendBadge(format, badgeData)
|
||||
} catch (e) {
|
||||
badgeData.text[1] = 'invalid'
|
||||
sendBadge(format, badgeData)
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class DockerBuild extends LegacyService {
|
||||
static get category() {
|
||||
return 'build'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'docker',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Docker Automated build',
|
||||
previewUrl: 'automated/jrottenberg/ffmpeg',
|
||||
keywords: ['docker', 'automated', 'build'],
|
||||
},
|
||||
{
|
||||
title: 'Docker Build Status',
|
||||
previewUrl: 'build/jrottenberg/ffmpeg',
|
||||
keywords: ['docker', 'build', 'status'],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static registerLegacyRouteHandler({ camp, cache }) {
|
||||
camp.route(
|
||||
/^\/docker\/build\/([^/]+)\/([^/]+)\.(svg|png|gif|jpg|json)$/,
|
||||
cache((data, match, sendBadge, request) => {
|
||||
let user = match[1] // eg, jrottenberg
|
||||
const repo = match[2] // eg, ffmpeg
|
||||
const format = match[3]
|
||||
if (user === '_') {
|
||||
user = 'library'
|
||||
}
|
||||
const path = `${user}/${repo}`
|
||||
const url = `https://registry.hub.docker.com/v2/repositories/${path}/buildhistory`
|
||||
const badgeData = getBadgeData('docker build', data)
|
||||
request(url, (err, res, buffer) => {
|
||||
if (
|
||||
checkErrorResponse(badgeData, err, res, { 404: 'repo not found' })
|
||||
) {
|
||||
sendBadge(format, badgeData)
|
||||
return
|
||||
}
|
||||
try {
|
||||
const parsedData = JSON.parse(buffer)
|
||||
const mostRecentStatus = parsedData.results[0].status
|
||||
if (mostRecentStatus === 10) {
|
||||
badgeData.text[1] = 'passing'
|
||||
badgeData.colorscheme = 'brightgreen'
|
||||
} else if (mostRecentStatus < 0) {
|
||||
badgeData.text[1] = 'failing'
|
||||
badgeData.colorscheme = 'red'
|
||||
} else {
|
||||
badgeData.text[1] = 'building'
|
||||
setBadgeColor(badgeData, data.colorB || '066da5')
|
||||
}
|
||||
sendBadge(format, badgeData)
|
||||
} catch (e) {
|
||||
badgeData.text[1] = 'invalid'
|
||||
sendBadge(format, badgeData)
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
// Docker Hub automated integration.
|
||||
camp.route(
|
||||
/^\/docker\/automated\/([^/]+)\/([^/]+)\.(svg|png|gif|jpg|json)$/,
|
||||
cache((data, match, sendBadge, request) => {
|
||||
let user = match[1] // eg, jrottenberg
|
||||
const repo = match[2] // eg, ffmpeg
|
||||
const format = match[3]
|
||||
if (user === '_') {
|
||||
user = 'library'
|
||||
}
|
||||
const path = `${user}/${repo}`
|
||||
const url = `https://registry.hub.docker.com/v2/repositories/${path}`
|
||||
const badgeData = getBadgeData('docker build', data)
|
||||
request(url, (err, res, buffer) => {
|
||||
if (
|
||||
checkErrorResponse(badgeData, err, res, { 404: 'repo not found' })
|
||||
) {
|
||||
sendBadge(format, badgeData)
|
||||
return
|
||||
}
|
||||
try {
|
||||
const parsedData = JSON.parse(buffer)
|
||||
const isAutomated = parsedData.is_automated
|
||||
if (isAutomated) {
|
||||
badgeData.text[1] = 'automated'
|
||||
setBadgeColor(badgeData, data.colorB || '066da5')
|
||||
} else {
|
||||
badgeData.text[1] = 'manual'
|
||||
badgeData.colorscheme = 'yellow'
|
||||
}
|
||||
sendBadge(format, badgeData)
|
||||
} catch (e) {
|
||||
badgeData.text[1] = 'invalid'
|
||||
sendBadge(format, badgeData)
|
||||
}
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = [DockerStars, DockerPulls, DockerBuild]
|
||||
@@ -1,295 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const ServiceTester = require('../service-tester')
|
||||
const { colorScheme: colorsB } = require('../test-helpers')
|
||||
const { isMetric } = require('../test-validators')
|
||||
const { invalidJSON } = require('../response-fixtures')
|
||||
const { isBuildStatus } = require('../test-validators')
|
||||
const isAutomatedBuildStatus = Joi.string().valid('automated', 'manual')
|
||||
|
||||
const t = new ServiceTester({ id: 'docker', title: 'Docker Hub' })
|
||||
module.exports = t
|
||||
|
||||
// stars endpoint
|
||||
|
||||
t.create('docker stars (valid, library)')
|
||||
.get('/stars/_/ubuntu.json?style=_shields_test')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker stars',
|
||||
value: isMetric,
|
||||
colorB: Joi.any()
|
||||
.equal('#066da5')
|
||||
.required(),
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker stars (override colorB)')
|
||||
.get('/stars/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker stars',
|
||||
value: isMetric,
|
||||
colorB: Joi.any()
|
||||
.equal('#fedcba')
|
||||
.required(),
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker stars (valid, user)')
|
||||
.get('/stars/jrottenberg/ffmpeg.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker stars',
|
||||
value: isMetric,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker stars (not found)')
|
||||
.get('/stars/_/not-a-real-repo.json')
|
||||
.expectJSON({ name: 'docker stars', value: 'repo not found' })
|
||||
|
||||
t.create('docker stars (connection error)')
|
||||
.get('/stars/_/ubuntu.json')
|
||||
.networkOff()
|
||||
.expectJSON({ name: 'docker stars', value: 'inaccessible' })
|
||||
|
||||
t.create('docker stars (unexpected response)')
|
||||
.get('/stars/_/ubuntu.json')
|
||||
.intercept(nock =>
|
||||
nock('https://hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/stars/count/')
|
||||
.reply(invalidJSON)
|
||||
)
|
||||
.expectJSON({ name: 'docker stars', value: 'invalid' })
|
||||
|
||||
// pulls endpoint
|
||||
|
||||
t.create('docker pulls (valid, library)')
|
||||
.get('/pulls/_/ubuntu.json?style=_shields_test')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker pulls',
|
||||
value: isMetric,
|
||||
colorB: Joi.any()
|
||||
.equal('#066da5')
|
||||
.required(),
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker pulls (override colorB)')
|
||||
.get('/pulls/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker pulls',
|
||||
value: isMetric,
|
||||
colorB: Joi.any()
|
||||
.equal('#fedcba')
|
||||
.required(),
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker pulls (valid, user)')
|
||||
.get('/pulls/jrottenberg/ffmpeg.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker pulls',
|
||||
value: isMetric,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker pulls (not found)')
|
||||
.get('/pulls/_/not-a-real-repo.json')
|
||||
.expectJSON({ name: 'docker pulls', value: 'repo not found' })
|
||||
|
||||
t.create('docker pulls (connection error)')
|
||||
.get('/pulls/_/ubuntu.json')
|
||||
.networkOff()
|
||||
.expectJSON({ name: 'docker pulls', value: 'inaccessible' })
|
||||
|
||||
t.create('docker pulls (unexpected response)')
|
||||
.get('/pulls/_/ubuntu.json')
|
||||
.intercept(nock =>
|
||||
nock('https://hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(invalidJSON)
|
||||
)
|
||||
.expectJSON({ name: 'docker pulls', value: 'invalid' })
|
||||
|
||||
// automated build endpoint
|
||||
|
||||
t.create('docker automated build (valid, library)')
|
||||
.get('/automated/_/ubuntu.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isAutomatedBuildStatus,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker automated build (valid, user)')
|
||||
.get('/automated/jrottenberg/ffmpeg.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isAutomatedBuildStatus,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker automated build (not found)')
|
||||
.get('/automated/_/not-a-real-repo.json')
|
||||
.expectJSON({ name: 'docker build', value: 'repo not found' })
|
||||
|
||||
t.create('docker automated build (connection error)')
|
||||
.get('/automated/_/ubuntu.json')
|
||||
.networkOff()
|
||||
.expectJSON({ name: 'docker build', value: 'inaccessible' })
|
||||
|
||||
t.create('docker automated build (unexpected response)')
|
||||
.get('/automated/_/ubuntu.json')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(invalidJSON)
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'invalid' })
|
||||
|
||||
t.create('docker automated build - automated')
|
||||
.get('/automated/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(200, { is_automated: true })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'automated', colorB: '#066da5' })
|
||||
|
||||
t.create('docker automated build - manual')
|
||||
.get('/automated/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(200, { is_automated: false })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'manual', colorB: colorsB.yellow })
|
||||
|
||||
t.create('docker automated build - colorB override in manual')
|
||||
.get('/automated/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(200, { is_automated: false })
|
||||
)
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isAutomatedBuildStatus,
|
||||
colorB: Joi.any()
|
||||
.equal('#fedcba')
|
||||
.required(),
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker automated build - colorB override in automated')
|
||||
.get('/automated/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu')
|
||||
.reply(200, { is_automated: true })
|
||||
)
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isAutomatedBuildStatus,
|
||||
colorB: Joi.any()
|
||||
.equal('#fedcba')
|
||||
.required(),
|
||||
})
|
||||
)
|
||||
|
||||
// build status endpoint
|
||||
|
||||
t.create('docker build status (valid, user)')
|
||||
.get('/build/jrottenberg/ffmpeg.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'docker build',
|
||||
value: isBuildStatus,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('docker build status (not found)')
|
||||
.get('/build/_/not-a-real-repo.json')
|
||||
.expectJSON({ name: 'docker build', value: 'repo not found' })
|
||||
|
||||
t.create('docker build status (connection error)')
|
||||
.get('/build/_/ubuntu.json')
|
||||
.networkOff()
|
||||
.expectJSON({ name: 'docker build', value: 'inaccessible' })
|
||||
|
||||
t.create('docker build status (unexpected response)')
|
||||
.get('/build/_/ubuntu.json')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(invalidJSON)
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'invalid' })
|
||||
|
||||
t.create('docker build status (passing)')
|
||||
.get('/build/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: 10 }] })
|
||||
)
|
||||
.expectJSON({
|
||||
name: 'docker build',
|
||||
value: 'passing',
|
||||
colorB: colorsB.brightgreen,
|
||||
})
|
||||
|
||||
t.create('docker build status (failing)')
|
||||
.get('/build/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: -1 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'failing', colorB: colorsB.red })
|
||||
|
||||
t.create('docker build status (building)')
|
||||
.get('/build/_/ubuntu.json?style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: 1 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'building', colorB: '#066da5' })
|
||||
|
||||
t.create('docker build status (override colorB for passing)')
|
||||
.get('/build/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: 10 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'passing', colorB: '#fedcba' })
|
||||
|
||||
t.create('docker build status (override colorB for failing)')
|
||||
.get('/build/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: -1 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'failing', colorB: '#fedcba' })
|
||||
|
||||
t.create('docker build status (override colorB for building)')
|
||||
.get('/build/_/ubuntu.json?colorB=fedcba&style=_shields_test')
|
||||
.intercept(nock =>
|
||||
nock('https://registry.hub.docker.com/')
|
||||
.get('/v2/repositories/library/ubuntu/buildhistory')
|
||||
.reply(200, { results: [{ status: 1 }] })
|
||||
)
|
||||
.expectJSON({ name: 'docker build', value: 'building', colorB: '#fedcba' })
|
||||
Reference in New Issue
Block a user