#!/usr/bin/env python # -*- coding: utf-8 -*- import re from subprocess import Popen, PIPE from time import time, gmtime, strftime aliases = {"zoidber": "zoidberg", "zoidberg10": "zoidberg", "webmaster": "dhmh", "mast3rranan": "ranan", "ranan2": "ranan"} exclude = ["locale/*", "module/lib/*"] date_format = "%Y-%m-%d" line_re = re.compile(r" (\d+) \**", re.I) def add_exclude_flags(args): for dir in exclude: args.extend(["-X", dir]) # remove small percentages def wipe(data, perc=1): s = (sum(data.values()) * perc) / 100 for k, v in data.items(): if v < s: del data[k] return data # remove aliases def de_alias(data): for k, v in aliases.iteritems(): if k not in data: continue alias = aliases[k] if alias in data: data[alias] += data[k] else: data[alias] = data[k] del data[k] return data def output(data): s = float(sum(data.values())) print "Total Lines: %d" % s for k, v in data.iteritems(): print "%15s: %.1f%% | %d" % (k, (v * 100) / s, v) print def file_list(): args = ["hg", "status", "-A"] add_exclude_flags(args) p = Popen(args, stdout=PIPE) out, err = p.communicate() return [x.split()[1] for x in out.splitlines() if x.split()[0] in "CMA"] def hg_annotate(path): args = ["hg", "annotate", "-u", path] p = Popen(args, stdout=PIPE) out, err = p.communicate() data = {} for line in out.splitlines(): author, non, line = line.partition(":") # probably binary file if author == path: return {} author = author.strip().lower() if not line.strip(): continue # don't count blank lines if author in data: data[author] += 1 else: data[author] = 1 return de_alias(data) def hg_churn(days=None): args = ["hg", "churn"] if days: args.append("-d") t = time() - 60 * 60 * 24 * days args.append("%s to %s" % (strftime(date_format, gmtime(t)), strftime(date_format))) add_exclude_flags(args) p = Popen(args, stdout=PIPE) out, err = p.communicate() data = {} for line in out.splitlines(): m = line_re.search(line) author = line.split()[0] lines = int(m.group(1)) if "@" in author: author, n, email = author.partition("@") author = author.strip().lower() if author in data: data[author] += lines else: data[author] = lines return de_alias(data) def complete_annotate(): files = file_list() data = {} for f in files: tmp = hg_annotate(f) for k, v in tmp.iteritems(): if k in data: data[k] += v else: data[k] = v return data if __name__ == "__main__": for d in (30, 90, 180): c = wipe(hg_churn(d)) print "Changes in %d days:" % d output(c) c = wipe(hg_churn()) print "Total changes:" output(c) print "Current source code version:" data = wipe(complete_annotate()) output(data)