quickenv 0.1.0

An unintrusive environment manager
# `quickenv`: An unintrusive environment manager

[`direnv`](https://direnv.net/) is a manager for loading/unloading environment
variables per-project. It achieves this by hooking into your shell and
executing a shellscript called `.envrc` upon `cd`, loading environment
variables generated by that shellscript into your current shell. It is useful
for automatically activating
[virtualenvs](https://docs.python.org/3/tutorial/venv.html), for example.

Unfortunately `direnv` can be a little bit "intrusive" to use. For a start, it
runs its own code in your shell. This alone is not noticeable in terms of
terminal responsiveness, but the various `.envrc`s that people end up writing
sometimes are.  `direnv` does not have a reliable, out-of-the-box way to cache
the execution of `.envrc`s, as it is arbitrary code, and so it runs everytime
you `cd` in and out of a project.

`quickenv` is a replacement for `direnv`. It works with existing `.envrc`s, and
as such is a drop-in replacement, but how you interact with `quickenv` and how
it loads environment variables is fundamentally different.

* `quickenv` does not hook into your shell. It only requires an addition to
  your `PATH`.
* `quickenv` does not load `.envrc` when changing directories. Instead you need
  to initialize `quickenv` per-project using `quickenv reload`, and rerun that
  command everytime the `.envrc` changes.
* `quickenv` does not even load environment variables into your shell. Instead
  you tell `quickenv` which binaries should run with those environment
  variables present (for example `quickenv shim python pytest poetry`), and
  quickenv will wrap those commands in a custom binary, and put that "shim" on
  your `PATH`.

`quickenv` is heavily inspired by [volta](https://volta.sh/) which achieves
version management for nodejs by also providing "shim" binaries for the most
common commands (`yarn`, `npm`, `node`).


## Installation

**quickenv is work in progress and most likely contains bugs. that said, I use it daily at work**

* `quickenv` currently assumes `direnv` is in your path, in order to load
its "standard library".

* `quickenv` also currently does not have pre-built binaries. You need to
[install Rust]https://rustup.rs/, check out this repository, and install it
yourself.

* `quickenv` assumes a POSIX environment.

```bash
# Install quickenv. Quickenv assumes itself to be installed in
# '~/.quickenv/bin/'. You can change that using QUICKENV_HOME.
cargo install quickenv
mkdir -p ~/.quickenv/bin/
mv ~/.cargo/bin/quickenv ~/.quickenv/bin/

# Into your bashrc/zshrc. This should be at the front of your PATH, such that
# quickenv can shim/shadow binaries effectively.
export PATH=$HOME/.quickenv/bin/:$PATH
```

## Usage

We're going to check out [sentry](https://github.com/getsentry/sentry), because
that's one of the `.envrc`s I use. Note that Sentry's `.envrc` only works on
MacOS.

```bash
git clone https://github.com/getsentry/sentry
cd sentry

# Execute the .envrc and cache the resulting environment variables in ~/.quickenv/envs/.
# Sentry will prompt you to create a virtualenv, install dependencies via homebrew, etc.
# Re-run this command manually everytime the .envrc changes.
quickenv reload

# Tell quickenv to place "shim" binaries for those commands in ~/.quickenv/bin/
quickenv shim sentry pytest

# These commands will now run with the virtualenv enabled
sentry devserver --workers
pytest tests/sentry/

# Other commands not explicitly shimmed will end up not running in the
# virtualenv at all. Whoops!
python
pip install ...

# Better shim them!
quickenv shim python pip
```

## Advanced usage

```bash
# Your git hooks don't execute in the virtualenv for some reason? Just replace/shadow
# git with a binary that itself loads the virtualenv.
quickenv shim git

# Actually activate the virtualenv in your current shell. `quickenv vars`
# prints all the extra environment variables with which each shimmed binary runs.
eval "$(quickenv vars)"

# Or shim 'bash', so that when you open a subshell, the virtualenv is activated.
quickenv shim bash

# Or shim 'make', so your Makefile runs in the virtualenv. This can save you from
# explicitly enumerating a bunch of commands, if you only ever run them via 'make'.
quickenv shim make
```

## License

Licensed under `MIT`, see `LICENSE`.