139 lines
4.3 KiB
Python
139 lines
4.3 KiB
Python
from typing import List, Optional
|
||
|
||
import questionary
|
||
import typer
|
||
from typing_extensions import Annotated
|
||
|
||
from devgen.modules.gitignore_generator import GitignoreGenerator
|
||
|
||
app = typer.Typer(
|
||
name="gitignore",
|
||
help="🙈 Generate .gitignore files from GitHub templates.",
|
||
no_args_is_help=True,
|
||
rich_markup_mode="markdown",
|
||
)
|
||
|
||
|
||
@app.command("list")
|
||
def list_templates(
|
||
cached: Annotated[
|
||
bool, typer.Option("--cached", "-c", help="List only cached templates.")
|
||
] = False,
|
||
) -> None:
|
||
"""List available gitignore templates."""
|
||
generator = GitignoreGenerator()
|
||
try:
|
||
if cached:
|
||
templates = generator.list_cached_templates()
|
||
typer.secho(" Cached Templates:", fg=typer.colors.CYAN, bold=True)
|
||
else:
|
||
typer.secho("Fetching available templates...", fg=typer.colors.YELLOW)
|
||
templates = generator.list_available_templates()
|
||
typer.secho(" Available Templates:", fg=typer.colors.CYAN, bold=True)
|
||
|
||
if not templates:
|
||
typer.echo("No templates found.")
|
||
return
|
||
|
||
# Print in columns or just list
|
||
typer.echo(", ".join(templates))
|
||
|
||
except Exception as e:
|
||
typer.secho(f" Error: {e}", fg=typer.colors.RED)
|
||
raise typer.Exit(code=1)
|
||
|
||
|
||
@app.command("generate")
|
||
def generate_gitignore(
|
||
templates: Annotated[
|
||
Optional[List[str]],
|
||
typer.Argument(
|
||
help="Names of templates to include (e.g. Python Node). If empty, interactive mode is used."
|
||
),
|
||
] = None,
|
||
output: Annotated[
|
||
str,
|
||
typer.Option("--output", "-o", help="Output file path."),
|
||
] = ".gitignore",
|
||
append: Annotated[
|
||
bool,
|
||
typer.Option(
|
||
"--append/--overwrite",
|
||
"-a/-w",
|
||
help="Append to existing file or overwrite.",
|
||
),
|
||
] = True,
|
||
offline: Annotated[
|
||
bool,
|
||
typer.Option("--offline", help="Use only cached templates."),
|
||
] = False,
|
||
) -> None:
|
||
"""Generate a .gitignore file."""
|
||
generator = GitignoreGenerator()
|
||
|
||
if not templates:
|
||
# Interactive mode
|
||
try:
|
||
if offline:
|
||
available = generator.list_cached_templates()
|
||
else:
|
||
typer.secho("Fetching templates list...", fg=typer.colors.YELLOW)
|
||
available = generator.list_available_templates()
|
||
|
||
if not available:
|
||
typer.secho(" No templates available.", fg=typer.colors.RED)
|
||
raise typer.Exit(code=1)
|
||
|
||
from devgen.utils import get_questionary_style
|
||
|
||
style = get_questionary_style()
|
||
|
||
# Interactive search loop
|
||
selected_templates = []
|
||
while True:
|
||
# Filter out already selected
|
||
choices = [t for t in available if t not in selected_templates]
|
||
# Add "Done" option at the top
|
||
choices.insert(0, "Done (Finish selection)")
|
||
|
||
choice = questionary.autocomplete(
|
||
"Search for a template (type to search, select 'Done' to finish):",
|
||
choices=choices,
|
||
ignore_case=True,
|
||
match_middle=True,
|
||
validate=lambda x: x in choices or x == "",
|
||
style=style,
|
||
).ask()
|
||
|
||
if choice is None:
|
||
raise typer.Exit(code=130)
|
||
|
||
if not choice or choice.startswith("Done"):
|
||
break
|
||
|
||
selected_templates.append(choice)
|
||
typer.secho(f"➕ Added '{choice}'", fg=typer.colors.GREEN)
|
||
|
||
templates = selected_templates
|
||
|
||
if not templates:
|
||
typer.secho("No templates selected.", fg=typer.colors.YELLOW)
|
||
raise typer.Exit()
|
||
|
||
except typer.Exit:
|
||
raise
|
||
except KeyboardInterrupt:
|
||
typer.secho("\nCancelled by user", fg=typer.colors.YELLOW)
|
||
raise typer.Exit()
|
||
except Exception as e:
|
||
typer.secho(f"❌ Error fetching templates: {e}", fg=typer.colors.RED)
|
||
raise typer.Exit(code=1)
|
||
|
||
try:
|
||
generator.generate(
|
||
templates, output_file=output, append=append, offline=offline
|
||
)
|
||
except Exception as e:
|
||
typer.secho(f"❌ Error generating .gitignore: {e}", fg=typer.colors.RED)
|
||
raise typer.Exit(code=1)
|