-
-
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] Last commit date and commit stats #1112
Changes from all commits
fa41821
aaeb8ed
5e8cd23
bde7897
b4cdfb3
be50171
89d8d98
48f7e1d
852cf9b
4ac0c72
f390ac9
bd3fcf7
5112fd9
f0136aa
3e33151
470f498
26a81a0
1592318
cb6c686
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 |
---|---|---|
@@ -0,0 +1,64 @@ | ||
'use strict'; | ||
|
||
const assert = require('assert'); | ||
const { | ||
coveragePercentage, | ||
colorScale, | ||
age | ||
} = require('./color-formatters'); | ||
|
||
describe('Color formatters', function() { | ||
it('should step appropriately', function() { | ||
const byPercentage = colorScale([Number.EPSILON, 80, 90, 100]); | ||
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. What's the purpose of 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 semantics of 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. Can you just use 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 existing percentage function makes 0 red and anything after that yellow. I don't see the point in differentiating between 0 and 1, which both seem terrible, though I was aiming for parity. 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 added tests at |
||
assert.equal(byPercentage(-1), 'red'); | ||
assert.equal(byPercentage(0), 'red'); | ||
assert.equal(byPercentage(0.5), 'yellow'); | ||
assert.equal(byPercentage(1), 'yellow'); | ||
assert.equal(byPercentage(50), 'yellow'); | ||
assert.equal(byPercentage(80), 'yellowgreen'); | ||
assert.equal(byPercentage(85), 'yellowgreen'); | ||
assert.equal(byPercentage(90), 'green'); | ||
assert.equal(byPercentage(100), 'brightgreen'); | ||
assert.equal(byPercentage(101), 'brightgreen'); | ||
}); | ||
|
||
it('should have parity with coveragePercentage', function() { | ||
const byPercentage = colorScale([Number.EPSILON, 80, 90, 100]); | ||
assert.equal(byPercentage(-1), coveragePercentage(-1)); | ||
assert.equal(byPercentage(0), coveragePercentage(0)); | ||
assert.equal(byPercentage(0.5), coveragePercentage(0.5)); | ||
assert.equal(byPercentage(1), coveragePercentage(1)); | ||
assert.equal(byPercentage(50), coveragePercentage(50)); | ||
assert.equal(byPercentage(80), coveragePercentage(80)); | ||
assert.equal(byPercentage(85), coveragePercentage(85)); | ||
assert.equal(byPercentage(90), coveragePercentage(90)); | ||
assert.equal(byPercentage(100), coveragePercentage(100)); | ||
assert.equal(byPercentage(101), coveragePercentage(101)); | ||
}); | ||
|
||
it('should step in reverse', function() { | ||
const byAge = colorScale([7, 30, 180, 365, 730], undefined, true); | ||
assert.equal(byAge(3), 'brightgreen'); | ||
assert.equal(byAge(7), 'green'); | ||
assert.equal(byAge(10), 'green'); | ||
assert.equal(byAge(60), 'yellowgreen'); | ||
assert.equal(byAge(250), 'yellow'); | ||
assert.equal(byAge(400), 'orange'); | ||
assert.equal(byAge(800), 'red'); | ||
}); | ||
|
||
it('should generate correct color for ages', function() { | ||
const monthsAgo = months => { | ||
const result = new Date(); | ||
// This looks wack but it works. | ||
result.setMonth(result.getMonth() - months); | ||
return result; | ||
}; | ||
|
||
assert.equal(age(Date.now()), 'brightgreen'); | ||
assert.equal(age(new Date()), 'brightgreen'); | ||
assert.equal(age(new Date(2001, 1, 1)), 'red'); | ||
assert.equal(age(monthsAgo(2)), 'yellowgreen'); | ||
assert.equal(age(monthsAgo(15)), 'orange'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,13 +49,15 @@ const { | |
ordinalNumber, | ||
starRating, | ||
omitv, | ||
maybePluralize | ||
maybePluralize, | ||
formatDate | ||
} = require('./lib/text-formatters'); | ||
const { | ||
coveragePercentage: coveragePercentageColor, | ||
downloadCount: downloadCountColor, | ||
floorCount: floorCountColor, | ||
version: versionColor, | ||
age: ageColor | ||
} = require('./lib/color-formatters'); | ||
const { | ||
analyticsAutoLoad, | ||
|
@@ -3714,6 +3716,90 @@ cache(function(data, match, sendBadge, request) { | |
}); | ||
})); | ||
|
||
// GitHub commit statistics integration. | ||
camp.route(/^\/github\/commit-activity\/(y|4w|w)\/([^\/]+)\/([^\/]+)\.(svg|png|gif|jpg|json)$/, | ||
cache(function(data, match, sendBadge, request) { | ||
const interval = match[1]; | ||
const user = match[2]; | ||
const repo = match[3]; | ||
const format = match[4]; | ||
const apiUrl = `${githubApiUrl}/repos/${user}/${repo}/stats/commit_activity`; | ||
const badgeData = getBadgeData('commit activity', data); | ||
if (badgeData.template === 'social') { | ||
badgeData.logo = getLogo('github', data); | ||
badgeData.links = [`https://github.com/${user}/${repo}`]; | ||
} | ||
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); | ||
let value; | ||
let intervalLabel; | ||
switch (interval) { | ||
case 'y': | ||
value = parsedData.reduce((sum, weekInfo) => sum + weekInfo.total, 0); | ||
intervalLabel = '/year'; | ||
break; | ||
case '4w': | ||
value = parsedData.slice(-4).reduce((sum, weekInfo) => sum + weekInfo.total, 0); | ||
intervalLabel = '/4 weeks'; | ||
break; | ||
case 'w': | ||
value = parsedData.slice(-1)[0].total; | ||
intervalLabel = '/week'; | ||
break; | ||
default: | ||
throw Error('Unhandled case'); | ||
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.
|
||
} | ||
badgeData.text[1] = `${metric(value)}${intervalLabel}`; | ||
badgeData.colorscheme = 'blue'; | ||
sendBadge(format, badgeData); | ||
} catch(e) { | ||
badgeData.text[1] = 'invalid'; | ||
sendBadge(format, badgeData); | ||
} | ||
}); | ||
})); | ||
|
||
// GitHub last commit integration. | ||
camp.route(/^\/github\/last-commit\/([^\/]+)\/([^\/]+)(?:\/(.+))?\.(svg|png|gif|jpg|json)$/, | ||
cache(function(data, match, sendBadge, request) { | ||
const user = match[1]; // eg, mashape | ||
const repo = match[2]; // eg, apistatus | ||
const branch = match[3]; | ||
const format = match[4]; | ||
let apiUrl = `${githubApiUrl}/repos/${user}/${repo}/commits`; | ||
if (branch) { | ||
apiUrl += `?sha=${branch}`; | ||
} | ||
const badgeData = getBadgeData('last commit', data); | ||
if (badgeData.template === 'social') { | ||
badgeData.logo = getLogo('github', data); | ||
badgeData.links = [`https://github.com/${user}/${repo}`]; | ||
} | ||
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); | ||
const commitDate = parsedData[0].commit.author.date; | ||
badgeData.text[1] = formatDate(commitDate); | ||
badgeData.colorscheme = ageColor(Date.parse(commitDate)); | ||
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) { | ||
|
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.
These should be
throw new Error
, notthrow Error
. Invoking constructors without thenew
keyword is deprecated.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.
I can't find a reference supporting this. I used to write
new Error
but stopped because it's extra tokens for seemingly no value. The ES5 spec specifically permits this. Is there an ES6 reference that says otherwise?I only bring it up because I'd enforce what you're asking for if I had a good reference.
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.
Ah, interesting @paulmelnikow! That's still in the ES2015 spec (https://www.ecma-international.org/ecma-262/6.0/#sec-error-constructor):
I guess it's okay then. I was basing my info off an internal lint rule we have at Facebook, but perhaps the info is outdated/incorrect.