from typer import Typer from rich.console import Console from rich.prompt import Prompt, Confirm from datetime import datetime import shutil import typer from repocat.config import load_config from repocat.models.catalog import RepoCatalogState from repocat.cli.move import move_command from repocat.cli.archive import archive_repo app = Typer() console = Console() @app.command("run") def review(): """ Führt interaktiv durch alle Repositories im Review-Ordner. """ catalog = RepoCatalogState.from_config(load_config()) archive_cat = next((c for c in catalog.categories if c.config.is_archive), None) if not archive_cat: console.print("[red]Keine Archiv-Kategorie in der Konfiguration gefunden.[/]") raise typer.Exit(1) review_cat = catalog.get_category("review") if not review_cat: console.print("[red]Kein 'review'-Eintrag in der Konfiguration gefunden.[/]") raise typer.Exit(1) if not review_cat.repos: console.print("[green]✓ Keine Repositories im Review-Ordner.[/]") return for repo in sorted(review_cat.repos, key=lambda r: r.name): console.rule(f"[bold cyan]{repo.name}") console.print(f"[bold]Alter:[/] {repo.age_days} Tage") console.print(f"[bold]Größe:[/] {repo.size_mb:.1f} MB") if repo.git: status = [] if repo.git.dirty: status.append("uncommitted") if repo.git.unpushed: status.append("unpushed") if not status: status.append("clean") else: status = ["kein Git"] console.print(f"[bold]Git:[/] {', '.join(status)}") while True: action = Prompt.ask( "Aktion \\[m]ove / \\[a]rchive / \\[d]elete / \\[s]kip / \\[q]uit", choices=["m", "a", "d", "s", "q"], show_choices=False ) if action in ("s", "skip", ""): break elif action in ("q", "quit"): console.print("[bold yellow]Abgebrochen.[/]") raise typer.Exit() elif action in ("d", "delete"): if Confirm.ask(f"Bist du sicher, dass du [red]{repo.name}[/] löschen willst?"): shutil.rmtree(repo.path) console.print(f"[red]✓ Gelöscht:[/] {repo.name}") break elif action in ("m", "move"): target_categories = [c.config.name for c in catalog.categories if c.config.name != "review" and not c.config.is_archive] target = Prompt.ask("Zielkategorie", choices=target_categories) move_command(source=f"review/{repo.name}", target=target) break elif action in ("a", "archive"): try: archive_file = archive_repo(repo.path, archive_cat.path, dry_run=False) console.print(f"[green]✓ Archiviert:[/] {archive_file.name}") break except Exception as e: console.print(f"[red]Fehler beim Archivieren:[/] {e}") else: console.print("[yellow]Ungültige Eingabe. Gültig sind: m, d, s, q[/]") console.print("[green]✓ Review abgeschlossen.[/]")