From 6fcb5ecfbbb4accb9991163b7b3992caa5a0b71e Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sun, 1 Feb 2026 07:58:06 +0000 Subject: [PATCH] Add models, analyzers, and formatters --- src/formatters/dashboard.py | 170 +++++++++++++++++------------------- 1 file changed, 82 insertions(+), 88 deletions(-) diff --git a/src/formatters/dashboard.py b/src/formatters/dashboard.py index 3578af7..d8fa0db 100644 --- a/src/formatters/dashboard.py +++ b/src/formatters/dashboard.py @@ -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)"