##// END OF EJS Templates
imported patch filteruser.patch
imported patch filteruser.patch

File last commit:

r7129:7e6a3bae default
r7212:402d3177 default
Show More
churn.py
184 lines | 5.7 KiB | text/x-python | PythonLexer
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 # churn.py - create a graph of revisions count grouped by template
Patrick Mezard
Make churn an official extension
r6348 #
# Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 # Copyright 2008 Alexander Solovyov <piranha@piranha.org.ua>
Patrick Mezard
Make churn an official extension
r6348 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Dirkjan Ochtman
help: better documentation intro for a few extensions
r7127 '''command to show certain statistics about revision history'''
Patrick Mezard
Make churn an official extension
r6348
Martin Geisler
i18n, churn: mark string for translation
r7051 from mercurial.i18n import _
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 from mercurial import patch, cmdutil, util, templater
Patrick Mezard
Make churn an official extension
r6348 import os, sys
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 import time, datetime
Patrick Mezard
Make churn an official extension
r6348
def get_tty_width():
if 'COLUMNS' in os.environ:
try:
return int(os.environ['COLUMNS'])
except ValueError:
pass
try:
import termios, array, fcntl
for dev in (sys.stdout, sys.stdin):
try:
fd = dev.fileno()
if not os.isatty(fd):
continue
arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
return array.array('h', arri)[1]
except ValueError:
pass
except ImportError:
pass
return 80
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 def maketemplater(ui, repo, tmpl):
tmpl = templater.parsestring(tmpl, quoted=False)
try:
t = cmdutil.changeset_templater(ui, repo, False, None, False)
except SyntaxError, inst:
raise util.Abort(inst.args[0])
t.use_template(tmpl)
return t
def changedlines(ui, repo, ctx1, ctx2):
lines = 0
ui.pushbuffer()
patch.diff(repo, ctx1.node(), ctx2.node())
diff = ui.popbuffer()
for l in diff.split('\n'):
if (l.startswith("+") and not l.startswith("+++ ") or
l.startswith("-") and not l.startswith("--- ")):
lines += 1
return lines
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 def countrate(ui, repo, amap, *pats, **opts):
"""Calculate stats"""
if opts.get('dateformat'):
def getkey(ctx):
t, tz = ctx.date()
date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
return date.strftime(opts['dateformat'])
else:
tmpl = opts.get('template', '{author|email}')
tmpl = maketemplater(ui, repo, tmpl)
def getkey(ctx):
ui.pushbuffer()
tmpl.show(changenode=ctx.node())
return ui.popbuffer()
count = pct = 0
rate = {}
df = False
if opts.get('date'):
df = util.matchdate(opts['date'])
get = util.cachefunc(lambda r: repo[r].changeset())
changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
for st, rev, fns in changeiter:
if not st == 'add':
continue
if df and not df(get(rev)[2][0]): # doesn't match date format
Patrick Mezard
Make churn an official extension
r6348 continue
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 ctx = repo[rev]
key = getkey(ctx)
key = amap.get(key, key) # alias remap
Alexander Solovyov
churn and stats commands merged
r7070 if opts.get('changesets'):
rate[key] = rate.get(key, 0) + 1
else:
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 parents = ctx.parents()
if len(parents) > 1:
ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,))
continue
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 ctx1 = parents[0]
lines = changedlines(ui, repo, ctx1, ctx)
rate[key] = rate.get(key, 0) + lines
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 if opts.get('progress'):
Matt Mackall
churn: major refactor...
r6759 count += 1
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 newpct = int(100.0 * count / max(len(repo), 1))
Matt Mackall
churn: major refactor...
r6759 if pct < newpct:
pct = newpct
Martin Geisler
i18n: mark strings for translation in churn extension
r6955 ui.write(_("\rGenerating stats: %d%%") % pct)
Patrick Mezard
Make churn an official extension
r6348 sys.stdout.flush()
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 if opts.get('progress'):
Patrick Mezard
Make churn an official extension
r6348 ui.write("\r")
sys.stdout.flush()
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 return rate
Alexander Solovyov
churn and stats commands merged
r7070 def churn(ui, repo, *pats, **opts):
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 '''Graph count of revisions grouped by template
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn and stats commands merged
r7070 Will graph count of changed lines or revisions grouped by template or
alternatively by date, if dateformat is used. In this case it will override
template.
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
Alexander Solovyov
churn and stats commands merged
r7070 By default statistics are counted for number of changed lines.
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
Examples:
Dirkjan Ochtman
convert comments to docstrings in a bunch of extensions
r6666
Alexander Solovyov
churn and stats commands merged
r7070 # display count of changed lines for every committer
hg churn -t '{author|email}'
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
# display daily activity graph
Alexander Solovyov
churn and stats commands merged
r7070 hg churn -f '%H' -s -c
Dirkjan Ochtman
convert comments to docstrings in a bunch of extensions
r6666
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 # display activity of developers by month
Alexander Solovyov
churn and stats commands merged
r7070 hg churn -f '%Y-%m' -s -c
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 # display count of lines changed in every year
Alexander Solovyov
churn and stats commands merged
r7070 hg churn -f '%Y' -s
The map file format used to specify aliases is fairly simple:
<alias email> <actual email>'''
Patrick Mezard
Make churn an official extension
r6348 def pad(s, l):
Matt Mackall
churn: major refactor...
r6759 return (s + " " * l)[:l]
Patrick Mezard
Make churn an official extension
r6348
amap = {}
aliases = opts.get('aliases')
if aliases:
Matt Mackall
churn: major refactor...
r6759 for l in open(aliases, "r"):
l = l.strip()
alias, actual = l.split()
amap[alias] = actual
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 rate = countrate(ui, repo, amap, *pats, **opts).items()
if not rate:
Patrick Mezard
Make churn an official extension
r6348 return
Alexander Solovyov
churn: py2.3 compatibility fix...
r7076 sortfn = ((not opts.get('sort')) and (lambda a, b: cmp(b[1], a[1])) or None)
rate.sort(sortfn)
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
Alexander Solovyov
churn: py2.3 compatibility fix...
r7076 maxcount = float(max([v for k, v in rate]))
maxname = max([len(k) for k, v in rate])
Patrick Mezard
Make churn an official extension
r6348
Matt Mackall
churn: major refactor...
r6759 ttywidth = get_tty_width()
ui.debug(_("assuming %i character terminal\n") % ttywidth)
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 width = ttywidth - maxname - 2 - 6 - 2 - 2
for date, count in rate:
print "%s %6d %s" % (pad(date, maxname), count,
"*" * int(count * width / maxcount))
Patrick Mezard
Make churn an official extension
r6348
cmdtable = {
Alexander Solovyov
churn and stats commands merged
r7070 "churn":
(churn,
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 [('r', 'rev', [], _('count rate for the specified revision or range')),
('d', 'date', '', _('count rate for revs matching date spec')),
('t', 'template', '{author|email}', _('template to group changesets')),
('f', 'dateformat', '',
_('strftime-compatible format for grouping by date')),
Alexander Solovyov
churn and stats commands merged
r7070 ('c', 'changesets', False, _('count rate by number of changesets')),
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 ('s', 'sort', False, _('sort by key (default: sort by count)')),
('', 'aliases', '', _('file with email aliases')),
('', 'progress', None, _('show progress'))],
Martin Geisler
churn: corrected help output
r7129 _("hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]")),
Patrick Mezard
Make churn an official extension
r6348 }