Set up Python develop environments
- use `pyenv` to manage the various develop environments
+ install several Python binaries
+ each environment receives its own `poetry` install
- add two virtual environments:
+ "interactive" => default environment with no library,
which receives accidental `pip install`s
+ "utils" => hosts various globally available tools/apps
(e.g., `mackup`)
- add installation and update scripts
This commit is contained in:
parent
5c3a914658
commit
dcdb32585a
8 changed files with 240 additions and 2 deletions
|
|
@ -80,6 +80,23 @@ alias more='less'
|
|||
alias tree='tree -C --dirsfirst'
|
||||
|
||||
|
||||
# Make working with Python more convenient
|
||||
|
||||
alias py='python'
|
||||
alias ipy='ipython'
|
||||
|
||||
if command_exists poetry; then
|
||||
alias pr='poetry run'
|
||||
fi
|
||||
|
||||
if command_exists pyenv; then
|
||||
alias pyvenvs='pyenv virtualenvs --bare --skip-aliases'
|
||||
alias pyver='pyenv version'
|
||||
alias pyvers='pyenv versions --skip-aliases'
|
||||
alias pywhich='pyenv which'
|
||||
fi
|
||||
|
||||
|
||||
# Aliases for various utilities
|
||||
alias datetime='date +"%Y-%m-%d %H:%M:%S %z (%Z)"'
|
||||
alias datetime-iso='date --iso-8601=seconds'
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ git clone --bare git@git.webartifex.biz:alexander/dotfiles.git "$HOME/.dotfiles"
|
|||
|
||||
# Backup old dotfiles
|
||||
rm -rf "$HOME/.dotfiles.bak" >/dev/null
|
||||
mkdir -p $HOME/.dotfiles.bak/.config/{bat,flameshot,git,Nextcloud,pop-system-updater,psql,shell} && \
|
||||
mkdir -p $HOME/.dotfiles.bak/.config/{bat,flameshot,git,Nextcloud,pop-system-updater,psql,pypoetry,shell} && \
|
||||
mkdir -p $HOME/.dotfiles.bak/.vim/{after/ftplugin,backup,swap,undo} && \
|
||||
/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | \
|
||||
xargs -I{} mv {} "$HOME/.dotfiles.bak"/{}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,16 @@ in_zsh() {
|
|||
[ -n "$ZSH_VERSION" ]
|
||||
}
|
||||
|
||||
# Prepend a folder to $PATH if it is not already there
|
||||
_prepend_to_path () {
|
||||
if [ -d "$1" ] ; then
|
||||
case :$PATH: in
|
||||
*:$1:*) ;;
|
||||
*) PATH=$1:$PATH ;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
# =========================
|
||||
|
|
@ -30,6 +40,13 @@ fi
|
|||
command_exists lesspipe && eval "$(SHELL=/bin/sh lesspipe)"
|
||||
|
||||
|
||||
# Initialize pyenv if it is installed
|
||||
if command_exists pyenv; then
|
||||
eval "$(pyenv init -)"
|
||||
eval "$(pyenv virtualenv-init -)"
|
||||
fi
|
||||
|
||||
|
||||
# Configure the keyboard:
|
||||
# - make right alt and menu keys the compose key, e.g., for umlauts
|
||||
# - make caps lock a ctrl modifier and Esc key
|
||||
|
|
@ -38,6 +55,32 @@ command_exists xcape && xcape -e "Caps_Lock=Escape"
|
|||
|
||||
|
||||
|
||||
# ==========================
|
||||
# Command not found handlers
|
||||
# ==========================
|
||||
|
||||
|
||||
# Check if an unknown command is in a local Python venv
|
||||
command_not_found_handle() {
|
||||
if [ -x ".venv/bin/$1" ]; then
|
||||
echo 'You forgot to activate the virtualenv' 1>&2
|
||||
exe=".venv/bin/$1"
|
||||
shift
|
||||
"$exe" "$@"
|
||||
return $?
|
||||
else
|
||||
echo "$1: command not found" 1>&2
|
||||
return 127
|
||||
fi
|
||||
}
|
||||
|
||||
# zsh uses another name for the handler
|
||||
command_not_found_handler() {
|
||||
command_not_found_handle "$@"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# ==============================
|
||||
# Working with files and folders
|
||||
# ==============================
|
||||
|
|
@ -194,6 +237,89 @@ genemail() {
|
|||
|
||||
|
||||
|
||||
# ===================================================
|
||||
# Set up & maintain the Python (develop) environments
|
||||
# ===================================================
|
||||
|
||||
|
||||
# TODO: This needs to be updated regularly (or find an automated solution)
|
||||
# The Python versions `pyenv` creates (in descending order)
|
||||
_py3_versions=('3.10.5' '3.9.13' '3.8.13' '3.7.13')
|
||||
_py2_version='2.7.18'
|
||||
|
||||
# Each Python environment uses its own `poetry` installation to avoid
|
||||
# integration problems between `pyenv` and `poetry`
|
||||
# Source: https://github.com/python-poetry/poetry/issues/5252#issuecomment-1055697424
|
||||
_py3_site_packages=('poetry')
|
||||
|
||||
# The pyenv virtualenv "utils" contains some globally available tools (e.g., `mackup`)
|
||||
_py3_utils=('mackup')
|
||||
|
||||
install-pyenv() {
|
||||
echo -e "\nInstalling pyenv\n"
|
||||
|
||||
# The official installer does a bit more than the `git clone`s below
|
||||
# `curl https://pyenv.run | bash`
|
||||
git clone https://github.com/pyenv/pyenv.git "$HOME/.pyenv"
|
||||
git clone https://github.com/pyenv/pyenv-doctor.git "$HOME/.pyenv/plugins/pyenv-doctor"
|
||||
git clone https://github.com/pyenv/pyenv-update.git "$HOME/.pyenv/plugins/pyenv-update"
|
||||
git clone https://github.com/pyenv/pyenv-virtualenv.git "$HOME/.pyenv/plugins/pyenv-virtualenv"
|
||||
git clone https://github.com/pyenv/pyenv-which-ext.git "$HOME/.pyenv/plugins/pyenv-which-ext"
|
||||
|
||||
# On a first install, "$PYENV_ROOT/bin" is NOT on the $PATH
|
||||
_prepend_to_path "$PYENV_ROOT/bin"
|
||||
}
|
||||
|
||||
re-install-pyenv() {
|
||||
echo -e "\nRemoving pyenv\n"
|
||||
rm -rf "$HOME/.pyenv" >/dev/null
|
||||
install-pyenv
|
||||
}
|
||||
|
||||
create-or-update-python-envs() {
|
||||
command_exists pyenv || install-pyenv
|
||||
|
||||
eval "$(pyenv init --path)"
|
||||
|
||||
# Keep a legacy Python 2.7, just in case
|
||||
echo -e "\nInstalling/updating Python $_py2_version\n"
|
||||
pyenv install --skip-existing $_py2_version
|
||||
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 -e "\nInstalling/updating Python $version\n"
|
||||
pyenv install --skip-existing $version
|
||||
|
||||
# Start the new environment with the latest `pip` and `setuptools` versions
|
||||
PYENV_VERSION=$version pip install --upgrade pip setuptools
|
||||
|
||||
# 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 -e "\nInstalling/updating global Python utilities\n"
|
||||
pyenv virtualenv $_py3_versions[1] 'utils'
|
||||
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
|
||||
# (This virtualenv is empty and is the target of accidental `pip install`s)
|
||||
echo -e "\nInstalling/updating the default/interactive Python environment\n"
|
||||
pyenv virtualenv $_py3_versions[1] 'interactive'
|
||||
PYENV_VERSION='interactive' pip install --upgrade pip setuptools
|
||||
|
||||
# Put all Python binaries and the utilities on the $PATH
|
||||
pyenv global 'interactive' $_py3_versions 'utils' $_py2_version
|
||||
}
|
||||
|
||||
|
||||
|
||||
# =============================
|
||||
# Automate the update machinery
|
||||
# =============================
|
||||
|
|
@ -278,6 +404,28 @@ update-zsh() {
|
|||
}
|
||||
|
||||
|
||||
# Update the entire Python tool chain
|
||||
update-python() {
|
||||
echo -e '\nUpdating the Python tool chain\n'
|
||||
|
||||
if command_exists pyenv; then
|
||||
echo -e '\nUpdating pyenv\n'
|
||||
pyenv update
|
||||
echo
|
||||
|
||||
echo -e '\nUpdating Python environments\n'
|
||||
create-or-update-python-envs
|
||||
echo
|
||||
fi
|
||||
|
||||
if command_exists zsh-pip-cache-packages; then
|
||||
echo -e '\nUpdating pip packages cache\n'
|
||||
zsh-pip-clear-cache
|
||||
zsh-pip-cache-packages
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Wrapper to run several update functions at once
|
||||
update-machine() {
|
||||
sudo --validate || return
|
||||
|
|
@ -295,9 +443,14 @@ update-machine() {
|
|||
remove-old-snaps
|
||||
fi
|
||||
|
||||
update-python
|
||||
|
||||
update-dotfiles
|
||||
update-zsh
|
||||
|
||||
echo -e '\nUpdating the configs managed by mackup'
|
||||
mackup restore --force
|
||||
|
||||
echo -e '\nUpdating password store\n'
|
||||
pass git pull
|
||||
echo
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue