Relux provides built-in functions (BIFs) that are always available without imports. BIFs are divided into two categories based on their purity — whether they require a shell context to operate.
Pure BIFs do not interact with any shell. They can be called from pure functions, condition markers, overlay expressions, and regular shell blocks.
Impure BIFs require a shell context (they send input or match output). They can only be called inside shell blocks and regular (non-pure) functions.
“Pure” here means shell-independent, not side-effect-free — a pure BIF may still touch the outside world (which reads the filesystem, timestamp reads the system clock) and need not be deterministic (uuid, rand). What it may not do is require a shell. sleep, log, and annotate do require one and are impure, despite doing nothing shell-specific.
Shell-independent also does not mean infallible. A pure fn body may contain a pure match (<expr> = <pattern> / <expr> ? <pattern>), and a non-matching pure match is an assertion failure: a pure fn that runs one can fail the test through whichever runtime site called it (a let, an overlay value, or a shell-block call). The one exception is a marker condition, where a pure-eval failure makes the condition falsy rather than failing the test.
Generate a random UUID v4 (e.g. "550e8400-e29b-41d4-a716-446655440000").
rand
rand(n)
string
Generate a random alphanumeric string of length n. Errors if n is not a valid integer.
rand
rand(n, mode)
string
Generate a random string of length n using the given charset mode. Modes: alpha, num, alphanum, hex, oct, bin. Errors if mode is unknown or n is not a valid integer.
Allocate a free TCP port on 127.0.0.1 from the window between the OS privileged and ephemeral port intervals. Probed at allocation and never handed out twice while the allocating test is running; freed after the test’s cleanup completes.
which
which(name)
string
Search PATH for an executable named name. Returns the absolute path to the first match, or "" if not found. Checks that the file has an executable permission bit set. If name contains a path separator, checks that path directly instead of searching PATH.
A naive “bind port 0, read the number, close” probe returns a port from the
OS ephemeral range — the same range the kernel uses for the source ports
of outbound connections. Between picking the port and your service binding
it, any client connection (a database bootstrap, a migration, a health
check) can be assigned that number, and a closed client keeps the port in
TIME_WAIT for 60 seconds. The result is a rare, unreproducible
Address already in use at service start.
available_port therefore allocates strictly outside the ephemeral
range. At first use relux reads the OS ephemeral interval
(/proc/sys/net/ipv4/ip_local_port_range on Linux,
net.inet.ip.portrange on macOS) and the privileged boundary, and
allocates from the window between them, starting at a random offset. Every
candidate is verified by binding it (ports in TIME_WAIT fail this probe
and are skipped). A handed-out port is owned by the running test — across
all its effects and functions — and is returned to the pool only after the
test’s cleanup has completed, so within one relux run, no two concurrent
tests can ever receive the same port.
The window can be narrowed with the manifest’s [available_ports] section
(see the configuration chapter). On exhaustion of the window the call
returns -1, like other BIF failures.
One residual caveat: this bookkeeping is per relux process, not a
machine-wide reservation, so relux cannot stop an unrelated process on the
machine — including another concurrent relux run invocation — from
binding the chosen port before your service does. The allocation window
makes that unlikely (the kernel never assigns those ports on its own), but
it is not a guarantee.
Derive a stable, human-readable id from s, formatted adjective-noun-NNNN (e.g. "brave-otter-0042"). Deterministic across runs and across relux versions. About 2^29 distinct values – a readable label, not collision-proof and not for security.
sha1
sha1(s)
string
SHA-1 digest of s as 40-character lowercase hexadecimal.
Current UTC time formatted with a GNU date-style strftime string. Fractional seconds accept any width (%<N>f, %.<N>f); an unknown specifier is emitted verbatim.
timestamp always renders the current instant in UTC – there is no local-timezone mode. It deviates from chrono’s strftime in two ways: fractional-second specifiers accept any width, not just chrono’s fixed 3/6/9 (%1f..%9f, %.1f..%.9f, and widths above 9 right-pad with zeros), and an unknown specifier is emitted verbatim instead of being blanked out. Like uuid and rand, timestamp is non-deterministic across calls – it reads the system clock – but it is still a pure BIF because it never touches a shell.
Match the shell prompt configured in Relux.toml. Advances the output cursor past the prompt.
match_ok
match_ok()
string
Match the shell prompt, send echo $?, match 0, and match the prompt again. Verifies the previous command exited with status 0.
match_not_ok
match_not_ok()
string
Match the shell prompt, verify the previous command exited with a non-zero status, and match the prompt again. The inverse of match_ok().
match_not_ok
match_not_ok(code)
string
Match the shell prompt, verify the previous command exited with a specific non-zero status code, and match the prompt again. Like match_exit_code(code) but also asserts the code is non-zero.
match_exit_code
match_exit_code(code)
string
Send echo $?, match code, and match the prompt. Verifies the previous command exited with the given status. code is passed as a bare literal (e.g. match_exit_code(1)).
Emit message to the event log and HTML report. Returns message.
annotate
annotate(text)
string
Emit text as a progress annotation. Renders inline on the live progress line (between the surrounding fn-call ( and )) and is recorded as an event in the structured log. Returns text.