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

1"""Configuration reporting utilities. 

2 

3Generates human-readable reports of tool configurations and validation warnings. 

4""" 

5 

6from loguru import logger 

7 

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) 

15 

16# Tools that don't require displaying native config (managed internally) 

17_TOOLS_WITHOUT_EXTERNAL_CONFIG = {"ruff", "black", "bandit"} 

18 

19 

20def get_config_report() -> str: 

21 """Generate a configuration report as a string. 

22 

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 

28 

29 summary = get_tool_config_summary() 

30 central_ll = get_effective_line_length("ruff") 

31 order_config = get_tool_order_config() 

32 

33 lines: list[str] = [] 

34 lines.append("=" * 60) 

35 lines.append("LINTRO CONFIGURATION REPORT") 

36 lines.append("=" * 60) 

37 lines.append("") 

38 

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("") 

46 

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("") 

55 

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("") 

70 

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("") 

82 

83 lines.append("=" * 60) 

84 return "\n".join(lines) 

85 

86 

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 

97 

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)