only.
-D Rather than create the usual statistics, create a file (datelc.csv)
- providing lines changed per day, where the first column displays
- the changes happened only on that day and the second sums the day it
- happnened with the previous ones. This option is suitable for
- feeding to a tool like gnuplot.
+ providing lines changed per day, where the first column displays
+ the changes happened only on that day and the second sums the day it
+ happened with the previous ones. This option is suitable for
+ feeding to a tool like gnuplot.
-h file Generate HTML output to the given file
-l num Only list the top <num> entries in each report.
- -n Use --numstat instead of generated patches to get the statistics.
+ -n Use --numstat instead of generated patches to get the statistics.
-o file Write text output to the given file (default is stdout).
- -p prefix Dump out the database categorized by changeset and by file type.
- It requires -n, otherwise it is not possible to get separated results.
+ -p prefix Dump out the database categorized by changeset and by file type.
+ It requires -n, otherwise it is not possible to get separated results.
-r pat Only generate statistics for changes to files whose
name matches the given regular expression.
each patch.
-t Generate a report by type of contribution (code, documentation, etc.).
- It requires -n, otherwise this option is ignored silently.
+ It requires -n, otherwise this option is ignored silently.
-u Group all unknown developers under the "(Unknown)"
employer.
- -x file Export raw statistics as CSV.
+ -x file Export raw statistics as CSV.
- -w Aggregate the data by weeks instead of months in the
- CSV file when -x is used.
+ -w Aggregate the data by weeks instead of months in the
+ CSV file when -x is used.
-z Dump out the hacker database to "database.dump".
self.patches = [ ]
self.signoffs = [ ]
self.reviews = [ ]
+ self.acks = [ ]
self.tested = [ ]
self.reports = [ ]
self.testcred = self.repcred = 0
self.signoffs.append (patch)
def addreview (self, patch):
self.reviews.append (patch)
+ def addacked (self, patch):
+ self.acks.append (patch)
def addtested (self, patch):
self.tested.append (patch)
def addreport (self, patch):
# -D Output date statistics
# -h hfile HTML output to hfile
# -l count Maximum length for output lists
-# -n Use numstats instead of generated patch from git log
+# -n Use numstats instead of generated patch from git log
# -o file File for text output
-# -p prefix Prefix for CSV output
+# -p prefix Prefix for CSV output
# -r pattern Restrict to files matching pattern
# -s Ignore author SOB lines
# -u Map unknown employers to '(Unknown)'
# -U Dump unknown hackers in report
# -x file.csv Export raw statistics as CSV
-# -w Aggregrate the raw statistics by weeks instead of months
+# -w Aggregrate the raw statistics by weeks instead of months
# -y Aggregrate the raw statistics by years instead of months
# -z Dump out the hacker database at completion
self.email = 'unknown@hacker.net'
self.sobs = [ ]
self.reviews = [ ]
+ self.acks = [ ]
self.testers = [ ]
self.reports = [ ]
self.filetypes = {}
def addreviewer (self, reviewer):
self.reviews.append (reviewer)
+ def addacker (self, reviewer):
+ self.acks.append (reviewer)
+
def addtester (self, tester):
self.testers.append (tester)
#
# Various other tags of interest.
#
+
+ # Reviewed-by:
m = patterns['reviewed-by'].match (Line)
if m:
email = database.RemapEmail (m.group (2))
p.addreviewer (LookupStoreHacker(m.group (1), email))
continue
+ # Acked-by:
+ m = patterns['acked-by'].match (Line)
+ if m:
+ email = database.RemapEmail (m.group (2))
+ p.addacker (LookupStoreHacker(m.group (1), email))
+ continue
+ # Tested-by:
m = patterns['tested-by'].match (Line)
if m:
email = database.RemapEmail (m.group (2))
sob.addsob (p)
for hacker in p.reviews:
hacker.addreview (p)
+ for hacker in p.acks:
+ # An ACK also counts as a review
+ # (but there is no easy way to not double count, if there are both)
+ hacker.addacked (p)
+ hacker.addreview (p)
for hacker in p.testers:
hacker.addtested (p)
for hacker in p.reports:
'filea': re.compile (r'^---\s+(.*)$'),
'fileb': re.compile (r'^\+\+\+\s+(.*)$'),
'reviewed-by': re.compile (r'^\s+Reviewed-by:' + _pemail+ '.*$'),
+ 'acked-by': re.compile (r'^\s+Acked-by:' + _pemail+ '.*$'),
'tested-by': re.compile (r'^\s+tested-by:' + _pemail + '.*$', re.I),
'reported-by': re.compile (r'^\s+Reported-by:' + _pemail + '.*$'),
'reported-and-tested-by': re.compile (r'^\s+reported-and-tested-by:' + _pemail + '.*$', re.I),
for h in hlist:
totalrevs += len (h.reviews)
count = 0
- BeginReport ('Developers with the most reviews (total %d)' % totalrevs)
+ BeginReport ('Developers with the most reviews, including ACKs (total %d)' % totalrevs)
for h in hlist:
scount = len (h.reviews)
if scount > 0:
break
EndReport ()
+def CompareAcks (h1, h2):
+ return len (h2.acks) - len (h1.acks)
+
+def ReportByAcks (hlist):
+ hlist.sort (CompareAcks)
+ totalacks = 0
+ for h in hlist:
+ totalacks += len (h.acks)
+ count = 0
+ BeginReport ('Developers with the most ACKs (total %d)' % totalacks)
+ for h in hlist:
+ scount = len (h.acks)
+ if scount > 0:
+ ReportLine (h.name, scount, (scount*100.0)/totalacks)
+ count += 1
+ if count >= ListCount:
+ break
+ EndReport ()
+
#
# tester reporting.
#
ReportByLRemoved (hlist, totalremoved)
ReportBySOBs (hlist)
ReportByRevs (hlist)
+ ReportByAcks (hlist)
ReportByTests (hlist)
ReportByTestCreds (hlist)
ReportByReports (hlist)