#!/usr/bin/env python3 """HLDP执行器 收到HLDP文件 → 解析@exec/@check → 查.code-map → 执行 → 返回 用法: hldp-exec 执行HLDP文件中的@exec指令 hldp-exec --dry-run 只翻译不执行 hldp-exec --code-map 显示当前.code-map内容 """ import sys, os, subprocess, re, json REPO = os.path.expanduser("~/guanghulab") CODE_MAP_PATH = os.path.join(REPO, ".code-map") def load_code_map(): """加载 .code-map → {编号: 路径}""" cm = {} if not os.path.exists(CODE_MAP_PATH): return cm with open(CODE_MAP_PATH) as f: for line in f: line = line.strip() if not line or line.startswith("#"): continue if "=" in line: k, v = line.split("=", 1) cm[k.strip()] = v.strip() return cm def resolve(code, code_map): """编号 → 实际命令""" if code in code_map: return code_map[code] # 尝试模糊匹配 for k, v in code_map.items(): if code in k: return v return None def parse_hldp(path): """解析HLDP文件,提取@exec和@check字段""" execs = [] checks = [] in_exec = False in_check = False with open(path) as f: for line in f: line = line.strip() if line.startswith("@exec:"): in_exec = True in_check = False cmd = line.split(":", 1)[1].strip() if cmd: execs.append(cmd) elif line.startswith("@check:"): in_exec = False in_check = True cmd = line.split(":", 1)[1].strip() if cmd: checks.append(cmd) elif line.startswith("@"): in_exec = False in_check = False elif in_exec and line.strip(): execs.append(line.strip()) elif in_check and line.strip(): checks.append(line.strip()) return execs, checks def translate(commands, code_map): """翻译编号→真实命令""" result = [] for cmd in commands: parts = cmd.split() if not parts: continue code = parts[0] resolved = resolve(code, code_map) if not resolved: result.append(("UNKNOWN", f"未知编号: {code}", cmd)) continue # 密钥类: 返回加载指令 if code.startswith("SC-"): result.append(("SECRET", resolved, cmd)) continue # 脚本/文件类: 组成完整命令 full_path = os.path.join(REPO, resolved) args = parts[1:] if resolved.endswith(".py"): full_cmd = f"python3 {full_path} " + " ".join(args) elif resolved.endswith(".js"): full_cmd = f"node {full_path} " + " ".join(args) else: full_cmd = f"{full_path} " + " ".join(args) result.append(("EXEC", full_cmd, cmd)) return result def run(translated, dry_run=False): """执行翻译后的命令""" for i, (typ, cmd, original) in enumerate(translated): print(f"[{i+1}] {original}") print(f" → {cmd}") if typ == "UNKNOWN": print(f" ✗ 无法执行: 编号未注册") continue if typ == "SECRET": print(f" ✓ 密钥指令已就绪(不在此处执行)") continue if dry_run: print(f" (dry-run, 未实际执行)") continue try: proc = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300) if proc.returncode == 0: print(f" ✓ 执行成功") if proc.stdout.strip(): # 截取前500字符 out = proc.stdout.strip()[:500] print(f" {out}") else: print(f" ✗ 执行失败 (code={proc.returncode})") if proc.stderr.strip(): print(f" {proc.stderr.strip()[:300]}") except Exception as e: print(f" ✗ 异常: {e}") if __name__ == "__main__": if len(sys.argv) < 2: print(__doc__) sys.exit(1) arg = sys.argv[1] if arg == "--code-map": cm = load_code_map() for k, v in sorted(cm.items()): print(f" {k:<12} = {v}") sys.exit(0) filepath = arg dry_run = "--dry-run" in sys.argv if not os.path.exists(filepath): print(f"✗ 文件不存在: {filepath}") sys.exit(1) cm = load_code_map() execs, checks = parse_hldp(filepath) if not execs and not checks: print("⚠ 该HLDP文件中没有 @exec 或 @check 字段") sys.exit(0) print(f"=== 执行 {filepath} ===") if execs: translated = translate(execs, cm) run(translated, dry_run) if checks: print(f"\n--- @check 校验 ---") translated = translate(checks, cm) run(translated, dry_run)