#!/usr/bin/python # # by Erik Osheim # # available under the GNU GPL version 2. # # This program is designed to provide analysis of patches or diff files. import optparse import re import sys # matches the diff stanza, which have no leading identifier diff_re = re.compile('^[0-9a-zA-Z,]+$') # analyze a particular patch, which is assumed to contain multiple files def info(f, verbose=False): paths = [] l = 0 first = True for line in f: if first: if diff_re.match(line): paths.append(['-', 0, 0, 0, 0]) first = False if diff_re.match(line): if not paths: paths.append(['-', 0, 0, 0, 0]) paths[-1][1] += 1 elif line.startswith('diff'): path = line.split()[-1] l = max(l, len(path)) paths.append([path, 0, 0, 0, 0]) elif line.startswith('Index'): path = line.split()[1] l = max(l, len(path)) paths.append([path, 0, 0, 0, 0]) elif line.startswith('---') or line.startswith('+++') or line.startswith('='): pass elif line.startswith('@@'): paths[-1][1] += 1 elif line.startswith('+') or line.startswith('>'): paths[-1][2] += 1 paths[-1][3] += 1 elif line.startswith('-') or line.startswith('<'): paths[-1][2] -= 1 paths[-1][4] += 1 if len(paths) != 1: title = '%d paths' % len(paths) else: title = '1 path' if verbose: title = 'TOTAL ' + title else: l = len(title) totals = [0, 0, 0, 0] for info in paths: for i in range(0, 4): totals[i] += info[i + 1] lens = [len(str(n)) + 1 for n in totals[:2]] fmt = '%%-%ds %%%dd groups, %%+%dd lines (+%%d -%%d)' % tuple([l] + lens) for info in paths: if verbose: print fmt % tuple(info) print fmt % tuple([title] + totals) if __name__ == "__main__": op = optparse.OptionParser() op.add_option('-v', '--verbose', dest='verbose', action='store_true') opts, args = op.parse_args() if args: for arg in args: info(open(arg, 'r'), verbose=opts.verbose) else: info(sys.stdin, verbose=opts.verbose)