Ephemeral, reproducible, cached development environment
Project description
EasyEnv CLI
Ephemeral, reproducible, cached development environments
EasyEnv CLI is a CLI/TUI tool for creating "one-off" but reproducible and cached development environments. One command โ ready env โ run user command โ keep system clean.
Features
- ๐ Instant ephemeral environments - Create isolated Python environments on-demand
- ๐ Reproducible builds - Lock files ensure byte-for-byte reproducibility
- ๐พ Smart caching - Reuse environments automatically with hash-based deduplication
- ๐งน Zero global pollution - Everything isolated in
~/.easyenv/cache - ๐ฆ Powered by uv - Lightning-fast package installation
- ๐ฏ Simple DSL - Human-readable specs:
py=3.12 pkgs:requests==2.32.3 - ๐ SBOM generation - Automatic software bill of materials
- ๐ฅ๏ธ Optional TUI - Browse and manage cached environments
Installation
# Install uv first (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install EasyEnv CLI
pip install easyenv-cli
# or
pipx install easyenv-cli
# or (using uv)
uv tool install easyenv-cli
Quick Start
Run command in ephemeral environment
# Basic usage
easyenv-cli run "py=3.12 pkgs:requests==2.32.3" -- python -c "import requests; print('โ')"
# Multiple packages
easyenv-cli run "py=3.11 pkgs:requests,numpy,pandas" -- python script.py
# With version constraints
easyenv-cli run "py=3.12 pkgs:requests==2.32.3,pendulum~=3.0" -- python app.py
Prepare environment without running
# Pre-build for later use
easyenv-cli prepare "py=3.12 pkgs:ruff==0.7.2"
Using YAML specs
Create env.yaml:
python: "3.12"
packages:
- "requests==2.32.3"
- "pendulum~=3.0"
- "numpy>=1.24.0"
scripts:
post_install:
- "python -c 'import requests; print(requests.__version__)'"
env:
PANDAS_IGNORE_WARNING: "1"
DEBUG: "true"
Run it:
easyenv-cli run env.yaml -- python my_script.py
Templates
# Save frequently-used specs as templates
easyenv-cli template add datasci "py=3.12 pkgs:numpy,pandas,matplotlib"
easyenv-cli template add testing "py=3.11 pkgs:pytest,coverage,ruff"
# Use templates
easyenv-cli use datasci -- jupyter lab
easyenv-cli use testing -- pytest tests/
# List templates
easyenv-cli template list
Cache management
# List cached environments
easyenv-cli list
# Show disk usage
easyenv-cli du
# Purge old environments
easyenv-cli purge --older-than 30d --dry-run
easyenv-cli purge --max-size 8GB
# Remove specific age
easyenv-cli purge --older-than 7d
Lock files for reproducibility
# Export lock file
easyenv-cli run "py=3.12 pkgs:requests" -- python -c "print('ok')"
easyenv-cli lock export abc123def456 -o production.lock.json
# Import lock file (reproduces exact environment)
easyenv-cli lock import production.lock.json
Diagnostics
# Check setup
easyenv-cli doctor
TUI (Terminal UI)
# Launch interactive cache browser
easyenv-cli tui
DSL Syntax
The EasyEnv DSL is a simple, space-separated format:
py=<version> pkgs:<pkg1>,<pkg2> extras:<label1>,<label2> flags:<k=v>
Components
py=<version>(required) - Python version (e.g.,3.12,3.11)pkgs:<packages>- Comma-separated package specs with version constraintsrequests==2.32.3- Exact versionnumpy>=1.24.0- Minimum versionpandas~=2.0- Compatible version
extras:<labels>- Custom labels for groupingflags:<k=v>- Key-value flags for future extensions
Examples
# Simple
py=3.12 pkgs:requests
# Multiple packages with versions
py=3.11 pkgs:requests==2.32.3,numpy>=1.24.0,pandas~=2.0
# With extras
py=3.12 pkgs:pytest,coverage extras:testing,ci
# Order doesn't matter
extras:dev pkgs:ruff py=3.12
YAML Format
For complex environments, use YAML:
python: "3.12"
packages:
- "requests==2.32.3"
- "numpy>=1.24.0"
- "pandas~=2.0"
extras:
- "dev"
- "testing"
scripts:
post_install:
- "python -c 'import requests; print(requests.__version__)'"
- "pytest --version"
env:
DEBUG: "true"
LOG_LEVEL: "info"
CUSTOM_VAR: "value"
flags:
optimize: "true"
How It Works
- Parse spec - DSL or YAML โ normalized specification
- Compute hash - Stable hash from spec + platform + Python/UV versions
- Check cache - Reuse if environment exists, otherwise create
- Create environment - Use
uvto create venv and install packages - Run command - Execute with PATH pointing to environment
- Keep clean - No global modifications, all isolated in cache
Cache Structure
~/.easyenv/cache/
โโโ index.db # SQLite index
โโโ abc123def456/ # Environment (hash-based)
โ โโโ bin/ # Virtual environment
โ โโโ meta.json # Metadata
โ โโโ bom.json # SBOM
โ โโโ spec.yaml # Original spec
โโโ xyz789ghi012/
โโโ ...
CI Integration
GitHub Actions Example
name: Test with EasyEnv
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Install EasyEnv CLI
run: pipx install easyenv-cli
- name: Run tests
run: |
easyenv-cli run "py=3.12 pkgs:pytest,coverage" -- pytest -v
- name: Lint
run: |
easyenv-cli run "py=3.12 pkgs:ruff" -- ruff check .
Configuration
EasyEnv CLI can be configured via ~/.config/easyenv/config.toml:
# Custom cache directory
cache_dir = "/custom/path/to/cache"
# Default Python version
default_python = "3.12"
# Purge policies
purge_older_than_days = 30
purge_max_size_gb = 10.0
# Defaults
verbose = false
offline = false
# Templates
[templates]
datasci = "py=3.12 pkgs:numpy,pandas,matplotlib"
webdev = "py=3.11 pkgs:flask,requests"
Advanced Usage
Offline mode
# Prepare environments first
easyenv-cli prepare "py=3.12 pkgs:requests" --offline
# Use offline (no network access)
easyenv-cli run "py=3.12 pkgs:requests" --offline -- python script.py
Custom index URLs
# Use private PyPI mirror
export UV_INDEX_URL="https://pypi.company.com/simple"
easyenv-cli run "py=3.12 pkgs:internal-package" -- python script.py
Verbose output
# See what's happening
easyenv-cli run "py=3.12 pkgs:requests" -v -- python script.py
Comparison
| Tool | Ephemeral | Cached | Reproducible | Speed | Global Install |
|---|---|---|---|---|---|
| EasyEnv CLI | โ | โ | โ | โก | โ |
| venv | โ | โ | โ ๏ธ | ๐ | โ |
| Docker | โ | โ | โ | ๐ | โ ๏ธ |
| nix | โ | โ | โ | โก | โ ๏ธ |
Roadmap
- Node/Bun runtime support
- Template registry (git-based)
- GitHub Actions cache integration
- Web-based cache browser
- Docker backend (optional)
- PowerToys Run / Flow Launcher integration
Requirements
- Python 3.11+
- uv (for environment creation)
- Linux, macOS, or Windows (WSL)
Development
# Clone repository
git clone https://github.com/yourusername/easyenv
cd easyenv
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest
# Type checking
mypy src/easyenv
# Linting
ruff check .
Releases
See CHANGELOG.md for release history.
For maintainers: See docs/RELEASE.md for release instructions.
Installation from PyPI
# Stable release
pip install easyenv-cli
# Specific version
pip install easyenv-cli==0.1.0
# Using uv (recommended)
uv tool install easyenv-cli
# From source
pip install git+https://github.com/ruslanlap/EasyEnv.git
License
MIT License - see LICENSE file for details.
Contributing
Contributions welcome! Please open an issue or PR.
Credits
Built with:
- uv - Fast Python package installer
- Typer - CLI framework
- Textual - TUI framework
- Pydantic - Data validation
EasyEnv - One command, ready environment, clean system. ๐
Project details
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 easyenv_cli-0.1.2.tar.gz.
File metadata
- Download URL: easyenv_cli-0.1.2.tar.gz
- Upload date:
- Size: 28.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c20ed7baad2583139352a739d0b5b46831c7d9527f2d3d1e702970a2ec3a7bb
|
|
| MD5 |
96a052e3bbc5f3d1ed9c9d482a71c4d2
|
|
| BLAKE2b-256 |
dc3d13653a7ba60c14dfdfac0b7d55d26bfa673ce27036ca6a22bea41e94520c
|
File details
Details for the file easyenv_cli-0.1.2-py3-none-any.whl.
File metadata
- Download URL: easyenv_cli-0.1.2-py3-none-any.whl
- Upload date:
- Size: 29.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc8c4fe0702caddef20f9650726376f75f8ea1d581916eaf2af62396ce18dbfa
|
|
| MD5 |
81be1f50878b3cd71d5a78cf65beb002
|
|
| BLAKE2b-256 |
38e38528e7df53b0088103b1784bb5f2dcc36dd3ff8a699fc7308c4be888f6d9
|