Files
shields/services/codeclimate/codeclimate.service.js
Paul Melnikow 83ac6ff1b3 Enforce use of template literals (#2242)
This is consistent with what we're pretty much already doing, and saves us from making the request during code review.

These were all autofixed and most of them seem easier to read. Some in the legacy services should be rewritten in more legible forms during refactor (ie using intermediate variables, or using request’s qs option). There are some in helper functions and elsewhere that should get rewritten separately. I don't want to change them in this PR because the changes will get lost in this diff, though we could identify them here and fix them before or just after.
2018-11-02 17:11:44 -04:00

205 lines
7.2 KiB
JavaScript

'use strict'
const LegacyService = require('../legacy-service')
const { makeBadgeData: getBadgeData } = require('../../lib/badge-data')
const {
coveragePercentage: coveragePercentageColor,
letterScore: letterScoreColor,
colorScale,
} = require('../../lib/color-formatters')
module.exports = class Codeclimate extends LegacyService {
static registerLegacyRouteHandler({ camp, cache }) {
camp.route(
/^\/codeclimate(\/(c|coverage|maintainability|issues|tech-debt)(-letter|-percentage)?)?\/(.+)\.(svg|png|gif|jpg|json)$/,
cache((data, match, sendBadge, request) => {
let type
if (match[2] === 'c' || !match[2]) {
// Top-level and /coverage URLs equivalent to /c, still supported for backwards compatibility. See #1387.
type = 'coverage'
} else if (match[2] === 'tech-debt') {
type = 'technical debt'
} else {
type = match[2]
}
// For maintainability, default is letter, alternative is percentage. For coverage, default is percentage, alternative is letter.
const isAlternativeFormat = match[3]
const userRepo = match[4] // eg, `twbs/bootstrap`.
const format = match[5]
request(
{
method: 'GET',
uri: `https://api.codeclimate.com/v1/repos?github_slug=${userRepo}`,
json: true,
},
(err, res, body) => {
const badgeData = getBadgeData(type, data)
if (err != null) {
badgeData.text[1] = 'invalid'
sendBadge(format, badgeData)
return
}
try {
if (!body.data || body.data.length === 0) {
badgeData.text[1] = 'not found'
sendBadge(format, badgeData)
return
}
const branchData =
type === 'coverage'
? body.data[0].relationships.latest_default_branch_test_report
.data
: body.data[0].relationships.latest_default_branch_snapshot
.data
if (branchData == null) {
badgeData.text[1] = 'unknown'
sendBadge(format, badgeData)
return
}
const url = `https://api.codeclimate.com/v1/repos/${
body.data[0].id
}/${type === 'coverage' ? 'test_reports' : 'snapshots'}/${
branchData.id
}`
request(url, (err, res, buffer) => {
if (err != null) {
badgeData.text[1] = 'invalid'
sendBadge(format, badgeData)
return
}
try {
const parsedData = JSON.parse(buffer)
if (type === 'coverage' && isAlternativeFormat) {
const score = parsedData.data.attributes.rating.letter
badgeData.text[1] = score
badgeData.colorscheme = letterScoreColor(score)
} else if (type === 'coverage') {
const percentage = parseFloat(
parsedData.data.attributes.covered_percent
)
badgeData.text[1] = `${percentage.toFixed(0)}%`
badgeData.colorscheme = coveragePercentageColor(percentage)
} else if (type === 'issues') {
const count = parsedData.data.meta.issues_count
badgeData.text[1] = count
badgeData.colorscheme = colorScale(
[1, 5, 10, 20],
['brightgreen', 'green', 'yellowgreen', 'yellow', 'red']
)(count)
} else if (type === 'technical debt') {
const percentage = parseFloat(
parsedData.data.attributes.ratings[0].measure.value
)
badgeData.text[1] = `${percentage.toFixed(0)}%`
badgeData.colorscheme = colorScale(
[5, 10, 20, 50],
['brightgreen', 'green', 'yellowgreen', 'yellow', 'red']
)(percentage)
} else if (
type === 'maintainability' &&
isAlternativeFormat
) {
// maintainability = 100 - technical debt
const percentage =
100 -
parseFloat(
parsedData.data.attributes.ratings[0].measure.value
)
badgeData.text[1] = `${percentage.toFixed(0)}%`
badgeData.colorscheme = colorScale(
[50, 80, 90, 95],
['red', 'yellow', 'yellowgreen', 'green', 'brightgreen']
)(percentage)
} else if (type === 'maintainability') {
const score = parsedData.data.attributes.ratings[0].letter
badgeData.text[1] = score
badgeData.colorscheme = letterScoreColor(score)
}
sendBadge(format, badgeData)
} catch (e) {
badgeData.text[1] = 'invalid'
sendBadge(format, badgeData)
}
})
} catch (e) {
badgeData.text[1] = 'invalid'
sendBadge(format, badgeData)
}
}
)
})
)
}
static get url() {
return {
base: 'codeclimate',
}
}
static get category() {
return 'build'
}
static get examples() {
return [
{
title: 'Code Climate issues',
exampleUrl: 'issues/twbs/bootstrap',
urlPattern: 'issues/:userRepo',
staticExample: { label: 'issues', message: '89', color: 'red' },
},
{
title: 'Code Climate maintainability',
exampleUrl: 'maintainability/angular/angular.js',
urlPattern: 'maintainability/:userRepo',
staticExample: { label: 'maintainability', message: 'F', color: 'red' },
},
{
title: 'Code Climate maintainability (percentage)',
exampleUrl: 'maintainability-percentage/angular/angular.js',
urlPattern: 'maintainability-percentage/:userRepo',
staticExample: {
label: 'maintainability',
message: '4.6%',
color: 'red',
},
},
{
title: 'Code Climate coverage',
exampleUrl: 'coverage/jekyll/jekyll',
urlPattern: 'coverage/:userRepo',
staticExample: {
label: 'coverage',
message: '95%',
color: 'green',
},
},
{
title: 'Code Climate coverage (letter)',
exampleUrl: 'coverage-letter/jekyll/jekyll',
urlPattern: 'coverage-letter/:userRepo',
staticExample: {
label: 'coverage',
message: 'A',
color: 'brightgreen',
},
},
{
title: 'Code Climate technical debt',
exampleUrl: 'tech-debt/jekyll/jekyll',
urlPattern: 'tech-debt/:userRepo',
staticExample: {
label: 'technical debt',
message: '3%',
color: 'brightgreen',
},
},
]
}
}