
This is the result of running 2to3 and manually converting the comparison functions to lambda expressions.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com
Hello Tom,
which is the branch that you use for the gitdm U-Boot stats? Is it master or u-boot? If it is u-boot, please, update gitlab to make u-boot the main branch.
The current patch applies to the master branch.
Best regards
Heinrich
ConfigFile.py | 4 +- csvdump.py | 4 +- database.py | 22 +++++------ gitdm | 27 ++++++------- gitlog.py | 8 ++-- logparser.py | 6 +-- reports.py | 106 +++++++++++++++----------------------------------- utils.py | 4 +- 8 files changed, 70 insertions(+), 111 deletions(-)
diff --git a/ConfigFile.py b/ConfigFile.py index 3a1e208..e58c601 100644 --- a/ConfigFile.py +++ b/ConfigFile.py @@ -147,10 +147,10 @@ def ReadFileType (filename): m = regex_file_type.match (line) if not m or len (m.groups ()) != 2: ConfigFile.croak ('Funky file type line "%s"' % (line))
if not patterns.has_key (m.group (1)):
if m.group (1) not in patterns: patterns[m.group (1)] = [] if m.group (1) not in order:
print '%s not found, appended to the last order' % m.group (1)
print('%s not found, appended to the last order' % m.group (1)) order.append (m.group (1)) patterns[m.group (1)].append (re.compile (m.group (2), re.IGNORECASE))
diff --git a/csvdump.py b/csvdump.py index 9d1a65e..55e38a0 100644 --- a/csvdump.py +++ b/csvdump.py @@ -50,7 +50,7 @@ def store_patch(patch): ChangeSets.append([patch.commit, str(patch.date), patch.email, domain, author, employer, patch.added, patch.removed])
for (filetype, (added, removed)) in patch.filetypes.iteritems():
for (filetype, (added, removed)) in patch.filetypes.items(): FileTypes.append([patch.commit, filetype, added, removed])
@@ -82,7 +82,7 @@ def OutputCSV (file): writer = csv.writer (file, quoting=csv.QUOTE_NONNUMERIC) writer.writerow (['Name', 'Email', 'Affliation', 'Date', 'Added', 'Removed', 'Changesets'])
- for date, stat in PeriodCommitHash.items():
- for date, stat in list(PeriodCommitHash.items()): # sanitise names " is common and " sometimes too empl_name = stat.employer.name.replace ('"', '.').replace ('\', '.') author_name = stat.name.replace ('"', '.').replace ('\', '.')
diff --git a/database.py b/database.py index bf13227..b267ed5 100644 --- a/database.py +++ b/database.py @@ -40,7 +40,7 @@ class Hacker: for edate, empl in self.employer[i]: if edate > date: return empl
print 'OOPS. ', self.name, self.employer, self.email, email, date
print('OOPS. ', self.name, self.employer, self.email, email, date) return None # Should not happen def addpatch (self, patch):
@@ -124,11 +124,11 @@ def LookupStoreHacker(name, email, mapunknown = True):
def AllHackers ():
- return HackersByID.values ()
return list(HackersByID.values ())
def DumpDB (): out = open ('database.dump', 'w')
- names = HackersByName.keys ()
- names = list(HackersByName.keys ()) names.sort () for name in names: h = HackersByName[name]
@@ -149,7 +149,7 @@ def DumpDB (): # push it backward through the changes we've already seen. # def ApplyFirstTag (tag):
- for n in HackersByName.keys ():
- for n in list(HackersByName.keys ()): if HackersByName[n].versions: HackersByName[n].versions = [tag]
@@ -185,7 +185,7 @@ def GetEmployer (name): return e
def AllEmployers ():
- return Employers.values ()
return list(Employers.values ())
# # Certain obnoxious developers, who will remain nameless (because we
@@ -215,8 +215,8 @@ class VirtualEmployer (Employer): self.__init__ (name) # Reset counts just in case
def store (self):
if Employers.has_key (self.name):
print Employers[self.name]
if self.name in Employers:
print(Employers[self.name]) sys.stderr.write ('WARNING: Virtual empl %s overwrites another\n' % (self.name)) if len (self.splits) == 0:
@@ -235,7 +235,7 @@ class FileType: order = order or self.order
for file_type in order:
if patterns.has_key (file_type):
if file_type in patterns: for patt in patterns[file_type]: if patt.search (filename): return file_type
@@ -261,7 +261,7 @@ def MixVirtuals (): EmailAliases = { }
def AddEmailAlias (variant, canonical):
- if EmailAliases.has_key (variant):
- if variant in EmailAliases: sys.stderr.write ('Duplicate email alias for %s\n' % (variant)) EmailAliases[variant] = canonical
@@ -288,7 +288,7 @@ def AddEmailEmployerMapping (email, employer, end = nextyear): for i in range (0, len(l)): date, xempl = l[i] if date == end: # probably both nextyear
print 'WARNING: duplicate email/empl for %s' % (email)
print('WARNING: duplicate email/empl for %s' % (email)) if date > end: l.insert (i, (end, empl)) return
@@ -305,7 +305,7 @@ def MapToEmployer (email, unknown = 0): pass namedom = email.split ('@') if len (namedom) < 2:
print 'Oops...funky email %s' % email
print('Oops...funky email %s' % email) return [(nextyear, GetEmployer ('Funky'))] s = namedom[1].split ('.') for dots in range (len (s) - 2, -1, -1):
diff --git a/gitdm b/gitdm index 61318ad..f426cc7 100755 --- a/gitdm +++ b/gitdm @@ -1,4 +1,4 @@ -#!/usr/bin/pypy +#!/usr/bin/python3 #-*- coding:utf-8 -*- #
@@ -15,7 +15,8 @@
import database, csvdump, ConfigFile, reports import getopt, datetime -import os, re, sys, rfc822, string, os.path +from email.utils import parsedate_tz +import os, re, sys, string, os.path import logparser from patterns import patterns
@@ -108,7 +109,7 @@ def ParseOpts(): elif opt[0] == '-p': CSVPrefix = opt[1] elif opt[0] == '-r':
print 'Filter on "%s"' % (opt[1])
print('Filter on "%s"' % (opt[1])) FileFilter = re.compile(opt[1]) elif opt[0] == '-s': AuthorSOBs = 0
@@ -120,7 +121,7 @@ def ParseOpts(): ReportUnknowns = True elif opt[0] == '-x': CSVFile = open(opt[1], 'w')
print "open output file " + opt[1] + "\n"
print("open output file " + opt[1] + "\n") elif opt [0] == '-w': Aggregate = 'week' elif opt [0] == '-y':
@@ -172,7 +173,7 @@ DateMap = { }
def AddDateLines(date, lines): if lines > 1000000:
print 'Skip big patch (%d)' % lines
print('Skip big patch (%d)' % lines) return try: DateMap[date] += lines
@@ -180,7 +181,7 @@ def AddDateLines(date, lines): DateMap[date] = lines
def PrintDateStats():
- dates = DateMap.keys()
- dates = list(DateMap.keys()) dates.sort() total = 0 datef = open('datelc.csv', 'w')
@@ -195,7 +196,7 @@ def PrintDateStats(): # Let's slowly try to move some smarts into this class. # class patch:
- (ADDED, REMOVED) = range(2)
(ADDED, REMOVED) = list(range(2))
def __init__(self, commit): self.commit = commit
@@ -219,7 +220,7 @@ class patch: self.reports.append(reporter)
def addfiletype(self, filetype, added, removed):
if self.filetypes.has_key(filetype):
if filetype in self.filetypes: self.filetypes[filetype][self.ADDED] += added self.filetypes[filetype][self.REMOVED] += removed else:
@@ -330,7 +331,7 @@ def grabpatch(logpatch): # m = patterns['date'].match(Line) if m:
dt = rfc822.parsedate(m.group(2))
dt = parsedate_tz(m.group(2)) p.date = datetime.date(dt[0], dt[1], dt[2]) if p.date > Today: sys.stderr.write('Funky date: %s\n' % p.date)
@@ -389,7 +390,7 @@ def GripeAboutAuthorName(name): if name in GripedAuthorNames: return GripedAuthorNames.append(name)
- print '%s is an author name, probably not what you want' % (name)
print('%s is an author name, probably not what you want' % (name))
def ApplyFileFilter(line, ignore): #
@@ -462,14 +463,14 @@ TotalChanged = TotalAdded = TotalRemoved = 0 # # Snarf changesets. # -print >> sys.stderr, 'Grabbing changesets...\r', +print('Grabbing changesets...\r', end=' ', file=sys.stderr)
patches = logparser.LogPatchSplitter(sys.stdin) printcount = CSCount = 0
for logpatch in patches: if (printcount % 50) == 0:
print >> sys.stderr, 'Grabbing changesets...%d\r' % printcount,
print('Grabbing changesets...%d\r' % printcount, end=' ', file=sys.stderr) printcount += 1 # We want to ignore commits on svn tags since in Subversion
@@ -528,7 +529,7 @@ for logpatch in patches: CSCount += 1 csvdump.AccumulatePatch(p, Aggregate) csvdump.store_patch(p) -print >> sys.stderr, 'Grabbing changesets...done ' +print('Grabbing changesets...done ', file=sys.stderr)
if DumpDB: database.DumpDB() diff --git a/gitlog.py b/gitlog.py index 71efee1..4b1c5d6 100644 --- a/gitlog.py +++ b/gitlog.py @@ -61,7 +61,7 @@ S_DONE = 5 def get_header(patch, line, input): if line == '': if patch.author == '':
print 'Funky auth line in', patch.commit
print('Funky auth line in', patch.commit) patch.author = database.LookupStoreHacker('Unknown', 'unknown@hacker.net') return S_DESC
@@ -78,7 +78,7 @@ def get_header(patch, line, input):
def get_desc(patch, line, input): if not line:
print 'Missing desc in', patch.commit
print('Missing desc in', patch.commit) return S_CHANGELOG patch.desc = line line = getline(input)
@@ -188,7 +188,7 @@ def grabpatch(input): return None m = patterns['commit'].match(line) if not m:
print 'noncommit', line
print('noncommit', line) return None p = patch(m.group(1)) state = S_HEADER
@@ -199,7 +199,7 @@ def grabpatch(input): line = getline(input) if line is None: if state != S_NUMSTAT:
print 'Ran out of patch', state
print('Ran out of patch', state) return None return p state = grabbers[state](p, line, input)
diff --git a/logparser.py b/logparser.py index b375034..88293c5 100644 --- a/logparser.py +++ b/logparser.py @@ -41,7 +41,7 @@ class LogPatchSplitter: def __iter__(self): return self
- def next(self):
- def __next__(self): patch = self.__grab_patch__() if not patch: raise StopIteration
@@ -85,6 +85,6 @@ if __name__ == '__main__': patches = LogPatchSplitter(sys.stdin)
for patch in patches:
print '---------- NEW PATCH ----------'
print('---------- NEW PATCH ----------') for line in patch:
print line,
print(line, end=' ')
diff --git a/reports.py b/reports.py index d7a96bc..3e03e69 100644 --- a/reports.py +++ b/reports.py @@ -69,11 +69,8 @@ def EndReport(): # # Comparison and report generation functions. # -def ComparePCount(h1, h2):
- return len(h2.patches) - len(h1.patches)
- def ReportByPCount(hlist, cscount):
- hlist.sort(ComparePCount)
- hlist.sort(key=lambda h: -len(h.patches)) count = 0 BeginReport('Developers with the most changesets') for h in hlist:
@@ -87,11 +84,8 @@ def ReportByPCount(hlist, cscount): break EndReport()
-def CompareLChanged(h1, h2):
- return h2.changed - h1.changed
- def ReportByLChanged(hlist, totalchanged):
- hlist.sort(CompareLChanged)
- hlist.sort(key=lambda h: -h.changed) count = 0 BeginReport('Developers with the most changed lines') for h in hlist:
@@ -103,11 +97,8 @@ def ReportByLChanged(hlist, totalchanged): break EndReport()
-def CompareLRemoved(h1, h2):
- return (h2.removed - h2.added) - (h1.removed - h1.added)
- def ReportByLRemoved(hlist, totalremoved):
- hlist.sort(CompareLRemoved)
- hlist.sort(key=lambda h: h.added - h.removed) count = 0 BeginReport('Developers with the most lines removed') for h in hlist:
@@ -121,11 +112,8 @@ def ReportByLRemoved(hlist, totalremoved): break EndReport()
-def CompareEPCount(e1, e2):
- return e2.count - e1.count
- def ReportByPCEmpl(elist, cscount):
- elist.sort(CompareEPCount)
- elist.sort(key=lambda e: -e.count) count = 0 BeginReport('Top changeset contributors by employer') for e in elist:
@@ -137,11 +125,8 @@ def ReportByPCEmpl(elist, cscount): EndReport()
-def CompareELChanged(e1, e2):
- return e2.changed - e1.changed
- def ReportByELChanged(elist, totalchanged):
- elist.sort(CompareELChanged)
- elist.sort(key=lambda e: -e.changed) count = 0 BeginReport('Top lines changed by employer') for e in elist:
@@ -154,11 +139,8 @@ def ReportByELChanged(elist, totalchanged):
-def CompareSOBs(h1, h2):
- return len(h2.signoffs) - len(h1.signoffs)
- def ReportBySOBs(hlist):
- hlist.sort(CompareSOBs)
- hlist.sort(key = lambda h: -len(h.signoffs)) totalsobs = 0 for h in hlist: totalsobs += len(h.signoffs)
@@ -176,11 +158,8 @@ def ReportBySOBs(hlist): # # Reviewer reporting. # -def CompareRevs(h1, h2):
- return len(h2.reviews) - len(h1.reviews)
- def ReportByRevs(hlist):
- hlist.sort(CompareRevs)
- hlist.sort(key=lambda h: -len(h.reviews)) totalrevs = 0 for h in hlist: totalrevs += len(h.reviews)
@@ -198,11 +177,8 @@ def ReportByRevs(hlist): # # tester reporting. # -def CompareTests(h1, h2):
- return len(h2.tested) - len(h1.tested)
- def ReportByTests(hlist):
- hlist.sort(CompareTests)
- hlist.sort(key=lambda h: -len(h.tested)) totaltests = 0 for h in hlist: totaltests += len(h.tested)
@@ -217,11 +193,8 @@ def ReportByTests(hlist): break EndReport()
-def CompareTestCred(h1, h2):
- return h2.testcred - h1.testcred
- def ReportByTestCreds(hlist):
- hlist.sort(CompareTestCred)
- hlist.sort(key=lambda h: -h.testcred) totaltests = 0 for h in hlist: totaltests += h.testcred
@@ -240,11 +213,8 @@ def ReportByTestCreds(hlist): # # Reporter reporting. # -def CompareReports(h1, h2):
- return len(h2.reports) - len(h1.reports)
- def ReportByReports(hlist):
- hlist.sort(CompareReports)
- hlist.sort(key=lambda h: -len(h.reports)) totalreps = 0 for h in hlist: totalreps += len(h.reports)
@@ -259,11 +229,8 @@ def ReportByReports(hlist): break EndReport()
-def CompareRepCred(h1, h2):
- return h2.repcred - h1.repcred
- def ReportByRepCreds(hlist):
- hlist.sort(CompareRepCred)
- hlist.sort(key=lambda h: -h.repcred) totalreps = 0 for h in hlist: totalreps += h.repcred
@@ -280,14 +247,11 @@ def ReportByRepCreds(hlist): # # Versions. # -def CompareVersionCounts(h1, h2):
- if h1.versions and h2.versions:
return len(h2.versions) - len(h1.versions)
- if h2.versions:
return 1
- if h1.versions:
return -1
- return 0
+def VersionCount(h):
if h.versions:
return len(h.versions)
else:
return 0
def MissedVersions(hv, allv): missed = [v for v in allv if v not in hv]
@@ -295,7 +259,7 @@ def MissedVersions(hv, allv): return ' '.join(missed)
def ReportVersions(hlist):
- hlist.sort(CompareVersionCounts)
- hlist.sort(key=lambda h: -VersionCount(h)) BeginReport('Developers represented in the most kernel versions') count = 0 allversions = hlist[0].versions
@@ -307,11 +271,8 @@ def ReportVersions(hlist): EndReport()
-def CompareESOBs(e1, e2):
- return e2.sobs - e1.sobs
- def ReportByESOBs(elist):
- elist.sort(CompareESOBs)
- elist.sort(key=lambda e: -e.sobs) totalsobs = 0 for e in elist: totalsobs += e.sobs
@@ -325,11 +286,8 @@ def ReportByESOBs(elist): break EndReport()
-def CompareHackers(e1, e2):
- return len(e2.hackers) - len(e1.hackers)
- def ReportByEHackers(elist):
- elist.sort(CompareHackers)
- elist.sort(key=lambda e: -len(e.hackers)) totalhackers = 0 for e in elist: totalhackers += len(e.hackers)
@@ -375,7 +333,7 @@ def ReportUnknowns(hlist, cscount): # mapping to (Unknown) is happening or not. # ulist = [ h for h in hlist if IsUnknown(h) ]
- ulist.sort(ComparePCount)
- ulist.sort(lambda h: len(h.patches)) count = 0 BeginReport('Developers with unknown affiliation') for h in ulist:
@@ -398,46 +356,46 @@ def ReportByFileType(hacker_list): by_hacker = {} for patch in h.patches: # Get a summary by hacker
for (filetype, (added, removed)) in patch.filetypes.iteritems():
if by_hacker.has_key(filetype):
for (filetype, (added, removed)) in patch.filetypes.items():
if filetype in by_hacker: by_hacker[filetype][patch.ADDED] += added by_hacker[filetype][patch.REMOVED] += removed else: by_hacker[filetype] = [added, removed] # Update the totals
if total.has_key(filetype):
if filetype in total: total[filetype][patch.ADDED] += added total[filetype][patch.REMOVED] += removed else: total[filetype] = [added, removed, []] # Print a summary by hacker
print h.name
for filetype, counters in by_hacker.iteritems():
print '\t', filetype, counters
print(h.name)
for filetype, counters in by_hacker.items():
print('\t', filetype, counters) h_added = by_hacker[filetype][patch.ADDED] h_removed = by_hacker[filetype][patch.REMOVED] total[filetype][2].append([h.name, h_added, h_removed]) # Print the global summary BeginReport('Contributions by type and developers')
- for filetype, (added, removed, hackers) in total.iteritems():
print filetype, added, removed
- for filetype, (added, removed, hackers) in total.items():
print(filetype, added, removed) for h, h_added, h_removed in hackers:
print '\t%s: [%d, %d]' % (h, h_added, h_removed)
print('\t%s: [%d, %d]' % (h, h_added, h_removed)) # Print the very global summary BeginReport('General contributions by type')
- for filetype, (added, removed, hackers) in total.iteritems():
print filetype, added, removed
for filetype, (added, removed, hackers) in total.items():
print(filetype, added, removed)
# # The file access report is a special beast. # def FileAccessReport(name, accesses, total): outf = open(name, 'w')
- files = accesses.keys()
- files = list(accesses.keys()) files.sort() for file in files: a = accesses[file]
diff --git a/utils.py b/utils.py index 2b3be5d..9f17911 100644 --- a/utils.py +++ b/utils.py @@ -21,7 +21,7 @@ class accumulator: return default
def append(self, key, item, unique = False):
if unique and self._data.has_key(key) and \
if unique and key in self._data and \ item in self._data[key]: return try:
@@ -30,7 +30,7 @@ class accumulator: self._data[key] = [item]
def keys(self):
return self._data.keys()
return list(self._data.keys()) def __getitem__(self, key): return self._data[key]