refactor(review): streamline repo review logic and data handling

- Replaces manual path handling with `RepoCatalogState` abstraction
- Simplifies repo status checks and removes redundant imports
- Improves clarity and maintainability of interactive review process
This commit is contained in:
2025-05-11 14:38:44 +02:00
parent 9bff626f30
commit 68b3233fcb

View File

@@ -1,19 +1,15 @@
from typer import Typer, confirm, prompt
from typer import Typer
from rich.console import Console
from rich.table import Table
from pathlib import Path
import shutil
from datetime import datetime
import typer
from rich.prompt import Prompt, Confirm
from datetime import datetime
import shutil
import typer
from repocat.cli.move import move_command
from repocat.config import load_config
from repocat.models.config import RepoCategory
from repocat.models.catalog import RepoCatalogState
from repocat.cli.move import move_command
from repocat.cli.archive import archive_repo
from repocat.cli.clean import get_dir_size, is_git_dirty, is_git_unpushed
app = Typer()
console = Console()
@@ -23,48 +19,39 @@ def review():
"""
Führt interaktiv durch alle Repositories im Review-Ordner.
"""
config = load_config()
base = config.base_dir
catalog = RepoCatalogState.from_config(load_config())
archive_cat = next((c for c in config.categories if c.is_archive), None)
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)
archive_path = base / archive_cat.subdir
archive_path.mkdir(parents=True, exist_ok=True)
review_cat = next((c for c in config.categories if c.name == "review"), None)
review_cat = catalog.get_category("review")
if not review_cat:
console.print("[red]Kein 'review'-Eintrag in der Konfiguration gefunden.[/]")
raise typer.Exit(1)
review_path = base / review_cat.subdir
if not review_path.exists():
console.print(f"[yellow]Hinweis:[/] Kein review-Ordner vorhanden unter {review_path}")
return
repos = [p for p in review_path.iterdir() if p.is_dir()]
if not repos:
if not review_cat.repos:
console.print("[green]✓ Keine Repositories im Review-Ordner.[/]")
return
for repo in sorted(repos):
for repo in sorted(review_cat.repos, key=lambda r: r.name):
console.rule(f"[bold cyan]{repo.name}")
age_days = (datetime.now() - datetime.fromtimestamp(repo.stat().st_mtime)).days
size_mb = get_dir_size(repo) / 1024 / 1024
console.print(f"[bold]Alter:[/] {repo.age_days} Tage")
console.print(f"[bold]Größe:[/] {repo.size_mb:.1f} MB")
status = []
if is_git_dirty(repo):
status.append("uncommitted")
if is_git_unpushed(repo):
status.append("unpushed")
if not status:
status.append("clean")
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]Alter:[/] {age_days} Tage")
console.print(f"[bold]Größe:[/] {size_mb:.1f} MB")
console.print(f"[bold]Git:[/] {', '.join(status)}")
while True:
@@ -81,17 +68,17 @@ def review():
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)
shutil.rmtree(repo.path)
console.print(f"[red]✓ Gelöscht:[/] {repo.name}")
break
elif action in ("m", "move"):
target_categories = [c.name for c in config.categories if c.name != "review" and not c.is_archive]
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, archive_path, dry_run=False)
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:
@@ -99,4 +86,4 @@ def review():
else:
console.print("[yellow]Ungültige Eingabe. Gültig sind: m, d, s, q[/]")
console.print("[green]✓ Review abgeschlossen.[/]")
console.print("[green]✓ Review abgeschlossen.[/]")