|
|
@@ -12,6 +12,9 @@ def getoutput(cmd):
|
|
12
|
12
|
output = commands.getoutput(cmd)
|
|
13
|
13
|
return output
|
|
14
|
14
|
|
|
|
15
|
+def getkeyssortedbyvalues(dict):
|
|
|
16
|
+ return map(lambda el : el[1], sorted(map(lambda el : (el[1], el[0]), dict.items())))
|
|
|
17
|
+
|
|
15
|
18
|
class DataCollector:
|
|
16
|
19
|
def __init__(self):
|
|
17
|
20
|
pass
|
|
|
@@ -63,7 +66,7 @@ class GitDataCollector(DataCollector):
|
|
63
|
66
|
DataCollector.collect(self, dir)
|
|
64
|
67
|
|
|
65
|
68
|
self.total_authors = int(getoutput('git-log |git-shortlog -s |wc -l'))
|
|
66
|
|
- self.total_commits = int(getoutput('git-rev-list --all |wc -l'))
|
|
|
69
|
+ self.total_commits = int(getoutput('git-rev-list HEAD |wc -l'))
|
|
67
|
70
|
self.total_files = int(getoutput('git-ls-files |wc -l'))
|
|
68
|
71
|
self.total_lines = int(getoutput('git-ls-files |xargs cat |wc -l'))
|
|
69
|
72
|
|
|
|
@@ -71,7 +74,7 @@ class GitDataCollector(DataCollector):
|
|
71
|
74
|
self.activity_by_day_of_week = {} # day -> commits
|
|
72
|
75
|
|
|
73
|
76
|
# activity
|
|
74
|
|
- lines = getoutput('git-rev-list --all --pretty=format:%at |grep -v ^commit').split('\n')
|
|
|
77
|
+ lines = getoutput('git-rev-list HEAD --pretty=format:%at |grep -v ^commit').split('\n')
|
|
75
|
78
|
for stamp in lines:
|
|
76
|
79
|
date = datetime.datetime.fromtimestamp(float(stamp))
|
|
77
|
80
|
|
|
|
@@ -89,6 +92,31 @@ class GitDataCollector(DataCollector):
|
|
89
|
92
|
else:
|
|
90
|
93
|
self.activity_by_day_of_week[day] = 1
|
|
91
|
94
|
|
|
|
95
|
+ # TODO author of the month
|
|
|
96
|
+ self.author_of_month = {} # month -> author -> commits
|
|
|
97
|
+ self.commits_by_month = {} # month -> commits
|
|
|
98
|
+
|
|
|
99
|
+ lines = getoutput('git-rev-list --pretty=format:"%at %an" HEAD |grep -v ^commit').split('\n')
|
|
|
100
|
+ for line in lines:
|
|
|
101
|
+ parts = line.split(' ')
|
|
|
102
|
+ stamp = int(parts[0])
|
|
|
103
|
+ author = ' '.join(parts[1:])
|
|
|
104
|
+
|
|
|
105
|
+ yymm = datetime.datetime.fromtimestamp(stamp).strftime('%Y-%m')
|
|
|
106
|
+ if yymm in self.author_of_month and author in self.author_of_month[yymm]:
|
|
|
107
|
+ if author in self.author_of_month[yymm]:
|
|
|
108
|
+ self.author_of_month[yymm][author] += 1
|
|
|
109
|
+ else:
|
|
|
110
|
+ self.author_of_month[yymm][author] = 1
|
|
|
111
|
+ else:
|
|
|
112
|
+ self.author_of_month[yymm] = {}
|
|
|
113
|
+ self.author_of_month[yymm][author] = 1
|
|
|
114
|
+ if yymm in self.commits_by_month:
|
|
|
115
|
+ self.commits_by_month[yymm] += 1
|
|
|
116
|
+ else:
|
|
|
117
|
+ self.commits_by_month[yymm] = 1
|
|
|
118
|
+
|
|
|
119
|
+ print self.author_of_month
|
|
92
|
120
|
|
|
93
|
121
|
def getActivityByDayOfWeek(self):
|
|
94
|
122
|
return self.activity_by_day_of_week
|
|
|
@@ -97,7 +125,7 @@ class GitDataCollector(DataCollector):
|
|
97
|
125
|
return self.activity_by_hour_of_day
|
|
98
|
126
|
|
|
99
|
127
|
def getAuthorInfo(self, author):
|
|
100
|
|
- commits = int(getoutput('git-rev-list --all --author="%s" |wc -l' % author))
|
|
|
128
|
+ commits = int(getoutput('git-rev-list HEAD --author="%s" |wc -l' % author))
|
|
101
|
129
|
commits_frac = (100 * float(commits)) / self.getTotalCommits()
|
|
102
|
130
|
date_first = '0000-00-00'
|
|
103
|
131
|
date_last = '0000-00-00'
|
|
|
@@ -171,15 +199,6 @@ class HTMLReportCreator(ReportCreator):
|
|
171
|
199
|
</ul>
|
|
172
|
200
|
""")
|
|
173
|
201
|
|
|
174
|
|
- f.write('<h2>Authors</h2>')
|
|
175
|
|
-
|
|
176
|
|
- f.write('<table class="authors">')
|
|
177
|
|
- f.write('<tr><th>Author</th><th>Commits (%)</th><th>First commit</th><th>Last commit</th></tr>')
|
|
178
|
|
- for author in data.getAuthors():
|
|
179
|
|
- info = data.getAuthorInfo(author)
|
|
180
|
|
- f.write('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%s</td><td>%s</td></tr>' % (author, info['commits'], info['commits_frac'], info['date_first'], info['date_last']))
|
|
181
|
|
- f.write('</table>')
|
|
182
|
|
-
|
|
183
|
202
|
f.write('<h2>Tags</h2>')
|
|
184
|
203
|
f.write('<table>')
|
|
185
|
204
|
f.write('<tr><th>Name</th><th>Date</th><th>Developers</th></tr>')
|
|
|
@@ -236,6 +255,39 @@ class HTMLReportCreator(ReportCreator):
|
|
236
|
255
|
f.write('</table>')
|
|
237
|
256
|
|
|
238
|
257
|
f.close()
|
|
|
258
|
+
|
|
|
259
|
+ # authors.html
|
|
|
260
|
+ f = open(path + '/authors.html', 'w')
|
|
|
261
|
+ self.printHeader(f)
|
|
|
262
|
+
|
|
|
263
|
+ f.write('<h1>Authors</h1>')
|
|
|
264
|
+
|
|
|
265
|
+ f.write('\n<h2>List of authors</h2>\n\n')
|
|
|
266
|
+
|
|
|
267
|
+ f.write('<table class="authors">')
|
|
|
268
|
+ f.write('<tr><th>Author</th><th>Commits (%)</th><th>First commit</th><th>Last commit</th></tr>')
|
|
|
269
|
+ for author in data.getAuthors():
|
|
|
270
|
+ info = data.getAuthorInfo(author)
|
|
|
271
|
+ f.write('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%s</td><td>%s</td></tr>' % (author, info['commits'], info['commits_frac'], info['date_first'], info['date_last']))
|
|
|
272
|
+ f.write('</table>')
|
|
|
273
|
+
|
|
|
274
|
+ f.write('\n<h2>Author of Month</h2>\n\n')
|
|
|
275
|
+ f.write('<table>')
|
|
|
276
|
+ f.write('<tr><th>Month</th><th>Author</th><th>Commits (%)</th></tr>')
|
|
|
277
|
+ for yymm in reversed(sorted(data.author_of_month.keys())):
|
|
|
278
|
+ authordict = data.author_of_month[yymm]
|
|
|
279
|
+ authors = getkeyssortedbyvalues(authordict)
|
|
|
280
|
+ authors.reverse()
|
|
|
281
|
+ commits = data.author_of_month[yymm][authors[0]]
|
|
|
282
|
+ f.write('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td></tr>' % (yymm, authors[0], commits, (100 * commits) / data.commits_by_month[yymm], data.commits_by_month[yymm]))
|
|
|
283
|
+
|
|
|
284
|
+ f.write('</table>')
|
|
|
285
|
+
|
|
|
286
|
+ f.write('\n<h2>Author of Year</h2>\n\n')
|
|
|
287
|
+ # TODO
|
|
|
288
|
+
|
|
|
289
|
+ f.write('</body></html>')
|
|
|
290
|
+ f.close()
|
|
239
|
291
|
pass
|
|
240
|
292
|
|
|
241
|
293
|
def printHeader(self, f):
|