# This file creates a function to install and update the Python develop environments _command_exists() { command -v "$1" 1>/dev/null 2>&1 } prepend-to-path () { # if not already there if [ -d "$1" ] ; then case :$PATH: in *:$1:*) ;; *) PATH=$1:$PATH ;; esac fi } # The Python versions pyenv creates (in descending order) # Important: The first version also holds the "interactive" and "utils" environments _py3_versions=('3.10.6' '3.9.13' '3.8.13' '3.7.13') _py2_version='2.7.18' # Each Python version receives its own copy of black, pipenv, and poetry # (e.g., to avoid possible integration problems between pyenv and poetry # Source: https://github.com/python-poetry/poetry/issues/5252#issuecomment-1055697424) _py3_site_packages=('black' 'pipenv' 'poetry') # The pyenv virtualenv "utils" contains some globally available tools (e.g., mackup) _py3_utils=('leglight' 'mackup' 'youtube-dl') # Important: this REMOVES the old ~/.pyenv installation _install_pyenv() { echo "(Re-)Installing pyenv" # Ensure that pyenv is on the $PATH # (otherwise, the pyenv installer emits warnings) mkdir -p "$PYENV_ROOT/bin" prepend-to-path "$PYENV_ROOT/bin" # Remove old pyenv for clean install rm -rf "$PYENV_ROOT" >/dev/null # Run the official pyenv installer curl https://pyenv.run | bash # Make pyenv usable after this installation in the same shell session _init_pyenv # defined in ~/.config/shell/utils.sh } create-or-update-python-envs() { _command_exists pyenv || _install_pyenv eval "$(pyenv init --path)" # Keep a legacy Python 2.7, just in case echo "Installing/updating Python $_py2_version" pyenv install --skip-existing $_py2_version pyenv rehash # needed on a first install PYENV_VERSION=$_py2_version pip install --upgrade pip setuptools PYENV_VERSION=$_py2_version python -c "import sys; print sys.version" for version in ${_py3_versions[@]}; do echo "Installing/updating Python $version" pyenv install --skip-existing $version pyenv rehash # needed on a first install # Start the new environment with the latest pip and setuptools versions PYENV_VERSION=$version pip install --upgrade pip setuptools PYENV_VERSION=$version python -c "import sys; print(sys.version)" # Put the specified utilities in the fresh environments or update them for lib in ${_py3_site_packages[@]}; do PYENV_VERSION=$version pip install --upgrade $lib done done # Create a virtualenv based off the latest Python version to host global utilities echo "Installing/updating the global Python utilities" pyenv virtualenv $_py3_versions[1] 'utils' pyenv rehash # needed on a first install PYENV_VERSION='utils' pip install --upgrade pip setuptools for util in ${_py3_utils[@]}; do PYENV_VERSION='utils' pip install --upgrade $util done # Create a virtualenv based off the latest Python version for interactive usage echo "Installing/updating the default/interactive Python environment" pyenv virtualenv $_py3_versions[1] 'interactive' pyenv rehash # needed on a first install PYENV_VERSION='interactive' pip install --upgrade pip setuptools # Install some tools to make interactive usage nicer PYENV_VERSION='interactive' pip install --upgrade black bpython ipython # Put all Python binaries/virtualenvs and the utilities on the $PATH pyenv global 'interactive' $_py3_versions 'utils' $_py2_version }