Last active
August 29, 2015 14:02
-
-
Save jacobk/1402403bd0094a538e0b to your computer and use it in GitHub Desktop.
Disco Golfo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var RSVP = require('rsvp'), | |
GitHubApi = require("github"), | |
_ = require('lodash'), | |
argv = require('minimist')(process.argv.slice(2)), | |
github = new GitHubApi({ | |
// required | |
version: "3.0.0", | |
// optional | |
// debug: true, | |
protocol: "https", | |
timeout: 5000 | |
}), | |
orgName = argv.org || 'mbloxlund', | |
teamName = argv.team || 'lund'; | |
var members; | |
// USAGE --token=gh_token (click generate token on app settings page) | |
// --org=gh_org (click generate token on app settings page) | |
// --team | |
github.authenticate({ | |
type: 'oauth', | |
token: argv.token | |
}); | |
function getTeam() { | |
return new RSVP.Promise(function(resolve, reject) { | |
github.orgs.getTeams({ | |
org: orgName | |
}, function(err, res) { | |
var match = _.find(res, function(team) { | |
return team.name.toLowerCase() === teamName; | |
}); | |
resolve(match); | |
}); | |
}); | |
} | |
function getMembers(team) { | |
console.log('Retrieving members of ' + teamName + '...'); | |
return new RSVP.Promise(function(resolve, reject) { | |
github.orgs.getTeamMembers({ | |
id: team.id | |
}, function(err, res) { | |
resolve(res); | |
}); | |
}); | |
} | |
function getRepositories() { | |
console.log('Retrieving repositories...'); | |
// Recursive function to slurp all pages in case of pagination | |
// Defaults to 30 per page (maxes out at 100) | |
var _getRepositories = function(prevRes) { | |
return new RSVP.Promise(function(resolve, reject) { | |
if (github.hasNextPage(prevRes)) { | |
console.log('Getting more pages with repositories...'); | |
github.getNextPage(prevRes, function(err, res) { | |
_getRepositories(res).then(function(nextRes) { | |
resolve(prevRes.concat(nextRes)); | |
}); | |
}); | |
} else { | |
resolve(prevRes); | |
} | |
}); | |
}; | |
return new RSVP.Promise(function(resolve, reject) { | |
github.repos.getFromOrg({ | |
org: orgName | |
}, function(err, res) { | |
resolve(_getRepositories(res)); | |
}); | |
}); | |
} | |
function getStatsForUserAndRepo(user, repo) { | |
return new RSVP.Promise(function(resolve, reject) { | |
github.repos.getStatsContributors({ | |
user: user, | |
repo: repo | |
}, function(err, res) { | |
resolve(res); | |
}); | |
}); | |
} | |
// Get all repo stats in parallell | |
function collectStatistics(data) { | |
console.log('Retrieving contribution stats...'); | |
var stats = _.map(data.repos, function(repo) { | |
return RSVP.hash({ | |
repo: repo, | |
stats: getStatsForUserAndRepo(orgName, repo.name) | |
}); | |
}); | |
data.stats = RSVP.all(stats); | |
return RSVP.hash(data); | |
} | |
function aggregateStatistics(data) { | |
console.log('Aggregating data...'); | |
var histogram = {}, | |
userName, userData; | |
_.each(data.stats, function(repoStats) { | |
console.log('Aggregating repo ' + repoStats.repo.name + '...'); | |
_.each(repoStats.stats, function(userStats) { | |
userName = userStats.author.login; | |
if (!_.has(histogram, userName)) { | |
histogram[userName] = { | |
a: 0, | |
d: 0, | |
c: 0 | |
}; | |
} | |
userData = histogram[userName]; | |
_.each(userStats.weeks, function(week) { | |
userData.a += week.a; | |
userData.d += week.d; | |
userData.c += week.c; | |
}); | |
}); | |
}); | |
data.aggregatedStats = histogram; | |
return data; | |
} | |
function filterStatistics(data) { | |
console.log('Processing aggregated data...'); | |
return _.reject(_.pairs(data.aggregatedStats), function(element) { | |
return _.isUndefined(_.find(data.members, function(member) { | |
return member.login === element[0]; | |
})); | |
}); | |
} | |
RSVP.on('error', function(reason) { | |
console.error('RSVP Error'); | |
console.dir(reason); | |
console.log(reason.stack); | |
}); | |
getTeam(argv.team) | |
.then(function(team) { | |
return RSVP.hash({ | |
repos: getRepositories(), | |
members: getMembers(team) | |
}); | |
}) | |
.then(collectStatistics) | |
.then(aggregateStatistics) | |
.then(filterStatistics) | |
.then(function(data) { | |
data = _.map(data, function(elm) { | |
return _.assign(elm[1], {user: elm[0]}); | |
}); | |
console.log('Rank by commits'); | |
_.chain(data).sortBy('c').reverse().each(function(user) { | |
console.log(user.user, user.c); | |
}); | |
console.log(''); | |
console.log('Rank by additions'); | |
_.chain(data).sortBy('a').reverse().each(function(user) { | |
console.log(user.user, user.a); | |
}); | |
console.log(''); | |
console.log('Rank by deletions'); | |
_.chain(data).sortBy('d').reverse().each(function(user) { | |
console.log(user.user, user.d); | |
}); | |
console.log(data.length); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "disco", | |
"version": "0.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"repository": { | |
"type": "git", | |
"url": "https://gist.github.com/1402403bd0094a538e0b.git" | |
}, | |
"author": "Jacob Kristhammar <[email protected]>", | |
"license": "ISC", | |
"dependencies": { | |
"minimist": "^0.1.0", | |
"lodash": "^2.4.1", | |
"github": "git://github.com/saw/node-github#03bd1bb66459b05fe2f38096c2290f54b2167902", | |
"rsvp": "^3.0.9" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment