Created
May 13, 2017 21:30
-
-
Save jagmoreira/b922d0524a5b7bc9500ea4b8c372e66b to your computer and use it in GitHub Desktop.
Updates all pyenv virtual environments to the latest micro version of Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks!