4 This produces structured analysis results:
5 It takes the JSON input produced by make_report.py
6 and applies the limits specifiec in --limitfile.
7 It then prints a summary and exits with 0 if all warning
8 categories are below their limits, or 1 if any of the
17 from fnmatch
import fnmatch
19 from tabulate
import tabulate
20 from operator
import itemgetter
22 if sys.stdout.encoding !=
'UTF-8':
23 sys.stdout = codecs.getwriter(
'utf-8')(sys.stdout.buffer,
'strict')
24 if sys.stderr.encoding !=
'UTF-8':
25 sys.stderr = codecs.getwriter(
'utf-8')(sys.stderr.buffer,
'strict')
27 from codereport
import CodeReport, ReportItem
31 def analysis(limitfile, results, verbose=False, md=False):
45 CROSS_SYMBOL =
"\u2716"
46 CHECK_SYMBOL =
"\u2714"
48 CROSS_SYMBOL =
"\u274C"
49 CHECK_SYMBOL =
"\u2705"
53 if sys.stdout.isatty():
54 return attr+s+bcolors.ENDC
59 return colored(s, bcolors.OKGREEN)
61 return colored(s, bcolors.WARNING)
63 return colored(s, bcolors.FAIL)
65 with
open(limitfile,
"r") as f:
71 for key
in config[
"limits"]:
72 limit = config[
"limits"][key]
73 limits[key] =
int(limit)
76 with
open(results,
"r") as f:
79 items = [ReportItem(**item) for item
in items]
84 if item.code
in config[
"ignore"]:
86 if not item.code
in codes:
89 for pattern
in limits.keys():
91 if fnmatch(item.code, pattern):
95 output += tabulate(reversed(sorted(list(codes.items()), key=itemgetter(1))), headers=(
"code",
"count"), tablefmt=
"psql")
100 for key, count
in counts.items():
108 line = (CHECK_SYMBOL, key_s, count, limit)
109 lines.append(map(green, map(str, line)))
111 line = (CHECK_SYMBOL, key_s, count, limit)
112 lines.append(map(orange, map(str, line)))
114 line = (CROSS_SYMBOL, key_s, count, limit)
115 lines.append(map(red, map(str, line)))
118 result_status = (
"Failed")
if exit == 1
else (
"Accepted")
121 output +=
"# Static analysis results: %s\n\n" % result_status
123 output +=
"Results: %s\n\n" % result_status
125 output += tabulate(lines, headers=(
"ok",
"pattern",
"count",
"limit"), tablefmt=
"pipe")
129 output += red(
"\n\n=> Failed rules")
135 p = argparse.ArgumentParser(description=__doc__)
136 p.add_argument(
"--limitfile", required=
True,
137 help=
"The input limit file (yml)")
138 p.add_argument(
"--itemfile", required=
True,
139 help=
"The input item file containing the warnings (json)")
140 p.add_argument(
"--verbose",
"-v", action=
"store_true",
142 p.add_argument(
"--markdown",
"-md", action=
"store_true",
143 help=
"Produce MD output instead of terminal ooutput")
145 args = p.parse_args()
147 assert os.path.exists(args.limitfile)
148 assert os.path.exists(args.itemfile)
150 exit, string =
analysis(args.limitfile, args.itemfile, args.verbose, args.markdown)
154 if "__main__" == __name__: