version: '3'
vars:
BINARY: portail
VERSION:
sh: cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].version'
tasks:
default:
desc: Show available tasks
cmds:
- task --list
build:
desc: Build debug binary
cmds:
- cargo build
build-release:
desc: Build release binary with LTO
cmds:
- cargo build --release
test:
desc: Run all tests
cmds:
- cargo test
test-fast:
desc: Run tests with nextest
cmds:
- cargo nextest run
lint:
desc: Run clippy and format check
cmds:
- cargo clippy --locked --all-targets -- -D warnings
- cargo fmt --check
format:
desc: Format code
cmds:
- cargo fmt
check:
desc: Run cargo check (default allocator)
cmds:
- cargo check --locked
check-all-allocs:
desc: Check all allocator variants compile
cmds:
- cargo check 2>&1
- cargo check --features jemalloc 2>&1
- cargo check --features portail_system_alloc 2>&1
bench:
desc: Run benchmarks
cmds:
- cargo bench
clean:
desc: Clean build artifacts
cmds:
- cargo clean
clean-all:
desc: Deep clean (build artifacts + Nix store garbage)
cmds:
- cargo clean
- nix-collect-garbage -d 2>/dev/null || echo "nix-collect-garbage not available"
- rm -rf .sccache
- echo "All build artifacts removed"
clean-nix:
desc: Clean Nix store garbage (keeps last 3 generations)
cmds:
- nix-collect-garbage --delete-older-than 7d 2>/dev/null || echo "nix not available"
amberify:
desc: Convert shell scripts to Amber
vars:
INPUT: '{{.INPUT | default "scripts/"}}'
OUTPUT: '{{.OUTPUT | default "scripts/amber/"}}'
cmds:
- mkdir -p {{.OUTPUT}}
- cargo run -- amberify --input {{.INPUT}} --output {{.OUTPUT}}
amberify-file:
desc: Convert a single shell script to Amber
vars:
INPUT: '{{.INPUT | required}}'
cmds:
- cargo run -- amberify --input {{.INPUT}}
ci:
desc: Run full CI pipeline
cmds:
- task: check
- task: lint
- task: test
complexity:
desc: Run complexity analysis
cmds:
- ./scripts/complexity-analysis.sh
spec:
desc: Verify route spec against golden file
cmds:
- cargo run -- spec-verify diff
drift:
desc: Capture/replay drift smoke test
cmds:
- cargo run -- drift-detect capture
audit:
desc: Security audit dependencies
cmds:
- cargo audit
features:
desc: Test with all feature flags
cmds:
- cargo test --features store-turso
turso:
desc: Test Turso backend
cmds:
- cargo test --features store-turso -- store
docker-build:
desc: Build Docker image
cmds:
- docker build -t {{.BINARY}}:latest .
docker-run:
desc: Run Docker container
deps: [docker-build]
cmds:
- docker run --rm -p 8787:8787 {{.BINARY}}:latest
docker-slim:
desc: Check compressed binary size
cmds:
- docker build -t {{.BINARY}}:slim --target build -f Dockerfile .
- docker run --rm {{.BINARY}}:slim ls -lh /build/target/release/{{.BINARY}}
nix-check:
desc: Run nix flake check
cmds:
- nix flake check --impure
nix-build:
desc: Build nix package
cmds:
- nix build .#portail
pit:
desc: Run PIT process watcher (background daemon)
cmds:
- cargo run -- pit
pit-scan:
desc: One-shot /proc scan and PIT log
cmds:
- cargo run -- pit --scan
pit-log:
desc: Tail the PIT log file
cmds:
- tail -f ~/.local/share/portail/pit.log 2>/dev/null || echo "No PIT log yet"
mermaid-render:
desc: Render mermaid diagrams in markdown to SVG (installs merman-cli)
cmds:
- |
if ! command -v merman-cli &> /dev/null; then
cargo install merman-cli
fi
merman-cli render --markdown {{.FILE | default "README.md"}}
mermaid-render-all:
desc: Render mermaid in all markdown files under docs/
cmds:
- |
if ! command -v merman-cli &> /dev/null; then
cargo install merman-cli
fi
find docs/ -name '*.md' -exec merman-cli render --markdown {} \;
release:
desc: Build release binary with UPX
cmds:
- cargo build --release
- upx --best --lzma target/release/{{.BINARY}}
- sha256sum target/release/{{.BINARY}} | tee target/release/{{.BINARY}}.sha256
release-sign:
desc: Sign release with cosign
deps: [release]
cmds:
- cosign sign-blob --yes --output-signature target/release/{{.BINARY}}.sig --output-certificate target/release/{{.BINARY}}.pem target/release/{{.BINARY}}
- cosign sign-blob --yes --output-signature target/release/{{.BINARY}}.sha256.sig --output-certificate target/release/{{.BINARY}}.sha256.pem target/release/{{.BINARY}}.sha256
release-verify:
desc: Verify release signature
cmds:
- cosign verify-blob --cert target/release/{{.BINARY}}.pem --signature target/release/{{.BINARY}}.sig target/release/{{.BINARY}}
login:
desc: Login to crates.io
cmds:
- cargo login
publish-dry:
desc: Dry run publish
cmds:
- cargo publish --dry-run
publish:
desc: Publish to crates.io
cmds:
- cargo publish
docs:
desc: Generate and open documentation
cmds:
- cargo doc --no-deps --document-private-items
- open target/doc/portail/index.html
chore-check:
desc: Check for auto-fixable issues (advisory, never blocks)
cmds:
- bash scripts/rust-chore.sh check
chore-fix:
desc: Auto-fix imports, warnings, formatting
cmds:
- bash scripts/rust-chore.sh fix
chore-verify:
desc: Verify cargo check + test after fixes
cmds:
- bash scripts/rust-chore.sh verify
chore-report:
desc: Generate chore report for CI
cmds:
- bash scripts/rust-chore.sh report
serve:
desc: Start the server (debug)
cmds:
- cargo run -- serve
init:
desc: Generate portail.toml interactively
cmds:
- cargo run -- init
c:
desc: cargo check (fast feedback)
cmds:
- cargo check
t:
desc: cargo test (all suites)
cmds:
- cargo test
w:
desc: cargo watch — auto-rebuild on changes
cmds:
- cargo watch -x check -x test
counts:
desc: Show test and warning counts
cmds:
- echo "Tests:" && cargo test 2>&1 | tail -1
- echo "Warnings:" && cargo check --lib --tests 2>&1 | grep -c "warning:" || echo 0
e2e:
desc: Run end-to-end test suite
cmds:
- bash scripts/e2e-test.sh
ramdisk:
desc: Mount RAM disk at target/ for instant compilation
cmds:
- |
if [ "$(uname)" = "Linux" ]; then
sudo mkdir -p target && sudo mount -t tmpfs -o size=8G tmpfs ./target
elif [ "$(uname)" = "Darwin" ]; then
diskutil erasevolume HFS+ 'RustRAM' $(hdiutil attach -nomount ram://16777216) 2>/dev/null || true
ln -sf /Volumes/RustRAM target
fi
echo "RAM disk ready at ./target"
test-fast:
desc: Run tests in parallel (nextest)
cmds:
- cargo nextest run
build-cranelift:
desc: Build with Cranelift backend (30%+ faster)
cmds:
- cargo +nightly build -Zcodegen-backend=cranelift
search:
desc: Search src/ with ripgrep (replaces grep)
vars:
PATTERN: '{{.PATTERN | required}}'
cmds:
- rg {{.PATTERN}} src/
tree:
desc: Directory tree with eza (replaces ls/tree)
cmds:
- eza --tree --git-ignore --icons
du:
desc: Disk usage with dua (replaces du -sh)
cmds:
- dua interactive
top:
desc: System monitor with btm (replaces top)
cmds:
- btm
json:
desc: JSON formatting with jq
vars:
FILE: '{{.FILE | default "Cargo.toml"}}'
cmds:
- jq '.' < {{.FILE}}
diff:
desc: Syntax-highlighted diff with delta (replaces diff)
cmds:
- delta {{.CLI_ARGS}}
ws:
desc: WebSocket test with websocat (replaces netcat)
vars:
URL: '{{.URL | default "ws://localhost:8787/a2a/ws"}}'
cmds:
- websocat {{.URL}}
bat:
desc: Read file with bat (replaces cat)
vars:
FILE: '{{.FILE | required}}'
cmds:
- bat {{.FILE}}
help:
desc: Show this help
cmds:
- task --list
setup:
desc: One-command full environment bootstrap for new contributors
cmds:
- bash scripts/contributor-setup.sh
coverage:
desc: Generate code coverage report (HTML) with cargo-llvm-cov
cmds:
- |
if ! command -v cargo-llvm-cov &> /dev/null; then
echo "Installing cargo-llvm-cov..."
cargo install cargo-llvm-cov
fi
cargo llvm-cov --open
coverage-report:
desc: Generate coverage report (terminal, no open)
cmds:
- |
if ! command -v cargo-llvm-cov &> /dev/null; then
echo "Installing cargo-llvm-cov..."
cargo install cargo-llvm-cov
fi
cargo llvm-cov
profile:
desc: Profile hot functions with samply (or dhat as fallback)
cmds:
- |
if command -v samply &> /dev/null; then
echo "Profile with samply..."
samply record cargo run -- serve
elif cargo install --list 2>/dev/null | grep -q 'dhat'; then
echo "Profile with dhat (heap only)..."
cargo run --features dhat-heap -- serve
else
echo "Install samply: cargo install samply"
echo "Or use dhat: cargo install dhat"
fi
docs-serve:
desc: Build docs and serve locally with mdbook or python http.server
cmds:
- |
if command -v mdbook &> /dev/null; then
if [ -f book.toml ]; then
mdbook serve --open
else
echo "No book.toml found, using cargo doc"
task: docs
fi
else
task: docs
fi
deny:
desc: Run cargo-deny license and duplicate check
cmds:
- cargo deny check
audit:
desc: Run cargo-audit security advisory check
cmds:
- cargo audit
install-hooks:
desc: Install git pre-commit hooks
cmds:
- |
HOOKS_DIR=".git/hooks"
HOOK_FILE="$HOOKS_DIR/pre-commit"
if [ -f "$HOOK_FILE" ]; then
echo "Pre-commit hook already exists, overwrite? [y/N]"
read -r resp
[ "$resp" != "y" ] && exit 0
fi
cat > "$HOOK_FILE" << 'EOF'
set -euo pipefail
echo "=== Pre-commit: cargo fmt --check ==="
cargo fmt --check || { echo "❌ Formatting issues — run 'cargo fmt' to fix"; exit 1; }
echo "=== Pre-commit: cargo clippy ==="
cargo clippy --locked --all-targets -- -D warnings || exit 1
echo "=== Pre-commit: cargo check ==="
cargo check --locked || exit 1
echo "✅ Pre-commit checks passed"
EOF
chmod +x "$HOOK_FILE"
echo "✅ Pre-commit hook installed at $HOOK_FILE"
outdated:
desc: Check for outdated dependencies
cmds:
- cargo outdated
tree:
desc: Display dependency tree
cmds:
- cargo tree
udeps:
desc: Find unused dependencies
cmds:
- |
if ! command -v cargo-udeps &> /dev/null; then
cargo install cargo-udeps
fi
cargo +nightly udeps