[Tokei] Implement a lines of code (LOC) badge (#5547)
* Implement LOC badge * Apply suggestions from code review Co-authored-by: Caleb Cartwright <calebcartwright@users.noreply.github.com> * Fix tokei tests after API change * Format the code * Rename tokei service file * Add comment about Tokei API behavior * Document tokei badge behavior Co-authored-by: Caleb Cartwright <calebcartwright@users.noreply.github.com>
This commit is contained in:
82
services/tokei/tokei.service.js
Normal file
82
services/tokei/tokei.service.js
Normal file
@@ -0,0 +1,82 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('@hapi/joi')
|
||||
const { metric } = require('../text-formatters')
|
||||
const { nonNegativeInteger } = require('../validators')
|
||||
const { BaseJsonService } = require('..')
|
||||
|
||||
const schema = Joi.object({
|
||||
lines: nonNegativeInteger,
|
||||
}).required()
|
||||
|
||||
const documentation = `
|
||||
<p>
|
||||
The <code>provider</code> is the domain name of git host.
|
||||
If no TLD is provided, <code>.com</code> will be added.
|
||||
For example, setting <code>gitlab</code> or <code>bitbucket.org</code> as the
|
||||
provider also works.
|
||||
<br><br>
|
||||
Tokei will automatically count all files with a recognized extension. It will
|
||||
automatically ignore files and folders in <code>.ignore</code> files. If you
|
||||
want to ignore files or folders specifically for tokei, add them to the
|
||||
<code>.tokeignore</code> in the root of your repository.
|
||||
See
|
||||
<a href="https://github.com/XAMPPRocky/tokei#excluding-folders">https://github.com/XAMPPRocky/tokei#excluding-folders</a>
|
||||
for more info.
|
||||
</p>
|
||||
`
|
||||
|
||||
module.exports = class Tokei extends BaseJsonService {
|
||||
static category = 'size'
|
||||
|
||||
static route = { base: 'tokei/lines', pattern: ':provider/:user/:repo' }
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Lines of code',
|
||||
namedParams: {
|
||||
provider: 'github',
|
||||
user: 'badges',
|
||||
repo: 'shields',
|
||||
},
|
||||
staticPreview: this.render({ lines: 119500 }),
|
||||
keywords: ['loc', 'tokei'],
|
||||
documentation,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static defaultBadgeData = {
|
||||
label: 'total lines',
|
||||
color: 'blue',
|
||||
}
|
||||
|
||||
static render({ lines }) {
|
||||
return { message: metric(lines) }
|
||||
}
|
||||
|
||||
async fetch({ provider, user, repo }) {
|
||||
// This request uses the tokei-rs (https://github.com/XAMPPRocky/tokei_rs) API.
|
||||
//
|
||||
// By default, the API returns an svg, but when the Accept HTTP header is set to
|
||||
// `application/json`, it sends json data. The `_requestJson` method
|
||||
// automatically sets the Accept Header to what we need, so we don't need to
|
||||
// specify it here.
|
||||
//
|
||||
// This behaviour of the API is "documented" here:
|
||||
// https://github.com/XAMPPRocky/tokei_rs/issues/8#issuecomment-475071147
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `https://tokei.rs/b1/${provider}/${user}/${repo}`,
|
||||
errorMessages: {
|
||||
400: 'repo not found',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ provider, user, repo }) {
|
||||
const { lines } = await this.fetch({ provider, user, repo })
|
||||
return this.constructor.render({ lines })
|
||||
}
|
||||
}
|
||||
31
services/tokei/tokei.tester.js
Normal file
31
services/tokei/tokei.tester.js
Normal file
@@ -0,0 +1,31 @@
|
||||
'use strict'
|
||||
|
||||
const { ServiceTester } = require('../tester')
|
||||
const { isMetric } = require('../test-validators')
|
||||
|
||||
const t = new ServiceTester({ id: 'tokei', title: 'Tokei LOC Tests' })
|
||||
module.exports = t
|
||||
|
||||
t.create('GitHub LOC')
|
||||
.get('/lines/github/badges/shields.json')
|
||||
.expectBadge({ label: 'total lines', message: isMetric })
|
||||
|
||||
t.create('GitLab LOC')
|
||||
.get('/lines/gitlab/tezos/tezos.json')
|
||||
.expectBadge({ label: 'total lines', message: isMetric })
|
||||
|
||||
t.create('GitHub LOC (with .com)')
|
||||
.get('/lines/github.com/badges/shields.json')
|
||||
.expectBadge({ label: 'total lines', message: isMetric })
|
||||
|
||||
t.create('GitLab LOC (with .com)')
|
||||
.get('/lines/gitlab.com/tezos/tezos.json')
|
||||
.expectBadge({ label: 'total lines', message: isMetric })
|
||||
|
||||
t.create('BitBucket LOC')
|
||||
.get('/lines/bitbucket.org/MonliH/tokei-shields-test.json')
|
||||
.expectBadge({ label: 'total lines', message: isMetric })
|
||||
|
||||
t.create('Invalid Provider')
|
||||
.get('/lines/example/tezos/tezos.json')
|
||||
.expectBadge({ label: 'total lines', message: 'repo not found' })
|
||||
Reference in New Issue
Block a user