Skip to main content

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 constraints
    • requests==2.32.3 - Exact version
    • numpy>=1.24.0 - Minimum version
    • pandas~=2.0 - Compatible version
  • extras:<labels> - Custom labels for grouping
  • flags:<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

  1. Parse spec - DSL or YAML โ†’ normalized specification
  2. Compute hash - Stable hash from spec + platform + Python/UV versions
  3. Check cache - Reuse if environment exists, otherwise create
  4. Create environment - Use uv to create venv and install packages
  5. Run command - Execute with PATH pointing to environment
  6. 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:


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

easyenv_cli-0.1.1.tar.gz (26.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

easyenv_cli-0.1.1-py3-none-any.whl (27.6 kB view details)

Uploaded Python 3

File details

Details for the file easyenv_cli-0.1.1.tar.gz.

File metadata

  • Download URL: easyenv_cli-0.1.1.tar.gz
  • Upload date:
  • Size: 26.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for easyenv_cli-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e579fff34c3a16140c0bff8ed17b016f84b4359ad2dd61a2a3af769b443d324e
MD5 26ee90123d830450ebe235a1cab3eab8
BLAKE2b-256 073752e4b4979352b81ca0c83c43d23b1ed7577fdc049a3f47ec844b6f6a0368

See more details on using hashes here.

File details

Details for the file easyenv_cli-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: easyenv_cli-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 27.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for easyenv_cli-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 38e11c6ed97280919f31a096f11e2c2dddb126eb47de0908b66a8be544f0c73c
MD5 10914dd415199d618a10e0166d7e050d
BLAKE2b-256 3573ea856274e2a2c0cfd3830b0d17b3a91d5a2d6689ce8dd22d6a739ddfaa88

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page