Initial upload: gitignore-cli-generator v1.0.0
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / type-check (push) Has been cancelled
CI / build (push) Has been cancelled
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / type-check (push) Has been cancelled
CI / build (push) Has been cancelled
This commit is contained in:
114
src/gitignore_cli/interactive.py
Normal file
114
src/gitignore_cli/interactive.py
Normal file
@@ -0,0 +1,114 @@
|
||||
"""Interactive mode module for wizard-like template selection."""
|
||||
|
||||
from typing import List
|
||||
|
||||
from rich.console import Console
|
||||
from rich.prompt import Prompt
|
||||
from rich.table import Table
|
||||
|
||||
from .template_loader import TemplateInfo, TemplateLoader
|
||||
|
||||
|
||||
console = Console()
|
||||
|
||||
|
||||
class InteractiveWizard:
|
||||
"""Handles interactive template selection via wizard flow."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.loader = TemplateLoader()
|
||||
|
||||
def run_wizard(self) -> List[str]:
|
||||
"""Run the interactive wizard and return selected template names."""
|
||||
selected: List[str] = []
|
||||
|
||||
console.print("\n[bold cyan]GitIgnore CLI Generator[/bold cyan]")
|
||||
console.print("This wizard will help you create a .gitignore file.\n")
|
||||
|
||||
categories = self.loader.get_templates_by_category()
|
||||
|
||||
for category_name, templates in sorted(categories.items()):
|
||||
selected.extend(self._select_category(category_name, templates))
|
||||
|
||||
if selected:
|
||||
console.print(f"\n[bold green]Selected {len(selected)} template(s):[/bold green]")
|
||||
for name in selected:
|
||||
template = self.loader.get_template_info(name)
|
||||
if template:
|
||||
console.print(f" - {template.name}: {template.description}")
|
||||
|
||||
return selected
|
||||
|
||||
def _select_category(self, category_name: str, templates: List[TemplateInfo]) -> List[str]:
|
||||
"""Present templates from a category for selection."""
|
||||
console.print(f"\n[bold yellow]=== {category_name.upper()} ===[/bold yellow]")
|
||||
|
||||
table = Table(title=f"{category_name.title()} Templates")
|
||||
table.add_column("#", justify="right", style="cyan")
|
||||
table.add_column("Template", style="magenta")
|
||||
table.add_column("Description", style="green")
|
||||
|
||||
for i, template in enumerate(templates, 1):
|
||||
table.add_row(str(i), template.name, template.description)
|
||||
|
||||
console.print(table)
|
||||
|
||||
console.print("\n[italic]Enter template numbers to add (e.g., '1,3,5'), 'all' for all, or press Enter to skip:[/italic]")
|
||||
user_input = Prompt.ask("Selection", default="").strip()
|
||||
|
||||
if not user_input:
|
||||
return []
|
||||
if user_input.lower() == "all":
|
||||
return [t.name for t in templates]
|
||||
|
||||
selected: List[str] = []
|
||||
selected_indices: set = set()
|
||||
|
||||
try:
|
||||
parts = user_input.replace(",", " ").split()
|
||||
for part in parts:
|
||||
if "-" in part:
|
||||
start_end = part.split("-")
|
||||
if len(start_end) == 2:
|
||||
start = int(start_end[0])
|
||||
end = int(start_end[1])
|
||||
for idx in range(start, end + 1):
|
||||
selected_indices.add(idx)
|
||||
else:
|
||||
selected_indices.add(int(part))
|
||||
except ValueError:
|
||||
console.print("[bold red]Invalid selection. Skipping this category.[/bold red]")
|
||||
return []
|
||||
|
||||
for idx in selected_indices:
|
||||
if 1 <= idx <= len(templates):
|
||||
selected.append(templates[idx - 1].name)
|
||||
|
||||
return selected
|
||||
|
||||
def confirm_generation(self, template_names: List[str]) -> bool:
|
||||
"""Confirm with user before generating the .gitignore file."""
|
||||
if not template_names:
|
||||
console.print("[yellow]No templates selected.[/yellow]")
|
||||
return False
|
||||
|
||||
console.print("\n[bold]Selected templates:[/bold]")
|
||||
for name in template_names:
|
||||
template = self.loader.get_template_info(name)
|
||||
if template:
|
||||
console.print(f" - {template.name}")
|
||||
|
||||
console.print("\n")
|
||||
confirm = Prompt.ask(
|
||||
"Generate .gitignore file?",
|
||||
choices=["y", "n"],
|
||||
default="y",
|
||||
)
|
||||
|
||||
return confirm.lower() == "y"
|
||||
|
||||
|
||||
def run_interactive_mode() -> List[str]:
|
||||
"""Run the interactive mode and return selected templates."""
|
||||
wizard = InteractiveWizard()
|
||||
return wizard.run_wizard()
|
||||
Reference in New Issue
Block a user