-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GitHub] Top language, languages count and code size badges #1160
Changes from 3 commits
3511feb
fd1afac
c9cc4d4
46368f8
82b2fa6
b529446
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3906,6 +3906,71 @@ cache(function(data, match, sendBadge, request) { | |
}); | ||
})); | ||
|
||
// GitHub languages integration. | ||
camp.route(/^\/github\/languages\/(top|count|bytes)\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, | ||
cache(function(data, match, sendBadge, request) { | ||
var type = match[1]; | ||
var user = match[2]; | ||
var repo = match[3]; | ||
var format = match[4]; | ||
var apiUrl = githubApiUrl + '/repos/' + user + '/' + repo + '/languages'; | ||
var badgeData = getBadgeData('', data); | ||
if (badgeData.template === 'social') { | ||
badgeData.logo = getLogo('github', data); | ||
} | ||
githubAuth.request(request, apiUrl, {}, function(err, res, buffer) { | ||
if (err != null) { | ||
badgeData.text[1] = 'inaccessible'; | ||
sendBadge(format, badgeData); | ||
return; | ||
} | ||
try { | ||
const parsedData = JSON.parse(buffer); | ||
var sumBytes = 0; | ||
switch(type) { | ||
case 'top': | ||
var topLanguage = 'language'; | ||
var maxBytes = 0; | ||
for (const language of Object.keys(parsedData)) { | ||
const bytes = parseInt(parsedData[language]); | ||
if (bytes >= maxBytes) { | ||
maxBytes = bytes; | ||
topLanguage = language; | ||
} | ||
sumBytes += bytes; | ||
} | ||
badgeData.text[0] = topLanguage; | ||
if (sumBytes === 0) { // eg, empty repo, only .md files, etc. | ||
badgeData.text[1] = 'none'; | ||
badgeData.colorscheme = 'blue'; | ||
} else { | ||
badgeData.text[1] = (maxBytes / sumBytes * 100).toFixed(1) + '%'; // eg, 9.1% | ||
} | ||
break; | ||
case 'count': | ||
badgeData.text[0] = 'languages'; | ||
badgeData.text[1] = Object.keys(parsedData).length; | ||
badgeData.colorscheme = 'blue'; | ||
break; | ||
case 'bytes': | ||
for (const language of Object.keys(parsedData)) { | ||
sumBytes += parseInt(parsedData[language]); | ||
} | ||
badgeData.text[0] = 'code size'; | ||
badgeData.text[1] = metric(sumBytes) + 'B'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you use |
||
badgeData.colorscheme = 'blue'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm really glad to have a repo size badge! Though, it would be more reliable to get this information from the Repositories endpoint. Would you be up for implementing it that way instead, under a different URL path? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How would you get the code size directly using that endpoint? The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that is right. It's in kilobytes. Here's a StackOverflow answer that talks about it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The more I think about it, the repo size is more about how many revisions and binary blobs are checked in. The size of the identifiable code could be useful, distinct from the repo size. Do they provide lines of code? That would also be really cool. 😃 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think it's the size on disk rather than the code size. I would be inclined to keep the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Awesome! Yes, a separate badge + PR for repo size makes sense to me. Wow, if that SO answer works, that would be cool! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I'll take care of that! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually the solutions proposed to calculate the lines of code using the API are dodgy according to a comment on the answer I had previously linked. I don't think a line count badge can be implemented reliably and efficiently with the current API possibilities. |
||
break; | ||
default: | ||
throw Error('Unreachable due to regex'); | ||
} | ||
sendBadge(format, badgeData); | ||
} catch(e) { | ||
badgeData.text[1] = 'invalid'; | ||
sendBadge(format, badgeData); | ||
} | ||
}); | ||
})); | ||
|
||
// Bitbucket issues integration. | ||
camp.route(/^\/bitbucket\/issues(-raw)?\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, | ||
cache(function(data, match, sendBadge, request) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -447,3 +447,31 @@ t.create('github pull request check state') | |
t.create('github pull request check contexts') | ||
.get('/status/contexts/pulls/badges/shields/1110.json') | ||
.expectJSONTypes(Joi.object().keys({ name: 'checks', value: '1 failure' })); | ||
|
||
t.create('top language') | ||
.get('/languages/top/badges/shields.json') | ||
.expectJSONTypes(Joi.object().keys({ | ||
name: Joi.equal('JavaScript'), | ||
value: Joi.string().regex(/^([1-9]?[0-9]\.[0-9]|100\.0)%$/), | ||
})); | ||
|
||
t.create('top language with empty repository') | ||
.get('/languages/top/pyvesb/emptyrepo.json') | ||
.expectJSONTypes(Joi.object().keys({ | ||
name: Joi.equal('language'), | ||
value: Joi.equal('none'), | ||
})); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can tighten this up a bit since these are literals: .expectJSON({ name: 'language', value: 'none' }) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
|
||
t.create('language count') | ||
.get('/languages/count/badges/shields.json') | ||
.expectJSONTypes(Joi.object().keys({ | ||
name: Joi.equal('languages'), | ||
value: Joi.string().regex(/^[0-9]*$/), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! Fixed. |
||
})); | ||
|
||
t.create('code size in bytes for all languages') | ||
.get('/languages/bytes/badges/shields.json') | ||
.expectJSONTypes(Joi.object().keys({ | ||
name: Joi.equal('code size'), | ||
value: Joi.string().regex(/^[0-9]*(k|M|G|T|P|E|Z|Y)B$/), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My bad, I had forked the repository before the helpers were added, this is now fixed. |
||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about
code-size
orsize
to match the label?