This is exactly the frustration that lead me to write Rad [0] (the README leads with an example). I've been working on it for over a year and the goal is basically to offer a programming language specifically for writing CLIs. It aims for declarative args (no Bash ops parsing each time), automatic --help generation, friendly (Python-like) syntax, and it's perfect for dev build scripts. I'll typically have something like this:
#!/usr/bin/env rad
---
Dev automation script.
---
args:
build b bool # Build the project
test t bool # Run tests
lint l bool # Run linter
run r bool # Start dev server
release R bool # Release mode
filter f str? # Test filter pattern
filter requires test
if build:
mode = release ? "--release" : ""
print("Building ({release ? 'release' : 'debug'})...")
$`cargo build {mode}`
if lint:
print("Linting...")
$`cargo clippy -- -D warnings`
if test:
f = filter ? "-- {filter}" : ""
print("Running tests{filter ? ' (filter: {filter})' : ''}...")
$`cargo test {f}`
if run:
bin = release ? "target/release/server" : "target/debug/server"
$`./{bin}`
Usage: ./dev -b (build), ./dev -blt -f "test_auth" (build, lint, test auth), ./dev -r (just run).
Actively being developed![0] https://github.com/amterp/rad