RepoRepair / cli /main_simple.py
Tanish2416's picture
Upload folder using huggingface_hub
3fe77a3 verified
Raw History Blame Contribute Delete
7.6 kB
"""Simplified CLI for RepoRepair - works without ChromaDB."""
import logging
from pathlib import Path
from typing import Optional
import typer
from rich.console import Console
from rich.panel import Panel
from config import get_settings
from tools.github_tool import GitHubTool
from tools.git_tool import GitTool
app = typer.Typer(
name="reporepair",
help="AI GitHub Issue to Pull Request Agent (Simplified)",
add_completion=False,
)
console = Console()
def setup_logging(verbose: bool = False) -> None:
"""Configure logging."""
settings = get_settings()
log_level = logging.DEBUG if verbose else logging.INFO
logging.basicConfig(
level=log_level,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=[logging.FileHandler(settings.log_file)],
)
@app.command()
def fix(
issue_url: str = typer.Argument(..., help="GitHub issue URL"),
dry_run: bool = typer.Option(True, "--dry-run/--no-dry-run", help="Analyze without creating PR"),
verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose logging"),
) -> None:
"""
Analyze a GitHub issue and generate a fix strategy.
Note: This simplified version shows what RepoRepair would do.
Full AI-powered fixes require additional packages (ChromaDB, sentence-transformers).
"""
setup_logging(verbose)
logger = logging.getLogger(__name__)
console.print(Panel.fit(
"[bold blue]RepoRepair[/bold blue] - Simplified Mode\n"
"Analyzing GitHub Issue",
border_style="blue",
))
try:
# Validate URL
import re
pattern = r"https://github\.com/([^/]+)/([^/]+)/issues/(\d+)"
match = re.match(pattern, issue_url)
if not match:
console.print("[bold red]Error:[/bold red] Invalid GitHub issue URL")
console.print("Expected: https://github.com/owner/repo/issues/123")
raise typer.Exit(code=1)
owner, repo, issue_number = match.groups()
issue_number = int(issue_number)
console.print(f"\n[bold]Repository:[/bold] {owner}/{repo}")
console.print(f"[bold]Issue:[/bold] #{issue_number}")
console.print(f"[bold]Mode:[/bold] {'Dry Run' if dry_run else 'Full Run'}\n")
# Initialize tools
settings = get_settings()
console.print("[yellow]>[/yellow] Connecting to GitHub...")
github_tool = GitHubTool(settings.github_token)
# Fetch issue
console.print("[yellow]>[/yellow] Fetching issue details...")
issue = github_tool.get_issue(owner, repo, issue_number)
console.print(f"\n[bold green]OK[/bold green] Issue fetched: {issue.title}")
console.print(f"[dim]Author: {issue.author}[/dim]")
console.print(f"[dim]State: {issue.state}[/dim]")
console.print(f"[dim]Labels: {', '.join(issue.labels) if issue.labels else 'None'}[/dim]\n")
console.print("[bold]Issue Description:[/bold]")
console.print(Panel(issue.body[:500] + ("..." if len(issue.body) > 500 else ""),
border_style="dim"))
# Clone repository
console.print("\n[yellow]>[/yellow] Cloning repository...")
git_tool = GitTool(settings.workspace_dir)
repo_path = git_tool.clone_repository(owner, repo, settings.github_token)
console.print(f"[bold green]OK[/bold green] Repository cloned to {repo_path}\n")
# Show what full version would do
console.print("[bold cyan]=== What Full RepoRepair Would Do ===[/bold cyan]\n")
console.print("[bold]1. AI Analysis (Planner Agent)[/bold]")
console.print(" - Analyze issue with Gemini AI")
console.print(" - Identify bug type and root cause")
console.print(" - Create fix strategy")
console.print(" - Generate search queries\n")
console.print("[bold]2. Code Search (Searcher Agent)[/bold]")
console.print(" - Index repository with ChromaDB")
console.print(" - Semantic search for relevant files")
console.print(" - Keyword search with grep")
console.print(" - Rank and filter results\n")
console.print("[bold]3. Code Generation (Coder Agent)[/bold]")
console.print(" - Load relevant files")
console.print(" - Generate code fix with Gemini")
console.print(" - Create new branch")
console.print(" - Apply changes\n")
console.print("[bold]4. Validation (Validator Agent)[/bold]")
console.print(" - Run tests in Docker")
console.print(" - Validate changes")
console.print(" - Retry if needed (max 3 attempts)\n")
console.print("[bold]5. Pull Request Creation[/bold]")
console.print(" - Commit changes")
console.print(" - Push to GitHub")
console.print(" - Create draft PR with detailed description\n")
# Show installation instructions
console.print("[bold yellow]! To Enable Full Features:[/bold yellow]")
console.print("\nInstall required packages:")
console.print("[cyan]pip install chromadb sentence-transformers[/cyan]")
console.print("\nNote: Requires Visual Studio C++ Build Tools on Windows")
console.print("Download: https://visualstudio.microsoft.com/visual-cpp-build-tools/\n")
# Summary
console.print("[bold green]OK Analysis Complete![/bold green]\n")
console.print(f"[bold]Next Steps:[/bold]")
console.print(f"1. Review the issue: {issue.url}")
console.print(f"2. Install full dependencies (see above)")
console.print(f"3. Run: [cyan]reporepair fix {issue_url}[/cyan]")
console.print(f"4. Review the generated draft PR")
console.print(f"5. Merge when satisfied!\n")
except (typer.Exit, typer.Abort):
raise
except Exception as e:
logger.exception("Unexpected error")
console.print(f"\n[bold red]ERROR:[/bold red] {e}")
raise typer.Exit(code=1)
@app.command()
def config() -> None:
"""Show current configuration."""
try:
settings = get_settings()
console.print("\n[bold]RepoRepair Configuration[/bold]\n")
console.print(f"[bold]Workspace:[/bold] {settings.workspace_dir}")
console.print(f"[bold]Log Level:[/bold] {settings.log_level}")
console.print(f"[bold]Max Diff Lines:[/bold] {settings.max_diff_lines}")
console.print(f"[bold]Planning Model:[/bold] {settings.gemini_planning_model}")
console.print(f"[bold]Coding Model:[/bold] {settings.gemini_coding_model}")
console.print(f"\n[bold]GitHub Token:[/bold] {'[green]Set[/green]' if settings.github_token else '[red]Missing[/red]'}")
console.print(f"[bold]Gemini API Key:[/bold] {'[green]Set[/green]' if settings.gemini_api_key else '[red]Missing[/red]'}")
console.print("\n[bold yellow]Mode:[/bold yellow] Simplified (missing optional dependencies)")
console.print("[dim]Install chromadb + sentence-transformers for full features[/dim]\n")
except Exception as e:
console.print(f"[bold red]Error loading config:[/bold red] {e}")
raise typer.Exit(code=1)
if __name__ == "__main__":
app()