dmenv: the stupid virtualenv manager
Installation
Download the dmenv installer, then run
python installer.py, or python3 installer.py, depending on how your Python interpreter is called. Just make
sure it's Python3, not 2.
The script will fetch pre-compiled binaries from GitHub. If you prefer, you can also install rust and install dmenv with cargo install dmenv.
Setup
First, dmenv needs a Python3 interpreter in PATH, which should be called python or python3. This should already be the case if you've just installed Python3, regardless of your operating system.
Second, dmenv needs a setup.py file to work.
-
If you don't have a
setup.pyyet, you can rundmenv init --name <project name>to generate one. In this case, make sure to read the comments inside and edit it to fit your needs. -
If you already have one, please note that
dmenvuses theextras_requirekeyword with adevkey to specify development dependencies, which you can use to replace yourdev-requirements.txtfile for instance.
And that's it. Now you are ready to use dmenv!
Here's a description of the main commands:
dmenv lock
Here's what dmenv lock does:
-
First, it creates a virtualenv for you with
python -m venvin.venv/<version>, where<version>is read frompython --version. Make sure to add.venvto your.gitignore! Note that this step is skipped ifdmenvdetects it is run from an existing virtualenv. -
Then it runs
pip intall --editable .[dev]so that your dev deps are installed, and the scripts listed inentry_pointsare created. -
Finally, it runs
pip freezeto generate arequirements.lockfile.
Now you can add the requirements.lock file to your version control system.
This leads us to the next command.
dmenv install
Now that the complete list of dependencies and their versions is written in the
requirements.lock file, anyone can run dmenv install to install all the
dependencies and get exactly the same versions you got when you ran dmenv lock.
Hooray reproducible builds!
dmenv run
As a convenience, you can use:dmenv run to run any binary from the virtualenv. If the program you want to run
needs command-line options, use a -- to separated them from dmenv options, like so:
dmenv run -- pytest --collect-only
dmenv upgrade-pip
Tired of pip telling you to upgrade itself? Run dmenv upgrade-pip :)
It's exactly the same as typing dmenv run -- python -m pip install --upgrade pip, but with less keystrokes :P
Using an other python interpreter
To use an other Python interpreter than the one in PATH, you can either:
- Modify your PATH environment variable so that it appears there. (For instance, with pyenv).
- Prefix all the
dmenvcommands with a--python /path/to/other/pythonflag.
FAQ
Q: How do I upgrade a dependency?
A: Just run dmenv lock again. If something breaks, either fix your code or
use more precise version specifiers in setup.py, like foobar < 2.0.
Q: How do I depend on a git specific repo/branch?
A: Edit the requirements.lock by hand like this:
foo==0.1
https://gitlab.com/foo/bar@my-branch
Q: But that sucks and it will disappear when I re-run dmenv lock!
A: See #7. We are looking for a proper solution. In the mean time, feel free to:
- Open a pull request if you've forked an upstream project
- Use a local pipy mirror and a little bit of CI to publish your sources there
Q: Why Rust? A:
- Because it has excellent support for what we need: manipulate paths and run commands in a cross-platform way
- Because it's my second favorite language
- Because distribution is really easy
- Because by not using Python at all
dmenvis less likely to break if something on your system changes.