From e9df73510182a9d8b0f32db8636824be095e0032 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 29 Jan 2026 15:42:20 +0000 Subject: [PATCH] Initial upload: gitignore-cli-generator v1.0.0 --- src/gitignore_cli/interactive.py | 114 +++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/gitignore_cli/interactive.py diff --git a/src/gitignore_cli/interactive.py b/src/gitignore_cli/interactive.py new file mode 100644 index 0000000..e7bf335 --- /dev/null +++ b/src/gitignore_cli/interactive.py @@ -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()