Task Headers and Parameters
This page covers task declaration syntax, dependency wiring, parameter binding, defaults, and execution semantics.
Task header grammar
task_name:
task_name: dep_a dep_b
build [target] [mode="release"]: lint test
Header parts:
- Task name.
- Optional parameter list.
- Optional dependency list after
:.
Parameter types
Required parameter
build [target]:
cargo build --bin {{ target }}
- Caller must provide value.
- Missing value fails before execution.
Defaulted parameter
build [target] [mode="release"]:
cargo build --bin {{ target }} --{{ mode }}
- Default used when argument omitted.
- Caller can override by position.
Invocation examples
broski build api
broski build api debug
broski run build api debug --explain
broski build api -- --features json
Binding rules
- Positional arguments bind left-to-right.
- Required params must be satisfied.
- Defaults apply only when corresponding position is not provided.
- Resolved params are available as
{{ param_name }}. - Resolved params influence graph fingerprints.
Dependencies and graph behavior
lint:
@in src/**/*
@out .broski/stamps/lint.ok
cargo clippy --all-targets --all-features -- -D warnings
touch .broski/stamps/lint.ok
build [target]: lint
@in src/**/* Cargo.toml Cargo.lock
@out dist/{{ target }}
cargo build --bin {{ target }}
builddepends onlint.- Changing
targetchanges fingerprint and can trigger rebuild.
Shebang task bodies
Tasks can start with shebang bodies.
validate-json [path]:
#!/usr/bin/env python3
import json, pathlib, sys
p = pathlib.Path("{{ path }}")
json.loads(p.read_text())
print("ok", p)
Use this when inline shell becomes hard to maintain.
Make and Just migration mapping
Make variables -> Broski params
build:
cargo build --bin $(TARGET)
build [target]:
@in src/**/* Cargo.toml
@out dist/{{ target }}
cargo build --bin {{ target }}
Run:
broski build api
Just recipe args -> Broski params
build target mode="release":
cargo build --bin {{target}} --{{mode}}
build [target] [mode="release"]:
@in src/**/* Cargo.toml
@out dist/{{ target }}
cargo build --bin {{ target }} --{{ mode }}
Common mistakes
- Treating task args as named flags. Current binding is positional.
- Forgetting to declare
@outfor deterministic cached build tasks. - Using params in command but not in output path when output is param-dependent.
- Overloading a single task with too many parameters.
Recommended patterns
Pattern: split orchestration and leaf tasks
ci: lint test build
build [target] [mode="release"]:
@in src/**/* Cargo.toml Cargo.lock
@out dist/{{ target }}
cargo build --bin {{ target }} --{{ mode }}
Pattern: dev task as interactive
dev:
@mode interactive
@requires docker
docker compose up