Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 78 additions & 190 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,253 +2,141 @@

**Hierarchical environment variable management for modern development workflows**

> [Documentation](https://sysid.github.io/hierarchical-environment-variable-management/)
> [Documentation](https://sysid.github.io/hierarchical-environment-variable-management/) | [Wiki](https://github.com/sysid/rs-env/wiki)

## Overview
[![Crates.io](https://img.shields.io/crates/v/rs-env.svg)](https://crates.io/crates/rs-env)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Managing environment variables across different environments (development, staging, production) and configurations (regions, features, services) is a common challenge in cloud-native projects. `rsenv` solves this by implementing hierarchical inheritance where child configurations automatically inherit and can override parent values.
## Why rs-env?

**Key Benefits:**
- **Zero Duplication**: Share common variables across environments while customizing specific values
- **Clear Provenance**: Easily trace where each variable value originates in the hierarchy
- **Type Safety**: Built-in validation and structured configuration management
- **Developer Experience**: Interactive selection, editing, and integration with popular tools

## Features

### Core Functionality
- **Hierarchical Inheritance**: Build environment trees from `.env` files with parent-child relationships
- **Smart Override Logic**: Child variables automatically override parent values with clear precedence rules
- **Standalone File Support**: Automatically detect and include independent `.env` files as single-node trees
- **Environment Expansion**: Full support for `$VAR` and `${VAR}` syntax in paths and comments
- **Flexible Linking**: Link files with comments supporting variable spacing: `# rsenv: parent.env`

### Interactive Tools
- **Fuzzy Selection**: Built-in fuzzy finder (skim) for rapid environment discovery and selection
- **Smart Editing**: Edit entire hierarchies side-by-side or individual files with full context
- **Tree Visualization**: Display hierarchical relationships and identify leaf nodes
- **Branch Analysis**: Linear representation of all environment chains
Managing environment variables across different environments (development, staging, production) and configurations (regions, features, services) creates massive duplication in traditional `.env` files. **rs-env solves this** by implementing hierarchical inheritance where child configurations automatically inherit and override parent values.

### Integrations
- **[direnv](https://direnv.net/)**: Automatic environment activation when entering directories
- **[JetBrains IDEs](https://plugins.jetbrains.com/plugin/7861-envfile)**: Native IDE integration via EnvFile plugin
- **Shell Integration**: Generate completion scripts for bash, zsh, fish, and powershell
**Key Benefits:**
- **Zero Duplication** - Share common variables across environments while customizing specific values
- **Clear Provenance** - Easily trace where each variable value originates in the hierarchy
- **Interactive Tools** - Fuzzy selection, side-by-side editing, and tree visualization
- **Modern Integrations** - Works with direnv, JetBrains IDEs, and popular shells

### Concept
![concept](doc/concept.png)
## Quick Demo

<a href="https://asciinema.org/a/605946?autoplay=1&speed=1.5" target="_blank"><img src="https://asciinema.org/a/605946.svg" /></a>

## Installation

### From crates.io
```bash
# From crates.io
cargo install rs-env
```

### From source
```bash
# From source
git clone https://github.com/sysid/rs-env
cd rs-env/rsenv
cargo install --path .
```

## Quick Start
**Requirements**: Rust 1.70+ ([Install Rust](https://rustup.rs/))

### 1. File Structure
Create linked environment files using `# rsenv:` comments:
## 30-Second Example

Create a hierarchy where child environments inherit from parents:

```bash
# base.env
# base.env - Shared configuration
export DATABASE_HOST=localhost
export LOG_LEVEL=info

# production.env
# production.env - Inherits from base, overrides specific values
# rsenv: base.env
export DATABASE_HOST=prod.example.com
export LOG_LEVEL=warn
export DATABASE_HOST=prod-db.example.com
export LOG_LEVEL=error
export ENVIRONMENT=production
```

### 2. Basic Usage
Build the complete environment:

```bash
# Build complete environment from hierarchy
# Build production environment
rsenv build production.env

# Load into current shell
# Load into your shell
source <(rsenv build production.env)

# Interactive selection with fuzzy finder
rsenv select environments/

# View tree structure
rsenv tree environments/

# Find all leaf environments
rsenv leaves environments/
```

### 3. Advanced Features
```bash
# Edit entire hierarchy side-by-side
rsenv tree-edit environments/

# Update direnv integration
rsenv envrc production.env

# Link files programmatically
rsenv link base.env staging.env production.env
# Verify
echo $DATABASE_HOST # prod-db.example.com (from production.env)
echo $LOG_LEVEL # error (from production.env)
```

## File Format
**Result**: `production.env` inherits `base.env` variables and overrides what changes. The `# rsenv: base.env` comment creates the parent-child link.

### Environment Files
- Use `export VAR=value` syntax (shell-compatible)
- Support single and double quotes
- Include `# rsenv: parent.env` comments for hierarchy
## Core Features

### Linking Syntax
```bash
# Basic parent reference
# rsenv: parent.env
### Hierarchical Inheritance
- Build environment trees from `.env` files with parent-child relationships
- Smart override logic: child variables automatically override parent values
- Standalone file support: independent `.env` files work as single-node trees

# Multiple parents (creates DAG structure)
# rsenv: base.env shared.env

# Environment variable expansion
# rsenv: $HOME/config/base.env

# Flexible spacing (all valid)
# rsenv:parent.env
# rsenv: parent.env
# rsenv: parent.env
```

## Command Reference

### Core Commands
| Command | Description | Example |
|---------|-------------|---------|
| `build` | Build complete environment from hierarchy | `rsenv build prod.env` |
| `leaves` | List all leaf environment files | `rsenv leaves environments/` |
| `tree` | Display hierarchical structure | `rsenv tree environments/` |
| `branches` | Show linear representation of all chains | `rsenv branches environments/` |

### Interactive Commands
| Command | Description | Example |
|---------|-------------|---------|
| `select` | Interactive environment selection + direnv update | `rsenv select environments/` |
| `edit` | Interactive selection and editing | `rsenv edit environments/` |
| `tree-edit` | Side-by-side editing of hierarchies | `rsenv tree-edit environments/` |

### Management Commands
| Command | Description | Example |
|---------|-------------|---------|
| `envrc` | Update .envrc file for direnv | `rsenv envrc prod.env .envrc` |
| `files` | List all files in hierarchy | `rsenv files prod.env` |
| `link` | Create parent-child relationships | `rsenv link base.env prod.env` |

### Global Options
- `-d, --debug`: Enable debug logging (use multiple times for increased verbosity)
- `--generate`: Generate shell completion scripts (bash, zsh, fish, powershell)
- `--info`: Display version and configuration information

## Examples

### Basic Workflow
<a href="https://asciinema.org/a/605946?autoplay=1&speed=1.5" target="_blank"><img src="https://asciinema.org/a/605946.svg" /></a>

### Interactive Selection
<a href="https://asciinema.org/a/605951?autoplay=1&speed=1.5" target="_blank"><img src="https://asciinema.org/a/605951.svg" /></a>

### Tree Editing
<a href="https://asciinema.org/a/605950?autoplay=1&speed=1.5" target="_blank"><img src="https://asciinema.org/a/605950.svg" /></a>

## Integrations

### direnv Integration
[direnv](https://direnv.net/) provides automatic environment activation:
### Interactive Tools
- **Fuzzy Selection** - Built-in fuzzy finder for rapid environment discovery
- **Smart Editing** - Edit entire hierarchies side-by-side or individual files
- **Tree Visualization** - Display relationships and identify leaf nodes

```bash
# Generate .envrc for automatic loading
rsenv envrc production.env .envrc
### Integrations
- **[direnv](https://direnv.net/)** - Automatic environment activation when entering directories
- **[JetBrains IDEs](https://plugins.jetbrains.com/plugin/7861-envfile)** - Native IDE integration via EnvFile plugin
- **Shell Completion** - bash, zsh, fish, and powershell support

# Interactive selection with direnv update
rsenv select environments/
## How It Works

# Manual direnv commands
direnv allow # Enable .envrc
direnv reload # Refresh environment
```
![Concept](doc/concept.png)

### JetBrains IDEs
Integration via [EnvFile plugin](https://plugins.jetbrains.com/plugin/7861-envfile):
Environment files form **directed acyclic graphs (DAGs)** where:
1. Child files link to parents via `# rsenv: parent.env` comments
2. Variables are inherited and merged from parent to child
3. Child values override parent values (last defined wins)
4. The `build` command compiles the complete environment

1. Install the EnvFile plugin
2. Create a run configuration script:
```bash
#!/bin/bash
# runenv.sh
rsenv build "${RUN_ENV}.env"
```
3. Configure the plugin to use `runenv.sh`
4. Set `RUN_ENV` environment variable in your run configuration
## Essential Commands

[![jetbrain](doc/jetbrain.png)](doc/jetbrain.png)
| Command | Purpose |
|---------|---------|
| `rsenv build <file>` | Build complete environment from hierarchy |
| `rsenv select <dir>` | Interactive selection + direnv update |
| `rsenv tree <dir>` | Display hierarchical structure |
| `rsenv edit <dir>` | Interactive selection and editing |

### Shell Integration
Generate completion scripts for your shell:
**[Full Command Reference](https://github.com/sysid/rs-env/wiki/Command-Reference)**

```bash
# Bash
rsenv --generate bash > ~/.bash_completion.d/rsenv
## Documentation

# Zsh
rsenv --generate zsh > ~/.zsh/completions/_rsenv
**New to rs-env?** Start with the [Quick Start Guide](https://github.com/sysid/rs-env/wiki/Quick-Start)

# Fish
rsenv --generate fish > ~/.config/fish/completions/rsenv.fish
```
**Comprehensive documentation** is available in the [rs-env Wiki](https://github.com/sysid/rs-env/wiki):

- **Getting Started**: [Quick Start](https://github.com/sysid/rs-env/wiki/Quick-Start), [Installation](https://github.com/sysid/rs-env/wiki/Installation), [Core Concepts](https://github.com/sysid/rs-env/wiki/Core-Concepts)
- **Core Features**: [Building Environments](https://github.com/sysid/rs-env/wiki/Building-Environments), [Viewing Hierarchies](https://github.com/sysid/rs-env/wiki/Viewing-Hierarchies), [File Format](https://github.com/sysid/rs-env/wiki/File-Format)
- **Interactive Tools**: [Interactive Selection](https://github.com/sysid/rs-env/wiki/Interactive-Selection), [Tree Editing](https://github.com/sysid/rs-env/wiki/Tree-Editing)
- **Integrations**: [direnv](https://github.com/sysid/rs-env/wiki/direnv-Integration), [JetBrains IDEs](https://github.com/sysid/rs-env/wiki/JetBrains-IDEs), [Shell Completion](https://github.com/sysid/rs-env/wiki/Shell-Completion)
- **Advanced**: [Managing Links](https://github.com/sysid/rs-env/wiki/Managing-Links), [Complex Hierarchies](https://github.com/sysid/rs-env/wiki/Complex-Hierarchies)
- **Reference**: [Command Reference](https://github.com/sysid/rs-env/wiki/Command-Reference), [Troubleshooting](https://github.com/sysid/rs-env/wiki/Troubleshooting)

## Contributing

## Development
Contributions are welcome! See the [Development Guide](https://github.com/sysid/rs-env/wiki/Development) for details on building, testing, and contributing.

### Building from Source
```bash
# Quick start for contributors
git clone https://github.com/sysid/rs-env
cd rs-env/rsenv
cargo test -- --test-threads=1
cargo build --release
```

### Running Tests
```bash
# Run all tests (single-threaded to prevent conflicts)
cargo test -- --test-threads=1
## License

# Run with debug output
RUST_LOG=debug cargo test -- --test-threads=1
MIT License - see [LICENSE](LICENSE) for details.

# Test via Makefile (includes interactive tests)
make test
```
## Links

### Project Structure
- **`src/lib.rs`**: Core environment expansion and tree building logic
- **`src/builder.rs`**: TreeBuilder for constructing hierarchical structures
- **`src/arena.rs`**: Arena-based tree data structures
- **`src/cli/`**: Command-line interface and command implementations
- **`tests/`**: Comprehensive test suite with example environments

### Testing Notes
- Interactive tests using skim require a valid terminal and are run via Makefile
- Tests run single-threaded to prevent file system conflicts
- Test resources in `tests/resources/environments/` demonstrate complex hierarchies

### Contributing
1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass: `cargo test -- --test-threads=1`
5. Run formatting: `cargo fmt`
6. Run linting: `cargo clippy`
7. Submit a pull request
- 📦 [crates.io Package](https://crates.io/crates/rs-env)
- 📖 [Wiki Documentation](https://github.com/sysid/rs-env/wiki)
- 🐛 [Issue Tracker](https://github.com/sysid/rs-env/issues)
- 💬 [Discussions](https://github.com/sysid/rs-env/discussions)
44 changes: 44 additions & 0 deletions doc/example-walkthrough/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Example Walkthrough

This directory contains a realistic example of hierarchical environment configuration used throughout the rs-env documentation.

## Structure

```
base.env # Shared base configuration
└─ cloud.env # Cloud-specific overrides
└─ production.env # Production-specific overrides
dev.env # Standalone development environment
```

## Files

- **base.env**: Base configuration shared across all environments
- DATABASE_HOST, DATABASE_PORT, LOG_LEVEL, APP_NAME

- **cloud.env**: Inherits from base.env, overrides for cloud deployments
- Overrides: DATABASE_HOST, LOG_LEVEL
- Adds: CLOUD_PROVIDER, REGION

- **production.env**: Inherits from cloud.env, production-specific settings
- Overrides: DATABASE_HOST, LOG_LEVEL, REGION
- Adds: ENVIRONMENT, API_KEY, ENABLE_MONITORING

- **dev.env**: Standalone file for local development (no parent)
- Independent configuration for development workflow

## Usage

```bash
# Build production environment (inherits base → cloud → production)
rsenv build production.env

# Build development environment (standalone)
rsenv build dev.env

# View the hierarchy
rsenv tree .

# List all leaf environments
rsenv leaves .
```
5 changes: 5 additions & 0 deletions doc/example-walkthrough/base.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Base configuration - shared across all environments
export DATABASE_HOST=localhost
export DATABASE_PORT=5432
export LOG_LEVEL=info
export APP_NAME=my-cloud-app
7 changes: 7 additions & 0 deletions doc/example-walkthrough/cloud.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# rsenv: base.env

# Cloud-specific configuration
export DATABASE_HOST=db.cloud.internal
export LOG_LEVEL=warn
export CLOUD_PROVIDER=aws
export REGION=us-east-1
7 changes: 7 additions & 0 deletions doc/example-walkthrough/dev.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Standalone development environment (no parent)
export DATABASE_HOST=localhost
export DATABASE_PORT=5432
export LOG_LEVEL=debug
export APP_NAME=my-cloud-app
export ENVIRONMENT=development
export DEBUG=true
Loading