Declaration words
command awl 17 In `runs command <name>`, names the command declaration a worker action runs. The declaration itself is written as a just recipe: `name params:` over indented command lines, no keyword.
-
formvalue-word -
positionsrun-capture, recipe-step
//! Tag a commit by name, with the end-of-options marker its arguments need.
workflow release_tagging
outcome tagged: type String, route success
worker release
action tag(tag_name: String, commit: String) -> String
runs command tag_release
/// `git tag` takes the end-of-options marker, so a tag name beginning with a
/// dash is a name and never an option.
tag_release tag_name commit:
git tag -- {{tag_name}} {{commit}}
step announce
route tagged("tag declared") set awl 17 Opens the document's `set working-directory := "…"` line — just's own file-level setting — naming the directory every command declaration in the document runs in.
-
formdeclaration -
positionstop-level
//! Census the files a flight changed, against a base pin it is given.
workflow gate_census
outcome censused: type String, route success
worker census
action changed_files(base_pin: String) -> String
runs command diff_census
set working-directory := "{workspace_root}"
export GIT_PAGER := "cat"
/// The census names its base pin; the range interpolates as ONE argument,
/// whatever bytes the pin carries.
diff_census base_pin cargo_bin="cargo":
git diff --no-ext-diff --name-only {{base_pin}}..HEAD
step census
route censused("census declared") export awl 17 Opens a document's `export NAME := "value"` line — just's own file-level export — an environment binding, as a literal, for every command declaration in the document.
-
formdeclaration -
positionstop-level
//! Census the files a flight changed, against a base pin it is given.
workflow gate_census
outcome censused: type String, route success
worker census
action changed_files(base_pin: String) -> String
runs command diff_census
set working-directory := "{workspace_root}"
export GIT_PAGER := "cat"
/// The census names its base pin; the range interpolates as ONE argument,
/// whatever bytes the pin carries.
diff_census base_pin cargo_bin="cargo":
git diff --no-ext-diff --name-only {{base_pin}}..HEAD
step census
route censused("census declared") A command declaration begins with a bare name and parameters followed by a colon. An action uses the command keyword to reference that declaration.
Complete syntax examples
tag_release tag_name commit:
git tag -- {{tag_name}} {{commit}}
set working-directory := "{workspace_root}"
export GIT_PAGER := "cat"
diff_census base_pin cargo_bin="cargo":
git diff --no-ext-diff --name-only {{base_pin}}..HEAD
Argument rules
Arguments are split once when the document is checked. A substituted parameter stays one argument, including spaces. Shell pipelines, redirections, substitutions and control operators are refused when written as shell syntax. To use a shell deliberately, name it as the program.
Blank lines and hash comments are skipped. A trailing backslash joins the next line. An at-sign prefix is stripped. Ignore-error prefixes and a first-line shebang are refused. Every declared command must contain an executable line.
A child process receives the declared environment. Working-directory and export declarations are explicit. A typed directory parameter can select a command’s working directory.
Capture and failure
A capture form chooses the command outcome, trimmed stdout text or decoded stdout JSON. The declared action result still controls validation. Nonzero exit, malformed output and unavailable programs are named failures.
Command contract details
-
name param param="default": - A bare command header. Parameters are untyped command words. Single-quoted raw defaults are accepted and formatted to double quotes. Defaults are literal; interpolation in one is refused.
-
{{param}} - A declared parameter interpolated into one argument, including inside quotes. Values never re-enter the parser. {{{{ writes a literal opening pair. Expressions and undeclared fills are refused.
-
Program position - The first argument must be a nonempty literal program. A parameter cannot supply all or any part of it.
-
Leading dash - A caller-filled argument beginning with a dash is refused while still in option position. A preceding literal -- permits it. A literal option prefix written by the author is allowed.
-
Quotes and shell syntax - Single quotes preserve literal bytes. Shell operators, globs, substitutions, home expansion and shell escape forms are refused where a shell would act on them; name a shell explicitly to execute shell code.
-
Line execution - Each line is a separate process, in written order. A directory or variable change on one line does not affect the next. The first nonzero exit fails the command.
-
Environment and stdin - Only PATH plus document exports are present. An exported PATH replaces the executor value. Standard input is closed.
-
Captured result - The concatenated stdout has one trailing newline removed, including a preceding carriage return. Stderr goes to the live transcript and failure detail. Capture binds stdout.
-
runs command NAME - Text capture returning String; runs text is accepted and formatted to the bare form.
-
runs json command NAME - Decode stdout into the declared return type. Missing required command parameters or values without a single-word argument form are refused.
-
run body in a workflow - Returns a record over a subset of exit_code: Int, stdout: String and stderr: String. Worker-only run text and run json selectors are refused in this family.
-
run body in a worker document - Bare run returns the outcome record; run text returns String; run json decodes a non-Nil declared type. Malformed JSON is terminal; nonzero exit is retryable; an unspawnable program or cancellation is terminal.