Coverage for lintro / utils / json_output.py: 100%

21 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""JSON output utilities for Lintro. 

2 

3This module provides functionality for creating JSON output from tool results. 

4""" 

5 

6from typing import Any 

7 

8from lintro.ai.metadata import normalize_ai_metadata 

9from lintro.enums.action import Action, normalize_action 

10from lintro.models.core.tool_result import ToolResult 

11 

12 

13def create_json_output( 

14 action: str | Action, 

15 results: list[ToolResult], 

16 total_issues: int, 

17 total_fixed: int, 

18 total_remaining: int, 

19 exit_code: int, 

20) -> dict[str, Any]: 

21 """Create JSON output data structure from tool results. 

22 

23 Args: 

24 action: The action being performed (check, fmt, test). 

25 results: List of tool result objects. 

26 total_issues: Total number of issues found. 

27 total_fixed: Total number of issues fixed (only for FIX action). 

28 total_remaining: Total number of issues remaining (only for FIX action). 

29 exit_code: Exit code for the run. 

30 

31 Returns: 

32 Dictionary containing JSON-serializable results and summary data. 

33 """ 

34 # Normalize action to Action enum if string 

35 action_enum = normalize_action(action) if isinstance(action, str) else action 

36 

37 json_data: dict[str, Any] = { 

38 "results": [], 

39 "summary": { 

40 "total_issues": total_issues, 

41 "total_fixed": total_fixed if action_enum == Action.FIX else 0, 

42 "total_remaining": total_remaining if action_enum == Action.FIX else 0, 

43 }, 

44 } 

45 for result in results: 

46 result_data: dict[str, Any] = { 

47 "tool": result.name, 

48 "success": getattr(result, "success", True), 

49 "issues_count": getattr(result, "issues_count", 0), 

50 "skipped": getattr(result, "skipped", False), 

51 "skip_reason": getattr(result, "skip_reason", None), 

52 } 

53 if action_enum == Action.FIX: 

54 result_data["fixed"] = getattr(result, "fixed_issues_count", 0) 

55 result_data["remaining"] = getattr( 

56 result, 

57 "remaining_issues_count", 

58 0, 

59 ) 

60 # Include AI metadata when present 

61 ai_metadata = getattr(result, "ai_metadata", None) 

62 if isinstance(ai_metadata, dict): 

63 normalized_ai_metadata = normalize_ai_metadata(ai_metadata) 

64 if normalized_ai_metadata: 

65 result_data["ai_metadata"] = normalized_ai_metadata 

66 # Extract AI summary from the first result that has one 

67 if ( 

68 "summary" in normalized_ai_metadata 

69 and "ai_summary" not in json_data 

70 ): 

71 json_data["ai_summary"] = normalized_ai_metadata["summary"] 

72 

73 json_data["results"].append(result_data) 

74 

75 return json_data