#!/usr/bin/env python3 """sap-cli 安装与配置脚本。 用法: python setup.py install # 安装 sap-cli 及依赖 python setup.py config # 交互式配置 SAP 连接 python setup.py verify # 验证安装和连接 python setup.py all # 一键完成:安装 + 配置 + 验证 """ from __future__ import annotations import os import sys import subprocess from pathlib import Path # ── 路径常量 ────────────────────────────────────────────── SKILL_DIR = Path(__file__).resolve().parent.parent ASSETS_DIR = SKILL_DIR / "assets" CONFIG_EXAMPLE = ASSETS_DIR / "config.ini.example" CONFIG_FILE = ASSETS_DIR / "config.ini" def _run(cmd: list[str], **kw) -> int: """运行命令并实时输出。""" print(f" $ {' '.join(cmd)}") return subprocess.call(cmd, **kw) def _pip_available() -> bool: try: subprocess.run([sys.executable, "-m", "pip", "--version"], capture_output=True, check=True) return True except Exception: return False # ── 安装 ───────────────────────────────────────────────── def do_install(): """安装 sap-cli 及其依赖。""" print("\n📦 安装 sap-cli ...") # 1. 检查 Python 版本 py_ver = sys.version_info if py_ver < (3, 10): print(f" ❌ Python 3.10+ required, got {py_ver.major}.{py_ver.minor}") sys.exit(1) print(f" ✅ Python {py_ver.major}.{py_ver.minor}.{py_ver.micro}") # 2. 安装依赖 if _pip_available(): print("\n Installing dependencies ...") ret = _run([sys.executable, "-m", "pip", "install", "requests>=2.28.0"]) if ret != 0: print(" ⚠️ pip install failed, trying manual install ...") else: print(" ⚠️ pip not available, skipping dependency install.") print(" 请手动安装: pip install requests") # 3. 验证 sapcli 包可导入 print("\n Verifying sapcli package ...") ret = _run([sys.executable, "-c", "from sapcli import __version__; print(f' ✅ sap-cli v{__version__}')"], cwd=str(ASSETS_DIR)) if ret != 0: print(" ❌ sapcli package import failed.") sys.exit(1) # 4. 验证 CLI 入口 ret = _run([sys.executable, "main.py", "--help"], cwd=str(ASSETS_DIR)) if ret != 0: print(" ❌ CLI entry point failed.") sys.exit(1) print("\n ✅ sap-cli 安装成功!") print(f" 安装位置: {ASSETS_DIR}") print(f" 运行方式: cd {ASSETS_DIR} && python main.py ") # ── 配置 ───────────────────────────────────────────────── def do_config(): """交互式配置 SAP 连接。""" print("\n⚙️ 配置 SAP 连接 ...") if CONFIG_FILE.exists(): print(f" 配置文件已存在: {CONFIG_FILE}") answer = input(" 是否覆盖?(y/N): ").strip().lower() if answer != "y": print(" 保留现有配置。") return # 从模板创建 if CONFIG_EXAMPLE.exists(): import shutil shutil.copy2(CONFIG_EXAMPLE, CONFIG_FILE) print(f" ✅ 已从模板创建: {CONFIG_FILE}") else: # 手动创建 CONFIG_FILE.write_text( "[SAP]\nhost = \nclient = \nuser = \npassword = \n", encoding="utf-8", ) print(f" ✅ 已创建空白配置: {CONFIG_FILE}") # 交互式填写 print("\n 请输入 SAP 连接信息(留空跳过):") host = input(" SAP 服务器地址 (如 http://sap.example.com:8000): ").strip() client = input(" SAP Client (如 100): ").strip() user = input(" 用户名: ").strip() password = input(" 密码: ").strip() if host or client or user or password: # 简单替换 content = CONFIG_FILE.read_text(encoding="utf-8") if host: content = _replace_config_value(content, "host", host) if client: content = _replace_config_value(content, "client", client) if user: content = _replace_config_value(content, "user", user) if password: content = _replace_config_value(content, "password", password) CONFIG_FILE.write_text(content, encoding="utf-8") print(" ✅ 配置已更新。") else: print(" ⚠️ 未填写任何信息,请手动编辑: " + str(CONFIG_FILE)) print("\n 💡 也可以通过环境变量配置(优先级更高):") print(" SAP_HOST / SAP_CLIENT / SAP_USER / SAP_PASSWORD") def _replace_config_value(content: str, key: str, value: str) -> str: """替换 config.ini 中的值。""" import re pattern = rf"^({key}\s*=\s*).*?$" return re.sub(pattern, rf"\g<1>{value}", content, flags=re.MULTILINE) # ── 验证 ───────────────────────────────────────────────── def do_verify(): """验证安装和连接。""" print("\n🔍 验证安装 ...") # 1. 包导入 ret = _run([sys.executable, "-c", "from sapcli import __version__; print(' ✅ 包导入正常')"], cwd=str(ASSETS_DIR)) if ret != 0: print(" ❌ 包导入失败") return False # 2. CLI 帮助 ret = _run([sys.executable, "main.py", "--help"], cwd=str(ASSETS_DIR)) if ret != 0: print(" ❌ CLI 入口失败") return False # 3. 配置文件 if CONFIG_FILE.exists(): print(f" ✅ 配置文件: {CONFIG_FILE}") else: print(f" ⚠️ 未找到配置文件,请运行: python setup.py config") return False # 4. SAP 连接测试 print("\n 测试 SAP 连接 ...") ret = _run([sys.executable, "main.py", "config", "show"], cwd=str(ASSETS_DIR)) if ret == 0: print(" ✅ SAP 连接正常!") return True else: print(" ⚠️ 连接测试失败,请检查配置。") return False # ── 一键全部 ───────────────────────────────────────────── def do_all(): """安装 + 配置 + 验证。""" do_install() do_config() do_verify() print("\n" + "=" * 50) print(" 🎉 sap-cli 已就绪!") print(" 使用示例:") print(f" cd {ASSETS_DIR}") print(" python main.py info --name ZMY_CLASS --type class") print("=" * 50) # ── 入口 ───────────────────────────────────────────────── def main(): commands = { "install": do_install, "config": do_config, "verify": do_verify, "all": do_all, } if len(sys.argv) < 2 or sys.argv[1] not in commands: print("Usage: python setup.py ") print() print("Commands:") print(" install - Install sap-cli and dependencies") print(" config - Configure SAP connection (interactive)") print(" verify - Verify installation and connection") print(" all - Install + config + verify (recommended)") sys.exit(1) commands[sys.argv[1]]() if __name__ == "__main__": main()