Support the statistics gathering for the churn graph

I'm still somewhat uncertain about how I want to create the graphs, I may need to add historgram support to CairoPlot to do precisely what I want:

			|
			|  |+++|
			|  |+++|
			|  |///|        ___
			|  |///|       |+++| <-- avg added per commit
			|  |///|       |+++|
			|__|///|_______|///|_<-- avg removed per commit
			  [tyler]     [other]

Uncertainly, BAH.

Signed-off-by: R. Tyler Ballance <tyler@monkeypox.org>
This commit is contained in:
R. Tyler Ballance 2009-01-08 00:42:42 -08:00
parent 07f86214a9
commit 8528d27df6
2 changed files with 42 additions and 5 deletions

View File

@ -6,7 +6,7 @@ import internal
import internal.log
def main():
sub_commands = ['leaderboard', 'timeofday']
sub_commands = ['leaderboard', 'timeofday', 'churn']
usage = 'usage: %%prog [options] <%s>' % '|'.join(sub_commands)
_op = OptionParser(usage=usage)
_op.add_option('-d', '--directory', default='.', dest='directory', help='Directory of the Git repository to analyze')

View File

@ -68,15 +68,16 @@ class GitLog(object):
# OW OW OW OW
numstat = [n.split('\t') for n in r[1].strip().split('\n')]
def _numstat_gen(line):
d = {'added' : 0, 'removed' : 0, 'filename' : line[2], 'newfile' : False}
d = {'added' : 0, 'removed' : 0, 'filename' : line[2], 'binary' : False}
if line[0] == '-' and line[1] == '-':
d['newfile'] = True
d['binary'] = True
else:
d['added'], d['removed'] = line[0],line[1]
d['added'], d['removed'] = int(line[0]),int(line[1])
return d
t['numstat'] = map(lambda n: len(n) == 3 and _numstat_gen(n), numstat)
t['numstat'] = [nm for nm in t['numstat'] if nm]
else:
t['numstat'] = None
t['numstat'] = []
rc.append(t)
self.results = rc
def timeofday(f):
@ -162,3 +163,39 @@ class GitLog(object):
except KeyError:
print 'This function does not support chart type: %s' % chart
def churn(self, width=None, height=None, filename=None, chart=internal.ChartType.Bar):
assert width or height
if not self.results:
self.load()
results = copy.deepcopy(self.results)
results.reverse()
filename = '%s_churn.png' % (self.filename or time.time())
rc = {}
for commit in results:
if not commit['numstat']:
continue
churn = []
for file in commit['numstat']:
if file['binary']:
continue
churn.append( (file['added'], file['removed'], file['filename']) )
author = commit['committer_handle']
if not rc.get(author):
rc[author] = {'commits' : 0, 'files' : [], 'added' : 0, 'removed' : 0}
rc[author]['commits'] += 1
rc[author]['files'].extend([f[2] for f in churn])
added = map(lambda c: c[0], churn)
removed = map(lambda c: c[1], churn)
rc[author]['added'] += added and reduce(lambda x,y: x+y, added) or 0
rc[author]['removed'] += removed and reduce(lambda x,y: x+y, removed) or 0
for k in rc.keys():
rc[k]['files'] = list(set(rc[k]['files']))
rc[k]['distinct_files'] = len(rc[k]['files'])
for k,r in rc.iteritems():
print '%s touched %d files, +%s, -%s lines (total: %s, net: %s)' % (k, r['distinct_files'], r['added'], r['removed'], r['added']+r['removed'], r['added']-r['removed'])