from typing import Optional import os import click from rich.console import Console from src.git_insights import GitInsights from src.utils.config import load_config console = Console() @click.group() @click.option("--repo-path", "-p", default=".", help="Path to git repository") @click.option("--days", "-d", default=30, type=int, help="Number of days to analyze") @click.pass_context def main(ctx: click.Context, repo_path: str, days: int) -> None: """Git Insights CLI - Analyze git repositories for productivity insights.""" ctx.ensure_object(dict) ctx.obj["repo_path"] = repo_path ctx.obj["days"] = days @main.command() @click.option("--format", "-f", type=click.Choice(["json", "markdown", "html", "console"]), default="console") @click.pass_context def analyze(ctx: click.Context, format: str) -> None: """Analyze repository for commit patterns, code churn, and productivity metrics.""" repo_path = ctx.obj["repo_path"] days = ctx.obj["days"] if not os.path.isdir(repo_path): console.print(f"[red]Error: Directory not found: {repo_path}[/red]") return try: insights = GitInsights(repo_path=repo_path, days=days) results = insights.analyze() if format == "json": from src.formatters import JSONFormatter console.print(JSONFormatter.format(results)) elif format == "markdown": from src.formatters import MarkdownFormatter console.print(MarkdownFormatter.format(results)) elif format == "html": from src.formatters import HTMLFormatter console.print(HTMLFormatter.format(results)) else: from src.formatters import DashboardFormatter DashboardFormatter.display(results) except Exception as e: console.print(f"[red]Error: {e}[/red]") raise @main.command() @click.pass_context def dashboard(ctx: click.Context) -> None: """Display productivity metrics in an interactive dashboard.""" repo_path = ctx.obj["repo_path"] days = ctx.obj["days"] if not os.path.isdir(repo_path): console.print(f"[red]Error: Directory not found: {repo_path}[/red]") return try: insights = GitInsights(repo_path=repo_path, days=days) results = insights.analyze() from src.formatters import DashboardFormatter DashboardFormatter.display(results) except Exception as e: console.print(f"[red]Error: {e}[/red]") raise @main.command() @click.option("--format", "-f", type=click.Choice(["json", "markdown", "html"]), default="json") @click.option("--output", "-o", default=None, type=str, help="Output file path") @click.pass_context def export(ctx: click.Context, format: str, output: Optional[str]) -> None: """Export analysis results to a file.""" repo_path = ctx.obj["repo_path"] days = ctx.obj["days"] if not os.path.isdir(repo_path): console.print(f"[red]Error: Directory not found: {repo_path}[/red]") return try: insights = GitInsights(repo_path=repo_path, days=days) results = insights.analyze() if format == "json": from src.formatters import JSONFormatter output_str = JSONFormatter.format(results) elif format == "markdown": from src.formatters import MarkdownFormatter output_str = MarkdownFormatter.format(results) else: from src.formatters import HTMLFormatter output_str = HTMLFormatter.format(results) if output: with open(output, "w") as f: f.write(output_str) console.print(f"[green]Exported to {output}[/green]") else: console.print(output_str) except Exception as e: console.print(f"[red]Error: {e}[/red]") raise