Skip to content

Instantly share code, notes, and snippets.

@bmmalone
Last active September 11, 2018 08:05
Show Gist options
  • Save bmmalone/d1532e5dee162328f93577648c103346 to your computer and use it in GitHub Desktop.
Save bmmalone/d1532e5dee162328f93577648c103346 to your computer and use it in GitHub Desktop.
A wrapper for creating virtual environments with venv
#! /usr/bin/env bash
# check that WORKON_HOME has been set
function _venv_verifty_workon_home {
if [ ! -v WORKON_HOME ]; then
printf "$1: please set WORKON_HOME, "
printf ".bashrc example: \"export WORKON_HOME=<path>\"\n"
printf "quitting.\n"
return 1
fi
return 0
}
# check that the given folder is the home of a venv
function _venv_verify_venv_home {
if [ ! -d "$1" ]; then
printf "$2: the venv does not exist: $1\n"
printf "quitting.\n"
return 1
fi
if [ ! -f "$1"/bin/activate ]; then
printf "$2: the venv folder exists, "
printf "but it does not contain an activate script: $1\n"
printf "quitting.\n"
return 1
fi
return 0
}
function mkvenv {
if [ "$#" -ne 1 ]; then
echo "usage: mkvenv <venv_name>"
return 1
fi
_venv_verifty_workon_home "mkvenv" || return 1
local VENV_HOME="$WORKON_HOME/$1"
if [ -d "$VENV_HOME" ]; then
echo "mkvenv: the venv already exists: $VENV_HOME"
return 1
fi
echo "creating virtual environment: $VENV_HOME"
python3 -m venv "$VENV_HOME"
workon "$1"
}
function mkipyvenv {
if [ "$#" -ne 1 ]; then
echo "usage: mkipyvenv <venv_name>"
return 1
fi
mkvenv "$1"
pip3 install --upgrade pip wheel
pip3 install jupyter
pip3 install ipykernel
python3 -m ipykernel install --user --name "$1" --display-name "$1"
}
function rmvenv {
if [ "$#" -ne 1 ]; then
echo "usage: rmvenv <venv_name>"
return 1
fi
_venv_verifty_workon_home "rmvenv" || return 1
local VENV_HOME="$WORKON_HOME/$1"
_venv_verify_venv_home "$VENV_HOME" "rmvenv" || return 1
echo "removing virtual environment: $VENV_HOME"
rm -rf "$WORKON_HOME/$1"
}
function lsvenv {
if [ "$#" -ne 0 ]; then
echo "usage: lsvenv"
return 1
fi
_venv_verifty_workon_home "lsvenv" || return 1
# this is taken to be only the folders in the workon folder
find "$WORKON_HOME" -mindepth 1 -maxdepth 1 -type 'd' -exec basename {} \;
}
function workon {
if [ "$#" -ne 1 ]; then
echo "usage: workon <venv_name>"
return 1
fi
_venv_verifty_workon_home "lsvenv" || return 1
local VENV_HOME="$WORKON_HOME/$1"
_venv_verify_venv_home "$VENV_HOME" "workon" || return 1
source "$VENV_HOME"/bin/activate
}
###
# Tab complete for all directories in the workon home (WO).
#
# This can cause some confusion in case someone puts extra folders in the WO
# directory, but the later functions (workon and rmvenv) catch that problem.
# This approach is much faster for listing the venvs, and we assume the user
# will not intentionally try to confuse themselves... it'll probably never
# cause any problems....
###
_complete_venv_options() {
COMPREPLY=( $(compgen -W "$(lsvenv)" -- ${COMP_WORDS[COMP_CWORD]}))
}
complete -F _complete_venv_options workon
complete -F _complete_venv_options rmvenv
###
# We can use `ipy` to ensure we always use the python instance in the virtual
# environment: https://coderwall.com/p/xdox9a/running-ipython-cleanly-inside-a-virtualenv
###
alias ipy="python -c 'import IPython; IPython.terminal.ipapp.launch_new_instance()'"
@bmmalone
Copy link
Author

This is a simplified version of the virtualenvwrapper package; however, this version specifically works with venv (only). It also only exposes four functions to manage virtual environments:

  • mkvenv <name>
  • rmvenv <name>
  • lsvenv
  • workon <name>

Additionally, it exposes one function to ensure you use the version of ipython which is installed in the venv (or an error is printed saying IPython is not installed).

  • ipy

It always uses the python3 executable that is found with which python3 (so no -p <path/to/python> functionality).

It includes some error handling, but you can break it if you want to.

After downloading this file, lines along the following should be added to the .bashrc file.

export WORKON_HOME=$HOME/.virtualenvs
source $HOME/local/bin/venv_wrapper.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment