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.
β¨ Script Management: Define and run custom command shortcuts
π¦ 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
- Install
- Quick Start
- CLI Commands Reference
- Script Configuration
- File Downloads
- Integrity Verification
- Complete Examples
- Tips and Best Practices
It's recommended that you use a virtual environment with rav
.
python3 -m pip install rav
Minimum python version is 3.7
cd ~/path/to/project
rav new
Run through the setup wizard to create
rav.yaml
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
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 |
Command | Description | Example |
---|---|---|
rav download <config> |
Download files using config | rav download staticfiles |
rav downloads <config> |
Alias for rav download |
rav downloads staticfiles |
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 |
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
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/[email protected]/dist/htmx.min.js
integrity: sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm
- name: tailwind.css
url: https://cdn.tailwindcss.com/3.4.0/tailwind.min.css
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
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
Generate a sample project to explore features:
rav sample # Creates rav.sample.yaml
rav run -f rav.sample.yaml echo
Rav supports custom yaml files by default. The yaml declaration needs to be any of the following:
rav
scripts
commands
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:
-f
or--file
is used to specify a custom rav file-f
or--file
must be used prior to the command shortcut name (e.g.rav run -f <your-new-file> <your-command>
)
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
Rav includes powerful file download capabilities with support for integrity verification, custom destinations, and batch downloads.
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/[email protected]/dist/htmx.min.js
- name: tailwind.css
url: https://cdn.tailwindcss.com/3.4.0/tailwind.min.css
rav download assets # Download all files in 'assets' config
rav downloads assets # Same as above (alias)
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/[email protected]/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/[email protected]/dist/css/bootstrap.min.css
destination: static/css
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 |
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
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/[email protected]/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
---------------------------------------
Rav supports Subresource Integrity (SRI) verification to ensure downloaded files haven't been tampered with.
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.
- SHA256:
sha256-<base64hash>
- SHA384:
sha384-<base64hash>
- SHA512:
sha512-<base64hash>
You can generate SRI hashes using online tools or command line:
Online Tools:
Command Line:
# SHA384 (recommended)
curl -s https://cdn.jsdelivr.net/npm/[email protected]/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
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/[email protected]/dist/htmx.min.js
integrity: sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm
- name: bootstrap.min.css
url: https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css
integrity: sha384-9ndCyUa/9zzCGWL/iDMdwc9/z3dNS0MaTp5XhVpw5gGa6NZJK5YF6vZmN3K5J5zF
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
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
[1/2] β¬οΈ Downloading: htmx.min.js
β From: https://cdn.jsdelivr.net/npm/[email protected]/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...
- 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: true
for critical security files - Keep hashes updated when updating file versions
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/[email protected]/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/[email protected]/dist/htmx.min.js
integrity: sha384-Akqfrbj/HpNVo8k11SXBb6TlBWmXXlYQrCSqEWmyKJe+hDm3Z/B2WVG4smwBkRVm
destination: static/js
- name: alpine.min.js
url: https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js
destination: static/js
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
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
- Group related commands using descriptive names
- Use comments in YAML to document complex workflows
- Chain commands with
rav run
for reusable components - Keep scripts simple - complex logic belongs in separate files
- 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
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
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