mirror of
https://github.com/kennethreitz/heroku-buildpack-python.git
synced 2026-06-05 23:10:16 +00:00
c550143a59
Not super urgent, but seeing as it closes #927, might as well do now. [skip changelog]
188 lines
7.4 KiB
Bash
Executable File
188 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
|
|
puts-warn "$PYTHON_2_EOL_UPDATE"
|
|
echo " Learn More: https://devcenter.heroku.com/articles/python-2-7-eol-faq"
|
|
# security update note
|
|
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
|
|
|
|
mcount "version.python.${PYTHON_VERSION}"
|
|
|
|
if [[ "$STACK" != "$CACHED_PYTHON_STACK" ]]; then
|
|
puts-step "Stack has changed from $CACHED_PYTHON_STACK to $STACK, clearing cache"
|
|
rm -rf .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 -rf .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
|
|
|
|
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
|