-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmypy2junit.py
94 lines (73 loc) · 2.56 KB
/
mypy2junit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import argparse
import fileinput
import re
import sys
from typing import List, Tuple
__version__ = '1.9.0'
RESULT_REGEX = re.compile(
# errors -> error if found only one error
r'Found (?P<count>\d+) errors?'
)
REPLACES = {
ord('<'): '<',
ord('"'): '"',
ord('&'): '&',
}
def process_lines(lines: List[str]) -> Tuple[str, bool]:
result = {'count': '0', 'total_files': '0'}
failures = []
output = ''
for line in lines:
if line.startswith('Found '):
match = re.match(
RESULT_REGEX,
line
)
if match:
result = match.groupdict()
continue
# example: Success: no issues found in 9 source files
if line.startswith('Success: no issues found in '):
break
file_, line, type_, *message = line.split(':')
type_ = type_.strip()
if type_ == 'error':
failures.append((file_, line, type_, message))
output += f"""<?xml version="1.0" encoding="utf-8"?>
<testsuite errors="0" failures="{result['count']}" name="" skips="0" tests="{result['count']}" time="0.0">"""
for failure in failures:
msg = f"{failure[0]}:{failure[1]}: {failure[2]}: "
msg += ':'.join(failure[3]).strip().translate(REPLACES)
output += f"""
<testcase classname="{failure[0]}" name="{failure[0]}:{failure[1]}" file="{failure[0]}" line="{failure[1]}" time="0.0">
<failure message="Mypy error on {failure[0]}:{failure[1]}" type="WARNING" file="{failure[0]}" line="{failure[1]}">{msg}</failure>
</testcase>"""
output += """
</testsuite>"""
return output, int(result['count']) == 0
def main():
parser = argparse.ArgumentParser()
parser.add_argument('files', metavar='FILE', nargs='*', help='files to read, if empty, stdin is used')
parser.add_argument('--output',
type=str,
dest='output',
help='Filename to output to')
parser.add_argument('--tee', action='store_true')
args = parser.parse_args()
if args.tee and not args.output:
print("You must specify --output if using --tee")
return -1
output, status = process_lines(
list(fileinput.input(files=args.files if len(args.files) > 0 else ('-', )))
)
if args.output:
with open(args.output, 'w') as file:
file.write(output)
if not args.output or args.tee:
print(
output
)
if not status:
sys.exit(1)
if __name__ == "__main__":
main()