Coverage for lintro / parsers / yamllint / yamllint_parser.py: 76%
37 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Parser for yamllint output."""
3import re
5from loguru import logger
7from lintro.enums.severity_level import normalize_severity_level
8from lintro.parsers.base_parser import strip_ansi_codes
9from lintro.parsers.yamllint.yamllint_issue import YamllintIssue
11# Pattern for yamllint parsable format: "filename:line:column: [level] message (rule)"
12_YAMLLINT_PATTERN: re.Pattern[str] = re.compile(
13 r"^([^:]+):(\d+):(\d+):\s*\[(error|warning)\]\s+(.+?)(?:\s+\(([^)]+)\))?$",
14)
17def parse_yamllint_output(output: str) -> list[YamllintIssue]:
18 """Parse yamllint output into a list of YamllintIssue objects.
20 Yamllint outputs in parsable format as:
21 filename:line:column: [level] message (rule)
23 Example outputs:
24 test_samples/yaml_violations.yml:3:1: [warning] missing document start
25 "---" (document-start)
26 test_samples/yaml_violations.yml:6:32: [error] trailing spaces
27 (trailing-spaces)
28 test_samples/yaml_violations.yml:11:81: [error] line too long (149 > 80
29 characters) (line-length)
31 Args:
32 output: The raw output from yamllint
34 Returns:
35 List of YamllintIssue objects
36 """
37 issues: list[YamllintIssue] = []
39 # Skip empty output
40 if not output.strip():
41 return issues
43 # Strip ANSI codes for consistent parsing across environments
44 output = strip_ansi_codes(output)
46 lines: list[str] = output.splitlines()
48 for line in lines:
49 line = line.strip()
50 if not line:
51 continue
53 match: re.Match[str] | None = _YAMLLINT_PATTERN.match(line)
54 if match:
55 try:
56 filename: str
57 line_num: str
58 column: str
59 level: str
60 message: str
61 rule: str | None
62 filename, line_num, column, level, message, rule = match.groups()
64 # Validate and convert line number
65 try:
66 line_int = int(line_num)
67 except ValueError:
68 logger.debug(f"Invalid line number in yamllint output: {line_num}")
69 continue
71 # Validate and convert column number
72 column_int: int = 0
73 if column:
74 try:
75 column_int = int(column)
76 except ValueError:
77 logger.debug(
78 f"Invalid column number in yamllint output: {column}",
79 )
80 column_int = 0
82 issues.append(
83 YamllintIssue(
84 file=filename,
85 line=line_int,
86 column=column_int,
87 level=normalize_severity_level(level),
88 rule=rule,
89 message=message.strip(),
90 ),
91 )
92 except (ValueError, TypeError, IndexError) as e:
93 logger.debug(f"Failed to parse yamllint line '{line}': {e}")
94 continue
96 return issues