feat(cli): add initial repository management commands
- Introduce CLI using Typer for repository management - Add commands for archiving, cleaning, moving, reviewing, and status - Implement configuration loading and default structure setup - Include utilities for Git status checks and directory size calculation - Lay groundwork for extensible repository operations Signed-off-by: Max P. <Mail@MPassarello.de>
This commit is contained in:
81
src/repocat/cli/move.py
Normal file
81
src/repocat/cli/move.py
Normal file
@@ -0,0 +1,81 @@
|
||||
from typer import Typer, Argument
|
||||
from rich.console import Console
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import typer
|
||||
|
||||
from repocat.config import load_config
|
||||
|
||||
app = Typer()
|
||||
console = Console()
|
||||
|
||||
|
||||
def complete_source_repo(incomplete: str):
|
||||
config = load_config()
|
||||
base = config.base_dir
|
||||
results = []
|
||||
|
||||
for cat in config.categories:
|
||||
if cat.is_archive:
|
||||
continue
|
||||
cat_path = base / cat.subdir
|
||||
if not cat_path.exists():
|
||||
continue
|
||||
for item in cat_path.iterdir():
|
||||
if item.is_dir():
|
||||
full_name = f"{cat.name}/{item.name}"
|
||||
if full_name.startswith(incomplete):
|
||||
results.append(full_name)
|
||||
return sorted(results)
|
||||
|
||||
|
||||
def complete_category(incomplete: str):
|
||||
config = load_config()
|
||||
return [c.name for c in config.categories if c.name.startswith(incomplete) and c.name != "archive"]
|
||||
|
||||
|
||||
@app.command("move")
|
||||
def move_command(
|
||||
source: str = Argument(..., help="Quell-Repo im Format <category>/<reponame>", autocompletion=complete_source_repo),
|
||||
target: str = Argument(..., help="Zielkategorie", autocompletion=complete_category),
|
||||
):
|
||||
"""
|
||||
Verschiebt ein Repository in eine andere Kategorie.
|
||||
"""
|
||||
config = load_config()
|
||||
base = config.base_dir
|
||||
|
||||
# Quelle aufspalten in Kategorie und Repo
|
||||
try:
|
||||
source_cat_name, repo_name = source.split("/", 1)
|
||||
except ValueError:
|
||||
console.print("[red]Ungültiges Format für Quelle. Bitte <kategorie>/<reponame> angeben.[/]")
|
||||
raise typer.Exit(1)
|
||||
|
||||
source_cat = next((c for c in config.categories if c.name == source_cat_name), None)
|
||||
if not source_cat:
|
||||
console.print(f"[red]Unbekannte Quellkategorie:[/] {source_cat_name}")
|
||||
raise typer.Exit(1)
|
||||
|
||||
target_cat = next((c for c in config.categories if c.name == target), None)
|
||||
if not target_cat:
|
||||
console.print(f"[red]Ungültige Zielkategorie:[/] {target}")
|
||||
raise typer.Exit(1)
|
||||
|
||||
source_path = base / source_cat.subdir / repo_name
|
||||
destination_path = base / target_cat.subdir / repo_name
|
||||
|
||||
if not source_path.exists():
|
||||
console.print(f"[red]Quell-Repository existiert nicht:[/] {source_path}")
|
||||
raise typer.Exit(1)
|
||||
|
||||
if destination_path.exists():
|
||||
console.print(f"[red]Zielordner existiert bereits:[/] {destination_path}")
|
||||
raise typer.Exit(1)
|
||||
|
||||
try:
|
||||
shutil.move(str(source_path), str(destination_path))
|
||||
console.print(f"[green]✓ Erfolgreich verschoben:[/] {source_cat.name}/{repo_name} → {target}")
|
||||
except Exception as e:
|
||||
console.print(f"[red]Fehler beim Verschieben:[/] {e}")
|
||||
raise typer.Exit(1)
|
||||
Reference in New Issue
Block a user