fix: gcov Windows本地化 + runner合并 + 决策覆盖率修复
- gcov从WSL 15.2改为Windows MinGW 9.2.0,消除.gcno格式不匹配 - coverage.py去除leaf_stats复位bug(决策覆盖率恢复) - runner.py合并V3编译+SOURCE分组执行+出力保存 - __init__.py gcov条件/outdir解析修复
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from runners.runner import BuildResult, RunResult
|
||||
|
||||
|
||||
class CobolRunner:
|
||||
"""COBOL 程序编译·执行器。
|
||||
|
||||
非DB程序(KIN系)使用 ``compile_with_links()`` + ``run_file_based()``。
|
||||
DB程序/旧式调用保持 ``compile()`` + ``run()`` 不变。
|
||||
"""
|
||||
|
||||
# ── 旧式(orchestrator.py 互換)──
|
||||
|
||||
def compile(self, src: str, dialect="ibm", gcov: bool = False) -> BuildResult:
|
||||
"""旧式编译(-std=ibm-strict)。orchestrator.py 用,不修改。"""
|
||||
stem = Path(src).stem
|
||||
out = str(Path(src).parent / stem)
|
||||
cmd = ["cobc", "-x", f"-std={dialect}-strict", "-o", out, src]
|
||||
@@ -14,8 +24,92 @@ class CobolRunner:
|
||||
return BuildResult(success=p.returncode == 0, artifact_path=out, log=p.stdout + p.stderr)
|
||||
|
||||
def run(self, binary: str, input_path: str, output_path: str) -> RunResult:
|
||||
"""旧式执行(stdin→stdout)。orchestrator.py 用。"""
|
||||
with open(input_path, "rb") as f:
|
||||
data = f.read()
|
||||
p = subprocess.run([binary], input=data, capture_output=True, timeout=30)
|
||||
Path(output_path).write_bytes(p.stdout)
|
||||
return RunResult(success=p.returncode == 0)
|
||||
|
||||
# ── 新式(非DB KIN系向け)──
|
||||
|
||||
def compile_with_links(self, src: str, work_dir: str,
|
||||
copybook_dirs: list[str] | None = None,
|
||||
sub_objects: list[str] | None = None,
|
||||
gcov: bool = False) -> BuildResult:
|
||||
"""编译主程序 + 链接 SUB.o,不使用 -std=ibm-strict。
|
||||
|
||||
Args:
|
||||
src: COBOL 源文件路径。
|
||||
work_dir: 编译工作目录(.gcno 产出位置,必须提前存在)。
|
||||
copybook_dirs: COPYBOOK 搜索路径列表(映射为 -I 参数)。
|
||||
sub_objects: SUB*.o 文件路径列表(静态链接)。
|
||||
gcov: 是否启用 ``--coverage``。
|
||||
|
||||
Returns:
|
||||
BuildResult,artifact_path 指向 .exe 的绝对路径。
|
||||
"""
|
||||
work_path = Path(work_dir).resolve()
|
||||
work_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
stem = Path(src).stem
|
||||
exe_path = work_path / f'{stem}.exe'
|
||||
|
||||
cmd = ["cobc", "-x", "-g"]
|
||||
if gcov:
|
||||
cmd.append("--coverage")
|
||||
for cpy in (copybook_dirs or []):
|
||||
cmd.extend(["-I", str(cpy)])
|
||||
cmd.extend(["-o", str(exe_path), str(src)])
|
||||
cmd.extend(str(o) for o in (sub_objects or []))
|
||||
|
||||
orig = os.getcwd()
|
||||
try:
|
||||
os.chdir(str(work_path))
|
||||
p = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
|
||||
finally:
|
||||
os.chdir(orig)
|
||||
|
||||
return BuildResult(
|
||||
success=p.returncode == 0,
|
||||
artifact_path=str(exe_path),
|
||||
log=(p.stdout + p.stderr)[:2000],
|
||||
)
|
||||
|
||||
def run_file_based(self, binary: str, run_dir: str,
|
||||
input_files: dict[str, str] | None = None,
|
||||
timeout: int = 60) -> RunResult:
|
||||
"""基于文件的执行。将输入文件复制到 run_dir 后启动程序。
|
||||
|
||||
Args:
|
||||
binary: 可执行文件路径。
|
||||
run_dir: 执行目录(CWD,输入文件在此,输出文件也在此)。
|
||||
input_files: {assign_name: source_path} 的映射。
|
||||
如 ``{"KIN04R01": "/path/to/input/KIN04R01"}``。
|
||||
timeout: 超时秒数。
|
||||
|
||||
Returns:
|
||||
RunResult。
|
||||
"""
|
||||
run_path = Path(run_dir).resolve()
|
||||
run_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 入力ファイル配置
|
||||
for assign_name, src_path in (input_files or {}).items():
|
||||
src = Path(src_path)
|
||||
if src.exists():
|
||||
dst = run_path / assign_name
|
||||
import shutil
|
||||
shutil.copy2(str(src), str(dst))
|
||||
|
||||
orig = os.getcwd()
|
||||
try:
|
||||
os.chdir(str(run_path))
|
||||
p = subprocess.run([str(binary)], capture_output=True, text=True, timeout=timeout)
|
||||
finally:
|
||||
os.chdir(orig)
|
||||
|
||||
return RunResult(
|
||||
success=p.returncode == 0,
|
||||
log=(p.stdout + p.stderr)[:2000],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user