Source code for project_config.reporters.yaml
"""YAML reporters."""
from __future__ import annotations
from typing import Any
from project_config.reporters.base import BaseColorReporter, BaseReporter
from project_config.serializers import yaml
[docs]class YamlReporter(BaseReporter):
"""Black/white reporter in YAML format."""
[docs] def generate_errors_report(self) -> str:
"""Generate an errors report in black/white YAML format."""
if not self.errors:
return ""
return yaml.dumps(self.errors).rstrip("\n")
[docs] def generate_data_report(
self,
data_key: str, # noqa: ARG002
data: dict[str, Any],
) -> str:
"""Generate a data report in black/white JSON format."""
report = yaml.dumps(data)
if report.startswith("plugins: []"):
report = "\n".join(report.splitlines()[1:])
return report.rstrip("\n")
[docs]class YamlColorReporter(BaseColorReporter):
"""Color reporter in YAML format."""
[docs] def _transform_errors(self, value: str) -> str:
report = ""
for line in value.splitlines():
if line.startswith(" - "): # definition
report += (
f' {self.format_metachar("-")}'
f' {self.format_key("definition")}'
f'{self.format_metachar(":")}'
f" {self.format_definition(line[16:])}\n"
)
elif line.startswith(" message"): # message
report += (
f" "
f' {self.format_key("message")}'
f'{self.format_metachar(":")}'
f" {self.format_error_message(line[13:])}\n"
)
elif line.startswith(" hint"): # hint
report += (
f" "
f' {self.format_key("hint")}'
f'{self.format_metachar(":")}'
f" {self.format_hint(line[10:])}\n"
)
elif line.startswith(" fixed"): # hint
report += (
f" "
f' {self.format_key("fixed")}'
f'{self.format_metachar(":")}'
f" {self.format_fixed('true')}\n"
)
elif line.startswith(" fixable"): # hint
report += (
f" "
f' {self.format_key("fixable")}'
f'{self.format_metachar(":")}'
f" {self.format_fixed('true')}\n"
)
elif line:
report += (
f"{self.format_file(line[:-1])}"
f"{self.format_metachar(':')}\n"
)
return report.rstrip("\n")
[docs] def generate_errors_report(self) -> Any:
"""Generate an errors report in YAML format with colors."""
if not self.errors:
return ""
return yaml.dumps(self.errors, transform=self._transform_errors)
[docs] def _transform_config_data(self, value: str) -> str:
report = ""
for line in value.splitlines():
if line.startswith(" - "):
report += (
f' {self.format_metachar("-")}'
f" {self.format_config_value(line[4:].strip())}"
)
else:
key, value = line.split(":", maxsplit=1)
report += (
f"{self.format_config_key(key)}"
f"{self.format_metachar(':')}"
f" {self.format_config_value(value.strip())}"
).rstrip()
report += "\n"
return report.rstrip("\n")
_transform_plugins_data = _transform_config_data
[docs] def _transform_style_data(self, value: str) -> str: # noqa: PLR0912
report = ""
section, subsection = None, None
def format_section(section_name: str) -> str:
return (
f"{self.format_config_key(section_name)}"
f"{self.format_metachar(':')}"
)
for line in value.splitlines():
if line.startswith("plugins:"):
if line.endswith("[]"):
continue
report += format_section("plugins")
section = "plugins"
elif line.startswith("rules:"):
report += format_section("rules")
section = "rules"
elif section == "plugins":
report += (
f' {self.format_metachar("-")}'
f" {self.format_config_value(line[4:].strip())}"
)
elif section == "rules":
if line.startswith(" - "): # files or action
report += (
f' {self.format_metachar("-")}'
f" {self.format_key(line[4:-1])}"
f'{self.format_metachar(":")}'
)
subsection = (
"files" if line.endswith("files:") else "action"
)
elif line.startswith(" "): # subsection
if subsection == "files":
if line == " not:":
report += (
f" {self.format_key('not')}"
f"{self.format_metachar(':')}"
)
elif line.lstrip().startswith("- "): # file
offset, file = line.split("-", maxsplit=1)
report += (
f"{offset}{self.format_metachar('-')}"
f" {self.format_file(file.strip())}"
)
else: # not: file
report += (
f" {self.format_file(line.strip())}"
)
else:
# actions
report += self.format_config_value(line)
elif line.startswith(" "):
report += (
f" {self.format_key(line[4:-1])}"
f'{self.format_metachar(":")}'
)
subsection = (
"files" if line.endswith("files:") else "action"
)
report += "\n"
return report.rstrip("\n")
[docs] def generate_data_report(
self,
data_key: str,
data: dict[str, Any],
) -> str:
"""Generate a data report in color YAML format."""
return yaml.dumps(
data,
transform=getattr(self, f"_transform_{data_key}_data"),
)