|
| 1 | +from pathlib import Path |
| 2 | + |
| 3 | +import typer |
| 4 | + |
| 5 | +from leetcode_py.tools.generator import generate_problem |
| 6 | + |
| 7 | +from ..utils.problem_finder import find_problem_by_number, find_problems_by_tag, get_problem_json_path |
| 8 | +from ..utils.resources import get_template_path |
| 9 | + |
| 10 | + |
| 11 | +def resolve_problems( |
| 12 | + problem_num: int | None, problem_slug: str | None, problem_tag: str | None |
| 13 | +) -> list[str]: |
| 14 | + if problem_num is not None: |
| 15 | + problem_name = find_problem_by_number(problem_num) |
| 16 | + if not problem_name: |
| 17 | + typer.echo(f"Error: Problem number {problem_num} not found", err=True) |
| 18 | + raise typer.Exit(1) |
| 19 | + return [problem_name] |
| 20 | + elif problem_slug is not None: |
| 21 | + return [problem_slug] |
| 22 | + elif problem_tag is not None: |
| 23 | + problems = find_problems_by_tag(problem_tag) |
| 24 | + if not problems: |
| 25 | + typer.echo(f"Error: No problems found with tag '{problem_tag}'", err=True) |
| 26 | + raise typer.Exit(1) |
| 27 | + typer.echo(f"Found {len(problems)} problems with tag '{problem_tag}'") |
| 28 | + return problems |
| 29 | + |
| 30 | + typer.echo( |
| 31 | + "Error: Exactly one of --problem-num, --problem-slug, or --problem-tag is required", err=True |
| 32 | + ) |
| 33 | + raise typer.Exit(1) |
| 34 | + |
| 35 | + |
| 36 | +def generate( |
| 37 | + problem_num: int | None = typer.Option(None, "-n", "--problem-num", help="Problem number"), |
| 38 | + problem_slug: str | None = typer.Option(None, "-s", "--problem-slug", help="Problem slug"), |
| 39 | + problem_tag: str | None = typer.Option(None, "-t", "--problem-tag", help="Problem tag (bulk)"), |
| 40 | + output: str = typer.Option("leetcode", "-o", "--output", help="Output directory"), |
| 41 | + force: bool = typer.Option(False, "--force", help="Force overwrite existing files"), |
| 42 | +): |
| 43 | + options_provided = sum(x is not None for x in [problem_num, problem_slug, problem_tag]) |
| 44 | + if options_provided != 1: |
| 45 | + typer.echo( |
| 46 | + "Error: Exactly one of --problem-num, --problem-slug, or --problem-tag is required", err=True |
| 47 | + ) |
| 48 | + raise typer.Exit(1) |
| 49 | + |
| 50 | + template_dir = get_template_path() |
| 51 | + output_dir = Path(output) |
| 52 | + |
| 53 | + # Determine which problems to generate |
| 54 | + problems = resolve_problems(problem_num, problem_slug, problem_tag) |
| 55 | + |
| 56 | + # Generate each problem |
| 57 | + for problem_name in problems: |
| 58 | + json_path = get_problem_json_path(problem_name) |
| 59 | + if not json_path.exists(): |
| 60 | + typer.echo(f"Warning: JSON file not found for problem '{problem_name}', skipping", err=True) |
| 61 | + continue |
| 62 | + |
| 63 | + try: |
| 64 | + generate_problem(json_path, template_dir, output_dir, force) |
| 65 | + except Exception as e: |
| 66 | + typer.echo(f"Error generating problem '{problem_name}': {e}", err=True) |
| 67 | + if len(problems) == 1: |
| 68 | + raise typer.Exit(1) |
0 commit comments