import argparse import sys from config import Config def main(): p = argparse.ArgumentParser(description="COBOL->Java/Spark Migration Verification") p.add_argument("--mode", choices=["native", "agent"], default="native", help="native=existing pipeline, agent=jcl-data-create mode") p.add_argument("--copybook", default="", help="COPYBOOK text file path (native mode)") p.add_argument("--cobol-src", default="", help="COBOL source file path") p.add_argument("--java-src", default="", help="Java source directory (must contain pom.xml)") p.add_argument("--mapping", default="", help="YAML field mapping file path") p.add_argument("--runner", choices=["native", "spark"], default="native") p.add_argument("--coverage", choices=["boundary", "branch"], default="boundary") p.add_argument("--tolerance", type=float, default=0.01) p.add_argument("--verbose", action="store_true") p.add_argument("--dry-run", action="store_true") p.add_argument("--output-dir", default="./reports") p.add_argument("--quality-gate-mode", choices=["warn", "off"], default="warn", help="质量门禁模式: warn=记录警告, off=关闭") p.add_argument("--gcov", action="store_true") # ── agent mode args ── p.add_argument("--design", default="", help="[agent] 詳細設計書 .md") p.add_argument("--file-db-md", default="", help="[agent] ファイル/DB 構造定義 .md") p.add_argument("--cpy", default="", help="[agent] COPYBOOK 格納ディレクトリ") p.add_argument("--db-md", default="", help="[agent] DB 定義書 .md") p.add_argument("--output", default="output", help="[agent] jcl 测试数据输出ディレクトリ") p.add_argument("--api-key", default="sk-6156cccdc9c14d949cf5bfc5afc67a03", help="[agent] DeepSeek API Key") p.add_argument("--api-model", default="deepseek-v4-flash", help="[agent] API 模型名") args = p.parse_args() # ── Native mode validation ── if args.mode == "native": missing = [] for name, val in [("--copybook", args.copybook), ("--cobol-src", args.cobol_src), ("--java-src", args.java_src), ("--mapping", args.mapping)]: if not val: missing.append(name) if missing: print(f"Error in native mode: missing required args: {', '.join(missing)}") sys.exit(2) # ── Agent mode validation ── if args.mode == "agent": missing = [] for name, val in [("--design", args.design), ("--cobol-src", args.cobol_src), ("--file-db-md", args.file_db_md), ("--cpy", args.cpy), ("--db-md", args.db_md)]: if not val: missing.append(name) if missing: print(f"Error in agent mode: missing required args: {', '.join(missing)}") sys.exit(2) # ── Dry-run ── if args.dry_run: from pathlib import Path issues = [] if args.mode == "native": for lb, pt in [("copybook", args.copybook), ("cobol-src", args.cobol_src), ("java-src", args.java_src), ("mapping", args.mapping)]: if not Path(pt).exists(): issues.append(f" {lb}: {pt} (not found)") elif args.mode == "agent": for lb, pt in [("design", args.design), ("cobol-src", args.cobol_src), ("file-db-md", args.file_db_md), ("db-md", args.db_md)]: if not Path(pt).exists(): issues.append(f" {lb}: {pt} (not found)") if not Path(args.cpy).is_dir(): issues.append(f" cpy: {args.cpy} (not a directory)") if issues: print("DRY-RUN issues:\n" + "\n".join(issues)) sys.exit(2) print("DRY-RUN: all inputs OK") sys.exit(0) c = Config() c.runner_mode = args.runner c.coverage_default = args.coverage c.tolerance = args.tolerance c.quality_gate_mode = args.quality_gate_mode c.gcov_enabled = args.gcov if args.mode == "native": from orchestrator import run_pipeline vr = run_pipeline(c, args.copybook, args.cobol_src, args.java_src, args.mapping) t = vr.fields_matched + vr.fields_mismatched print(f"{vr.program}: {vr.status} ({vr.fields_matched}/{t}, {vr.duration_s:.0f}s)" if t else f"{vr.program}: {vr.status}") sys.exit(vr.exit_code) elif args.mode == "agent": from orchestrator_jcl import run_jcl_pipeline results = run_jcl_pipeline( cfg=c, design_md=args.design, cobol_src=args.cobol_src, file_db_md=args.file_db_md, cpy_dir=args.cpy, db_md=args.db_md, java_src=args.java_src, mapping=args.mapping, output_dir=args.output, api_key=args.api_key, api_model=args.api_model, ) for gn, vr in sorted(results.items()): t = vr.fields_matched + vr.fields_mismatched if t: print(f"{vr.program}: {vr.status} ({vr.fields_matched}/{t}, {vr.duration_s:.0f}s)") else: print(f"{vr.program}: {vr.status} ({vr.duration_s:.0f}s)") sys.exit(0) if __name__ == "__main__": main()