Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Updates all pyenv virtual environments to the latest micro version of Python
#!/usr/bin/env bash
#
# update_envs_micro_python.sh
#
# Updates all pyenv virtual environments to the latest micro version of Python
#
# Author: Joao Moreira (jagmoreira)
#
# First update pyenv to get any new python versions
if type pyenv >/dev/null 2>&1; then
# Homebrew pyenv
if type brew >/dev/null 2>&1 && [[ -n "$(brew ls | grep pyenv)" ]]; then
brew upgrade pyenv
# Linux pyenv
else
pyenv update
fi
else
echo "Pyenv does not appear to be installed in your system..."
echo
exit 1
fi
# Exit script if any errors occur (commands return non-zero status)
set -e
# If any command in a pipe returns an error, fail the whole pipe
set -o pipefail
# Get currently installed main pythons with derived virtualenvs
MAIN_PYTHONS="$(pyenv versions --skip-aliases --bare | grep / | cut -f 1 -d / | uniq)"
for VERSION in $MAIN_PYTHONS; do
echo
echo "Checking for micro version updates for python $VERSION."
echo
# Get the latest micro version for each A.B python
MAJOR_MINOR="$(echo $VERSION | cut -f 1,2 -d .)"
LATEST_MICRO=$(pyenv install -l | grep -E "(^| )$MAJOR_MINOR" | sort -b -V | tail -n 1 | sed -e 's/^[ \t]*//')
# If there are no new micro versions we move on to the next main Python
if [[ "$VERSION" = "$LATEST_MICRO" ]]; then
echo
echo -n "Version $VERSION is already the latest version in the"
echo " $MAJOR_MINOR.x series."
echo
continue
fi
echo
echo "Found a new micro version for python $VERSION!"
echo "$VERSION -> $LATEST_MICRO"
echo
# Install the latest micro and upgrade pip
pyenv install -s "$LATEST_MICRO"
pyenv rehash
export PYENV_VERSION="$LATEST_MICRO"
pip install --upgrade pip
# Get all virtual environments for this minor version
VENVS="$(pyenv versions --skip-aliases --bare | grep $VERSION/ | cut -f 3 -d /)"
N_VENVS=$(echo $VENVS| wc -w)
echo
echo "Found $N_VENVS virtual environments built with python $VERSION."
echo
for ENV in $VENVS; do
echo
echo "Upgrading micro python version of '$ENV' virtualenv: $VERSION-> $LATEST_MICRO"
echo
ENV_PIP_REQS="__tmp_${ENV}_requirements.pip"
export PYENV_VERSION="$ENV" # "Activate" the virtualenv
pip freeze > $ENV_PIP_REQS
pyenv uninstall -f "$ENV"
pyenv virtualenv "$LATEST_MICRO" "$ENV"
pyenv rehash
echo
echo "Re-installing $ENV with all its packages."
echo
# PYENV_VERSION is still set. No need to update it since it's just a
# string with the virtualenv name, which did not change.
pip install --upgrade pip
# If numpy is present install it manually, otherwise some package
# installations might fail due to mall-formed installation requirements
set +e # Temporarily disabling error checking to catch empty grep result
NUMPY="$(grep numpy= $ENV_PIP_REQS)"
set -e
if [[ -n $NUMPY ]]; then
pip install $NUMPY
fi
# Installation of old versions of statsmodels may fail due to mall-formed
# installation requirements. To prevent this, we install all other
# packages first then try the full requirements file again
if [[ -n "$(grep statsmodels $ENV_PIP_REQS)" ]]; then
sed -e '/statsmodels/d' $ENV_PIP_REQS | pip install -r /dev/stdin
fi
pip install -r $ENV_PIP_REQS
done
# Check for any existing environments for the old minor version
if [[ -z "$(pyenv versions --skip-aliases --bare | grep $VERSION/)" ]]; then
echo
echo -n "No more virtualenvs for python $VERSION."
echo " Deleting this minor version..."
echo
pyenv uninstall -f "$VERSION"
fi
done
# Final cleanup
unset PYENV_VERSION
rm -f __tmp_*_requirements.pip
@karthicraghupathi

This comment has been minimized.

Copy link

karthicraghupathi commented Apr 17, 2020

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.