|
|
@@ -51,7 +51,6 @@ class DataCollector:
|
|
51
|
51
|
"""Manages data collection from a revision control repository."""
|
|
52
|
52
|
def __init__(self):
|
|
53
|
53
|
self.stamp_created = time.time()
|
|
54
|
|
- pass
|
|
55
|
54
|
|
|
56
|
55
|
##
|
|
57
|
56
|
# This should be the main function to extract data from the repository.
|
|
|
@@ -150,7 +149,6 @@ class GitDataCollector(DataCollector):
|
|
150
|
149
|
except ValueError:
|
|
151
|
150
|
stamp = 0
|
|
152
|
151
|
self.tags[tag] = { 'stamp': stamp, 'hash' : hash, 'date' : datetime.datetime.fromtimestamp(stamp).strftime('%Y-%m-%d') }
|
|
153
|
|
- pass
|
|
154
|
152
|
|
|
155
|
153
|
# Collect revision statistics
|
|
156
|
154
|
# Outputs "<stamp> <author>"
|
|
|
@@ -208,7 +206,7 @@ class GitDataCollector(DataCollector):
|
|
208
|
206
|
# author stats
|
|
209
|
207
|
if author not in self.authors:
|
|
210
|
208
|
self.authors[author] = {}
|
|
211
|
|
- # TODO commits
|
|
|
209
|
+ # commits
|
|
212
|
210
|
if 'last_commit_stamp' not in self.authors[author]:
|
|
213
|
211
|
self.authors[author]['last_commit_stamp'] = stamp
|
|
214
|
212
|
self.authors[author]['first_commit_stamp'] = stamp
|
|
|
@@ -249,11 +247,11 @@ class GitDataCollector(DataCollector):
|
|
249
|
247
|
# TODO Optimize this, it's the worst bottleneck
|
|
250
|
248
|
# outputs "<stamp> <files>" for each revision
|
|
251
|
249
|
self.files_by_stamp = {} # stamp -> files
|
|
252
|
|
- revlines = getpipeoutput(['git-rev-list --pretty=format:"%at %H" HEAD', 'grep -v ^commit']).strip().split('\n')
|
|
|
250
|
+ revlines = getpipeoutput(['git-rev-list --pretty=format:"%at %T" HEAD', 'grep -v ^commit']).strip().split('\n')
|
|
253
|
251
|
lines = []
|
|
254
|
252
|
for revline in revlines:
|
|
255
|
253
|
time, rev = revline.split(' ')
|
|
256
|
|
- linecount = int(getpipeoutput(['git-ls-tree -r "%s"' % rev, 'wc -l']).split('\n')[0])
|
|
|
254
|
+ linecount = int(getpipeoutput(['git-ls-tree -r --name-only "%s"' % rev, 'wc -l']).split('\n')[0])
|
|
257
|
255
|
lines.append('%d %d' % (int(time), linecount))
|
|
258
|
256
|
|
|
259
|
257
|
self.total_commits = len(lines)
|
|
|
@@ -304,8 +302,11 @@ class GitDataCollector(DataCollector):
|
|
304
|
302
|
if line.find('files changed,') == -1:
|
|
305
|
303
|
pos = line.find(' ')
|
|
306
|
304
|
if pos != -1:
|
|
307
|
|
- (stamp, author) = (int(line[:pos]), line[pos+1:])
|
|
308
|
|
- self.changes_by_date[stamp] = { 'files': files, 'ins': inserted, 'del': deleted, 'lines': total_lines }
|
|
|
305
|
+ try:
|
|
|
306
|
+ (stamp, author) = (int(line[:pos]), line[pos+1:])
|
|
|
307
|
+ self.changes_by_date[stamp] = { 'files': files, 'ins': inserted, 'del': deleted, 'lines': total_lines }
|
|
|
308
|
+ except ValueError:
|
|
|
309
|
+ print 'Warning: unexpected line "%s"' % line
|
|
309
|
310
|
else:
|
|
310
|
311
|
print 'Warning: unexpected line "%s"' % line
|
|
311
|
312
|
else:
|
|
|
@@ -400,11 +401,10 @@ class HTMLReportCreator(ReportCreator):
|
|
400
|
401
|
ReportCreator.create(self, data, path)
|
|
401
|
402
|
self.title = data.projectname
|
|
402
|
403
|
|
|
403
|
|
- # TODO copy the CSS if it does not exist
|
|
|
404
|
+ # copy the CSS if it does not exist
|
|
404
|
405
|
if not os.path.exists(path + '/gitstats.css'):
|
|
405
|
406
|
basedir = os.path.dirname(os.path.abspath(__file__))
|
|
406
|
407
|
shutil.copyfile(basedir + '/gitstats.css', path + '/gitstats.css')
|
|
407
|
|
- pass
|
|
408
|
408
|
|
|
409
|
409
|
f = open(path + "/index.html", 'w')
|
|
410
|
410
|
format = '%Y-%m-%d %H:%m:%S'
|
|
|
@@ -689,7 +689,6 @@ class HTMLReportCreator(ReportCreator):
|
|
689
|
689
|
f.close()
|
|
690
|
690
|
|
|
691
|
691
|
self.createGraphs(path)
|
|
692
|
|
- pass
|
|
693
|
692
|
|
|
694
|
693
|
def createGraphs(self, path):
|
|
695
|
694
|
print 'Generating graphs...'
|