Add models, analyzers, and formatters
Some checks failed
CI / test (push) Failing after 9s

This commit is contained in:
2026-02-01 07:58:06 +00:00
parent a0a44b93ad
commit 6fcb5ecfbb

View File

@@ -1,111 +1,105 @@
from typing import Any
from rich.console import Console
from rich.layout import Layout
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from rich.box import ROUNDED
from src.formatters.base import BaseFormatter
class DashboardFormatter:
"""Rich console dashboard formatter."""
class DashboardFormatter(BaseFormatter):
"""Terminal dashboard formatter using Rich."""
@staticmethod
def display(data: Any) -> None:
"""Display data as a Rich dashboard."""
"""Display data as an interactive dashboard."""
console = Console()
title = Text("Git Insights - Productivity Dashboard", style="bold green", justify="center")
console.print(Panel(title, box=ROUNDED, style="green"))
console.print()
layout = Layout()
layout.split_column(
Layout(name="header", size=3),
Layout(name="body"),
)
layout["body"].split_row(
Layout(name="left"),
Layout(name="right"),
)
header = Panel(
Text("Git Insights Dashboard", justify="center", style="bold blue"),
style="white on blue",
)
layout["header"].update(header)
if hasattr(data, "commit_analysis") and data.commit_analysis:
DashboardFormatter._print_commit_stats(console, data.commit_analysis)
ca = data.commit_analysis
left_content = f"""
[bold]Commit Overview[/bold]
Total Commits: [green]{ca.total_commits}[/green]
Unique Authors: [blue]{ca.unique_authors}[/blue]
Avg Commits/Day: [yellow]{ca.average_commits_per_day:.1f}[/yellow]
[bold]Top Contributors[/bold]
"""
for author in ca.top_authors[:5]:
left_content += f"\n {author.name}: {author.commit_count} commits"
layout["left"].update(
Panel(left_content, title="Commit Analysis"),
)
if hasattr(data, "velocity_analysis") and data.velocity_analysis:
DashboardFormatter._print_velocity(console, data.velocity_analysis)
va = data.velocity_analysis
right_content = f"""
[bold]Velocity Metrics[/bold]
Commits/Day: [green]{va.commits_per_day}[/green]
Commits/Week: [blue]{va.commits_per_week}[/blue]
Trend: [yellow]{va.velocity_trend}[/yellow]
Most Active: [magenta]{va.most_active_day}[/magenta]
"""
layout["right"].update(
Panel(right_content, title="Velocity Analysis"),
)
console.print(layout)
if hasattr(data, "code_churn_analysis") and data.code_churn_analysis:
DashboardFormatter._print_churn(console, data.code_churn_analysis)
cc = data.code_churn_analysis
churn_panel = Panel(
f"""
[bold]Code Churn Statistics[/bold]
Lines Added: [green]+{cc.total_lines_added:,}[/green]
Lines Deleted: [red]-{cc.total_lines_deleted:,}[/red]
Net Change: [blue]{cc.net_change:+}[/blue]
Avg Churn/Commit: [yellow]{cc.average_churn_per_commit:.1f}[/yellow]
""",
title="Code Churn",
)
console.print(churn_panel)
if hasattr(data, "risky_commit_analysis") and data.risky_commit_analysis:
DashboardFormatter._print_risky(console, data.risky_commit_analysis)
ra = data.risky_commit_analysis
if ra.total_risky > 0:
risky_panel = Panel(
f"""
[bold]Risky Commits Summary[/bold]
Large Commits: [red]{len(ra.large_commits)}[/red]
Merge Commits: [yellow]{len(ra.merge_commits)}[/yellow]
Revert Commits: [blue]{len(ra.revert_commits)}[/blue]
Total Risky: [red]{ra.total_risky}[/red]
""",
title="Risk Detection",
)
console.print(risky_panel)
@staticmethod
def _print_commit_stats(console: Console, ca: Any) -> None:
"""Print commit statistics."""
table = Table(title="[bold]Commit Overview[/bold]", box=ROUNDED)
table.add_column("Metric", style="cyan")
table.add_column("Value", style="magenta")
table.add_row("Total Commits", str(ca.total_commits))
table.add_row("Unique Authors", str(ca.unique_authors))
table.add_row("Avg Commits/Day", f"{ca.average_commits_per_day:.1f}")
console.print(Panel(table, title="[bold yellow]Commits[/bold yellow]", box=ROUNDED))
console.print()
if ca.top_authors:
author_table = Table(title="[bold]Top Contributors[/bold]", box=ROUNDED)
author_table.add_column("Author", style="green")
author_table.add_column("Commits", justify="right", style="blue")
for author in ca.top_authors[:5]:
author_table.add_row(author.name, str(author.commit_count))
console.print(Panel(author_table, box=ROUNDED))
console.print()
@staticmethod
def _print_velocity(console: Console, va: Any) -> None:
"""Print velocity metrics."""
table = Table(box=ROUNDED)
table.add_column("Metric", style="cyan")
table.add_column("Value", style="magenta")
trend_style = "green" if va.velocity_trend == "increasing" else "orange" if va.velocity_trend == "decreasing" else "blue"
table.add_row("Commits/Day", f"{va.commits_per_day:.1f}")
table.add_row("Commits/Week", f"{va.commits_per_week:.1f}")
table.add_row("Velocity Trend", f"[{trend_style}]{va.velocity_trend}[/{trend_style}]")
table.add_row("Most Active Day", va.most_active_day)
table.add_row("Most Active Hour", va.most_active_hour)
console.print(Panel(table, title="[bold yellow]Velocity[/bold yellow]", box=ROUNDED))
console.print()
@staticmethod
def _print_churn(console: Console, cc: Any) -> None:
"""Print code churn metrics."""
table = Table(box=ROUNDED)
table.add_column("Metric", style="cyan")
table.add_column("Value", style="magenta")
net_color = "green" if cc.net_change >= 0 else "red"
table.add_row("Lines Added", f"[green]+{cc.total_lines_added:,}[/green]")
table.add_row("Lines Deleted", f"[red]-{cc.total_lines_deleted:,}[/red]")
table.add_row("Net Change", f"[{net_color}]{cc.net_change:+,}[/{net_color}]")
table.add_row("Avg Churn/Commit", f"{cc.average_churn_per_commit:.1f}")
table.add_row("High Churn Commits", str(len(cc.high_churn_commits)))
console.print(Panel(table, title="[bold yellow]Code Churn[/bold yellow]", box=ROUNDED))
console.print()
@staticmethod
def _print_risky(console: Console, ra: Any) -> None:
"""Print risky commit metrics."""
table = Table(box=ROUNDED)
table.add_column("Metric", style="cyan")
table.add_column("Value", style="magenta")
risk_color = "red" if ra.risk_score > 20 else "orange" if ra.risk_score > 10 else "green"
table.add_row("Total Risky Commits", str(ra.total_risky_commits))
table.add_row("Risk Score", f"[{risk_color}]{ra.risk_score:.1f}%[/]")
table.add_row("Large Changes", str(len(ra.large_change_commits)))
table.add_row("Merge Commits", str(len(ra.merge_commits)))
table.add_row("Reverts", str(len(ra.revert_commits)))
console.print(Panel(table, title="[bold yellow]Risky Commits[/bold yellow]", box=ROUNDED))
console.print()
def format(data: Any) -> str:
"""Format data as string (not used for dashboard)."""
return "Dashboard output (use display() method)"