feat: bootstrap coinhunter cli package
This commit is contained in:
70
src/coinhunter/cli.py
Executable file
70
src/coinhunter/cli.py
Executable file
@@ -0,0 +1,70 @@
|
||||
"""CoinHunter unified CLI entrypoint."""
|
||||
|
||||
import argparse
|
||||
import importlib
|
||||
import sys
|
||||
|
||||
MODULE_MAP = {
|
||||
"smart-executor": "smart_executor",
|
||||
"auto-trader": "auto_trader",
|
||||
"precheck": "precheck",
|
||||
"external-gate": "external_gate",
|
||||
"review-context": "review_context",
|
||||
"review-engine": "review_engine",
|
||||
"market-probe": "market_probe",
|
||||
"check-api": "check_api",
|
||||
"rotate-external-gate-log": "rotate_external_gate_log",
|
||||
"init": "init_user_state",
|
||||
}
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="coinhunter",
|
||||
description="CoinHunter trading operations CLI",
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
epilog=(
|
||||
"Examples:\n"
|
||||
" coinhunter check-api\n"
|
||||
" coinhunter smart-executor hold\n"
|
||||
" coinhunter smart-executor --analysis '...' --reasoning '...' buy ENJUSDT 50\n"
|
||||
" coinhunter precheck\n"
|
||||
" coinhunter precheck --ack '分析完成:HOLD'\n"
|
||||
" coinhunter external-gate\n"
|
||||
" coinhunter review-context 12\n"
|
||||
" coinhunter market-probe bybit-ticker BTCUSDT\n"
|
||||
" coinhunter init\n"
|
||||
),
|
||||
)
|
||||
parser.add_argument("command", choices=sorted(MODULE_MAP.keys()))
|
||||
parser.add_argument("args", nargs=argparse.REMAINDER)
|
||||
return parser
|
||||
|
||||
|
||||
def run_python_module(module_name: str, argv: list[str]) -> int:
|
||||
module = importlib.import_module(f".{module_name}", package="coinhunter")
|
||||
if not hasattr(module, "main"):
|
||||
raise RuntimeError(f"Module {module_name} has no main()")
|
||||
old_argv = sys.argv[:]
|
||||
try:
|
||||
sys.argv = [f"coinhunter {module_name}", *argv]
|
||||
result = module.main()
|
||||
return int(result) if isinstance(result, int) else 0
|
||||
except SystemExit as exc:
|
||||
return exc.code if isinstance(exc.code, int) else 0
|
||||
finally:
|
||||
sys.argv = old_argv
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = build_parser()
|
||||
parsed = parser.parse_args()
|
||||
module_name = MODULE_MAP[parsed.command]
|
||||
argv = list(parsed.args)
|
||||
if argv and argv[0] == "--":
|
||||
argv = argv[1:]
|
||||
return run_python_module(module_name, argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user