#!/usr/bin/pypy # -*- python -*- # # Crank through the log looking at when developers did their first and # last patches. # # git log | firstlast -v versiondb # import argparse, pickle import sys import gitlog import database import ConfigFile # # Arg processing # def SetupArgs(): p = argparse.ArgumentParser() p.add_argument('-v', '--versiondb', help = 'Version database file', required = False, default = 'committags.db') p.add_argument('-c', '--config', help = 'Configuration file', required = True) p.add_argument('-d', '--dbdir', help = 'Where to find the config database files', required = False, default = '') p.add_argument('-f', '--first', help = 'First version for detailed tracking', required = False, default = '') p.add_argument('-l', '--last', help = 'Last version for detailed tracking', required = False, default = '') return p.parse_args() # # Try to track the first directory a new developer touches. # FirstDirs = { } def TrackFirstDirs(patch): dirs = [ ] for file in patch.files: split = file.split('/') if split[0] in ['arch', 'drivers', 'fs']: track = '/'.join(split[0:2]) else: track = split[0] if track not in dirs: dirs.append(track) for dir in dirs: try: FirstDirs[dir] += 1 except KeyError: FirstDirs[dir] = 1 def cmpdirs(d1, d2): return FirstDirs[d2] - FirstDirs[d1] def PrintFirstDirs(): dirs = FirstDirs.keys() dirs.sort(cmpdirs) for dir in dirs[:20]: print '%5d: %s' % (FirstDirs[dir], dir) # # Let's also track who they worked for. # FirstEmpls = { } def TrackFirstEmpl(name): try: FirstEmpls[name] += 1 except KeyError: FirstEmpls[name] = 1 def cmpempls(e1, e2): return FirstEmpls[e2] - FirstEmpls[e1] def PrintFirstEmpls(): empls = FirstEmpls.keys() empls.sort(cmpempls) print '\nEmployers:' for e in empls[:20]: print '%5d: %s' % (FirstEmpls[e], e) # # Version comparison stuff. Kernel-specific, obviously. # def die(gripe): sys.stderr.write(gripe + '\n') sys.exit(1) def versionmap(vers): split = vers.split('.') if not (2 <= len(split) <= 3): die('funky version %s' % (vers)) if split[0] in ['v2', '2']: return int(split[2]) if split[0] in ['v3', '3']: return 100 + int(split[1]) die('Funky version %s' % (vers)) T_First = 0 T_Last = 999999 def SetTrackingVersions(args): global T_First, T_Last if args.first: T_First = versionmap(args.first) if args.last: T_Last = versionmap(args.last) def TrackingVersion(vers): return T_First <= versionmap(vers) <= T_Last # # Main program. # args = SetupArgs() VDB = pickle.load(open(args.versiondb, 'r')) ConfigFile.ConfigFile(args.config, args.dbdir) SetTrackingVersions(args) Firsts = { } Lasts = { } patch = gitlog.grabpatch(sys.stdin) while patch: try: v = VDB[patch.commit] except KeyError: print 'Funky commit', patch.commit continue try: x = patch.author.patches except AttributeError: print 'Attr err', patch.commit continue # # The first patch we see is the last they committed, since git # lists things in backwards order. # if len(patch.author.patches) == 0: patch.author.lastvers = v try: Lasts[v].append(patch.author) except KeyError: Lasts[v] = [patch.author] patch.author.firstvers = v patch.author.addpatch(patch) patch = gitlog.grabpatch(sys.stdin) for h in database.AllHackers(): if len(h.patches) > 0: try: Firsts[h.firstvers].append(h) except KeyError: Firsts[h.firstvers] = [h] # # Track details, but only for versions we care about # if TrackingVersion(h.firstvers): p = h.patches[-1] TrackFirstDirs(p) empl = h.emailemployer(p.email, p.date) TrackFirstEmpl(empl.name) for v in Lasts.keys(): print v, len(Firsts[v]), len(Lasts[v]) PrintFirstDirs() PrintFirstEmpls()