From 88ba27f9eacc37d6691334dab8a26a74242d592f Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 9 May 2026 13:09:28 -0700 Subject: [PATCH] feat(editor): add --summary flag to --audit-watertight MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI-friendly one-line rollup mode for the welded watertight audit. Replaces the per-mesh PASS/FAIL detail lines with a single status line: watertight: FAIL (121 meshes, 27 failure(s)) [/tmp/migtest, weld 0.001000] watertight: PASS (6 meshes, 0 failure(s)) [/tmp/camp, weld 0.001000] Format: "watertight: ( meshes, failure(s)) [, weld ]". Exit code unchanged — failure count capped at 255, matching the verbose-mode contract. Useful for build dashboards / CI grep lines / Slack-bot notifications where the full per-mesh dump would be too noisy. Verbose mode is still the default; opt in with --summary. --- tools/editor/cli_audits.cpp | 13 +++++++++++++ tools/editor/cli_help.cpp | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/editor/cli_audits.cpp b/tools/editor/cli_audits.cpp index f020ad16..bddee72c 100644 --- a/tools/editor/cli_audits.cpp +++ b/tools/editor/cli_audits.cpp @@ -354,10 +354,13 @@ int handleAuditWatertight(int& i, int argc, char** argv) { // CI-friendly: zero on full success. std::string root = argv[++i]; bool jsonOut = false; + bool summary = false; float weldEps = 1e-4f; while (i + 1 < argc && argv[i + 1][0] == '-') { if (std::strcmp(argv[i + 1], "--json") == 0) { jsonOut = true; ++i; + } else if (std::strcmp(argv[i + 1], "--summary") == 0) { + summary = true; ++i; } else if (std::strcmp(argv[i + 1], "--weld") == 0 && i + 2 < argc) { try { weldEps = std::stof(argv[i + 2]); } catch (...) {} i += 2; @@ -414,6 +417,16 @@ int handleAuditWatertight(int& i, int argc, char** argv) { std::printf("%s\n", j.dump(2).c_str()); return std::min(failCount, 255); } + if (summary) { + // Single rollup line for CI dashboards: PASS/FAIL + + // counts. Goes to stdout so build systems can capture it. + std::printf("watertight: %s (%zu meshes, %d failure(s)) " + "[%s, weld %.6f]\n", + failCount == 0 ? "PASS" : "FAIL", + rows.size(), failCount, + root.c_str(), weldEps); + return std::min(failCount, 255); + } std::printf("Watertight audit: %s (weld eps %.6f)\n", root.c_str(), weldEps); if (rows.empty()) { diff --git a/tools/editor/cli_help.cpp b/tools/editor/cli_help.cpp index 84ee183a..72a882b1 100644 --- a/tools/editor/cli_help.cpp +++ b/tools/editor/cli_help.cpp @@ -589,8 +589,8 @@ void printUsage(const char* argv0) { std::printf(" Convert a multi-group WOB building into a single WOC collision file (weld is per-group)\n"); std::printf(" --bake-zone-collision [out.woc] [--weld ] [--steep ]\n"); std::printf(" Walk every .wom + .wob under zoneDir, weld each independently, append to one shared WOC\n"); - std::printf(" --audit-watertight [--weld ] [--json]\n"); - std::printf(" Walk every .wom under root, run welded watertight check; exit code = failure count (CI-friendly)\n"); + std::printf(" --audit-watertight [--weld ] [--json] [--summary]\n"); + std::printf(" Walk every .wom under root, run welded watertight check; --summary prints a one-line rollup\n"); std::printf(" --audit-watertight-wob [--weld ] [--json]\n"); std::printf(" Walk every .wob, check that EVERY group is closed (per-group weld) — interior rooms must be solid\n"); std::printf(" --import-obj [wom-base]\n");