`pm3py rawcli` lives behind the optional [rawcli] extra; a plain install of pm3py doesn't pull prompt_toolkit. Catch the ModuleNotFoundError and print an install hint (pip install 'pm3py[rawcli]') with exit code 2, instead of dumping a traceback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
38 lines
1.3 KiB
Python
38 lines
1.3 KiB
Python
"""`pm3py` top-level CLI dispatcher.
|
|
|
|
Subcommands live in submodules; ``rawcli`` is the first (the interactive raw-command TUI). Room
|
|
is left for ``flash`` (wrapping pm3flash) and a future ``client`` command CLI.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import sys
|
|
|
|
|
|
def build_parser() -> argparse.ArgumentParser:
|
|
parser = argparse.ArgumentParser(prog="pm3py", description="pm3py command-line tools")
|
|
sub = parser.add_subparsers(dest="command")
|
|
p = sub.add_parser("rawcli", help="interactive raw-command TUI for a connected Proxmark3")
|
|
p.add_argument("--port", default=None, help="serial port (default: auto-detect)")
|
|
return parser
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
parser = build_parser()
|
|
args = parser.parse_args(argv)
|
|
if args.command == "rawcli":
|
|
try:
|
|
import prompt_toolkit # noqa: F401
|
|
except ModuleNotFoundError:
|
|
print(
|
|
"pm3py rawcli needs prompt_toolkit, which isn't installed.\n"
|
|
" install it with: pip install 'pm3py[rawcli]'\n"
|
|
" or directly: pip install prompt_toolkit",
|
|
file=sys.stderr,
|
|
)
|
|
return 2
|
|
from pm3py.cli.rawcli.app import run
|
|
return run(port=args.port)
|
|
parser.print_help()
|
|
return 1
|