How to automatically activate virtualenvs when cd'ing into a directory
Solution 1:
Add following in your .bashrc or .zshrc
function cd() {
builtin cd "$@"
if [[ -z "$VIRTUAL_ENV" ]] ; then
## If env folder is found then activate the vitualenv
if [[ -d ./.env ]] ; then
source ./.env/bin/activate
fi
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate
parentdir="$(dirname "$VIRTUAL_ENV")"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
fi
fi
}
This code will not deactivate the virtualenv even if someone goes into subfolder. Inspired by answers of @agnul and @Gilles.
If the virtualenv is made by pipenv, then please consider this wiki page.
Furthermore, for added security please consider direnv.
Solution 2:
Put something like this in your .zshrc
function cd() {
if [[ -d ./venv ]] ; then
deactivate
fi
builtin cd $1
if [[ -d ./venv ]] ; then
. ./venv/bin/activate
fi
}
Edit: As noted in comments cd
-ing into a subfolder of the current virtual env would deactivate it. One idea could be to deactivate the current env only if cd
-ing into a new one, like
function cd() {
builtin cd $1
if [[ -n "$VIRTUAL_ENV" && -d ./venv ]] ; then
deactivate
. ./venv/bin/activate
fi
}
that could still be improved, maybe turning it into a "prompt command" or attempting some prefix matching on the folder names to check there's a virtual env somewhere up the path, but my shell-fu is not good enough.
Solution 3:
Rather than writing a custom script you could use direnv. It's not a zsh specific solution (for that you could try zsh-autoenv), but is well-maintained and easy to use with zsh. Once you've installed it, you'd want to put eval "$(direnv hook zsh)"
at the end of your .zshrc
. At that point you can do:
$ source ~/.zshrc
$ cd foo
$ echo "layout python" > .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
$ direnv allow
direnv: loading .envrc
direnv: export +VIRTUAL_ENV ~PATH
Now you should be in your virtualenv. You can test by running pip freeze
to see that your virtualenv specific packages are installed. To deactivate
$ cd ..
direnv: unloading
Solution 4:
By far the easiest option (in 2019+) is to add virtualenvwrapper
into your ~/.zshrc
plugins
For example:
plugins=(
git pip python brew virtualenvwrapper
)
Solution 5:
You should try something like autoenv if not direnv.
The first one is considered to be "lightweight", while the second one "simply, higher quality software", listening respectively to each one's author, talking about the other one's project. Thus, they seem to me fairly good options, to try both!
Anyway, both have been tested on zsh
shells.
In particular, autoenv
is really simple to use, after installing it:
$ git clone git://github.com/inishchith/autoenv.git ~/.autoenv
$ echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc
just "follow the white rabbit " and try for example
$ mkdir project
$ echo "echo 'whoa'" > project/.env
$ cd project
whoa
"If a directory contains a .env
file, it will automatically be executed when you cd
into it. When enabled (set AUTOENV_ENABLE_LEAVE
to a non-null string), if a directory contains a .env.leave
file, it will automatically be executed when you leave it."
Have a look at https://github.com/inishchith/autoenv for more detailed instructions!...