Coverage for lintro / utils / config_reporting.py: 100%
60 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"""Configuration reporting utilities.
3Generates human-readable reports of tool configurations and validation warnings.
4"""
6from loguru import logger
8from lintro.utils.unified_config import (
9 get_effective_line_length,
10 get_ordered_tools,
11 get_tool_order_config,
12 get_tool_priority,
13 validate_config_consistency,
14)
16# Tools that don't require displaying native config (managed internally)
17_TOOLS_WITHOUT_EXTERNAL_CONFIG = {"ruff", "black", "bandit"}
20def get_config_report() -> str:
21 """Generate a configuration report as a string.
23 Returns:
24 Formatted configuration report
25 """
26 # Late import to avoid circular dependency
27 from lintro.utils.unified_config import get_tool_config_summary
29 summary = get_tool_config_summary()
30 central_ll = get_effective_line_length("ruff")
31 order_config = get_tool_order_config()
33 lines: list[str] = []
34 lines.append("=" * 60)
35 lines.append("LINTRO CONFIGURATION REPORT")
36 lines.append("=" * 60)
37 lines.append("")
39 # Global settings section
40 lines.append("── Global Settings ──")
41 lines.append(f" Central line_length: {central_ll or 'Not configured'}")
42 lines.append(f" Tool order strategy: {order_config.get('strategy', 'priority')}")
43 if order_config.get("custom_order"):
44 lines.append(f" Custom order: {', '.join(order_config['custom_order'])}")
45 lines.append("")
47 # Tool execution order section
48 lines.append("── Tool Execution Order ──")
49 tool_names = list(summary.keys())
50 ordered_tools = get_ordered_tools(tool_names)
51 for idx, tool_name in enumerate(ordered_tools, 1):
52 priority = get_tool_priority(tool_name)
53 lines.append(f" {idx}. {tool_name} (priority: {priority})")
54 lines.append("")
56 # Per-tool configuration section
57 lines.append("── Per-Tool Configuration ──")
58 for tool_name, info in summary.items():
59 injectable = "✅ Syncable" if info.is_injectable else "⚠️ Native only"
60 effective = info.effective_config.get("line_length", "default")
61 lines.append(f" {tool_name}:")
62 lines.append(f" Status: {injectable}")
63 lines.append(f" Effective line_length: {effective}")
64 if info.lintro_tool_config:
65 lines.append(f" Lintro config: {info.lintro_tool_config}")
66 if info.native_config and tool_name not in _TOOLS_WITHOUT_EXTERNAL_CONFIG:
67 # Only show native config for tools with external config files
68 lines.append(f" Native config: {info.native_config}")
69 lines.append("")
71 # Warnings section
72 all_warnings = validate_config_consistency()
73 if all_warnings:
74 lines.append("── Configuration Warnings ──")
75 for warning in all_warnings:
76 lines.append(f" {warning}")
77 lines.append("")
78 else:
79 lines.append("── Configuration Warnings ──")
80 lines.append(" None - all configs consistent!")
81 lines.append("")
83 lines.append("=" * 60)
84 return "\n".join(lines)
87def print_config_report() -> None:
88 """Print a report of configuration status for all tools."""
89 report = get_config_report()
90 in_warnings_section = False
91 for line in report.split("\n"):
92 # Track when we're in the warnings section
93 if line.startswith("── Configuration Warnings ──"):
94 in_warnings_section = True
95 elif line.startswith("──") and "Warnings" not in line:
96 in_warnings_section = False
98 # Route actual warnings in the warnings section to warning level
99 if in_warnings_section and line.startswith(" ") and line.strip():
100 logger.warning(line)
101 else:
102 logger.info(line)