Skip to content

Instantly share code, notes, and snippets.

@dahlia
Last active February 15, 2021 16:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dahlia/0c422a1f06db6c7e204143754842e26a to your computer and use it in GitHub Desktop.
Save dahlia/0c422a1f06db6c7e204143754842e26a to your computer and use it in GitHub Desktop.
My Python installer using pyenv
#!/usr/bin/env bash
set -e
versions=(
2.7.18
3.7.9
3.8.7
3.9.1
pypy3.6-7.3.1
)
version() {
# shellcheck disable=SC2046,SC2183
printf "%03d%03d%03d" $(echo "$1" | tr '.' ' ')
}
hline() {
printf -- "-%.0s" $(seq "$(tput cols)")
}
if ! command -v pyenv > /dev/null; then
echo "pyenv seems uninstall" > /dev/stderr
exit 1
fi
if command -v xcrun > /dev/null; then
CFLAGS="-I$(xcrun --show-sdk-path)/usr/include $CFLAGS"
export CFLAGS
fi
if command -v brew > /dev/null; then
# Older Python versions cannot be built with OpenSSL 1.1
brew install rbenv/tap/openssl@1.0
brew unlink openssl@1.0
CFLAGS="-I$(brew --prefix readline)/include $CFLAGS"
OPENSSL10_CFLAGS="-I$(brew --prefix openssl@1.0)/include $CFLAGS"
CFLAGS="-I$(brew --prefix openssl@1.1)/include $CFLAGS"
LDFLAGS="-L$(brew --prefix readline)/lib $LDFLAGS"
OPENSSL10_LDFLAGS="-L$(brew --prefix openssl@1.0)/lib $LDFLAGS"
LDFLAGS="-L$(brew --prefix openssl@1.1)/lib $LDFLAGS"
OPENSSL10_CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl@1.0)"
CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl@1.1)"
export CFLAGS
export LDFLAGS
export CONFIGURE_OPTS
fi
# Sort versions in ascending order
readarray -t versions < <(printf '%s\n' "${versions[@]}" | sort -rV)
for ver in "${versions[@]}"; do
if [[ "$ver" = 3.* ]]; then
py3_latest="${py3_latest:-$ver}"
elif [[ "$ver" = 2.* ]]; then
py2_latest="${py2_latest:-$ver}"
fi
if [[ "$py2_latest" != "" && "$py3_latest" != "" ]]; then
break
fi
done
# Each latest version in major versions (2 and 3) go first
i=$((2))
for ver in "${versions[@]}"; do
if [[ "$ver" = "$py3_latest" || "$ver" = "$py2_latest" ]]; then
continue
fi
versions[$i]="$ver"
((i++))
done
versions[0]="$py2_latest"
versions[1]="$py3_latest"
for (( i=${#versions[@]}-1; i>=0; i-- )); do
{
hline
echo "${versions[i]}"
hline
} > /dev/stderr
if ! [[ "${versions[i]}" = pypy* ]] && { \
[ "$(version "${versions[i]}")" -lt "$(version 2.7.0)" ] || \
[ "$(version "${versions[i]}")" -ge "$(version 3.0.0)" ] && \
[ "$(version "${versions[i]}")" -lt "$(version 3.6.0)" ]
}; then
# Older Python versions that should be built with OpenSSL 1.0 (not 1.1)
brew unlink openssl@1.1
CFLAGS="${OPENSSL10_CFLAGS:-$CFLAGS}" \
LDFLAGS="${OPENSSL10_LDFLAGS:-$LDFLAGS}" \
CONFIGURE_OPTS="${OPENSSL10_CONFIGURE_OPTS:-$CONFIGURE_OPTS}" \
PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA=openssl@1.0 \
pyenv install -f "${versions[i]}"
brew unlink openssl@1.0
brew link openssl@1.1
else
pyenv install -f "${versions[i]}"
fi
done
pyenv global "${versions[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment