ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
make_report.py
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file make_report.py
1 #!/usr/bin/env python3
2 
3 """
4 This produces a structured normalized report json file based on warnings generated by another tool.
5 Currently implemented is clang-tidy warnings.
6 """
7 
8 import argparse
9 import re
10 from collections import namedtuple
11 from itertools import groupby
12 import os
13 import html
14 from fnmatch import fnmatch
15 import json
16 import sys
17 
18 
19 from codereport import CodeReport, ReportItem
20 
21 def parse_clang_tidy_item(itemstr):
22 
23  try:
24  m = re.match(r"(?P<file>[/.\-+\w]+):(?P<line>\d+):(?P<col>\d+): (?P<sev>.*?):(?P<msg>[\s\S]*?)\[(?P<code>.*)\]\n(?P<info>[\s\S]*)", itemstr)
25 
26  item = ReportItem(
27  path=m.group("file"),
28  line=int(m.group("line")),
29  col=int(m.group("col")),
30  message=m.group("msg").strip(),
31  code=m.group("code"),
32  severity=m.group("sev")
33  )
34 
35  print(repr(item))
36 
37  return item
38  except:
39  print("Failed parsing clang-tidy item:")
40  print("-"*20)
41  print(itemstr)
42  print("-"*20)
43  raise
44 
46 
47  # cleanup
48  itemstr = output
49  itemstr = re.sub(r"Enabled checks:\n[\S\s]+?\n\n", "", itemstr)
50  itemstr = re.sub(r"clang-tidy-\d\.\d.*\n?", "", itemstr)
51  itemstr = re.sub(r"clang-apply-.*", "", itemstr)
52  itemstr = re.sub(r".*-header-filter.*", "", itemstr)
53 
54  items = []
55  prevstart = 0
56 
57  matches = list(re.finditer(r"([\w/.\-+]+):(\d+):(\d+): (?:(?:warning)|(?:error)):", itemstr))
58  for idx, m in enumerate(matches):
59  # print(m)
60  start, end = m.span()
61  if idx > 0:
62  item = itemstr[prevstart:start]
63  items.append(item)
64  if idx+1 == len(matches):
65  item = itemstr[start:]
66  items.append(item)
67  prevstart = start
68 
69  items = set(map(parse_clang_tidy_item, sorted(items)))
70 
71  return items
72 
73 
74 def main():
75  p = argparse.ArgumentParser(description=__doc__)
76  p.add_argument("mode", choices=("clang-tidy",),
77  help="Type of input warnings")
78  p.add_argument("inputfile",
79  help="The input file containing the warnings")
80  p.add_argument("output", default="codereport_clang_tidy.json",
81  help="The resulting JSON file")
82  p.add_argument("--exclude", "-e", action="append", default=[],
83  help="Exclude files that match any of these patterns")
84  p.add_argument("--filter", action="append", default=[],
85  help="Only include files that match any of these patterns")
86 
87  args = p.parse_args()
88 
89  if args.mode == "clang-tidy":
90  with open(args.inputfile, "r", encoding="utf-8") as f:
91  inputstr = f.read()
92  items = parse_clang_tidy_output(inputstr)
93 
94  def select(item):
95  accept = True
96  if len(args.filter) > 0:
97  accept = accept and all(fnmatch(item.path, e) for e in args.filter)
98 
99  accept = accept and not any(fnmatch(item.path, e) for e in args.exclude)
100  return accept
101 
102  items = filter(select, items)
103 
104 
105  data = [i.dict() for i in items]
106  print("Write to", args.output)
107  with open(args.output, "w+") as jf:
108  json.dump(data, jf, indent=2)
109 
110 
111 if "__main__" == __name__:
112  main()
113 
114