Files
DevGen/devgen/cli/gitignore.py
T
2025-12-12 11:10:30 +05:45

134 lines
4.2 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:
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:
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 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("\n Cancelled 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)