yatr 🦬
Yet another task runner. But this one's actually good.
yatr test # Run tests
yatr build # Build with dependencies
yatr --watch test # Re-run on file changes
Why yatr?
| Feature | Make | Just | cargo-make | yatr |
|---|---|---|---|---|
| Simple config | ❌ | ✅ | ⚠️ | ✅ |
| Parallel execution | ❌ | ✅ | ✅ | ✅ |
| Task caching | ❌ | ❌ | ⚠️ | ✅ |
| Scripting | Shell | Shell | Multiple | Rhai |
| Cross-platform | ❌ | ⚠️ | ✅ | ✅ |
| Watch mode | ❌ | ❌ | ❌ | ✅ |
| Zero runtime deps | N/A | ✅ | ❌ | ✅ |
yatr sits in the sweet spot: simpler than cargo-make, more powerful than just.
Installation
Or build from source:
Quick Start
Create a yatr.toml in your project root:
[]
= "Run tests"
= ["cargo test"]
[]
= "Build release"
= ["test"]
= ["cargo build --release"]
Run tasks:
Configuration
Basic Tasks
[]
= "Format code"
= ["cargo fmt", "cargo clippy --fix --allow-dirty"]
Task Dependencies
[]
= "Full check pipeline"
= ["fmt", "lint", "test"]
= [] # Just runs dependencies
Parallel Execution
[]
= "Run all linters"
= true
= [
"cargo fmt --check",
"cargo clippy -- -D warnings",
"cargo doc --no-deps"
]
Environment Variables
[]
= "debug"
= "postgres://localhost/test"
[]
= { = "1" }
= ["cargo test"]
Rhai Scripting
For complex logic, use inline Rhai scripts:
[]
= "Bump patch version"
= '''
let cargo = read_file("Cargo.toml");
let toml = parse_toml(cargo);
let version = toml["package"]["version"];
let new_version = semver_bump(version, "patch");
print(`Bumping ${version} -> ${new_version}`);
let updated = cargo.replace(version, new_version);
write_file("Cargo.toml", updated);
'''
Available Rhai functions:
| Function | Description |
|---|---|
read_file(path) |
Read file contents |
write_file(path, content) |
Write file |
file_exists(path) |
Check if file exists |
exec(cmd) |
Run shell command |
glob(pattern) |
Find files matching pattern |
parse_json(str) |
Parse JSON string |
parse_toml(str) |
Parse TOML string |
semver_bump(ver, part) |
Bump version (major/minor/patch) |
get_env(key) |
Get environment variable |
Caching
Tasks are cached by default based on:
- Task configuration (commands, env vars)
- Source file contents (if
sourcesspecified)
[]
= ["cargo build --release"]
= ["src/**/*.rs", "Cargo.toml", "Cargo.lock"]
= ["target/release/myapp"]
Disable caching:
[]
= true
= ["./deploy.sh"]
Watch Mode
Re-run tasks when files change:
Configure watch patterns:
[]
= ["cargo test"]
= ["src/**/*.rs", "tests/**/*.rs"]
Shell Mode
By default, commands run without a shell (cross-platform safe). Enable shell for pipes, redirects, etc:
[]
= true
= ["find src -name '*.rs' | wc -l"]
Or per-invocation:
CLI Reference
yatr [OPTIONS] [TASK]...
yatr <COMMAND>
Commands:
run Run one or more tasks
list List available tasks
watch Watch for changes and re-run
graph Show task dependency graph
cache Manage task cache
init Create yatr.toml template
check Validate configuration
Options:
-c, --config <PATH> Config file path
-v, --verbose Verbose output
-q, --quiet Suppress output
--cwd <DIR> Working directory
--no-color Disable colors
-h, --help Print help
-V, --version Print version
Examples
# Run tasks
# List tasks
# Watch mode
# Dependency graph
|
# Cache management
Full Configuration Reference
# Global environment variables
[]
= "value"
# Global settings
[]
= true # Enable caching (default: true)
= ".yatr" # Cache directory
= 0 # Max parallel tasks (0 = CPU count)
= 300 # Watch debounce delay
# Task definition
[]
= "Task description" # Optional description
= ["cmd1", "cmd2"] # Commands to run (or use 'script')
= "..." # Rhai script (alternative to 'run')
= ["other-task"] # Run these first
= false # Run commands in parallel
= { = "value" } # Task-specific env vars
= "./subdir" # Working directory
= false # Use shell for commands
= ["**/*.rs"] # File patterns for watch mode
= ["src/**"] # Files affecting cache key
= ["target/"] # Output files/dirs
= false # Disable caching
= false # Continue on failure
= 300 # Timeout in seconds
License
MIT OR Apache-2.0