Variables Demo
Every meshfox:var setting, side by side — see SPEC.md's "Variables"
section for the full writeup. All ten are declared once here, in the
root node's own body:
A declaration on its own does nothing — only a block that opts in via its
own env= attribute ever resolves or prompts for one, and only for
whatever it actually references. Each node below demonstrates one
setting in isolation by referencing just its own variable(s).
Plain default
GREETING has a default and no other flags — it's used silently,
never prompted for, unless something overrides it (--set, the process
environment, or an answer already sitting in the cache from a previous
run).
echo "$GREETING, world"
exit code: 0
Hello, world
Required confirmation
INSTALL_PATH also has a default, but it's required — nothing but
an explicit override/the environment/an already-cached answer is allowed
to resolve it silently. The very first time this block runs, it's
prompted for interactively, with /usr/local/bin offered as the
prompt's own pre-filled suggestion (confirm with a bare Enter, or type
something else). Whatever's answered is then cached, so every later run
resolves straight from there — this is a one-time confirmation, not a
standing "ask every run".
echo "installing to $INSTALL_PATH"
exit code: 0
installing to /usr/local/bin
Select, not required
LOG_LEVEL is type="select" with a default and no required —
type only changes how a prompt is shown if one ever happens (a menu
of choices instead of free text); it doesn't affect whether one
happens. With a default present and no required, it resolves
silently exactly like GREETING above.
echo "log level: $LOG_LEVEL"
exit code: 0
log level: info
Select, required
REGION combines type="select" with required — the two are
independent axes (type is about how to ask, required is about
whether a default gets to skip asking). First run shows a menu with
us-east-1 pre-selected as the suggested answer; any confirmed choice
is cached from then on.
echo "deploying to $REGION"
exit code: 0
deploying to us-east-1
Bool
VERBOSE is type="bool" with a default — a plain (non-required)
boolean, so it resolves silently too; a prompt for it (had it been
required, or had nothing else supplied a value) would ask y/n
rather than free text.
echo "verbose: $VERBOSE"
exit code: 0
verbose: false
Int
RETRY_COUNT is type="int" with a default — same "resolves silently,
type only shapes how a prompt would look" story as LOG_LEVEL/
VERBOSE above, except an int prompt/form field is validated: only
something that actually parses as a whole number is ever accepted (a
terminal prompt keeps re-asking, the web form blocks submit, the TUI's
own field only lets you type digits and a leading +/- in the first
place) — see meshfox_core::vars::validate_value. Unlike type's other
values, this is real enforcement, not just a hint for how to ask.
echo "retrying up to $RETRY_COUNT time(s)"
exit code: 0
retrying up to 3 time(s)
Secret
API_TOKEN is secret — no default, never read from or written to
the on-disk cache, never pre-filled anywhere. The only way to supply one
without an interactive prompt is --set/the process environment; asked
for fresh every single time some block's env= needs it, masked as it's
typed. secret and required are independent flags, but in practice a
secret variable is already "confirmed fresh" on every run regardless —
it can never be silently reused from a cache the way a plain required
variable's second run can.
Deliberately without cache here — caching would freeze a secret's
value into this very file, defeating the point of it never being
persisted anywhere.
echo "calling the API with a token ${#API_TOKEN} characters long"
Computed
RESOURCE_ID has from="computed/create" instead of a default —
its value comes from actually running the create block below and
reading back what it wrote to $MESHFOX_VARS_OUT (a NAME=value-per-line
file meshfox hands every from= source block a fresh path to), not from
any override/environment/cache/prompt. Running use-it automatically
runs create first — from= is an implicit dependency, the same as an
explicit deps= entry — and fails the whole run if create exits
nonzero or never writes RESOURCE_ID.
echo "RESOURCE_ID=resource-42" >> "$MESHFOX_VARS_OUT"
echo "using $RESOURCE_ID"
exit code: 0
using resource-42
Session
DEPLOY_CONFIG is type="select" with required session — unlike a
plain required variable (whose confirmation is cached and reused
forever after), session means the answer is never written to the
on-disk cache at all, so every separate meshfox run invocation asks
again. Referenced by more than one block in the same invocation, it's
still only ever prompted for once — session only skips the cache, not
the same once-per-invocation reuse every other variable already gets.
Deliberately without cache here, same reason secret-token above has
none: this needs a fresh interactive answer (or --set) every run, so
there's no single "settled" output to freeze into the file.
echo "deploying to $DEPLOY_CONFIG"
Dynamic choices
REGION_DYNAMIC has choices_var="REGIONS_LIST" instead of a literal
choices= — and REGIONS_LIST is itself from=-computed by
list-regions below, so REGION_DYNAMIC's own options ultimately come
from actually running a script, not a hardcoded list. Running use-region
automatically runs list-regions first (the same implicit-dependency
mechanism from= always gets, followed transitively through
choices_var) — REGION_DYNAMIC itself still needs an interactive
answer (or --set) once its choices are known, so this is also without
cache.
Two things to know when the list comes from a script (a font list from
fc-list, a branch list from git branch):
- The source block runs before the form is shown, with an empty
environment: it sees no
env=variable of this canvas (only what its owndeps=chain published, such as aninterpreter="$PYTHON"built by a setup block). So the list cannot depend on another variable's answer (a language chosen in the same form, say) — print every option and let the user filter: typing in the picker narrows it, in the web UI, the TUI and the terminal prompt alike. - If the source fails (non-zero exit, a missing tool), the field has no
choices and says why — which variable they wait for and the end of the
block's output (
choicesPending) — instead of showing an empty list. A run cannot go on past it, andconfigureleaves it unsaved.
echo "REGIONS_LIST=us-east-1,eu-west-1,ap-southeast-1" >> "$MESHFOX_VARS_OUT"
echo "using $REGION_DYNAMIC"
Combined
env= takes a comma-separated list — a single block can reference
several declared variables at once, mixing plain, required, select,
bool, and int ones freely. Each is still resolved independently (its
own override/environment/cache/default, required skipping that last
step, int validated on the way in, same as anywhere else) — env=
just collects whichever of them this one block actually needs into its
process environment together.
echo "$GREETING! installing to $INSTALL_PATH (log level $LOG_LEVEL, verbose=$VERBOSE, retries=$RETRY_COUNT)"
exit code: 0
Hello! installing to /usr/local/bin (log level info, verbose=false, retries=3)