Skip to content

Commit 40b8286

Browse files
refactoring __main__ for consistent pattern
1 parent b556f8d commit 40b8286

1 file changed

Lines changed: 89 additions & 29 deletions

File tree

src/datamanager/__main__.py

Lines changed: 89 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -496,18 +496,10 @@ def _rollback_interactive(ctx: typer.Context) -> None:
496496
pass
497497

498498

499-
@app.command()
500-
def delete(
501-
ctx: typer.Context,
502-
name: str = typer.Argument(..., help="The logical name of the dataset to delete."),
503-
) -> None:
504-
"""
505-
Marks a dataset for permanent deletion.
506-
This action is finalized via a Pull Request and CI/CD pipeline.
507-
"""
499+
def _run_delete_logic(ctx: typer.Context, name: str) -> None:
500+
"""The core logic for marking a dataset for deletion."""
508501
console.print(f"🗑️ Preparing deletion for [bold red]{name}[/].")
509502

510-
# Verify the dataset exists before proceeding
511503
if not manifest.get_dataset(name):
512504
console.print(f"[red]Error: Dataset '{name}' not found.[/]")
513505
raise typer.Exit(1)
@@ -516,7 +508,6 @@ def delete(
516508
"[bold yellow]WARNING:[/] This will propose the [underline]permanent deletion[/] of the dataset and all its version history from Cloudflare R2."
517509
)
518510

519-
# Use a text prompt for strong confirmation
520511
confirmation = questionary.text(
521512
f"To confirm, please type the name of the dataset ({name}):"
522513
).ask()
@@ -525,7 +516,6 @@ def delete(
525516
console.print("Confirmation failed. Deletion cancelled.")
526517
return
527518

528-
# Mark the dataset for deletion in the manifest
529519
if manifest.mark_for_deletion(name):
530520
console.print(
531521
f"\n[bold green]✅ Dataset '{name}' has been marked for deletion.[/]"
@@ -538,20 +528,13 @@ def delete(
538528
" 4. Open a Pull Request to finalize the deletion."
539529
)
540530
else:
541-
# This case should be caught by the check above, but is here for safety
542531
console.print(f"[red]Error: Could not mark '{name}' for deletion.[/]")
543532
raise typer.Exit(1)
544533

545534

546-
@app.command()
547-
def prune_versions(
548-
ctx: typer.Context,
549-
name: str = typer.Argument(..., help="The logical name of the dataset to prune."),
550-
keep: int = typer.Option(
551-
..., "--keep", "-k", help="The number of most recent versions to keep."
552-
),
553-
) -> None:
554-
"""Marks old versions of a dataset for permanent deletion."""
535+
# --- New Refactored Prune Logic ---
536+
def _run_prune_versions_logic(ctx: typer.Context, name: str, keep: int) -> None:
537+
"""The core logic for marking old versions for deletion."""
555538
console.print(f"🔪 Preparing to prune old versions of [cyan]{name}[/]...")
556539

557540
dataset = manifest.get_dataset(name)
@@ -586,7 +569,6 @@ def prune_versions(
586569
console.print("Pruning cancelled.")
587570
return
588571

589-
# Mark the versions for deletion in the manifest
590572
manifest.mark_versions_for_deletion(name, versions_to_delete)
591573
console.print(
592574
f"\n[bold green]✅ {len(versions_to_delete)} version(s) have been marked for deletion.[/]"
@@ -600,6 +582,87 @@ def prune_versions(
600582
)
601583

602584

585+
# --- Updated CLI Commands (now thin wrappers) ---
586+
@app.command()
587+
def delete(
588+
ctx: typer.Context,
589+
name: str = typer.Argument(..., help="The logical name of the dataset to delete."),
590+
) -> None:
591+
"""Marks a dataset for permanent deletion via a PR."""
592+
_run_delete_logic(ctx, name)
593+
594+
595+
@app.command()
596+
def prune_versions(
597+
ctx: typer.Context,
598+
name: str = typer.Argument(..., help="The logical name of the dataset to prune."),
599+
keep: int = typer.Option(
600+
..., "--keep", "-k", help="The number of most recent versions to keep."
601+
),
602+
) -> None:
603+
"""Marks old versions of a dataset for permanent deletion via a PR."""
604+
_run_prune_versions_logic(ctx, name, keep)
605+
606+
607+
# --- New Interactive Functions for TUI ---
608+
def _delete_interactive(ctx: typer.Context) -> None:
609+
"""Guides the user through deleting a dataset interactively."""
610+
console.print("\n[bold]Interactive Dataset Deletion[/]")
611+
all_datasets = manifest.read_manifest()
612+
if not all_datasets:
613+
console.print("[yellow]No datasets found to delete.[/]")
614+
return
615+
616+
dataset_names = [ds["fileName"] for ds in all_datasets]
617+
selected_name = questionary.select(
618+
"Which dataset would you like to mark for deletion?", choices=dataset_names
619+
).ask()
620+
621+
if selected_name is None:
622+
console.print("Deletion cancelled.")
623+
return
624+
625+
try:
626+
_run_delete_logic(ctx, name=selected_name)
627+
except typer.Exit:
628+
pass
629+
630+
631+
def _prune_versions_interactive(ctx: typer.Context) -> None:
632+
"""Guides the user through pruning old versions interactively."""
633+
console.print("\n[bold]Interactive Version Pruning[/]")
634+
all_datasets = manifest.read_manifest()
635+
if not all_datasets:
636+
console.print("[yellow]No datasets found to prune.[/]")
637+
return
638+
639+
dataset_names = [ds["fileName"] for ds in all_datasets]
640+
selected_name = questionary.select(
641+
"Which dataset would you like to prune?", choices=dataset_names
642+
).ask()
643+
644+
if selected_name is None:
645+
console.print("Pruning cancelled.")
646+
return
647+
648+
keep_str = questionary.text(
649+
"How many of the most recent versions do you want to keep?",
650+
validate=lambda text: text.isdigit()
651+
and int(text) > 0
652+
or "Please enter a positive number.",
653+
).ask()
654+
655+
if keep_str is None:
656+
console.print("Pruning cancelled.")
657+
return
658+
659+
try:
660+
_run_prune_versions_logic(ctx, name=selected_name, keep=int(keep_str))
661+
except typer.Exit:
662+
pass
663+
664+
665+
# --- Final, Corrected Main TUI Callback ---
603666
@app.callback(invoke_without_command=True)
604667
def main(ctx: typer.Context, no_prompt: bool = COMMON_OPTIONS["no_prompt"]) -> None:
605668
"""
@@ -609,7 +672,6 @@ def main(ctx: typer.Context, no_prompt: bool = COMMON_OPTIONS["no_prompt"]) -> N
609672
ctx.ensure_object(dict)
610673
ctx.obj["no_prompt"] = no_prompt
611674

612-
# If a sub-command was provided just return – ctx.obj is now populated.
613675
if ctx.invoked_subcommand:
614676
return
615677

@@ -620,13 +682,13 @@ def main(ctx: typer.Context, no_prompt: bool = COMMON_OPTIONS["no_prompt"]) -> N
620682
console.print("[bold yellow]Welcome to the Data Manager TUI![/]")
621683

622684
actions: dict[str, Callable[[typer.Context], None] | str] = {
623-
"Verify R2 configuration": verify,
624685
"List all datasets": list_datasets,
625686
"Prepare a dataset for release": _prepare_interactive,
626687
"Pull a dataset version": _pull_interactive,
627688
"Rollback a dataset to a previous version": _rollback_interactive,
628-
"Delete a dataset": delete,
629-
"Prune old dataset versions": prune_versions,
689+
"Delete a dataset": _delete_interactive,
690+
"Prune old dataset versions": _prune_versions_interactive,
691+
"Verify R2 configuration": verify,
630692
"Exit": "exit",
631693
}
632694

@@ -640,9 +702,7 @@ def main(ctx: typer.Context, no_prompt: bool = COMMON_OPTIONS["no_prompt"]) -> N
640702

641703
action = actions[choice]
642704
if callable(action):
643-
# Call the function directly
644705
action(ctx)
645-
646706
else:
647707
raise NotImplementedError(f"Action '{choice}' is not implemented yet.")
648708

0 commit comments

Comments
 (0)