forked from home-assistant/home-assistant.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate_credits.js
160 lines (150 loc) · 5.31 KB
/
update_credits.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
var fs = require('fs')
, async = require('async')
, GitHubApi = require('github')
, mu = require('mu2')
, moment = require('moment-timezone');
if(!process.env.GITHUB_TOKEN) {
console.error('You must set the GITHUB_TOKEN environment variable to a GitHub personal access token.');
return;
}
var organizationName = process.env.GITHUB_ORGANIZATION_NAME || 'home-assistant';
mu.root = __dirname;
var github = new GitHubApi({
headers: { 'user-agent': 'Home Assistant Contributors List Updater <[email protected]>' }
});
github.authenticate({ type: 'oauth', token: process.env.GITHUB_TOKEN });
var usersMap = {};
github.repos.getForOrg({
org: organizationName,
type: 'public',
per_page: 100
}, function(err, repos){
var headerSource = (err && err.headers) ? err.headers : repos.meta;
var ratelimitLimit = Number(headerSource['x-ratelimit-limit']);
var ratelimitRemaining = Number(headerSource['x-ratelimit-remaining']);
console.log('Rate limits: '+ratelimitRemaining+'/'+ratelimitLimit, '(remaining/limit)');
if(err) {
if(err.code == 403 && ratelimitRemaining == 0) {
var resetUnixTime = moment.unix(err.headers['x-ratelimit-reset']);
var resetTimeFormatted = resetUnixTime.format();
var resetAt = moment().to(resetUnixTime);
console.error('Error when getting list of repos in org, because rate limits are exhausted. Rate limits reset', resetAt, 'from now ('+resetTimeFormatted+')');
} else {
console.error('Error when attempting to get a list of all repos in org...', err.message);
}
return;
}
async.each(repos, function(repo, cb){
github.repos.getContributors({ owner: organizationName, repo: repo.name, per_page: 100 }, function(err, contributors){
getContributors(err, contributors, repo, cb);
});
}, function(err){
if(err){
console.error('Error when iterating organization repos', err);
return;
}
console.log('Done getting contributors for '+repos.length+' found organization repos...');
async.each(Object.keys(usersMap), function(login, cb){
github.users.getForUser({username: login}, function(err, userInfo){
if(err){
console.error('Got error when get user details for', login, err);
cb(err);
return;
}
if (userInfo.name) {
userInfo.name = userInfo.name.replace(/^@/, '')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/[\\`*_{}[\]()#+-.!~|]/g, '\\$&');
}
usersMap[login].info.name = userInfo.name || userInfo.login;
usersMap[login].info.username = userInfo.login;
cb();
});
}, function(err){
if(err){
console.error('Got error when running', err);
return;
} else {
console.log('Building contributors!!!');
buildContributors();
}
});
});
});
function getContributors(err, res, repo, callback){
if(err) {
console.error('Error when getting contributors', err);
callback(err);
return
} else {
console.log('Processing the '+res.length+' contributors to '+repo.name);
async.each(res, function(contributor, cb){
if(!usersMap[contributor.login]) {
usersMap[contributor.login] = {
counts: {},
info: {login: contributor.login, id: contributor.id}
};
}
usersMap[contributor.login].counts[repo.name] = contributor.contributions;
cb(null);
}, function(){
if (github.hasNextPage(res)) {
github.getNextPage(res, function(newErr, newContributors){
getContributors(newErr, newContributors, repo, callback);
});
} else {
callback(null);
}
});
}
}
function buildContributors(){
var fearlessLeader = usersMap['balloob'];
fearlessLeader.countString = buildCountString(fearlessLeader.counts);
delete usersMap['balloob'];
var users = Object.keys(usersMap).map(function (key) {
var obj = usersMap[key];
obj.countString = buildCountString(obj.counts);
return obj;
}).sort(function(a, b){
var nameA = a.info.name.toLowerCase();
var nameB = b.info.name.toLowerCase();
if (nameA < nameB) { return -1; }
if (nameA > nameB) { return 1; }
return 0;
});
var headerDate = moment().tz('UTC').format('YYYY-MM-DD HH:mm:ss ZZ');
var footerDate = moment().tz('UTC').format('dddd, MMMM Do YYYY, h:mm:ss a zz');
var output = '';
mu.compileAndRender('credits.mustache', {
allUsers: users,
fearlessLeader: fearlessLeader,
headerDate: headerDate,
footerDate: footerDate
}).on('data', function (data) {
output += data.toString();
}).on('end', function(){
fs.writeFile('../source/developers/credits.markdown', output, function (writeErr) {
if (writeErr) {
console.log('Error when writing credits.markdown', writeErr);
} else {
console.log('Done getting user info, wrote credits.markdown file!');
}
});
});
}
function buildCountString(counts){
var totalCommits = 0;
var countStrings = [];
Object.keys(counts).sort(function(a, b){
return counts[b] - counts[a];
}).forEach(function (countKey) {
var count = counts[countKey];
var word = (count > 1) ? 'commits' : 'commit';
totalCommits = totalCommits+count;
countStrings.push(count+' '+word+' to '+countKey);
});
countStrings.unshift(totalCommits+' total commits to the home-assistant organization');
return countStrings.join(', ');
}