Initial upload of ai-code-audit-cli project
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / build (push) Has been cancelled
CI / release (push) Has been cancelled

This commit is contained in:
2026-02-03 10:30:12 +00:00
parent 59790a3f96
commit ec01628f73

149
src/reporting/formatter.py Normal file
View File

@@ -0,0 +1,149 @@
"""Report formatting for AI Code Audit CLI."""
import json
from datetime import datetime
from typing import Optional
from ..cli.options import OutputFormat, ScanOptions
from .confidence import ConfidenceScorer
from ..core.models import ScanResult, Issue, IssueCategory, SeverityLevel
class ReportFormatter:
"""Format scan results into various output formats."""
def __init__(self, options: ScanOptions):
"""Initialize the report formatter."""
self.options = options
def format_json(
self, result: ScanResult, confidence_scorer: ConfidenceScorer
) -> str:
"""Format results as JSON."""
score = confidence_scorer.calculate(result)
breakdown = confidence_scorer.get_score_breakdown(result)
report = {
"audit_report": {
"generated_at": datetime.now().isoformat(),
"target_path": result.target_path,
"summary": {
"files_scanned": result.files_scanned,
"total_issues": len(result.issues),
"confidence_score": score,
"score_grade": confidence_scorer.get_score_grade(score),
},
"score_breakdown": breakdown,
"issues_by_severity": self._count_by_severity(result),
"issues_by_category": self._count_by_category(result),
"issues": [self._format_issue(issue) for issue in result.issues],
"warnings": result.warnings,
}
}
return json.dumps(report, indent=2)
def format_markdown(
self, result: ScanResult, confidence_scorer: ConfidenceScorer
) -> str:
"""Format results as Markdown."""
score = confidence_scorer.calculate(result)
lines = [
"# AI Code Audit Report",
"",
f"**Generated:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
f"**Target:** {result.target_path}",
f"**Files Scanned:** {result.files_scanned}",
"",
"## Summary",
"",
f"| Metric | Value |",
f"|--------|-------|",
f"| Confidence Score | **{score}/100** |",
f"| Grade | {confidence_scorer.get_score_grade(score)} |",
f"| Total Issues | {len(result.issues)} |",
f"| Warnings | {len(result.warnings)} |",
"",
"### Issues by Severity",
"",
self._markdown_severity_table(result),
"",
"### Issues by Category",
"",
self._markdown_category_table(result),
"",
"## Issues Detail",
"",
]
if result.issues:
for i, issue in enumerate(result.issues, 1):
lines.append(f"### {i}. [{issue.severity.value.upper()}] {issue.category.value}")
lines.append(f"- **File:** `{issue.file_path}`")
lines.append(f"- **Line:** {issue.line_number}")
lines.append(f"- **Message:** {issue.message}")
if issue.suggestion:
lines.append(f"- **Suggestion:** {issue.suggestion}")
lines.append("")
else:
lines.append("No issues found! Great job!")
lines.append("")
if result.warnings:
lines.append("## Warnings")
lines.append("")
for warning in result.warnings:
lines.append(f"- {warning}")
lines.append("")
lines.append("---")
lines.append("*Generated by AI Code Audit CLI*")
return "\n".join(lines)
def _markdown_severity_table(self, result: ScanResult) -> str:
"""Generate markdown table for severity counts."""
counts = self._count_by_severity(result)
table = "| Severity | Count |\n|---------|-------|\n"
for severity in SeverityLevel:
count = counts.get(severity.value, 0)
table += f"| {severity.value.capitalize()} | {count} |\n"
return table
def _markdown_category_table(self, result: ScanResult) -> str:
"""Generate markdown table for category counts."""
counts = self._count_by_category(result)
table = "| Category | Count |\n|---------|-------|\n"
for category in IssueCategory:
count = counts.get(category.value, 0)
table += f"| {category.value.replace('_', ' ').title()} | {count} |\n"
return table
def _count_by_severity(self, result: ScanResult) -> dict:
"""Count issues by severity."""
counts = {}
for issue in result.issues:
sev = issue.severity.value
counts[sev] = counts.get(sev, 0) + 1
return counts
def _count_by_category(self, result: ScanResult) -> dict:
"""Count issues by category."""
counts = {}
for issue in result.issues:
cat = issue.category.value
counts[cat] = counts.get(cat, 0) + 1
return counts
def _format_issue(self, issue: Issue) -> dict:
"""Format an issue for JSON output."""
return {
"severity": issue.severity.value,
"category": issue.category.value,
"file_path": issue.file_path,
"line_number": issue.line_number,
"message": issue.message,
"suggestion": issue.suggestion,
"scanner": issue.scanner_name,
}