import os from typing import Optional 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.option( "--config", "-c", default=None, type=str, help="Path to config file", ) @click.pass_context def main( ctx: click.Context, repo_path: str, days: int, config: Optional[str], ) -> None: """Git Insights CLI - Analyze git repositories for productivity insights.""" ctx.ensure_object(dict) ctx.obj["repo_path"] = repo_path ctx.obj["days"] = days ctx.obj["config"] = config @main.command() @click.option( "--format", "-f", type=click.Choice(["json", "markdown", "html", "console"]), default="console", help="Output format", ) @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"] config_path = ctx.obj["config"] config = load_config(config_path) if config_path else None 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, config=config, ) 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"] config_path = ctx.obj["config"] config = load_config(config_path) if config_path else None 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, config=config, ) 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", help="Output format", ) @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"] config_path = ctx.obj["config"] config = load_config(config_path) if config_path else None 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, config=config, ) 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 @main.command() @click.option( "--output", "-o", default=None, type=str, help="Output file path", ) @click.pass_context def report(ctx: click.Context, output: Optional[str]) -> None: """Generate a comprehensive productivity report.""" repo_path = ctx.obj["repo_path"] days = ctx.obj["days"] config_path = ctx.obj["config"] config = load_config(config_path) if config_path else None 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, config=config, ) results = insights.analyze() from src.formatters import HTMLFormatter report_str = HTMLFormatter.format(results) if output: with open(output, "w") as f: f.write(report_str) console.print(f"[green]Report generated: {output}[/green]") else: console.print(report_str) except Exception as e: console.print(f"[red]Error: {e}[/red]") raise