Installation
To install virtualenv-commands you can use easy_install, pip, download the latest release, or clone the github project.
% easy_install virtualenv-commands
The following commands install the latest release in your home directory.
% wget http://cloud.github.com/downloads/thisismedium/virtualenv-commands/latest.tar.gz
% tar xzf latest.tar.gz
% cd virtualenv-commands-latest
% python setup.py install --user
% rehash; ve --help
Command Framework
Part of the virtualenv-commands package is a simple git-style command framework. A wrapper script called ve is designed to run subcommands found in the current execution path that begin with ve-. This paradigm enforces consistent semantics and allows additional, highly personalized commands to be easily written by anyone.
Initialize
The simplest command in this project is ve-init. It simply passes its arguments through to virtualenv. It can be run from the command line as ve init new-env or as ve-init new-env. By running commands in the subcommand style, the fact that ve-init is a separate script is transparent to the script user.
% ve init --no-site-packages example
% . example/bin/activate
% easy_install django
% deactivate
Clone
We use virtualenv quite a bit here are Medium. Something that we need to do often is derive a new virtual environment from an existing one. Perhaps it's time to roll out an updated version of some framework or we want to test a few new libraries without much hassle. Two commands help with this: clone and extend.
The clone command makes a fully copy of an existing environment. Doing this makes sense if the derived environment needs to snapshot an existing environment that may change later or if packages will be removed from the derived environment.
% ve clone example example-copy
% . example-copy/bin/activate
% easy_install sphinx
% python -c 'import django, sphinx'
% deactivate
Extend
Related to clone is extend. Rather than create a full copy of an existing environment, this command creates an empty environment and links it to a source environment. The environments are "chained" together, but changes to the new environment can override the source environment without modifying it. This approach is more lightweight and very useful when you only want to track a particular environment with a few tweaks.
% ve extend --create example try-dateutil
% . try-dateutil/bin/activate
% easy_install python-dateutil
% deactivate
## Make a change in the source environment
% . example/bin/activate
% easy_install feedparser
% deactivate
It's a simple matter to see how these three environments were affected by trying to import feedparser and dateutil in each. The example environment fails to import dateutil since that package is only in try-dateutil. The example-copy environment fails to import both modules because it is a snapshot of example taken before feedparser was installed. Both modules import successfully in try-dateutil since dateutil is local to it and feedparser is imported from the linked example environment.
% example/bin/python -c 'import feedparser, dateutil'
% example-copy/bin/python -c 'import feedparser, dateutil'
% try-dateutil/bin/python -c 'import feedparser, dateutil'
Conclusion
The virtualenv utility is very useful for managing Python package dependencies across projects in the same development environment. Our virtualenv-commands project enhances virtualenv with a command framework and extended API for inspecting and manipulating virtual environments. The initial release implements commands that initialize, clone, and extend virtual environments.
