Coverage for plugin/scripts/_validate_log.py: 100%
24 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-15 14:46 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-15 14:46 +0000
1#!/usr/bin/env python3
2"""The reporting sink every `validate.py` check writes to.
4Its own module because all three halves of the validator need it — the structure checks,
5the field checks, and the orchestration — and a shim they all import cannot live in the
6module that imports them.
8Two audiences from one call: a human reading symbol-prefixed lines on stderr, and
9``--json``, which needs the ERROR and WARNING messages as data. That is the whole reason
10this is a class and not `print`.
11"""
13from __future__ import annotations
15import sys
18class Log:
19 """Tiny stand-in for the CLI's loguru sink.
21 Prints human-readable, symbol-prefixed lines to stderr and, so `--json`
22 can report a structured verdict, accumulates the ERROR/WARNING messages.
23 """
25 _SYMBOLS = {"error": "✗", "warning": "!", "success": "✓", "info": " ", "debug": " "}
27 def __init__(self, *, verbose: bool = False) -> None:
28 """Start the sink with empty error/warning buffers."""
29 self.errors: list[str] = []
30 self.warnings: list[str] = []
31 self._verbose = verbose
33 def _emit(self, level: str, message: str) -> None:
34 """Print a symbol-prefixed line (debug only when verbose)."""
35 if level == "debug" and not self._verbose:
36 return
37 print(f"{self._SYMBOLS[level]} {message}", file=sys.stderr)
39 def error(self, message: str) -> None:
40 """Record and print an error."""
41 self.errors.append(message)
42 self._emit("error", message)
44 def warning(self, message: str) -> None:
45 """Record and print a warning."""
46 self.warnings.append(message)
47 self._emit("warning", message)
49 def success(self, message: str) -> None:
50 """Print a success line."""
51 self._emit("success", message)
53 def info(self, message: str) -> None:
54 """Print an info line."""
55 self._emit("info", message)
57 def debug(self, message: str) -> None:
58 """Print a debug line (verbose only)."""
59 self._emit("debug", message)