feat(dashboard): add milestone view and configurable columns

fixes #16, fixes #19

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
sylvain
2026-03-13 03:50:45 +01:00
parent ebf72c9a56
commit 60c6aaede3
8 changed files with 325 additions and 52 deletions

View File

@@ -10,10 +10,16 @@ import requests
from rich.console import Console
from gitea_dashboard.client import GiteaClient
from gitea_dashboard.collector import collect_all
from gitea_dashboard.collector import collect_all, collect_milestones
from gitea_dashboard.config import load_config, merge_config
from gitea_dashboard.display import render_dashboard, sort_repos
from gitea_dashboard.exporter import export_json
from gitea_dashboard.display import (
AVAILABLE_COLUMNS,
parse_columns,
render_dashboard,
render_milestones,
sort_repos,
)
from gitea_dashboard.exporter import export_json, export_milestones_json
_DEFAULT_URL = "http://192.168.0.106:3000"
@@ -24,9 +30,12 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
Options:
--repo / -r : noms de repos a inclure (repeatable)
--exclude / -x : noms de repos a exclure (repeatable)
--milestones : affiche la vue milestones au lieu du dashboard repos
--columns : liste des colonnes a afficher
--config : chemin vers un fichier de configuration YAML alternatif
Returns:
Namespace avec .repo (list[str] | None) et .exclude (list[str] | None)
Namespace avec les options parsees.
"""
parser = argparse.ArgumentParser(
description="Dashboard CLI affichant l'etat des repos Gitea.",
@@ -77,6 +86,17 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
default=None,
help="Chemin vers un fichier de configuration YAML alternatif.",
)
parser.add_argument(
"--milestones",
action="store_true",
default=False,
help="Affiche la vue milestones au lieu du dashboard repos.",
)
parser.add_argument(
"--columns",
default=None,
help="Colonnes a afficher (separees par virgules). Prefixe '-' pour exclure. 'help' pour lister.",
)
return parser.parse_args(argv)
@@ -143,18 +163,24 @@ def _run_health_check(client: GiteaClient, console: Console) -> None:
console.print(f"{len(repos)} repos accessibles")
def _print_columns_help(console: Console) -> None:
"""Affiche les colonnes disponibles."""
console.print("Colonnes disponibles :")
for name, desc in AVAILABLE_COLUMNS.items():
console.print(f" {name:15s} {desc}")
def main(argv: list[str] | None = None) -> None:
"""Point d'entree principal.
Args:
argv: Arguments CLI. Si None, utilise sys.argv (via argparse).
1. Parse les options CLI (--repo, --exclude)
2. Lit GITEA_URL (defaut: http://192.168.0.106:3000) et GITEA_TOKEN (requis)
1. Parse les options CLI
2. Resout la configuration (CLI > env > config > defaults)
3. Cree le GiteaClient
4. Collecte les donnees via collect_all() avec filtres
5. Affiche via render_dashboard()
6. Gere les erreurs : config manquante, connexion refusee, timeout
4. Route vers le mode appropriate (health, milestones, dashboard)
5. Gere les erreurs : config manquante, connexion refusee, timeout
"""
args = parse_args(argv)
console = Console(stderr=True)
@@ -165,6 +191,15 @@ def main(argv: list[str] | None = None) -> None:
console.print(f"[red]Erreur config : {exc}[/red]")
sys.exit(1)
# Handle --columns help before auth check
if args.columns is not None:
cols = parse_columns(args.columns, no_desc=args.no_desc)
if cols == ["__help__"]:
_print_columns_help(Console())
return
else:
cols = None
auth = args.resolved_auth if hasattr(args, "resolved_auth") and args.resolved_auth else None
if not auth:
auth = os.environ.get("GITEA_TOKEN")
@@ -187,6 +222,14 @@ def main(argv: list[str] | None = None) -> None:
_run_health_check(client, console)
return
if args.milestones:
milestones = collect_milestones(client, include=args.repo, exclude=args.exclude)
if args.format == "json":
print(export_milestones_json(milestones)) # noqa: T201
else:
render_milestones(milestones)
return
repos = collect_all(client, include=args.repo, exclude=args.exclude)
except requests.ConnectionError:
console.print("[red]Erreur : connexion refusee. Verifiez l'URL et le serveur Gitea.[/red]")
@@ -208,4 +251,11 @@ def main(argv: list[str] | None = None) -> None:
sorted_repos = sort_repos(repos, args.sort)
print(export_json(sorted_repos)) # noqa: T201
else:
render_dashboard(repos, sort_key=args.sort, show_description=not args.no_desc)
# Resolve columns for dashboard
active_cols = cols if cols is not None else parse_columns(None, no_desc=args.no_desc)
render_dashboard(
repos,
sort_key=args.sort,
show_description="description" in active_cols,
columns=active_cols,
)