"""sap-cli 应用入口:解析参数、初始化连接、路由命令。""" from __future__ import annotations import io import logging import os import sys import requests from sapcli.config import load_config from sapcli.client import ADTClient from sapcli.commands import ( cmd_create, cmd_delete, cmd_unlock, cmd_download, cmd_info, cmd_init, cmd_refresh, cmd_sync, cmd_sync_all, cmd_config, cmd_list, cmd_whereused, cmd_search, cmd_transport, cmd_check, cmd_format, cmd_diff, cmd_package, cmd_cds, cmd_analyze, cmd_scaffold, cmd_show_table, cmd_read_table, cmd_run_program, cmd_activate, cmd_upload, cmd_syntax_check, cmd_unit_test, cmd_history, cmd_clone, cmd_enhancement, ) from sapcli.auth import cmd_auth_login, cmd_auth_logout, cmd_auth_status from sapcli.exceptions import SapCliError, ConfigError from sapcli.cli.parser import build_parser def _setup_encoding() -> None: """确保 stdout/stderr 使用 UTF-8 编码。""" if hasattr(sys.stdout, "buffer"): sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") if hasattr(sys.stderr, "buffer"): sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace") def _setup_logging() -> None: """配置日志(写入文件,不影响 stdout)。""" log_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "log") os.makedirs(log_dir, exist_ok=True) log_file = os.path.join(log_dir, "adt_tools.log") logging.basicConfig( level=logging.DEBUG, format="%(asctime)s | %(levelname)-7s | %(message)s", handlers=[ logging.FileHandler(log_file, encoding="utf-8", mode="a"), ], ) def _suppress_ssl_warnings() -> None: """禁用 urllib3 的 InsecureRequestWarning。""" requests.packages.urllib3.disable_warnings( requests.packages.urllib3.exceptions.InsecureRequestWarning ) def main() -> None: """sap-cli 主入口。""" _setup_encoding() _setup_logging() _suppress_ssl_warnings() parser = build_parser() args = parser.parse_args() if not args.command: parser.print_help() sys.exit(1) # config 命令不需要 SAP 连接 if args.command == "config": cmd_config(args) return # auth 不需要 SAP 连接 if args.command == "auth": auth_action = getattr(args, "auth_action", None) if auth_action == "login": cmd_auth_login(args) elif auth_action == "logout": cmd_auth_logout(args) else: cmd_auth_status(args) return # clone 自行按 --from/--to profile 构建源/目标连接,跳过默认登录 if args.command == "clone": try: cmd_clone(args, None) except SapCliError as e: print(f"\n ✗ {e}") sys.exit(1) return # 加载配置 try: sap_cfg, loaded_from = load_config(args.config, profile=getattr(args, "profile", None)) if loaded_from: logging.getLogger("sapcli").info("Config loaded from: %s", loaded_from) except ConfigError as e: print(f" ✗ {e}") print(f" 请创建配置文件 (config.ini) 或设置环境变量:") print(f" SAP_HOST, SAP_CLIENT, SAP_USER, SAP_PASSWORD") sys.exit(1) # 建立 SAP 连接 verify_ssl = getattr(args, "verify_ssl", False) client = ADTClient(sap_cfg.host, sap_cfg.client, sap_cfg.user, sap_cfg.password, verify_ssl=verify_ssl) print("\n → 正在登录...") client.login() print(" ✓ 登录成功\n") # 命令路由表 command_map = { "download": cmd_download, "sync": cmd_sync_all if getattr(args, "all", False) else cmd_sync, "info": cmd_info, "delete": cmd_delete, "unlock": cmd_unlock, "create": cmd_create, "init": cmd_init, "refresh": cmd_refresh, "list": cmd_list, "whereused": cmd_whereused, "search": cmd_search, "transport": cmd_transport, "check": cmd_check, "format": cmd_format, "activate": cmd_activate, "upload": cmd_upload, "syntax-check": cmd_syntax_check, "diff": cmd_diff, "package": cmd_package, "cds": cmd_cds, "analyze": cmd_analyze, "scaffold": cmd_scaffold, "show-table": cmd_show_table, "read-table": cmd_read_table, "run-program": cmd_run_program, "unit-test": cmd_unit_test, "history": cmd_history, "enhancement": cmd_enhancement, } # 批量 sync 参数校验 if args.command == "sync" and getattr(args, "all", False): if args.name and args.type: print(" ✗ --all 模式下不需要 --name 和 --type 参数") sys.exit(1) elif args.command == "sync" and not getattr(args, "all", False): if not args.name or not args.type: print(" ✗ 单对象模式需要 --name 和 --type 参数") sys.exit(1) # 执行命令 handler = command_map.get(args.command) if handler is None: print(f" ✗ 未知命令: {args.command}") sys.exit(1) try: handler(args, client) except SapCliError as e: print(f"\n ✗ {e}") sys.exit(1)