Types
One portable project-task action. Fields not used by kind stay at the constructor defaults, keeping the wire shape simple and versionable.
kind: string | Which action this is; every other field is read only if this kind uses it. |
|---|---|
argv: [string] | Program and its arguments; no shell is involved. |
cwd: string | Working directory for the child, relative to the task root; empty inherits. |
env: [string] | Environment additions spelled |
timeout: string | Deadline as a duration string, such as |
expect: string | Expected result of the child or service. |
output: string | Output policy: |
stdout_path: string | Task-relative file the captured standard output is written to. |
stderr_path: string | Task-relative file the captured standard error is written to. |
stdin: string | Literal text fed to the child on standard input. |
stdin_path: string | Task-relative file fed to the child on standard input. |
stdin_delay: string | How long to hold the pipe empty before writing stdin, as a duration string. |
ready_argv: [string] | Probe command retried until it succeeds or the deadline passes. |
ready_path: string | File polled for the readiness fragment instead of running a probe. |
ready_contains: string | Fragment |
ready_interval: string | How long to wait between readiness attempts, as a duration string. |
signal: string | Portable signal name: |
name: string | Name the action publishes or addresses — a service, temporary directory, or reserved port. |
path: string | Task-relative path the action reads, writes, or removes. |
content: string | Text the action writes, or the fragment it waits for. |
source: string | Task-relative path to copy or rename from. |
destination: string | Task-relative path to copy or rename to. |
actual: string | Task-relative path holding what the run produced. |
expected: string | Task-relative path holding what it should have produced. |
update: bool | Whether a comparison rewrites |
missing_ok: bool | Whether removing a path that is not there succeeds anyway. |
contains: [string] | Fragments the file must contain. |
excludes: [string] | Fragments the file must not contain. |
A named root or dependency in a project task graph.
name: string | Task name, as |
|---|---|
description: string | One line shown in the task listing. |
deps: [string] | Names of tasks that must run first. |
inputs: [string] | Files the task reads, for change detection. |
outputs: [string] | Files the task produces, for change detection. |
profile: string | Build profile the task runs under; empty takes the default. |
working_directory: string | Directory the actions run in, relative to the project root. |
requires: [string] | Capabilities the host must have, such as |
actions: [BuildAction] | The steps to run, in order. |
cleanup: [BuildAction] | Steps run afterwards whether or not the task succeeded. |
cache: string | When |
One closed native dependency recipe. configuration is used by CMake; args carries Meson options or Make targets. Libraries retain their platform selector until the host chooses the current target.
kind: string | Which build system drives the dependency: CMake, Meson, Make, or prebuilt. |
|---|---|
headers: [string] | Header files the recipe installs for dependents. |
libraries: [Library] | Library artifacts the recipe produces, one per platform. |
configuration: string | CMake build configuration, such as |
args: [string] | Meson options or Make targets, depending on |
A platform-specific native library artifact emitted by a dependency recipe.
platform: string | Platform selector the artifact is for. |
|---|---|
file: string | Path of the artifact, relative to the recipe output directory. |
A callback-style debounced watcher over std.fs.watch.
Public because watch hands one out: a call typed from its declaration resolves the declared return type, and a module-private type is unknown to the caller — as a user module's private struct would be.
roots: [string] | Roots to watch, each recursively. |
|---|---|
debounce_ms: int | How long a group stays open after the last interesting event. |
interesting: fn(string, string) -> bool | Called as |
on_change: fn([string]) -> void | Called once per group with the paths it collected, deduplicated and in first-arrival order. |
stop: Channel<int> | Anything sent here asks the running loop to stop. |
task: Optional<Future<int>> | The running loop, so |
Constants
Quiet period before a burst of filesystem events is reported. An editor save is several events (a temp file, a rename, a metadata touch); fifty milliseconds of silence is what separates one save from the next.
Exit status of watch_main that asks the CLI to re-resolve the module graph and start again (a manifest changed).
Functions
Creates a native library descriptor.
platform: Platform selector the artifact is for.file: Path of the artifact, relative to the recipe output directory.
Returns the current target operating-system name.
Returns the absolute root of the current package graph.
Returns the native recipe's dedicated output directory.
Returns the dependency whose native recipe is executing.
Creates a CMake native dependency recipe.
headers: Header files the recipe installs for dependents.libraries: Library artifacts the recipe produces, one per platform.configuration: CMake build configuration, such asRelease.args: Extra arguments passed to CMake.
use std.build
fn main() {
let libraries = [
build.lib("linux", "lib/libcodec.a"),
build.lib("windows", "lib/codec.lib"),
]
let recipe = build.cmake_recipe(
["include/codec.h"],
libraries,
"Release",
["-DBUILD_TESTING=OFF"],
)
build.emit_recipe(recipe)
println(build.os() + ":" + build.dep_name())
println(build.repo_root() + ":" + build.out_dir())
}Creates a Meson native dependency recipe.
headers: Header files the recipe installs for dependents.libraries: Library artifacts the recipe produces, one per platform.args: Meson options for the configure step.
Creates a Make native dependency recipe.
headers: Header files the recipe installs for dependents.libraries: Library artifacts the recipe produces, one per platform.args: Make targets to build.
Creates a recipe for prebuilt native artifacts.
headers: Header files the recipe installs for dependents.libraries: Library artifacts the recipe produces, one per platform.
Publishes the package's native dependency recipe.
recipe: The native dependency recipe to publish for this package.
A child process expressed as argv, never as a shell command string.
argv: Program and its arguments; no shell is involved.
use std.build
fn main() {
let check = build.process(["moon", "check", "main.mn"])
let captured = build.process_capture(["moon", "--version"], "", "version.txt")
let binary = build.project_binary_to("app", ".moon/bin/app")
build.emit([build.task("check", [check, captured, binary])])
}Build one root-project executable selected by its manifest exe_name. The artifact is written to .moon/artifacts/<platform output name>.
name: Manifestexe_nameof the executable to build.
Build one root-project executable selected by its manifest exe_name and write it to a task-relative path. The task's resolved profile is reused.
name: Manifestexe_nameof the executable to build.path: Task-relative path the binary is written to.
A process with explicit cwd, environment additions, deadline, expected result (success, failure, or timeout) and output policy.
argv: Program and its arguments; no shell is involved.cwd: Working directory for the child, relative to the task root; empty inherits.env: Environment additions spelled"KEY=VALUE".timeout: Deadline as a duration string, such as"30s".expect: Expected result:success,failure, ortimeout.output: Output policy:failures(the default),always,never, orinherit.
A child process whose captured streams are written to task-relative files. A later compare_files action can then pin either stream without a shell redirect or pipeline.
argv: Program and its arguments; no shell is involved.stdout_path: Task-relative file the captured standard output is written to.stderr_path: Task-relative file the captured standard error is written to.
The complete process constructor for integration tasks: typed argv plus cwd/environment, a deadline and expected result, output policy, and stream capture destinations.
argv: Program and its arguments; no shell is involved.cwd: Working directory for the child, relative to the task root; empty inherits.env: Environment additions spelled"KEY=VALUE".timeout: Deadline as a duration string, such as"30s".expect: Expected result:success,failure, ortimeout.output: Output policy:failures(the default),always,never, orinherit.stdout_path: Task-relative file the captured standard output is written to.stderr_path: Task-relative file the captured standard error is written to.
A captured process with typed stdin. Set either stdin or stdin_path (not both); stdin_delay may keep the pipe empty first to exercise parked readers without a shell pipeline.
argv: Program and its arguments; no shell is involved.cwd: Working directory for the child, relative to the task root; empty inherits.env: Environment additions spelled"KEY=VALUE".timeout: Deadline as a duration string, such as"30s".expect: Expected result:success,failure, ortimeout.output: Output policy:failures(the default),always,never, orinherit.stdin: Literal text fed on standard input; leave empty to usestdin_path.stdin_path: Task-relative file fed on standard input; leave empty to usestdin.stdin_delay: How long to hold the pipe empty first, as a duration string.stdout_path: Task-relative file the captured standard output is written to.stderr_path: Task-relative file the captured standard error is written to.
A long-lived child kept alive through the selected task root. The readiness argv is retried until success or timeout; teardown is guaranteed.
argv: Program and arguments for the long-lived child.ready_argv: Probe retried until it succeeds ortimeoutpasses.cwd: Working directory for the child, relative to the task root; empty inherits.env: Environment additions spelled"KEY=VALUE".timeout: How long readiness may take, as a duration string.ready_interval: How long to wait between readiness attempts, as a duration string.
use std.build
fn main() {
let port = "$" + "{PORT}"
let server = build.service_options(
"api",
["moon", "run", "server.mn"],
"",
["PORT=" + port],
"20s",
"failures",
["curl", "-fsS", "http://127.0.0.1:" + port + "/health"],
"",
"",
"100ms",
"term",
)
let probe = build.wait_service("api", "20s", "100ms")
let stop = build.signal_service("api", "term")
build.emit([build.task("integration", [build.reserve_port("PORT"), server, probe, stop])])
}A named service with live pipe-backed logs and either process or text readiness. Named services may be signalled and awaited by later actions.
name: Name later actions signal and await the service by.argv: Program and arguments for the long-lived child.cwd: Working directory for the child, relative to the task root; empty inherits.env: Environment additions spelled"KEY=VALUE".timeout: How long readiness may take, as a duration string.ready_interval: How long to wait between readiness attempts, as a duration string.ready_argv: Probe retried until it succeeds; leave empty to use text readiness.ready_path: Log file polled forready_containsinstead of running a probe.ready_contains: Fragment that marks the service ready.stdout_path: Task-relative file the captured standard output is written to.stderr_path: Task-relative file the captured standard error is written to.
Deliver a portable named signal (int, term, kill, or hup) to a running named service. Signal actions are explicitly skipped by projects that do not declare a POSIX requirement.
name: Service to signal, asservice_optionsnamed it.signal: Portable signal name:int,term,kill, orhup.
Create a unique temporary directory for the task session and publish its path as MOON_TASK_TEMP_<name> to later child/service actions.
name: Name the path is published under asMOON_TASK_TEMP_<name>.
Reserve a loopback TCP port until the next child/service action and publish it as MOON_TASK_PORT_<name>.
name: Name the port is published under asMOON_TASK_PORT_<name>.
Every existing file matching a glob pattern, sorted, with / separators.
* and ? match inside one path segment; ** matches across segments, so src/**/*.mn reaches nested directories while src/*.mn does not. The leading literal segments select the directory that is walked, so a pattern never scans more of the tree than it names. A pattern with no wildcard is returned as itself.
Build scripts use this to declare one action per file — a task whose steps are files reports per file as it runs, instead of hiding a whole tree behind one opaque step.
pattern: Path pattern where*and?stay inside a segment and**spans them.
use std.build
fn main() {
let actions = build.glob("src/**/*.mn").map(
|path| build.process(["moon", "fmt", "--check", path]),
)
println(build.temp_path("generated"))
println(build.temp_path_forward("generated"))
println(build.temp_file_uri("generated"))
println(build.reserved_port("HTTP_PORT"))
build.emit([build.task("fmt", actions)])
}The path temp_dir(name) publishes, spelled as the placeholder the runner expands in argv, paths, and templates. Build scripts name resources through these helpers rather than writing ${MOON_TASK_TEMP_<name>} by hand: the placeholder spelling is the runner's protocol, not the script's.
name: Name given totemp_dir.
The port reserve_port(name) publishes, as the placeholder the runner expands.
name: Name given toreserve_port.
Await a named service under a deadline. expect accepts success, failure, exit:N, or signal:int|term|kill|hup.
name: Service to await, asservice_optionsnamed it.timeout: Deadline as a duration string, such as"30s".expect: Expected outcome:success,failure,exit:N, orsignal:int|term|kill|hup.
Poll a task-relative text file until it contains the requested fragment.
path: Task-relative file to poll.content: Fragment that ends the wait once the file contains it.timeout: Deadline as a duration string, such as"30s".interval: How long to wait between polls, as a duration string.
Creates an action that writes the supplied file contents.
path: Task-relative file to create or overwrite.content: Text to write verbatim.
use std.build
fn main() {
let files = [
build.make_directory("out"),
build.write_file("out/a.txt", "moon\n"),
build.append_file("out/a.txt", "Tour\n"),
build.copy_file("out/a.txt", "out/b.txt"),
build.assert_text("out/b.txt", ["moon"], ["Sun"]),
build.compare_files("out/a.txt", "out/b.txt"),
build.remove_path("out"),
]
build.emit([build.task("files", files)])
}Write text after expanding the same explicit ${NAME} placeholders used by argv and paths. ${NAME|path-forward} uses / separators and ${NAME|file-uri} renders an absolute path as a portable file URL; no shell interpolation is performed.
path: Task-relative file to create or overwrite.content: Text to write after expanding${NAME}placeholders.
Append content to a task-relative file without invoking a shell redirect.
path: Task-relative file to append to.content: Text to append verbatim.
Creates an action that copies one file to another.
source: Task-relative file to read.destination: Task-relative file to create or overwrite.
Recursively copy a source tree into a destination that must not exist. Symlinks and other special entries are rejected rather than followed.
source: Task-relative directory to copy.destination: Task-relative directory that must not already exist.
Copy text while dropping every line whose bytes begin with one of the supplied prefixes. Newline bytes for retained lines are preserved.
source: Task-relative text file to read.destination: Task-relative file the retained lines are written to.excluded_prefixes: Lines starting with any of these are dropped.
Atomically rename one task-relative path to another.
source: Task-relative path to move.destination: Task-relative path to move it to.
Delay the next task action without relying on a platform sleep executable.
duration: How long to wait, as a duration string.
Creates an action that compares two files byte for byte.
actual: Task-relative file the run produced.expected: Task-relative file it must match byte for byte.
Require two directory trees to have the same relative file/directory inventory and byte-identical file contents. Special entries are rejected.
actual: Task-relative directory the run produced.expected: Task-relative directory it must match entry for entry.
Creates an action that makes a directory and its parents.
path: Task-relative directory to create along with its parents.
Creates an action that removes a path tree.
path: Task-relative path to remove, together with everything under it.
Require every contains fragment and reject every excludes fragment in a task-relative UTF-8 text file.
path: Task-relative UTF-8 text file to inspect.contains: Fragments the file must contain.excludes: Fragments the file must not contain.
Evaluate primitive JSON-path checks such as gc_telemetry.regions.created > 0 or gc_telemetry.regions.created == $gc_telemetry.regions.released against the first JSON object record in a file.
path: Task-relative file whose first JSON object record is checked.- `checks`: Primitive JSON-path assertions, such as `gc.regions.created > 0`.
Require a task-relative directory to contain fewer than max_exclusive entries. Useful for descriptor/procfs leak censuses without shell pipes.
path: Task-relative directory to census.max_exclusive: Entry count the directory must stay below.
The concise task constructor. Use task_options when the root has metadata, requirements, declared files, or cleanup actions.
name: Task name, asmoon taskaddresses it.actions: Steps to run, in order.
use std.build
fn main() {
let generate = build.task("generate", [build.write_file("out.txt", "moon")])
let check = build.task_options(
"check",
"verify generated output",
["generate"],
["out.txt"],
[],
"",
"",
[],
[build.assert_text("out.txt", ["moon"], [])],
[],
)
build.emit([generate, check])
}Creates a project task with explicit dependencies, resources, and actions.
name: Task name, asmoon taskaddresses it.description: One line shown in the task listing.deps: Names of tasks that must run first.inputs: Files the task reads.outputs: Files the task produces.profile: Build profile to run under; empty takes the default.working_directory: Directory the actions run in.requires: Capabilities the host must have, such asposix.actions: Steps to run, in order.cleanup: Steps run afterwards whether or not the task succeeded.
Emits the private, versioned graph declaration consumed by moon task.
tasks: The task graph to publish formoon task.
The same task with an explicit cache policy: "outputs", "inputs", or "never". "inputs" is for a test task — declared inputs and no outputs — that need not run again while nothing it reads, nor the compiler, has changed; moon task --cache-status shows the decision and --no-cache overrides it.
task: The task to annotate.policy:"outputs","inputs", or"never".
fn main() {
let unit = std.build.cached(
std.build.task_options("unit", "unit tests", [], ["src", "tests"], [], "test", "", [], [
std.build.process(["moon", "test"]),
], []),
"inputs",
)
std.build.emit([unit])
}The paths the toolchain never wakes for: hidden paths, .moon/, zig-out/, and vendor/, which are outputs or copies of inputs.
path: Path to classify.
A watcher over roots with the toolchain's defaults: a WATCH_DEBOUNCE_MS window and watch_ignored paths filtered out.
roots: Roots to watch, each recursively.on_change: Called once per group of changes with the changed paths.
fn main() {
let mut files = std.build.watch(["src"], |paths| println("changed: " + paths.join(", ")))
files.start()
// Later, from an async shutdown path: `await files.stop()`.
}A watcher with an explicit window and predicate.
roots: Roots to watch, each recursively.debounce_ms: Quiet period that closes a group; non-positive takesWATCH_DEBOUNCE_MS.interesting: Called asinteresting(kind, path)for each raw event.on_change: Called once per group with the paths it collected.
Reports grouped file changes from an open watcher until asked to stop: on_change fires once per group with the paths it collected, deduplicated in first-arrival order. The first interesting event opens a group, every further one pushes the deadline out by debounce_ms, and the group closes after that much quiet. Returns how many groups were delivered.
The loop owns handle and closes it on the way out. A stop request is any value sent on stop; a group still open at that point is delivered first. This is the loop watch runs; a caller holding its own Watcher (moon_fswatch does) can drive it directly.
handle: The open watcher events are pulled from; closed when the loop returns.debounce_ms: Quiet period that closes a group; non-positive takesWATCH_DEBOUNCE_MS.interesting: Called asinteresting(kind, path)for each raw event; only a true opens or extends a group.on_change: Called once per group with the paths it collected.stop: Receiving anything here ends the loop.
The --watch driver. Reads the WatchSpec JSON at the path given as the program's first argument, runs the command once, then once per group of interesting changes, printing a header line per cycle. Exits WATCH_RERESOLVE when a manifest changes, so the CLI can rebuild the watch list from the new module graph; otherwise it runs until the process is stopped.
async fn main() {
std.process.exit(await std.build.watch_main())
}