From b96bfe3cee2675a0f98b5641b4d2d6ee43be8cac Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Fri, 30 Jan 2026 20:35:28 +0000 Subject: [PATCH] Initial upload: git-insights-cli with CI/CD workflow --- src/formatters/html_formatter.py | 132 +++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/formatters/html_formatter.py diff --git a/src/formatters/html_formatter.py b/src/formatters/html_formatter.py new file mode 100644 index 0000000..54bee65 --- /dev/null +++ b/src/formatters/html_formatter.py @@ -0,0 +1,132 @@ +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
+
+ + + {% for author in commit_analysis.top_authors[:5] %} + + {% endfor %} +
AuthorCommits
{{ author.name }}{{ author.commit_count }}
+
+ {% endif %} + + {% if velocity_analysis %} +
+

Velocity Analysis

+
+
{{ "%.1f"|format(velocity_analysis.commits_per_day) }}
+
Commits/Day
+
+
+
{{ "%.1f"|format(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 %} +
+

Risky Commits

+
+
{{ risky_commit_analysis.total_risky_commits }}
+
Total Risky
+
+
+
{{ "%.1f"|format(risky_commit_analysis.risk_score) }}%
+
Risk Score
+
+
+ {% 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=data.commit_analysis if hasattr(data, "commit_analysis") else None, + velocity_analysis=data.velocity_analysis if hasattr(data, "velocity_analysis") else None, + code_churn_analysis=data.code_churn_analysis if hasattr(data, "code_churn_analysis") else None, + risky_commit_analysis=data.risky_commit_analysis if hasattr(data, "risky_commit_analysis") else None, + )