Skip to content

Instantly share code, notes, and snippets.

@teticio
Last active August 16, 2022 19:36
Show Gist options
  • Save teticio/cc5d2b7676a0fba0aa4b0d3ff139704a to your computer and use it in GitHub Desktop.
Save teticio/cc5d2b7676a0fba0aa4b0d3ff139704a to your computer and use it in GitHub Desktop.
Pipenv automatically assigns names to the virtual environments based on a hash of the directory where the Pipfile resides. If this directory is moved, then pipenv will no longer find the venv. Not only does the virtual environment (venv) have to be renamed, but all references to it (e.g., in shebangs) must also be updated.
#/usr/bin/env bash
######################################################################
# Pipenv automatically assigns names to the virtual environments #
# based on a hash of the directory where the Pipfile resides. If #
# this directory is moved, then pipenv will no longer find the venv. #
# Not only does the virtual environment (venv) have to be renamed, #
# but all references to it (e.g., in shebangs) must also be updated. #
######################################################################
# get hashed environment name
function get_venv_name() {
python3 -c "import sys; \
from pipenv.project import Project; \
project = Project(); \
project.s.PIPENV_PIPFILE = '$1/Pipfile'; \
sys.exit(project.virtualenv_name) \
" 2>&1 >/dev/null
}
# get base directory for venv (e.g. $HOME/.local/share/virtualenvs)
function get_base() {
python3 -c "import sys; \
from pipenv.project import get_workon_home; \
sys.exit(get_workon_home()) \
" 2>&1 >/dev/null
}
venv1=$(get_venv_name $1)
venv2=$(get_venv_name $2)
base=$(get_base)
echo Migrating $base/$venv1 to $base/$venv2
# rename venv directory so that pipenv finds it
mv $base/$venv1 $base/$venv2
# update references to new directory
grep -rl $base/$venv2 --exclude-dir site-packages -e $venv1 \
| xargs sed -i "s/$venv1/$venv2/g"
# update kernelspecs
grep -rl $HOME/.local/share/jupyter/kernels --include *.json -e $venv1 \
| xargs sed -i "s/$venv1/$venv2/g"
@teticio
Copy link
Author

teticio commented Aug 15, 2022

Note that pipenv uses the physical directory (i.e., it does not do any symbolic link tracking). To determine the physical directory with pwd, use the -P option.

@teticio
Copy link
Author

teticio commented Aug 15, 2022

For the script to work on MacOS, change sed -i "s/$venv1/$venv2/g" to sed -i "" "s/$venv1/$venv2/g".

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