A pragmatic monorepo task runner with content-aware caching and watch mode.
- simple TOML configuration
- dependency graphs across units and languages
- content-aware caching
- watch mode for development workflows
- no daemon, no remote service, intentionally non-hermetic
Repository docs include scdoc man page sources under docs/man/.
cargo install scripts_runnerThis installs the scripts binary.
scriptscurrently targets Unix-like environments (macOS and Linux). Tasks are executed throughsh, so Windows is not supported yet.
SCRIPTS files are plain TOML with one task per top-level table.
[build]
command = "cargo build --release"
watch = ["src/**", "Cargo.toml", "Cargo.lock"]
bin = ["target/release"]
[test]
deps = [":build"]
command = "cargo test"
watch = ["src/**", "tests/**"]Run tasks:
scripts run :build
scripts run :test
scripts run :build --force
scripts run :build --watchdeps: optional list of dependencies. Use<unit>:<task>for another unit, or<task>/:<task>for the current unit.command: optional shell command. Tasks without a command can still exist to group dependencies.watch: optional list of files or glob patterns to hash.- omitted: always run
[]: hash only the command text- non-empty list: hash command text plus watched file contents
bin: optional list of paths added toPATHfor the task and its dependents
At the git root you can add an optional SCRIPTS_WORKSPACE.toml file:
bin_append = ["tools/bin", "target/release"]Each entry is added to PATH for every task. Entries can also be objects for
explicit path resolution:
bin_append = [
{ path = "tools/bin", relative_to = "git_root" },
{ path = "node_modules/.bin", relative_to = "unit" },
]Run a task and its dependencies.
scripts run app:build
scripts run build
scripts run :build --watch
scripts run dev -- echo done
scripts run --force tools/pkg:build
scripts run --quiet app:build
scripts run --verbose app:buildNotes:
- use
app:buildfor another unit, orbuild/:buildfor the current unit - anything after
--is appended to the root task command and becomes part of the cache key --watchstarts after the graph finishes, then re-runs the target graph when watched inputs change--quietsuppresses routine task status lines but still streams task output--verboseshows the working directory and shell command for each task- task status lines are written to stderr so stdout stays usable for task output
Start a shell with PATH prepared for a task.
scripts env app:dev
scripts env devPrint a task's dependency graph.
scripts print-tree app:build
scripts tree app:build --flat
scripts print-tree app:test --jsontree is available as an alias for print-tree.
Remove the repository cache file.
scripts clean
scripts clean appAny path inside the repository can be used; it is only used to locate the git root.
Generate a shell completion script.
scripts completions bash > ~/.local/share/bash-completion/completions/scripts
scripts completions zsh > ~/.zfunc/_scripts
scripts completions fish > ~/.config/fish/completions/scripts.fishSupported shells: bash, elvish, fish, powershell, zsh.
<unit>:<task>— run a specific task in another unit<task>— run a task in the current unit:<task>— also run a task in the current unit
If you provide a path-like target without a task name, scripts will ask for
<unit>:<task> explicitly.
This repo includes scdoc sources for:
docs/man/scripts.1.scddocs/man/SCRIPTS.5.scddocs/man/SCRIPTS_WORKSPACE.toml.5.scd
Build them from the repo root with scripts itself:
scripts run manClean generated manpages with:
scripts run clean-manOr build files directly with scdoc:
mkdir -p target/man
scdoc < docs/man/scripts.1.scd > target/man/scripts.1
scdoc < docs/man/SCRIPTS.5.scd > target/man/SCRIPTS.5
scdoc < docs/man/SCRIPTS_WORKSPACE.toml.5.scd > target/man/SCRIPTS_WORKSPACE.toml.5Preview them with man ./target/man/scripts.1,
man ./target/man/SCRIPTS.5, and
man ./target/man/SCRIPTS_WORKSPACE.toml.5.
Units are directories containing a SCRIPTS file.
Dependencies resolve by searching upward from the depending unit toward the git root:
(unit root)/..(unit root)/../..- and so on until
(git root)
The first matching path that contains a SCRIPTS file wins.
For each task with watch present, scripts hashes:
- a cache format version
- the task command text
- dependency,
bin, andwatchdeclarations - the contents of any watched files
The repository .scripts_cache file is ignored when hashing watched files, so broad patterns like watch = ["."] do not invalidate themselves.
A task is cached only when its own hash matches and none of its dependencies had to rerun.
- Hermeticity.
scriptsdoes not isolate builds from the host environment or require every dependency to be modeled insidescripts. - Remote execution. This is a local orchestration tool, not a distributed build system.
- Process supervision.
scripts run --watchreruns completed task graphs; it does not manage long-running service lifecycles.