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
|
import textwrap
from typing import TYPE_CHECKING
from collections.abc import Iterable
from debputy.util import _info
if TYPE_CHECKING:
from junit_xml import TestSuite, TestCase, to_xml_report_file
else:
try:
from junit_xml import TestSuite, TestCase, to_xml_report_file
except ImportError:
pass
from debputy.linting.lint_util import (
LintReport,
LintDiagnosticResult,
LintDiagnosticResultState,
debputy_severity,
)
class JunitLintReport(LintReport):
def __init__(self, output_filename: str) -> None:
super().__init__()
self._output_filename = output_filename
def finish_report(self) -> None:
# Nothing to do for now
all_test_cases = list(self._as_test_cases())
test_suites = [
TestSuite(
"debputy lint",
test_cases=all_test_cases,
timestamp=str(self.start_timestamp),
)
]
with open(self._output_filename, "w", encoding="utf-8") as wfd:
to_xml_report_file(wfd, test_suites, encoding="utf-8")
_info(f"Wrote {self._output_filename}")
def _as_test_cases(self) -> Iterable["TestCase"]:
for filename, duration in self.durations.items():
results = self.diagnostics_by_file.get(filename, [])
yield self._as_test_case(filename, results, duration)
def _as_test_case(
self,
filename: str,
diagnostic_results: Iterable[LintDiagnosticResult],
duration: float,
) -> "TestCase":
if not duration:
duration = 0.000001
case = TestCase(
filename,
# The JUnit schema has `classname` as mandatory
classname=filename,
allow_multiple_subelements=True,
elapsed_sec=duration,
)
for diagnostic_result in diagnostic_results:
if diagnostic_result.result_state == LintDiagnosticResultState.FIXED:
continue
diagnostic = diagnostic_result.diagnostic
severity = debputy_severity(diagnostic)
if diagnostic_result.is_file_level_diagnostic:
range_desc = "entire file"
else:
range_desc = str(diagnostic.range)
code = f" [{diagnostic.code}]" if diagnostic.code else ""
authority = diagnostic.source
assert authority is not None
output = textwrap.dedent(
f"""\
{filename}{code} ({severity}) {range_desc} [{authority}]: {diagnostic.message}
"""
)
case.add_failure_info(
message=f"[{severity}]: {diagnostic.message}",
output=output,
)
return case
|