#!/usr/bin/env python3 """ Report Generator Generates audit reports in multiple formats: - Markdown (default, human-readable) - JSON (machine-readable, CI/CD integration) - HTML (interactive dashboard) """ import json from datetime import datetime from pathlib import Path from typing import Dict, List def generate_markdown_report(summary: Dict, findings: Dict[str, List[Dict]], metadata: Dict) -> str: """ Generate a Markdown-formatted audit report. Args: summary: Executive summary data findings: All findings organized by category metadata: Project metadata Returns: Markdown report as string """ report = [] # Header report.append("# Codebase Audit Report") report.append(f"\n**Generated**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") report.append(f"**Codebase**: `{metadata.get('path', 'Unknown')}`") report.append(f"**Tech Stack**: {', '.join(metadata.get('tech_stack', {}).keys())}") report.append(f"**Total Files**: {metadata.get('total_files', 0):,}") report.append(f"**Lines of Code**: {metadata.get('total_lines', 0):,}") report.append("\n---\n") # Executive Summary report.append("## Executive Summary") report.append(f"\n### Overall Health Score: **{summary.get('overall_score', 0)}/100**\n") # Score breakdown report.append("#### Category Scores\n") for category, score in summary.get('category_scores', {}).items(): emoji = score_to_emoji(score) report.append(f"- **{category.replace('_', ' ').title()}**: {score}/100 {emoji}") # Issue summary report.append("\n#### Issue Summary\n") report.append(f"- **Critical Issues**: {summary.get('critical_issues', 0)}") report.append(f"- **High Issues**: {summary.get('high_issues', 0)}") report.append(f"- **Total Issues**: {summary.get('total_issues', 0)}") report.append("\n---\n") # Detailed Findings report.append("## Detailed Findings\n") severity_order = ['critical', 'high', 'medium', 'low'] for severity in severity_order: severity_findings = [] for category, category_findings in findings.items(): for finding in category_findings: if finding.get('severity') == severity: severity_findings.append((category, finding)) if severity_findings: severity_emoji = severity_to_emoji(severity) report.append(f"### {severity_emoji} {severity.upper()} ({len(severity_findings)} issues)\n") for category, finding in severity_findings: report.append(f"#### {finding.get('title', 'Untitled Issue')}") report.append(f"\n**Category**: {category.replace('_', ' ').title()}") report.append(f"**Subcategory**: {finding.get('subcategory', 'N/A')}") if finding.get('file'): file_ref = f"{finding['file']}" if finding.get('line'): file_ref += f":{finding['line']}" report.append(f"**Location**: `{file_ref}`") report.append(f"\n{finding.get('description', 'No description')}") if finding.get('code_snippet'): report.append(f"\n```\n{finding['code_snippet']}\n```") report.append(f"\n**Impact**: {finding.get('impact', 'Unknown impact')}") report.append(f"\n**Remediation**: {finding.get('remediation', 'No remediation suggested')}") report.append(f"\n**Effort**: {finding.get('effort', 'Unknown').upper()}\n") report.append("---\n") # Recommendations report.append("## Recommendations\n") report.append(generate_recommendations(summary, findings)) # Footer report.append("\n---\n") report.append("*Report generated by Codebase Auditor Skill (2024-25 Standards)*") return '\n'.join(report) def generate_json_report(summary: Dict, findings: Dict[str, List[Dict]], metadata: Dict) -> str: """ Generate a JSON-formatted audit report. Args: summary: Executive summary data findings: All findings organized by category metadata: Project metadata Returns: JSON report as string """ report = { 'generated_at': datetime.now().isoformat(), 'metadata': metadata, 'summary': summary, 'findings': findings, 'schema_version': '1.0.0', } return json.dumps(report, indent=2) def generate_html_report(summary: Dict, findings: Dict[str, List[Dict]], metadata: Dict) -> str: """ Generate an HTML dashboard report. Args: summary: Executive summary data findings: All findings organized by category metadata: Project metadata Returns: HTML report as string """ # Simplified HTML template html = f""" Codebase Audit Report

🔍 Codebase Audit Report

Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}

Codebase: {metadata.get('path', 'Unknown')}

Overall Score: {summary.get('overall_score', 0)}/100
Critical Issues
{summary.get('critical_issues', 0)}
High Issues
{summary.get('high_issues', 0)}
Total Issues
{summary.get('total_issues', 0)}
Lines of Code
{metadata.get('total_lines', 0):,}

Findings

""" # Add findings severity_order = ['critical', 'high', 'medium', 'low'] for severity in severity_order: for category, category_findings in findings.items(): for finding in category_findings: if finding.get('severity') == severity: html += f"""
{severity} {finding.get('title', 'Untitled')}

{finding.get('description', 'No description')}

""" if finding.get('file'): html += f"

Location: {finding['file']}" if finding.get('line'): html += f":{finding['line']}" html += "

" if finding.get('code_snippet'): html += f"
{finding['code_snippet']}
" html += f"""

Impact: {finding.get('impact', 'Unknown')}

Remediation: {finding.get('remediation', 'No suggestion')}

""" html += """ """ return html def score_to_emoji(score: float) -> str: """Convert score to emoji.""" if score >= 90: return "✅" elif score >= 70: return "âš ī¸" else: return "❌" def severity_to_emoji(severity: str) -> str: """Convert severity to emoji.""" severity_map = { 'critical': '🚨', 'high': 'âš ī¸', 'medium': '⚡', 'low': 'â„šī¸', } return severity_map.get(severity, '') def generate_recommendations(summary: Dict, findings: Dict) -> str: """Generate recommendations based on findings.""" recommendations = [] critical_count = summary.get('critical_issues', 0) high_count = summary.get('high_issues', 0) overall_score = summary.get('overall_score', 0) if critical_count > 0: recommendations.append(f"1. **Immediate Action Required**: Address all {critical_count} critical security and quality issues before deploying to production.") if high_count > 5: recommendations.append(f"2. **Sprint Focus**: Prioritize fixing the {high_count} high-severity issues in the next sprint. These significantly impact code quality and maintainability.") if overall_score < 70: recommendations.append("3. **Technical Debt Sprint**: Schedule a dedicated sprint to address accumulated technical debt and improve code quality metrics.") if 'testing' in findings and len(findings['testing']) > 0: recommendations.append("4. **Testing Improvements**: Increase test coverage to meet the 80% minimum threshold. Focus on critical paths first (authentication, payment, data processing).") if 'security' in findings and len(findings['security']) > 0: recommendations.append("5. **Security Review**: Conduct a thorough security review and penetration testing given the security issues found.") if not recommendations: recommendations.append("1. **Maintain Standards**: Continue following best practices and maintain current quality levels.") recommendations.append("2. **Continuous Improvement**: Consider implementing automated code quality checks in CI/CD pipeline.") return '\n'.join(recommendations)