Skip to content

Cli

patiencepilot.ui.cli

Basic command line text interface.

main

main(argv: Sequence[str] | None = None) -> int

Run the command line interface.

Source code in src/patiencepilot/ui/cli.py
22
23
24
def main(argv: Sequence[str] | None = None) -> int:
    """Run the command line interface."""
    return run(argv)

run

run(
    argv: Sequence[str] | None = None,
    *,
    stdin: TextIO | None = None,
    stdout: TextIO | None = None,
    stderr: TextIO | None = None,
) -> int

Run the command line interface with injectable streams.

Parameters:

Name Type Description Default
argv Sequence[str] | None

Command line arguments without the executable name. Uses sys.argv when omitted.

None
stdin TextIO | None

Input stream for state notation when --state - is used.

None
stdout TextIO | None

Output stream for command results.

None
stderr TextIO | None

Error and status stream.

None
Source code in src/patiencepilot/ui/cli.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def run(
    argv: Sequence[str] | None = None,
    *,
    stdin: TextIO | None = None,
    stdout: TextIO | None = None,
    stderr: TextIO | None = None,
) -> int:
    """Run the command line interface with injectable streams.

    Args:
        argv: Command line arguments without the executable name. Uses
            ``sys.argv`` when omitted.
        stdin: Input stream for state notation when ``--state -`` is used.
        stdout: Output stream for command results.
        stderr: Error and status stream.
    """
    input_stream = sys.stdin if stdin is None else stdin
    output_stream = sys.stdout if stdout is None else stdout
    error_stream = sys.stderr if stderr is None else stderr

    parser = build_parser()
    try:
        args = parser.parse_args(argv)
        return _dispatch(args, input_stream, output_stream, error_stream)
    except (PatiencePilotError, OSError, ValueError, json.JSONDecodeError) as error:
        print(f"patiencepilot-cli: {error}", file=error_stream)
        return 2

build_parser

build_parser() -> argparse.ArgumentParser

Return the CLI argument parser.

Source code in src/patiencepilot/ui/cli.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def build_parser() -> argparse.ArgumentParser:
    """Return the CLI argument parser."""
    parser = argparse.ArgumentParser(
        prog="patiencepilot-cli",
        description="Play and inspect Solitaire games from the command line.",
    )
    parser.add_argument("--version", action="version", version=f"patiencepilot-cli {__version__}")
    subparsers = parser.add_subparsers(dest="command", required=True)

    new_parser = subparsers.add_parser("new", help="Deal a new game.")
    _add_variant_args(new_parser)
    new_parser.add_argument("--seed", metavar="VALUE", help="Seed for a reproducible deal.")
    _add_save_arg(new_parser)

    show_parser = subparsers.add_parser("show", help="Display the current state.")
    _add_source_args(show_parser)

    validate_parser = subparsers.add_parser("validate", help="Validate a saved session or state notation.")
    _add_source_args(validate_parser)

    moves_parser = subparsers.add_parser("moves", help="List legal moves.")
    _add_source_args(moves_parser)

    apply_parser = subparsers.add_parser("apply", help="Apply a move ID.")
    _add_source_args(apply_parser)
    apply_parser.add_argument("move", metavar="MOVE_ID", help="Move ID such as DRAW, W->F, or T0->T3:2.")
    _add_save_arg(apply_parser)

    undo_parser = subparsers.add_parser("undo", help="Undo the most recent saved-session move.")
    _add_source_args(undo_parser)
    _add_save_arg(undo_parser)

    advice_parser = subparsers.add_parser("advice", help="Ask the configured advice provider for a move.")
    _add_source_args(advice_parser)
    advice_parser.add_argument("--solver", default="dummy", metavar="NAME", help="Registered solver name or alias.")
    advice_parser.add_argument("--time-limit", type=float, metavar="SECONDS", help="Optional solver time limit.")
    advice_parser.add_argument("--node-limit", type=int, metavar="NODES", help="Optional solver node limit.")
    advice_parser.add_argument("--depth-limit", type=int, metavar="DEPTH", help="Optional solver depth limit.")

    return parser