]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - misc/coverage2text.py
code coverage: replace figleaf with coverage.py, should work on py2.6 now.
[tahoe-lafs/tahoe-lafs.git] / misc / coverage2text.py
1
2 import sys
3 from coverage import coverage
4 from coverage.results import Numbers
5 from coverage.summary import SummaryReporter
6 from twisted.python import usage
7
8 # this is an adaptation of the code behind "coverage report", modified to
9 # display+sortby "lines uncovered", which (IMHO) is more important of a
10 # metric than lines covered or percentage covered. Concentrating on the files
11 # with the most uncovered lines encourages getting the tree and test suite
12 # into a state that provides full line-coverage on all files.
13
14 # much of this code was adapted from coverage/summary.py in the 'coverage'
15 # distribution, and is used under their BSD license.
16
17 class Options(usage.Options):
18     optParameters = [
19         ("sortby", "s", "uncovered", "how to sort: uncovered, covered, name"),
20         ]
21
22 class MyReporter(SummaryReporter):
23     def report(self, outfile=None, sortby="uncovered"):
24         self.find_code_units(None, ["/System", "/Library", "/usr/lib",
25                                     "support/lib", "src/allmydata/test"])
26
27         # Prepare the formatting strings
28         max_name = max([len(cu.name) for cu in self.code_units] + [5])
29         fmt_name = "%%- %ds  " % max_name
30         fmt_err = "%s   %s: %s\n"
31         header1 = (fmt_name % ""    ) + "     Statements    "
32         header2 = (fmt_name % "Name") + " Uncovered  Covered"
33         fmt_coverage = fmt_name + "%9d  %7d "
34         if self.branches:
35             header1 += "   Branches   "
36             header2 += " Found  Excutd"
37             fmt_coverage += " %6d %6d"
38         header1 += "  Percent"
39         header2 += "  Covered"
40         fmt_coverage += " %7d%%"
41         if self.show_missing:
42             header1 += "          "
43             header2 += "   Missing"
44             fmt_coverage += "   %s"
45         rule = "-" * len(header1) + "\n"
46         header1 += "\n"
47         header2 += "\n"
48         fmt_coverage += "\n"
49
50         if not outfile:
51             outfile = sys.stdout
52
53         # Write the header
54         outfile.write(header1)
55         outfile.write(header2)
56         outfile.write(rule)
57
58         total = Numbers()
59         total_uncovered = 0
60
61         lines = []
62         for cu in self.code_units:
63             try:
64                 analysis = self.coverage._analyze(cu)
65                 nums = analysis.numbers
66                 uncovered = nums.n_statements - nums.n_executed
67                 total_uncovered += uncovered
68                 args = (cu.name, uncovered, nums.n_executed)
69                 if self.branches:
70                     args += (nums.n_branches, nums.n_executed_branches)
71                 args += (nums.pc_covered,)
72                 if self.show_missing:
73                     args += (analysis.missing_formatted(),)
74                 if sortby == "covered":
75                     sortkey = nums.pc_covered
76                 elif sortby == "uncovered":
77                     sortkey = uncovered
78                 else:
79                     sortkey = cu.name
80                 lines.append((sortkey, fmt_coverage % args))
81                 total += nums
82             except KeyboardInterrupt:                       # pragma: no cover
83                 raise
84             except:
85                 if not self.ignore_errors:
86                     typ, msg = sys.exc_info()[:2]
87                     outfile.write(fmt_err % (cu.name, typ.__name__, msg))
88         lines.sort()
89         if sortby in ("uncovered", "covered"):
90             lines.reverse()
91         for sortkey,line in lines:
92             outfile.write(line)
93
94         if total.n_files > 1:
95             outfile.write(rule)
96             args = ("TOTAL", total_uncovered, total.n_executed)
97             if self.branches:
98                 args += (total.n_branches, total.n_executed_branches)
99             args += (total.pc_covered,)
100             if self.show_missing:
101                 args += ("",)
102             outfile.write(fmt_coverage % args)
103
104 def report(o):
105     c = coverage()
106     c.load()
107     r = MyReporter(c, show_missing=False, ignore_errors=False)
108     r.report(sortby=o['sortby'])
109
110 if __name__ == '__main__':
111     o = Options()
112     o.parseOptions()
113     report(o)
114
115
116