from datetime import datetime from typing import Any from jinja2 import Template from src.formatters.base import BaseFormatter HTML_TEMPLATE = """ Git Insights Report

Git Insights Report

Generated: {{ timestamp }}

{% if commit_analysis %}

Commit Analysis

{{ commit_analysis.total_commits }}
Total Commits
{{ commit_analysis.unique_authors }}
Authors
{{ "%.1f"|format(commit_analysis.average_commits_per_day) }}
Avg/Day

Top Contributors

{% for author in commit_analysis.top_authors[:5] %} {% endfor %}
AuthorCommitsLines +Lines -
{{ author.name }} {{ author.commit_count }} {{ author.lines_added }} {{ author.lines_deleted }}
{% endif %} {% if velocity_analysis %}

Velocity Analysis

{{ velocity_analysis.commits_per_day }}
Commits/Day
{{ velocity_analysis.commits_per_week }}
Commits/Week
{{ velocity_analysis.velocity_trend|capitalize }}
Trend
{% endif %} {% if code_churn_analysis %}

Code Churn

+{{ code_churn_analysis.total_lines_added }}
Lines Added
-{{ code_churn_analysis.total_lines_deleted }}
Lines Deleted
{{ code_churn_analysis.net_change }}
Net Change
{% endif %} {% if risky_commit_analysis and risky_commit_analysis.total_risky > 0 %}

Risky Commits

{{ risky_commit_analysis.total_risky }} potentially risky commits detected

{% if risky_commit_analysis.large_commits %}

Large Commits ({{ risky_commit_analysis.large_commits|length }})

{% for commit in risky_commit_analysis.large_commits[:5] %} {% endfor %}
SHAAuthorChanges
{{ commit.sha }} {{ commit.author_name }} +{{ commit.additions }} / -{{ commit.deletions }}
{% endif %}
{% endif %}
""" class HTMLFormatter(BaseFormatter): """HTML output formatter.""" @staticmethod def format(data: Any) -> str: """Format data as HTML.""" template = Template(HTML_TEMPLATE) return template.render( timestamp=datetime.now().isoformat(), commit_analysis=getattr(data, "commit_analysis", None), velocity_analysis=getattr(data, "velocity_analysis", None), code_churn_analysis=getattr(data, "code_churn_analysis", None), risky_commit_analysis=getattr(data, "risky_commit_analysis", None), )