()
| 345 | |
| 346 | |
| 347 | def main() -> int: |
| 348 | if not BIN.exists(): |
| 349 | print(f"error: tracedecay binary not found at {BIN}", file=sys.stderr) |
| 350 | print(f"hint: run `cargo build --release` first", file=sys.stderr) |
| 351 | return 2 |
| 352 | |
| 353 | sys.path.insert(0, str(ROOT)) |
| 354 | repos = load_repos() |
| 355 | if not repos: |
| 356 | print(f"error: no repos in {REPOS_CONF}", file=sys.stderr) |
| 357 | return 2 |
| 358 | |
| 359 | log = open(LOG_PATH, "w") |
| 360 | for repo in repos: |
| 361 | name = repo["name"] |
| 362 | path = repo["path"] |
| 363 | if not Path(path).exists(): |
| 364 | print(f"skip {name}: {path} not found", file=sys.stderr) |
| 365 | continue |
| 366 | print(f"=== {name} ({path}) ===", file=sys.stderr, flush=True) |
| 367 | try: |
| 368 | cli = McpClient(path, repo_name=name) |
| 369 | except McpInitError as exc: |
| 370 | # Skip the repo but record the failure in the matrix so it |
| 371 | # surfaces in build_matrix.py instead of just vanishing. |
| 372 | print(f"skip {name}: {exc.hint} — see {exc.stderr_path}", file=sys.stderr) |
| 373 | log.write(f"{name}\t_init_\t{{}}\tBAD\t{exc.hint}\n") |
| 374 | log.flush() |
| 375 | continue |
| 376 | try: |
| 377 | discovered = discover(cli) |
| 378 | probes = load_probe_set(repo.get("languages", []), discovered) |
| 379 | for tool, queries in probes.items(): |
| 380 | for query in queries: |
| 381 | resp, dt = cli.call(tool, query, timeout=TIMEOUT) |
| 382 | st, detail = classify(resp, dt) |
| 383 | log.write(f"{name}\t{tool}\t{json.dumps(query)[:120]}\t{st}\t{detail}\n") |
| 384 | log.flush() |
| 385 | finally: |
| 386 | cli.close() |
| 387 | log.close() |
| 388 | print(f"log written to {LOG_PATH}", file=sys.stderr) |
| 389 | return 0 |
| 390 | |
| 391 | |
| 392 | if __name__ == "__main__": |
no test coverage detected