From: Brian Warner Date: Thu, 12 Feb 2009 02:40:50 +0000 (-0700) Subject: figleaf_htmlizer: rewrite in class form, behavior should be the same as before X-Git-Tag: allmydata-tahoe-1.3.0~24 X-Git-Url: https://git.rkrishnan.org/?a=commitdiff_plain;h=6bde1b0345293862af857edb101f864565109a8f;p=tahoe-lafs%2Ftahoe-lafs.git figleaf_htmlizer: rewrite in class form, behavior should be the same as before --- diff --git a/src/allmydata/util/figleaf_htmlizer.py b/src/allmydata/util/figleaf_htmlizer.py index 1709b45c..cf65963a 100644 --- a/src/allmydata/util/figleaf_htmlizer.py +++ b/src/allmydata/util/figleaf_htmlizer.py @@ -23,234 +23,234 @@ class RenderOptions(usage.Options): if filenames: self.filenames = list(filenames) -def read_exclude_patterns(f): - if not f: - return [] - exclude_patterns = [] - - fp = open(f) - for line in fp: - line = line.rstrip() - if line and not line.startswith('#'): - pattern = re.compile(line) - exclude_patterns.append(pattern) - - return exclude_patterns - -def report_as_html(coverage, directory, exclude_patterns=[], root=None): - ### now, output. - - keys = coverage.keys() - info_dict = {} - for k in keys: - skip = False - for pattern in exclude_patterns: - if pattern.search(k): - skip = True - break - - if skip: - continue - - if k.endswith('figleaf.py'): - continue - - display_filename = k - if root: - if not k.startswith(root): - continue - display_filename = k[len(root):] - assert not display_filename.startswith("/") - assert display_filename.endswith(".py") - display_filename = display_filename[:-3] # trim .py - display_filename = display_filename.replace("/", ".") +class Renderer: - if not k.startswith("/"): - continue + def run(self): + opts = RenderOptions() + opts.parseOptions() - try: - pyfile = open(k) - #print 'opened', k - except IOError: - continue - - try: - lines = figleaf.get_lines(pyfile) - except KeyboardInterrupt: - raise - except Exception, e: - pyfile.close() - continue + ### load - # ok, got all the info. now annotate file ==> html. + coverage = {} + for filename in opts.filenames: + d = figleaf.read_coverage(filename) + coverage = figleaf.combine_coverage(coverage, d) - covered = coverage[k] - n_covered = n_lines = 0 + if not coverage: + sys.exit(-1) - pyfile = open(k) - output = [] - for i, line in enumerate(pyfile): - is_covered = False - is_line = False + self.load_exclude_patterns(opts["exclude-patterns"]) + ### make directory + self.prepare_reportdir(opts["output-directory"]) + self.report_as_html(coverage, opts["output-directory"], opts["root"]) - i += 1 + def load_exclude_patterns(self, f): + self.exclude_patterns = [] + if not f: + return + for line in open(f, "r").readlines(): + line = line.rstrip() + if line and not line.startswith('#'): + self.exclude_patterns.append(re.compile(line)) - if i in covered: - is_covered = True - - n_covered += 1 - n_lines += 1 - elif i in lines: - is_line = True - - n_lines += 1 + def prepare_reportdir(self, dirname='html'): + try: + os.mkdir(dirname) + except OSError: # already exists + pass + + def report_as_html(self, coverage, directory, root=None): + ### now, output. + + keys = coverage.keys() + info_dict = {} + for k in keys: + skip = False + for pattern in self.exclude_patterns: + if pattern.search(k): + skip = True + break + + if skip: + continue - color = 'black' - if is_covered: - color = 'green' - elif is_line: - color = 'red' + if k.endswith('figleaf.py'): + continue - line = escape_html(line.rstrip()) - output.append('%4d. %s' % (color, i, line.rstrip())) + display_filename = k + if root: + if not k.startswith(root): + continue + display_filename = k[len(root):] + assert not display_filename.startswith("/") + assert display_filename.endswith(".py") + display_filename = display_filename[:-3] # trim .py + display_filename = display_filename.replace("/", ".") + + if not k.startswith("/"): + continue - try: - pcnt = n_covered * 100. / n_lines - except ZeroDivisionError: - pcnt = 0 - info_dict[k] = (n_lines, n_covered, pcnt, display_filename) - - html_outfile = make_html_filename(display_filename) - html_outfp = open(os.path.join(directory, html_outfile), 'w') - html_outfp.write('source file: %s
\n' % (k,)) - html_outfp.write('file stats: %d lines, %d executed: %.1f%% covered\n' % (n_lines, n_covered, pcnt)) - - html_outfp.write('
\n')
-        html_outfp.write("\n".join(output))
-        html_outfp.close()
-
-    ### print a summary, too.
-
-    info_dict_items = info_dict.items()
-
-    def sort_by_pcnt(a, b):
-        a = a[1][2]
-        b = b[1][2]
-        return -cmp(a,b)
-
-    def sort_by_uncovered(a, b):
-        a_uncovered = a[1][0] - a[1][1]
-        b_uncovered = b[1][0] - b[1][1]
-        return -cmp(a_uncovered, b_uncovered)
-
-    info_dict_items.sort(sort_by_uncovered)
-
-    summary_lines = sum([ v[0] for (k, v) in info_dict_items])
-    summary_cover = sum([ v[1] for (k, v) in info_dict_items])
-
-    summary_pcnt = 0
-    if summary_lines:
-        summary_pcnt = float(summary_cover) * 100. / float(summary_lines)
-
-
-    pcnts = [ float(v[1]) * 100. / float(v[0]) for (k, v) in info_dict_items if v[0] ]
-    pcnt_90 = [ x for x in pcnts if x >= 90 ]
-    pcnt_75 = [ x for x in pcnts if x >= 75 ]
-    pcnt_50 = [ x for x in pcnts if x >= 50 ]
-
-    stats_fp = open('%s/stats.out' % (directory,), 'w')
-    stats_fp.write("total files: %d\n" % len(pcnts))
-    stats_fp.write("total source lines: %d\n" % summary_lines)
-    stats_fp.write("total covered lines: %d\n" % summary_cover)
-    stats_fp.write("total uncovered lines: %d\n" %
-                   (summary_lines - summary_cover))
-    stats_fp.write("total coverage percentage: %.1f\n" % summary_pcnt)
-    stats_fp.close()
-
-    ## index.html
-    index_fp = open('%s/index.html' % (directory,), 'w')
-    # summary info
-    index_fp.write('figleaf code coverage report\n')
-    index_fp.write('

Summary

%d files total: %d files > ' - '90%%, %d files > 75%%, %d files > 50%%

' - % (len(pcnts), len(pcnt_90), - len(pcnt_75), len(pcnt_50))) - - def emit_table(items, show_totals): - index_fp.write('' - '' - '' - '\n') - if show_totals: - index_fp.write('' - '' - '' - '' - '' - '' - '\n' - % (summary_lines, summary_cover, - (summary_lines - summary_cover), - summary_pcnt,)) - - for filename, stuff in items: - (n_lines, n_covered, percent_covered, display_filename) = stuff - html_outfile = make_html_filename(display_filename) - - index_fp.write('' - '' - '\n' - % (html_outfile, display_filename, n_lines, - n_covered, (n_lines - n_covered), - percent_covered,)) - - index_fp.write('
Filename# lines# covered# uncovered% covered
totals:%d%d%d%.1f%%
%s%d%d%d%.1f
\n') - - # sorted by number of lines that aren't covered - index_fp.write('

Sorted by Lines Uncovered

\n') - emit_table(info_dict_items, True) - - # sorted by module name - index_fp.write('

Sorted by Module Name (alphabetical)

\n') - info_dict_items.sort() - emit_table(info_dict_items, False) - - index_fp.close() - - return len(info_dict) - -def prepare_reportdir(dirname='html'): - try: - os.mkdir(dirname) - except OSError: # already exists - pass - -def make_html_filename(orig): - return orig + ".html" - -def escape_html(s): - s = s.replace("&", "&") - s = s.replace("<", "<") - s = s.replace(">", ">") - s = s.replace('"', """) - return s + try: + pyfile = open(k) + #print 'opened', k + except IOError: + continue -def main(): - opts = RenderOptions() - opts.parseOptions() + try: + lines = figleaf.get_lines(pyfile) + except KeyboardInterrupt: + raise + except Exception, e: + pyfile.close() + continue - ### load + # ok, got all the info. now annotate file ==> html. - coverage = {} - for filename in opts.filenames: - d = figleaf.read_coverage(filename) - coverage = figleaf.combine_coverage(coverage, d) + covered = coverage[k] + n_covered = n_lines = 0 - if not coverage: - sys.exit(-1) + pyfile = open(k) + output = [] + for i, line in enumerate(pyfile): + is_covered = False + is_line = False + + i += 1 + + if i in covered: + is_covered = True + + n_covered += 1 + n_lines += 1 + elif i in lines: + is_line = True + + n_lines += 1 + + color = 'black' + if is_covered: + color = 'green' + elif is_line: + color = 'red' + + line = self.escape_html(line.rstrip()) + output.append('%4d. %s' % (color, i, line.rstrip())) + + try: + pcnt = n_covered * 100. / n_lines + except ZeroDivisionError: + pcnt = 0 + info_dict[k] = (n_lines, n_covered, pcnt, display_filename) + + html_outfile = self.make_html_filename(display_filename) + html_outfp = open(os.path.join(directory, html_outfile), 'w') + html_outfp.write('source file: %s
\n' % (k,)) + html_outfp.write('file stats: %d lines, %d executed: %.1f%% covered\n' % (n_lines, n_covered, pcnt)) + + html_outfp.write('
\n')
+            html_outfp.write("\n".join(output))
+            html_outfp.close()
+
+        ### print a summary, too.
+
+        info_dict_items = info_dict.items()
+
+        def sort_by_pcnt(a, b):
+            a = a[1][2]
+            b = b[1][2]
+            return -cmp(a,b)
+
+        def sort_by_uncovered(a, b):
+            a_uncovered = a[1][0] - a[1][1]
+            b_uncovered = b[1][0] - b[1][1]
+            return -cmp(a_uncovered, b_uncovered)
+
+        info_dict_items.sort(sort_by_uncovered)
+
+        summary_lines = sum([ v[0] for (k, v) in info_dict_items])
+        summary_cover = sum([ v[1] for (k, v) in info_dict_items])
+
+        summary_pcnt = 0
+        if summary_lines:
+            summary_pcnt = float(summary_cover) * 100. / float(summary_lines)
+
+
+        pcnts = [ float(v[1]) * 100. / float(v[0]) for (k, v) in info_dict_items if v[0] ]
+        pcnt_90 = [ x for x in pcnts if x >= 90 ]
+        pcnt_75 = [ x for x in pcnts if x >= 75 ]
+        pcnt_50 = [ x for x in pcnts if x >= 50 ]
+
+        stats_fp = open('%s/stats.out' % (directory,), 'w')
+        stats_fp.write("total files: %d\n" % len(pcnts))
+        stats_fp.write("total source lines: %d\n" % summary_lines)
+        stats_fp.write("total covered lines: %d\n" % summary_cover)
+        stats_fp.write("total uncovered lines: %d\n" %
+                       (summary_lines - summary_cover))
+        stats_fp.write("total coverage percentage: %.1f\n" % summary_pcnt)
+        stats_fp.close()
+
+        ## index.html
+        index_fp = open('%s/index.html' % (directory,), 'w')
+        # summary info
+        index_fp.write('figleaf code coverage report\n')
+        index_fp.write('

Summary

%d files total: %d files > ' + '90%%, %d files > 75%%, %d files > 50%%

' + % (len(pcnts), len(pcnt_90), + len(pcnt_75), len(pcnt_50))) + + def emit_table(items, show_totals): + index_fp.write('' + '' + '' + '\n') + if show_totals: + index_fp.write('' + '' + '' + '' + '' + '' + '\n' + % (summary_lines, summary_cover, + (summary_lines - summary_cover), + summary_pcnt,)) + + for filename, stuff in items: + (n_lines, n_covered, percent_covered, display_filename) = stuff + html_outfile = self.make_html_filename(display_filename) + + index_fp.write('' + '' + '\n' + % (html_outfile, display_filename, n_lines, + n_covered, (n_lines - n_covered), + percent_covered,)) + + index_fp.write('
Filename# lines# covered# uncovered% covered
totals:%d%d%d%.1f%%
%s%d%d%d%.1f
\n') + + # sorted by number of lines that aren't covered + index_fp.write('

Sorted by Lines Uncovered

\n') + emit_table(info_dict_items, True) + + # sorted by module name + index_fp.write('

Sorted by Module Name (alphabetical)

\n') + info_dict_items.sort() + emit_table(info_dict_items, False) + + index_fp.close() + + return len(info_dict) + + def make_html_filename(self, orig): + return orig + ".html" + + def escape_html(self, s): + s = s.replace("&", "&") + s = s.replace("<", "<") + s = s.replace(">", ">") + s = s.replace('"', """) + return s - ### make directory - prepare_reportdir(opts["output-directory"]) - report_as_html(coverage, opts["output-directory"], - read_exclude_patterns(opts["exclude-patterns"]), - opts["root"]) +def main(): + r = Renderer() + r.run()