mirror of
https://github.com/kennethreitz/heroku-buildpack-python.git
synced 2026-06-05 23:10:16 +00:00
cba3201ac2
Since these variables refer to the latest version of PyPy, compared to the similarly named `PYPY27` and `PYPY36` variables (ie same name except without the underscore) which refer to the major/minor version only. The similar names caused me to use the wrong one locally whilst working on another PR, which was caught by tests but demonstrates why we should rename them. Closes @W-7935256@. [skip changelog]
190 lines
7.4 KiB
Bash
Executable File
190 lines
7.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set +e
|
|
runtime-fixer runtime.txt
|
|
PYTHON_VERSION=$(cat runtime.txt)
|
|
|
|
# The location of the pre-compiled python binary.
|
|
VENDORED_PYTHON="${VENDOR_URL}/runtimes/$PYTHON_VERSION.tar.gz"
|
|
|
|
SECURITY_UPDATE="Python has released a security update! Please consider upgrading to"
|
|
SECURITY_UPDATE_PYPY="The PyPy project has released a security update! Please consider upgrading to"
|
|
|
|
ONLY_SUPPORTED_2_VERSION="Only the latest version of Python 2 is supported on the platform. Please consider upgrading to"
|
|
|
|
PYTHON_2_EOL_UPDATE="Python 2 has reached it's community EOL. Upgrade your Python runtime to maintain a secure application as soon as possible."
|
|
|
|
# check if runtime exists
|
|
if curl --output /dev/null --silent --head --fail "$VENDORED_PYTHON"; then
|
|
if [[ "$PYTHON_VERSION" == $PY38* ]]; then
|
|
# do things to alert the user of security release available
|
|
if [ "$PYTHON_VERSION" != "$LATEST_38" ]; then
|
|
puts-warn "$SECURITY_UPDATE" "$LATEST_38"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
|
fi
|
|
fi
|
|
if [[ "$PYTHON_VERSION" == $PY37* ]]; then
|
|
# do things to alert the user of security release available
|
|
if [ "$PYTHON_VERSION" != "$LATEST_37" ]; then
|
|
puts-warn "$SECURITY_UPDATE" "$LATEST_37"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
|
fi
|
|
fi
|
|
if [[ "$PYTHON_VERSION" == $PY36* ]]; then
|
|
# security update note
|
|
if [ "$PYTHON_VERSION" != "$LATEST_36" ]; then
|
|
puts-warn "$SECURITY_UPDATE" "$LATEST_36"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
|
fi
|
|
fi
|
|
if [[ "$PYTHON_VERSION" == $PY35* ]]; then
|
|
# security update note
|
|
if [ "$PYTHON_VERSION" != "$LATEST_35" ]; then
|
|
puts-warn "$SECURITY_UPDATE" "$LATEST_35"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
|
fi
|
|
fi
|
|
if [[ "$PYTHON_VERSION" == $PY34* ]]; then
|
|
# security update note
|
|
if [ "$PYTHON_VERSION" != "$LATEST_34" ]; then
|
|
puts-warn "$SECURITY_UPDATE" "$LATEST_34"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
|
fi
|
|
fi
|
|
if [[ "$PYTHON_VERSION" == $PY27* ]]; then
|
|
# security update note
|
|
if [[ "$(date "+%Y")" -gt "2019" ]]; then
|
|
puts-warn "$PYTHON_2_EOL_UPDATE"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-2-7-eol-faq"
|
|
fi
|
|
if [ "$PYTHON_VERSION" != "$LATEST_27" ]; then
|
|
puts-warn "$ONLY_SUPPORTED_2_VERSION" "$LATEST_27"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
|
fi
|
|
fi
|
|
if [[ "$PYTHON_VERSION" == $PYPY27* ]]; then
|
|
# security update note
|
|
if [ "$PYTHON_VERSION" != "$LATEST_PYPY_27" ]; then
|
|
puts-warn "$SECURITY_UPDATE_PYPY" "$LATEST_PYPY_27"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
|
fi
|
|
fi
|
|
if [[ "$PYTHON_VERSION" == $PYPY36* ]]; then
|
|
# security update note
|
|
if [ "$PYTHON_VERSION" != "$LATEST_PYPY_36" ]; then
|
|
puts-warn "$SECURITY_UPDATE_PYPY" "$LATEST_PYPY_36"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
|
fi
|
|
fi
|
|
else
|
|
puts-warn "Requested runtime ($PYTHON_VERSION) is not available for this stack ($STACK)."
|
|
puts-warn "Aborting. More info: https://devcenter.heroku.com/articles/python-support"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$STACK" != "$CACHED_PYTHON_STACK" ]]; then
|
|
puts-step "Stack has changed from $CACHED_PYTHON_STACK to $STACK, clearing cache"
|
|
rm -fr .heroku/python-stack .heroku/python-version .heroku/python .heroku/vendor .heroku/python .heroku/python-sqlite3-version
|
|
fi
|
|
|
|
if [ -f .heroku/python-version ]; then
|
|
if [ ! "$(cat .heroku/python-version)" = "$PYTHON_VERSION" ]; then
|
|
puts-step "Found $(cat .heroku/python-version), removing"
|
|
rm -fr .heroku/python
|
|
else
|
|
SKIP_INSTALL=1
|
|
fi
|
|
fi
|
|
|
|
# Check if we should reinstall python dependencies
|
|
if [[ ! -f "$CACHE_DIR/.heroku/requirements.txt" ]]; then
|
|
# IF there's no cached dependencies, update cached version of requirements.txt
|
|
# This should only run for new apps and first deploys after this update
|
|
cp -R "$BUILD_DIR/requirements.txt" "$CACHE_DIR/.heroku/requirements.txt"
|
|
else
|
|
# IF there IS a cached directory, check for differences with the new one
|
|
if ! diff "$BUILD_DIR/requirements.txt" "$CACHE_DIR/.heroku/requirements.txt" &> /dev/null; then
|
|
puts-step "Requirements file has been changed, clearing cached dependencies"
|
|
# if there are any differences, clear the Python cache
|
|
# Installing Python over again does not take noticably more time
|
|
cp -R "$BUILD_DIR/requirements.txt" "$CACHE_DIR/.heroku/requirements.txt"
|
|
rm -rf .heroku/python
|
|
unset SKIP_INSTALL
|
|
else
|
|
puts-step "No change in requirements detected, installing from cache"
|
|
fi
|
|
fi
|
|
|
|
if [ ! "$SKIP_INSTALL" ]; then
|
|
puts-step "Installing $PYTHON_VERSION"
|
|
|
|
# Prepare destination directory.
|
|
mkdir -p .heroku/python
|
|
|
|
mcount "version.python.$PYTHON_VERSION"
|
|
|
|
if ! curl "${VENDORED_PYTHON}" -s | tar zxv -C .heroku/python &> /dev/null; then
|
|
puts-warn "Requested runtime ($PYTHON_VERSION) is not available for this stack ($STACK)."
|
|
puts-warn "Aborting. More info: https://devcenter.heroku.com/articles/python-support"
|
|
exit 1
|
|
fi
|
|
|
|
# Record for future reference.
|
|
echo "$PYTHON_VERSION" > .heroku/python-version
|
|
echo "$STACK" > .heroku/python-stack
|
|
|
|
hash -r
|
|
fi
|
|
|
|
set -e
|
|
|
|
PIP_VERSION='20.1.1'
|
|
# Must use setuptools <47.2.0 until we fix:
|
|
# https://github.com/heroku/heroku-buildpack-python/issues/1006
|
|
SETUPTOOLS_VERSION='47.1.1'
|
|
WHEEL_VERSION='0.34.2'
|
|
|
|
if [[ "${PYTHON_VERSION}" == ${PY34}* ]]; then
|
|
# Python 3.4 support was dropped in pip 19.2+, setuptools 44+ and wheel 0.34+.
|
|
PIP_VERSION='19.1.1'
|
|
SETUPTOOLS_VERSION='43.0.0'
|
|
WHEEL_VERSION='0.33.6'
|
|
elif [[ "${PYTHON_VERSION}" == ${PY27}* || "${PYTHON_VERSION}" == ${PYPY27}* ]]; then
|
|
# Python 2.7 support was dropped in setuptools 45+.
|
|
SETUPTOOLS_VERSION='44.1.1'
|
|
fi
|
|
|
|
# We don't use get-pip.py, since:
|
|
# - it uses `--force-reinstall`, which is unnecessary here and slows down repeat builds
|
|
# - it means downloading pip twice (once embedded in get-pip.py, and again during
|
|
# the install, since get-pip.py can't install the embedded version directly)
|
|
# - we would still have to manage several versions of get-pip.py, to support older Pythons.
|
|
# Instead, we use the pip wheel to install itself, using the method described here:
|
|
# https://github.com/pypa/pip/issues/2351#issuecomment-69994524
|
|
PIP_WHEEL_FILENAME="pip-${PIP_VERSION}-py2.py3-none-any.whl"
|
|
PIP_WHEEL_URL="https://lang-python.s3.amazonaws.com/common/${PIP_WHEEL_FILENAME}"
|
|
PIP_WHEEL="${TMPDIR:-/tmp}/${PIP_WHEEL_FILENAME}"
|
|
|
|
if ! curl -sSf "${PIP_WHEEL_URL}" -o "$PIP_WHEEL"; then
|
|
mcount "failure.python.download-pip"
|
|
puts-warn "Failed to download pip"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -f "$BUILD_DIR/Pipfile" ]]; then
|
|
# The buildpack is pinned to old pipenv, which requires older pip.
|
|
# Pip 9.0.2 doesn't support installing itself from a wheel, so we have to use split
|
|
# versions here (ie: installer pip version different from target pip version).
|
|
PIP_VERSION='9.0.2'
|
|
PIP_TO_INSTALL="pip==${PIP_VERSION}"
|
|
else
|
|
PIP_TO_INSTALL="${PIP_WHEEL}"
|
|
fi
|
|
|
|
puts-step "Installing pip ${PIP_VERSION}, setuptools ${SETUPTOOLS_VERSION} and wheel ${WHEEL_VERSION}"
|
|
|
|
/app/.heroku/python/bin/python "${PIP_WHEEL}/pip" install --quiet --disable-pip-version-check --no-cache \
|
|
"${PIP_TO_INSTALL}" "setuptools==${SETUPTOOLS_VERSION}" "wheel==${WHEEL_VERSION}"
|
|
|
|
hash -r
|