A cross-platform Python CLI to shortcut tp command-line commands. Inspired by Makefiles and npm scripts.
Project description
rav
A cross-platform Python CLI to shortcut to command-line commands with powerful file download capabilities and integrity verification. Inspired by Makefiles and npm scripts.
Features
โจ Script Management: Define and run custom command shortcuts
๐ Command Groups: Share working_dir and prefix across related commands
๐ฆ File Downloads: Download files with integrity verification
๐ Security: Subresource Integrity (SRI) hash verification
๐จ Rich Output: Beautiful terminal output with progress indicators
โก Multiple Formats: Support for single commands and multi-command sequences
๐ง Flexible Config: Use rav, scripts, or commands as top-level keys
๐ Variables: Define reusable values with ${{ vars.NAME }} syntax
Table of Contents
- Install
- Quick Start
- CLI Commands Reference
- Script Configuration
- Variables
- Command Groups
- File Downloads
- Integrity Verification
- Complete Examples
- Tips and Best Practices
Install
It's recommended that you use a virtual environment with rav.
python3 -m pip install rav
Minimum python version is 3.9
Quick Start
Option 1: Interactive Setup
cd ~/path/to/project
rav new
Run through the setup wizard to create
rav.yaml
Option 2: Manual Setup
Create rav.yaml:
scripts:
echo: echo hello world
server: python -m http.server 8000
Run commands:
rav run echo # or rav x echo
rav run server # Start development server
rav list # Show all available commands
CLI Commands Reference
Core Commands
| Command | Description | Example |
|---|---|---|
rav run <command> |
Execute a script command | rav run server |
rav x <command> |
Shortcut for rav run |
rav x echo |
rav list |
List all available commands | rav list |
rav new |
Create new rav project with wizard | rav new |
rav sample |
Generate sample rav.yaml file | rav sample |
rav version |
Show rav version | rav version |
Download Commands
| Command | Description | Example |
|---|---|---|
rav download <config> |
Download files using config | rav download staticfiles |
rav downloads <config> |
Alias for rav download |
rav downloads staticfiles |
Command Options
| Option | Description | Example |
|---|---|---|
-f, --file |
Use custom rav file | rav run -f custom.yaml echo |
--overwrite |
Force overwrite existing files | rav sample --overwrite |
--verbose |
Enable verbose output | rav --verbose run command |
Quick Examples
Script execution:
rav x server # Start development server
rav x test # Run tests
rav x build # Build project
Custom files:
rav run -f project.yaml deploy
rav list -f staging.yaml
Project management:
rav new # Interactive project setup
rav sample # Create example file
rav list # View available commands
Script Configuration
The configuration block is flexible. Use rav, scripts, or commands as the top-level key.
rav.yaml
name: web-development-toolkit
scripts:
# Development servers
dev: python -m http.server 8000
dev-secure: python -m http.server 8443 --bind 127.0.0.1
# Testing and quality assurance
test: pytest tests/ -v
lint: flake8 src/ tests/
format: black src/ tests/
# Build and deployment
build:
- npm run build
- python setup.py sdist bdist_wheel
- echo "Build complete!"
deploy:
- rav run test
- rav run build
- rsync -av dist/ user@server:/var/www/
downloads:
frontend-deps:
destination: static/vendor
overwrite: true
files:
- name: htmx.min.js
url: https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js
integrity: sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm
- name: tailwind.css
url: https://cdn.tailwindcss.com/3.4.0/tailwind.min.css
Flexible Configuration Keys
The following all work and will run in this exact order (rav first, scripts second, commands last):
rav:
echo: echo "this is awesome"
server: venv/bin/python -m http.server
scripts:
echo: echo "this is awesome"
server: venv/bin/python -m http.server
commands:
echo: echo "this is awesome"
server: venv/bin/python -m http.server
Basic Syntax
Commands follow this simple pattern:
rav run <command> # Execute a script command
rav x <command> # Shortcut for rav run
rav list # Show all available commands
Sample Project
Generate a sample project to explore features:
rav sample # Creates rav.sample.yaml
rav run -f rav.sample.yaml echo
Custom Rav File
Rav supports custom yaml files by default. The yaml declaration needs to be any of the following:
ravscriptscommands
project.yaml
rav:
sweet: echo "this is working"
echo: echo "so is this"
rav.basic.yaml
scripts:
sweet: echo "this is working"
echo: echo "so is this"
rav run -f project.yaml sweet
or
rav run --file rav.other.yaml echo
Here's a few rules for custom files:
-for--fileis used to specify a custom rav file-for--filemust be used prior to the command shortcut name (e.g.rav run -f <your-new-file> <your-command>)
Multiple Commands at Once
rav.yaml
scripts:
multi:
- echo this is
- echo awesome
- echo simple
- echo and
- echo easy
Run with:
rav run multi
This is the same as running:
echo this is && echo awesome && echo simple && echo and && echo easy
Variables
Define reusable values with ${{ vars.NAME }} syntax. Great for templates and boilerplates where configuration varies between projects.
Basic Usage
vars:
PROJECT_NAME: myproject
PORT: "8000"
scripts:
server: uv run uvicorn ${{ vars.PROJECT_NAME }}.asgi:application --port ${{ vars.PORT }}
migrate: uv run python manage.py migrate
echo: echo "Running ${{ vars.PROJECT_NAME }}"
Run with:
rav run server
# Executes: uv run uvicorn myproject.asgi:application --port 8000
Configuration Keys
Both vars and variables work as the top-level key:
vars:
PROJECT_NAME: myproject
variables:
PROJECT_NAME: myproject
Environment Variable Fallback
Variables fall back to environment variables if not defined in YAML:
scripts:
whoami: echo "Home is ${{ vars.HOME }}" # Uses $HOME from environment
greet: echo "Hello ${{ vars.USER }}" # Uses $USER from environment
Variables with Command Groups
Variables work seamlessly with command groups:
vars:
PROJECT_NAME: myproject
PYTHON: uv run python
scripts:
backend:
working_dir: backend/src
prefix: ${{ vars.PYTHON }}
backend:server: manage.py runserver
backend:migrate: manage.py migrate
View Resolved Variables
Use rav list --expanded to see commands with variables resolved:
rav list --expanded
โโโโโโโโโโโณโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Command โ Script โ
โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ
โ server โ uv run uvicorn myproject.asgi:application --port 8000โ
โ echo โ echo "Running myproject" โ
โโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Command Groups
Command groups allow you to define shared working_dir and prefix settings that are inherited by related commands. This is useful when you have multiple commands that share common configuration.
Basic Group Syntax
Define a group using a name ending with : pattern. Commands prefixed with that group name inherit its settings:
scripts:
# Group definition
backend:
working_dir: backend/src
prefix: "uv run"
cmd: uvicorn app:application --reload
# These inherit working_dir and prefix from backend:
backend:migrate: python manage.py migrate
backend:shell: python manage.py shell
backend:test: pytest
Running rav run backend:migrate executes:
cd backend/src && uv run python manage.py migrate
Group Configuration Options
| Option | Description |
|---|---|
working_dir |
Directory to cd into before running commands |
prefix |
String prepended to each command |
cmd |
Default command when running the group itself |
Overriding Group Settings
Individual commands can override their group's settings:
scripts:
backend:
working_dir: backend/src
prefix: "uv run"
cmd: uvicorn app:application --reload
# Inherits both working_dir and prefix
backend:migrate: python manage.py migrate
# Override just the prefix (empty = no prefix)
backend:install:
prefix:
cmd: uv sync --dev
# Override both working_dir and prefix
backend:docs:
working_dir: backend/docs
prefix: "mkdocs"
cmd: serve
Real-World Example: Django with Doppler and UV
Using command groups with secret injection and Python environment management:
scripts:
# Backend group with uv runner
backend:
working_dir: backend/src
prefix: "uv run python manage.py"
backend:migrate: migrate
backend:makemigrations: makemigrations
backend:createsuperuser: createsuperuser
backend:shell: shell
backend:collectstatic: collectstatic --noinput
# Production with secrets injection
prod:
working_dir: backend/src
prefix: "doppler run -- uv run python manage.py"
prod:migrate: migrate
prod:collectstatic: collectstatic --noinput
# Frontend group
frontend:
working_dir: frontend
prefix: "npm run"
frontend:dev: dev
frontend:build: build
frontend:test: test
Usage:
rav run backend:migrate # โ cd backend/src && uv run python manage.py migrate
rav run prod:migrate # โ cd backend/src && doppler run -- uv run python manage.py migrate
rav run frontend:build # โ cd frontend && npm run build
Multi-Command Groups
Groups work with multi-command lists too:
scripts:
backend:
working_dir: backend/src
prefix: "uv run"
backend:setup:
- echo "Setting up database..."
- python manage.py migrate
- python manage.py collectstatic --noinput
- echo "Setup complete!"
Each command in the list gets the prefix applied:
cd backend/src && uv run echo "Setting up database..." && uv run python manage.py migrate && ...
Passing Arguments
Arguments are appended to the last command:
rav run backend:migrate myapp
# โ cd backend/src && uv run python manage.py migrate myapp
Expanded List View
Use --expanded to see fully resolved commands:
rav list --expanded
File Downloads
Rav includes powerful file download capabilities with support for integrity verification, custom destinations, and batch downloads.
Basic Download Configuration
Add a downloads section to your rav.yaml:
name: my-project
scripts:
serve: python -m http.server
downloads:
assets:
destination: static/vendor
files:
- name: htmx.min.js
url: https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js
- name: tailwind.css
url: https://cdn.tailwindcss.com/3.4.0/tailwind.min.css
Download Commands
rav download assets # Download all files in 'assets' config
rav downloads assets # Same as above (alias)
Advanced Download Configuration
downloads:
frontend-deps:
name: Frontend Dependencies
destination: static/vendor
verbose: true # Show detailed progress
overwrite: true # Overwrite existing files
raise_on_error: false # Continue on individual file errors
files:
- name: htmx.min.js
url: https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js
integrity: sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm
destination: static/js # Override global destination
overwrite: false # Override global overwrite setting
- name: bootstrap.min.css
url: https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css
destination: static/css
Configuration Options
| Option | Level | Description | Default |
|---|---|---|---|
name |
Download | Human-readable name for the download set | - |
destination |
Download/File | Where to save files | Required |
verbose |
Download | Show detailed download progress | true |
overwrite |
Download/File | Overwrite existing files | false |
raise_on_error |
Download | Stop on any download error | false |
integrity |
File | SRI hash for verification | - |
url |
File | Download URL | Required |
name or filename |
File | Local filename | URL basename |
File-Level Overrides
Individual files can override the download-level settings:
downloads:
mixed-settings:
destination: assets/
overwrite: false
verbose: true
files:
- name: important-file.js
url: https://example.com/file.js
overwrite: true # Override: will overwrite
destination: critical/ # Override: different folder
- name: optional-file.css
url: https://example.com/style.css
# Uses download-level settings
Download Output
Rav provides rich, colored output showing download progress:
๐ฅ Starting download: frontend-deps
Destination: static/vendor
Files to download: 3
Overwrite existing: true
[1/3] โฌ๏ธ Downloading: htmx.min.js
โ From: https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js
โ Integrity: sha384-Akqfrbj/...
โ
Integrity verified (sha384)
โ
Success! (45,234 bytes)
[2/3] โญ๏ธ Skipping existing file: bootstrap.min.css
[3/3] โฌ๏ธ Downloading: alpine.min.js
โ
Success! (15,678 bytes)
---------------------------------------
๐ Download Summary:
โ
Downloaded: 2 files
โญ๏ธ Skipped: 1 files
---------------------------------------
Integrity Verification
Rav supports Subresource Integrity (SRI) verification to ensure downloaded files haven't been tampered with.
What is SRI?
Subresource Integrity is a security feature that allows you to verify that downloaded files haven't been modified. It uses cryptographic hashes (SHA256, SHA384, SHA512) to ensure file integrity.
Supported Hash Algorithms
- SHA256:
sha256-<base64hash> - SHA384:
sha384-<base64hash> - SHA512:
sha512-<base64hash>
Getting SRI Hashes
You can generate SRI hashes using online tools or command line:
Online Tools:
Command Line:
# SHA384 (recommended)
curl -s https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js | \
openssl dgst -sha384 -binary | openssl base64 -A
# SHA256
curl -s https://example.com/file.js | \
openssl dgst -sha256 -binary | openssl base64 -A
Using Integrity Verification
Add the integrity field to any file in your download configuration:
downloads:
secure-assets:
destination: static/vendor
files:
- name: htmx.min.js
url: https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js
integrity: sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm
- name: bootstrap.min.css
url: https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css
integrity: sha384-9ndCyUa/9zzCGWL/iDMdwc9/z3dNS0MaTp5XhVpw5gGa6NZJK5YF6vZmN3K5J5zF
Integrity Verification Process
When integrity is specified, rav will:
- Download the file to a temporary location
- Calculate the file's hash using the specified algorithm
- Compare against the expected hash
- Move file to final destination only if verification passes
- Delete file and report error if verification fails
Error Handling
With raise_on_error: false (default):
- Failed verification logs an error and continues
- Failed files are not saved to destination
- Download summary shows verification failures
With raise_on_error: true:
- Failed verification stops the entire download process
- Throws an exception with detailed error information
Example Output with Integrity
[1/2] โฌ๏ธ Downloading: htmx.min.js
โ From: https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js
โ Integrity: sha384-Akqfrbj/...
โ Downloading to temp for verification: /tmp/rav_downloads/htmx.min.js
โ
Integrity verified (sha384)
โ Downloaded to final destination: static/vendor/htmx.min.js
โ
Success! (45,234 bytes)
[2/2] โฌ๏ธ Downloading: compromised-file.js
โ From: https://example.com/file.js
โ Integrity: sha384-Expected123...
โ Integrity check failed: sha384-Actual456... != sha384-Expected123...
Security Best Practices
- Always use integrity hashes for CDN files
- Use SHA384 or SHA512 for better security than SHA256
- Verify hashes from trusted sources (official documentation, package registries)
- Set
raise_on_error: truefor critical security files - Keep hashes updated when updating file versions
Complete Examples
Web Development Project
A complete rav.yaml for a modern web development workflow:
name: my-web-app
scripts:
# Development
dev: python -m http.server 8000
dev-watch:
- npm run watch
- rav run dev
# Code quality
lint:
- flake8 src/
- npm run lint
- echo "โ
Linting complete"
format:
- black src/
- prettier --write static/js/
test:
- pytest tests/ -v --cov=src
- npm test
# Build pipeline
build:
- rm -rf dist/
- rav download frontend-deps
- npm run build
- python setup.py sdist bdist_wheel
- echo "๐ Build complete!"
# Deployment
deploy-staging:
- rav run test
- rav run build
- rsync -av dist/ staging@server:/var/www/staging/
deploy-prod:
- rav run test
- rav run build
- rsync -av dist/ prod@server:/var/www/production/
downloads:
frontend-deps:
name: Frontend Dependencies
destination: static/vendor
verbose: true
overwrite: true
files:
# CSS Frameworks
- name: bootstrap.min.css
url: https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css
integrity: sha384-9ndCyUa/9zzCGWL/iDMdwc9/z3dNS0MaTp5XhVpw5gGa6NZJK5YF6vZmN3K5J5zF
destination: static/css
# JavaScript Libraries
- name: htmx.min.js
url: https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js
integrity: sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm
destination: static/js
- name: alpine.min.js
url: https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js
destination: static/js
Data Science Project
Perfect for Jupyter notebooks and data analysis:
name: data-analysis-project
scripts:
# Environment management
setup:
- python -m venv venv
- venv/bin/pip install -r requirements.txt
- echo "โ
Environment ready!"
# Jupyter workflows
notebook: venv/bin/jupyter lab --port=8888
notebook-clean: venv/bin/jupyter nbconvert --clear-output notebooks/*.ipynb
# Data processing
download-data: python scripts/download_datasets.py
process:
- python scripts/clean_data.py
- python scripts/feature_engineering.py
- echo "๐ Data processing complete"
# Analysis and reporting
analyze: venv/bin/python scripts/analyze.py
report:
- venv/bin/jupyter nbconvert --to html notebooks/analysis.ipynb
- echo "๐ Report generated: notebooks/analysis.html"
# Model training
train:
- rav run process
- python scripts/train_model.py
- echo "๐ค Model training complete"
downloads:
datasets:
destination: data/raw
files:
- name: sample_data.csv
url: https://example.com/datasets/sample.csv
- name: reference_data.json
url: https://api.example.com/reference/data.json
DevOps/Infrastructure Project
For managing deployments and infrastructure:
name: infrastructure-toolkit
scripts:
# Infrastructure
plan: terraform plan
apply: terraform apply -auto-approve
destroy: terraform destroy -auto-approve
# Docker workflows
build: docker build -t myapp:latest .
run: docker run -p 8080:8080 myapp:latest
push:
- docker tag myapp:latest registry.com/myapp:latest
- docker push registry.com/myapp:latest
# Kubernetes
deploy:
- kubectl apply -f k8s/
- kubectl rollout status deployment/myapp
logs: kubectl logs -f deployment/myapp
status: kubectl get pods,services,deployments
# Monitoring setup
setup-monitoring:
- rav download monitoring-stack
- kubectl apply -f monitoring/
- echo "๐ Monitoring stack deployed"
downloads:
monitoring-stack:
destination: monitoring
files:
- name: prometheus.yaml
url: https://raw.githubusercontent.com/prometheus/prometheus/main/documentation/examples/prometheus.yml
- name: grafana-dashboard.json
url: https://grafana.com/api/dashboards/1860/revisions/latest/download
Tips and Best Practices
Script Organization
- Group related commands using descriptive names
- Use comments in YAML to document complex workflows
- Chain commands with
rav runfor reusable components - Keep scripts simple - complex logic belongs in separate files
File Downloads
- Always use integrity hashes for security
- Organize by purpose (frontend-deps, datasets, configs)
- Use descriptive destination paths for better organization
- Set appropriate overwrite policies per use case
Project Structure
my-project/
โโโ rav.yaml # Main configuration
โโโ rav.dev.yaml # Development-specific config
โโโ rav.prod.yaml # Production-specific config
โโโ scripts/ # Complex automation scripts
โโโ static/vendor/ # Downloaded dependencies
โโโ data/raw/ # Downloaded datasets
Cross-Platform Compatibility
scripts:
# Universal commands (recommended)
test: python -m pytest tests/
serve: python -m http.server 8000
# Platform-specific alternatives
serve-win: python -m http.server 8000
serve-unix: python3 -m http.server 8000
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rav-0.4.3.tar.gz.
File metadata
- Download URL: rav-0.4.3.tar.gz
- Upload date:
- Size: 49.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a6a84900b2bf00fb0f148a7a96a845533cd4fbb40d88988af9c61788a65a875
|
|
| MD5 |
6d6befdc59f63dff2cf35bdc80c825ae
|
|
| BLAKE2b-256 |
e16cbfaef05a839b357c48c3150b26f653eff106bf3bb557e2c9c3b4a5eca32f
|
Provenance
The following attestation bundles were made for rav-0.4.3.tar.gz:
Publisher:
release.yaml on jmitchel3/rav
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rav-0.4.3.tar.gz -
Subject digest:
8a6a84900b2bf00fb0f148a7a96a845533cd4fbb40d88988af9c61788a65a875 - Sigstore transparency entry: 829386019
- Sigstore integration time:
-
Permalink:
jmitchel3/rav@62aa19350e67b77bb9728bb2988ffbe1dd0cc841 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/jmitchel3
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@62aa19350e67b77bb9728bb2988ffbe1dd0cc841 -
Trigger Event:
push
-
Statement type:
File details
Details for the file rav-0.4.3-py3-none-any.whl.
File metadata
- Download URL: rav-0.4.3-py3-none-any.whl
- Upload date:
- Size: 18.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73e443f80b072d15942d227a46f90cd7909700e7b8c117ed389b1cce08db3435
|
|
| MD5 |
c13455014eaea4171f3f43b7161fe522
|
|
| BLAKE2b-256 |
42b51fc1faa3a19730042c9b60539416bce5f1b1db8d224bc2aa07004a30dc59
|
Provenance
The following attestation bundles were made for rav-0.4.3-py3-none-any.whl:
Publisher:
release.yaml on jmitchel3/rav
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rav-0.4.3-py3-none-any.whl -
Subject digest:
73e443f80b072d15942d227a46f90cd7909700e7b8c117ed389b1cce08db3435 - Sigstore transparency entry: 829386025
- Sigstore integration time:
-
Permalink:
jmitchel3/rav@62aa19350e67b77bb9728bb2988ffbe1dd0cc841 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/jmitchel3
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@62aa19350e67b77bb9728bb2988ffbe1dd0cc841 -
Trigger Event:
push
-
Statement type: