Metadata-Version: 2.4
Name: refract-venv
Version: 0.1.0
Summary: Lightweight centralized virtual environment manager for Python
Author: YakShavingCatHerder
License-Expression: MIT
Project-URL: Homepage, https://github.com/YakShavingCatHerder/refract
Project-URL: Repository, https://github.com/YakShavingCatHerder/refract
Project-URL: Issues, https://github.com/YakShavingCatHerder/refract/issues
Keywords: virtualenv,venv,cli,python,developer-tools
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

<img width="1228" height="407" alt="Screenshot 2026-08-18 at 20 58 54" src="https://github.com/user-attachments/assets/c9759315-d5ed-4844-b3d4-612b71d779e5" />

**Lightweight Virtual Environment Manager for Python**

Refract centralizes your Python virtual environments in a single location, providing simple commands to create, manage, and switch between project contexts—without the complexity of traditional virtual environment tools.

## Demo

![refract demo](demo/refract.gif)

##  Features

- **Centralized Management**: All environments stored in `~/.refract/envs/`
- **Simple Commands**: Intuitive syntax that's easy to remember
- **Global Access**: Use `refract` from anywhere in your system
- **Zero Dependencies**: Only requires Python standard library
- **Seamless Switching**: Instant environment activation with new shell sessions
- **Colored Prompts**: Clear visual indication of active environment in shell prompt
- **Clean Organization**: Automatic directory structure management

##  Table of Contents

