(sigil test cli)
(sigil test cli) - Reusable Test CLI Logic
Provides argument parsing and test execution for both the sigil test command and standalone test harnesses. This module allows test harnesses to share the exact same behavior as sigil test.
The native-backend path requires the host to supply a build-fn (the runner's top-level dep inversion — see (sigil test native-backend)). Pass it via test-main's keyword args:
(test-main args build-fn: <fn> config: 'dev)
Harness binaries built by sigil-build call (test-main args) without kwargs — they don't need the native-backend path because the harness itself is already a native binary running bytecode tests. If a user passes --backend=native to a harness without a build-fn injected, the runner errors with a clear message.
Exports
parse-test-argsprocedureParse test command arguments into an options alist.
Recognizes the following flags: --native Run only native (C) tests --sgl Run only Sigil (.sgl) tests -f, --filter Run only tests matching PATTERN -c, --compact Compact output (dots instead of full names) -q, --quiet Minimal output (exit code only) --fail-fast Stop on first failure --no-color Disable colored output --report PATH Write JSON report to PATH and print summary line
Returns: (options . remaining-args) options - alist of parsed options remaining-args - non-flag arguments (test files/directories)
file-executable?procedureCheck if a file is executable
discover-native-testsprocedureDiscover native test executables in build directories. Looks for test- executables in build//bin/
expand-test-argsprocedureExpand test arguments (files or directories) to test file paths.
resolve-report-writerprocedureLook up write-test-report once, up front. (sigil test report) imports (sigil json) and is loaded lazily so the bootstrap stdlib does not need it. Returns the procedure, or #f if unavailable in this build.
*exit-hook-setter*variable%set-exit-hook! is new in the runtime, and this package declares sigil: "^0.17" — so a harness built from it can legitimately be run by an older 0.17.x binary that satisfies the range but predates the hook. Resolve it dynamically: on such a runtime this is #f, the guard silently degrades to the old behaviour, and nothing crashes with an unbound variable.
%module-lookup itself must therefore be available across the WHOLE declared range, not just at the top of it — a compat guard that is itself unbound on an old binary has the defect it was written to prevent. Checked, rather than assumed: it was registered in natives.c by commit 66071524 (2025-12-22, first released in v0.14.5) and the registration is present in the source at v0.17.0, v0.17.5, v0.17.10, v0.17.15 and v0.17.20 — i.e. at the floor of ^0.17 as well as the ceiling. Also probed live on the shipped v0.17.20: returns #f for %set-exit-hook! there, and the procedure on a patched binary.
install-abandoned-run-guard!procedureInstall the hook exit runs just before the process dies.
Ports are captured explicitly because report mode reparameterizes current-output-port to a string port for the duration of the run — a diagnostic written to the ambient port would be swallowed by the very capture buffer that is about to be discarded.
test-mainprocedureMain entry point for running tests.
This function can be called from:
- The
sigil testCLI command (via sigil-cli's (sigil cli test) orchestrator, which supplies build-fn:) - A standalone test harness binary (no kwargs — bytecode mode only)
Arguments: args - command-line arguments (excluding program name)
Keyword arguments: build-fn: callback for native-backend compile + link. Required when the user passes --backend=native; if absent the runner errors with a clear message. config: symbol like 'dev / 'release. Defaults to whatever --config sets, then 'dev. Passed through to build-fn.
Returns: exit code (0 = success, 1 = failures)