feat: junitxml formater
This commit is contained in:
@@ -59,7 +59,7 @@ def run(argv=None):
|
|||||||
help='custom configuration (as YAML source)')
|
help='custom configuration (as YAML source)')
|
||||||
parser.add_argument('-f', '--format',
|
parser.add_argument('-f', '--format',
|
||||||
choices=('parsable', 'standard', 'colored', 'github',
|
choices=('parsable', 'standard', 'colored', 'github',
|
||||||
'json', 'auto'),
|
'json', 'junitxml', 'auto'),
|
||||||
default='auto', help='format for parsing output')
|
default='auto', help='format for parsing output')
|
||||||
parser.add_argument('-s', '--strict',
|
parser.add_argument('-s', '--strict',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import os
|
|||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
import datetime
|
||||||
|
|
||||||
from yamllint.linter import PROBLEM_LEVELS
|
from yamllint.linter import PROBLEM_LEVELS
|
||||||
|
|
||||||
@@ -23,6 +24,16 @@ def run_on_gh():
|
|||||||
return 'GITHUB_ACTIONS' in os.environ and 'GITHUB_WORKFLOW' in os.environ
|
return 'GITHUB_ACTIONS' in os.environ and 'GITHUB_WORKFLOW' in os.environ
|
||||||
|
|
||||||
|
|
||||||
|
def escape_xml(text):
|
||||||
|
"""Escape text for XML."""
|
||||||
|
text = text.replace('&', '&')
|
||||||
|
text = text.replace('<', '<')
|
||||||
|
text = text.replace('>', '>')
|
||||||
|
text = text.replace('"', '"')
|
||||||
|
text = text.replace('"', ''')
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
class Formater(object):
|
class Formater(object):
|
||||||
"""Any formater."""
|
"""Any formater."""
|
||||||
# the formater name
|
# the formater name
|
||||||
@@ -219,7 +230,52 @@ class JSONFormater(Formater):
|
|||||||
lst = []
|
lst = []
|
||||||
for k, v in all_problems.items():
|
for k, v in all_problems.items():
|
||||||
lst += self.show_problems_for_file(v, k)
|
lst += self.show_problems_for_file(v, k)
|
||||||
return json.dumps(lst, indent=4)
|
return json.dumps(lst, indent=4) + '\n'
|
||||||
|
|
||||||
|
def show_problems_for_file(self, problems, file):
|
||||||
|
"""Show all problems of a specific file."""
|
||||||
|
return list(map(self.show_problem, problems, [file] * len(problems)))
|
||||||
|
|
||||||
|
def show_problem(self, problem, file):
|
||||||
|
"""Show all problems of a specific file."""
|
||||||
|
return {**problem.dict, "file": file}
|
||||||
|
|
||||||
|
|
||||||
|
class JunitFormater(Formater):
|
||||||
|
"""The parsable formater."""
|
||||||
|
name = 'junitxml'
|
||||||
|
|
||||||
|
def show_problems_for_all_files(self, all_problems):
|
||||||
|
"""Show all problems of all files."""
|
||||||
|
string = '<?xml version="1.0" encoding="utf-8"?>\n<testsuites>\n'
|
||||||
|
|
||||||
|
errors = warnings = 0
|
||||||
|
lst = []
|
||||||
|
for k, v in all_problems.items():
|
||||||
|
lst += self.show_problems_for_file(v, k)
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
for item in lst:
|
||||||
|
if item['level'] is None:
|
||||||
|
continue
|
||||||
|
elif item['level'] == 'warning':
|
||||||
|
warnings += 1
|
||||||
|
to_append = '<testcase classname="%s:%d:%d" name="%s" time="0.0"><failure message="%s"><\/failure><\/testcase>' # noqa
|
||||||
|
elif item['level'] == 'error':
|
||||||
|
errors += 1
|
||||||
|
to_append = '<testcase classname="%s:%d:%d" name="%s" time="0.0"><error message="%s"><\/error><\/testcase>' # noqa
|
||||||
|
lines.append(' ' * 8 + to_append % (
|
||||||
|
item['file'],
|
||||||
|
item['line'],
|
||||||
|
item['column'],
|
||||||
|
item['rule'],
|
||||||
|
escape_xml(item['desc']))
|
||||||
|
)
|
||||||
|
|
||||||
|
string += ' '*4 + '<testsuite name="pytest" errors="%d" failures="%d" skipped="0" tests="%d" time="0" timestamp="%s" hostname="%s">\n' % (errors, warnings, errors + warnings, datetime.datetime.now().isoformat(), platform.node()) # noqa
|
||||||
|
string += '\n'.join(lines) + '\n'
|
||||||
|
string += ' </testsuite>\n</testsuites>\n'
|
||||||
|
return string
|
||||||
|
|
||||||
def show_problems_for_file(self, problems, file):
|
def show_problems_for_file(self, problems, file):
|
||||||
"""Show all problems of a specific file."""
|
"""Show all problems of a specific file."""
|
||||||
|
|||||||
Reference in New Issue
Block a user