- [Demo](#demo)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Commands Reference](#commands-reference)
- [Usage Examples](#usage-examples)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)

##  Installation

Refract itself depends only on Python's standard library. The `refract` command and `refract install` (shell integration) are separate steps.

**macOS and Linux only.** Windows is not supported.

### Prerequisites

- Python 3.10 or higher
- bash or zsh

pip is optional. pipx is optional.

### From source (Python 3 only)

Best for minimal servers that may not have pip:

```bash
git clone git@github.com:YakShavingCatHerder/refract.git
cd refract
./install.sh
source ~/.zshrc    # bash: source ~/.bashrc
```

This copies `refract.py` to `~/.local/bin/refract`, then runs `refract install`.

### From source with pip

```bash
git clone git@github.com:YakShavingCatHerder/refract.git
cd refract
./install.sh --pip
source ~/.zshrc    # bash: source ~/.bashrc
```

### From source with pipx (optional)

```bash
./install.sh --pipx
source ~/.zshrc    # bash: source ~/.bashrc
```

### From PyPI

The distribution name is `refract-venv`. The command is `refract`.

```bash
pip install refract-venv
refract install
source ~/.zshrc    # bash: source ~/.bashrc
```

If you already use pipx for CLI tools:

```bash
pipx install refract-venv
refract install
source ~/.zshrc    # bash: source ~/.bashrc
```

### What `refract install` does

- Creates `~/.refract/` and `refract.json` (default colorway: green/black)
- Installs prompt integration in `~/.zshrc` and `~/.bashrc`
- Installs the shell wrapper in both files (reloads after `refract colorway`)
- Tells you to restart or source your shell

It does **not** install the `refract` executable. Re-running it is idempotent: existing snippets are updated, not duplicated.

### Uninstall

From a source checkout:

```bash
./uninstall.sh
```

If you installed the package:

```bash
pip uninstall refract-venv
# or: pipx uninstall refract-venv
```

Virtual environments in `~/.refract/envs/` are left in place. Remove them with `rm -rf ~/.refract`.

##  Quick Start

After installation, you can immediately start using refract:

```bash
# Create your first environment
refract init myproject

# List all environments
refract list

# Activate an environment
refract use myproject

# Remove an environment when done
refract rm myproject
```

##  Commands Reference

`refract init <name>`

Creates a new virtual environment with the specified name.

**Parameters:**
- `environment_name`: Must be a valid Python identifier (letters, numbers, underscores only)

**Example:**
```bash
$ refract init django_project
Created new virtualenv at /path/to/.refract/envs/django_project
```

**What happens:**
- Creates a new virtual environment in `~/.refract/envs/<name>/`
- Uses Python's built-in `venv` module
- Validates the environment name format
- Prevents duplicate environment creation
---------------
`refract list`

Displays all available virtual environments.

**Example Output:**
```bash
$ refract list
Available virtualenvs:
  * django_project
  * flask_api
  * data_analysis
  * machine_learning
```

**What happens:**
- Scans `~/.refract/envs/` directory
- Lists all subdirectories as available environments
- Shows helpful message if no environments exist

---------------
`refract use <name>`

Activates the specified virtual environment by opening a new shell session.

**Example:**
```bash
$ refract use django_project
[refract] Switching to environment 'django_project'...
```

**What happens:**
1. Validates the environment exists
2. Creates a temporary activation script that:
  - Sources your shell profile files (`.bash_profile`, `.zshrc`, etc.)
  - Activates the virtual environment
  - Opens a new shell session with the environment active
  - Sets up colored prompt showing the active refract environment with `[refract:name]` prefix
3. Runs the script in a new shell process
4. Removes the temporary script as a cleanup process

**After activation, you'll see:**
```bash
[refract:django_project] user@machine ~ %
```
---------------
`refract rm <name>`

Removes the specified virtual environment.

**Example:**
```bash
$ refract rm old_project
Removed environment 'old_project'
```

**What happens:**
- Validates the environment exists
- Completely removes the environment directory
- Provides confirmation message
---------------
`refract current`

Shows the currently active refract environment.

**Example:**
```bash
$ refract current
Currently in refract environment: django_project
```

**What happens:**
- Checks for the `REFRACT_ENV` environment variable
- Displays the active environment name in light gray if one is active
- Shows "No refract environment currently active" if none is active
---------------
`refract install`

Initializes Refract config and shell integration. The executable must already be on your PATH (via `./install.sh`, `pip`, or `pipx`).

**What happens:**
- Creates `~/.refract/` and `refract.json` if needed
- Writes prompt hooks and the shell wrapper into `~/.zshrc` and `~/.bashrc`
- Does not create a symlink or install the `refract` command

## Usage Examples

### Example 1: Web Development Workflow

```
# Create environments for different projects
$ refract init frontend
Created new virtualenv at /Users/path/.refract/envs/frontend

$ refract init backend
Created new virtualenv at /Users/path/.refract/envs/backend

# List all environments
$ refract list
Available virtualenvs:
  * frontend
  * backend

# Switch to frontend work
$ refract use frontend
[refract] Switching to environment 'frontend'...

# In the new shell session:
[refract:frontend] $ npm install
[refract:frontend] $ npm start

# Switch to backend work (in another terminal)
$ refract use backend
[refract] Switching to environment 'backend'...

# In the new shell session:
[refract:backend] $ pip install django
[refract:backend] $ python manage.py runserver
```

### Example 2: Data Science Workflow
```
# Create specialized environments
$ refract init data_analysis
$ refract init ml_experiment
$ refract init visualization

# Switch between different analysis contexts
$ refract use data_analysis
[refract:data_analysis] $ pip install pandas numpy matplotlib

$ refract use ml_experiment
[refract:ml_experiment] $ pip install scikit-learn tensorflow

$ refract use visualization
[refract:visualization] $ pip install plotly seaborn bokeh
```

### Example 3: Project Cleanup
```bash
# List all environments
$ refract list
Available virtualenvs:
  * old_project
  * experiment_1
  * experiment_2
  * current_project

# Remove completed experiments
$ refract rm experiment_1
Removed environment 'experiment_1'

$ refract rm experiment_2
Removed environment 'experiment_2'

# Verify cleanup
$ refract list
Available virtualenvs:
  * old_project
  * current_project
```
---------------

### Directory Structure

Refract creates and manages the following structure:

```
~/.refract/
├── envs/                    # All virtual environments
│   ├── project_a/
│   │   ├── bin/
│   │   ├── lib/
│   │   └── ...
│   ├── project_b/
│   │   ├── bin/
│   │   ├── lib/
│   │   └── ...
│   └── ...
└── refract.json            # Configuration file
```

### Colored Prompts Feature

Refract automatically modifies your shell prompt to show the active environment:

- **Format**: `[refract:environment_name]` appears at the beginning of your prompt
- **Color**: Green background with black text by default to make current venv easily visible
- **Shell Support**: Works with both bash and zsh
- **Environment Variable**: Sets `REFRACT_ENV` for programmatic access

##  Troubleshooting

### Common Issues

#### "command not found: refract"

**Problem**: The `refract` command isn't available globally.

**Solution**:
```bash
# From a source checkout, install the command then shell integration
./install.sh

# If the command exists but shell hooks do not
refract install

# Make sure ~/.local/bin is on PATH
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```

#### Refract environment is active, but prompt prefix is missing

**Problem**: `refract use <name>` activates the environment, but `[refract:<name>]` is not shown in your prompt.

**Why this happens**: Some shell themes/frameworks rebuild the prompt and can override custom prompt text.

**How to verify activation**:
```bash
echo $REFRACT_ENV
which python
```

If active, `REFRACT_ENV` should contain your environment name and `which python` should point to `~/.refract/envs/<name>/bin/python`.

#### "Permission denied: refract"

**Problem**: The installed script does not have execute permissions.

**Solution**:
```bash
chmod +x ~/.local/bin/refract
```

#### "Environment 'name' does not exist"

**Problem**: Trying to use an environment that hasn't been created.

**Solution**:
```bash
# Check available environments
refract list

# Create the environment first
refract init name
```

#### "Environment name must be a valid identifier"

**Problem**: Using invalid characters in environment names.

**Solution**: Use only letters, numbers, and underscores:
```bash
#  Valid names
refract init my_project
refract init project123
refract init _private

#  Invalid names
refract init my-project    # hyphens not allowed
refract init "my project"  # spaces not allowed
refract init my.project    # dots not allowed
```

### Debug Mode

Enable debug output to troubleshoot issues:

```bash
refract --debug list
```

This will show additional information about paths and configuration.

### Manual Environment Management

If you need to manually manage environments:

```bash
# List all environments
ls ~/.refract/envs/

# Remove an environment manually
rm -rf ~/.refract/envs/environment_name

# Check refract configuration
cat ~/.refract/refract.json
```

##  Contributing

### Development Setup

1. Clone the repository
2. Install from source:
   ```bash
   ./install.sh --pip
   ```
### Testing

CLI tests use a temporary `HOME` and require `refract` on PATH (install the wheel or run `./install.sh --pip` first):

```bash
python -m unittest discover -s tests -v -p 'test_cli.py'
```

`./install.sh` methods are tested in CI with `REFRACT_TEST_INSTALL_SH=1`.

Regenerate the README GIF with [VHS](https://github.com/charmbracelet/vhs):

```bash
./demo/record.sh
```

### Code Style

- Follow PEP 8 guidelines
- Use descriptive variable names
- Add docstrings to functions
- Include error handling

##  License

This project is licensed under the MIT License - see the LICENSE file for details.

##  Acknowledgments

- Built with 1 dependency: Python's standard library
- Inspired by the need for simpler, cli-native management of virtual environments; perfect for deploying to lightweight servers when needed
- Thanks to the Python community for the excellent `venv` module; this isn't a diss, just a specific use-case ;)

---

**Happy coding with refract! **
