mirror of
https://github.com/kennethreitz/heroku-buildpack-python.git
synced 2026-06-05 23:10:16 +00:00
2097eab028
Before: - if `wheel` was not already installed, then `get-pip.py` would automatically install the latest version on PyPI, which is `0.34.2` (or `0.33.6` for Python 3.4). - if `wheel` was already installed, then it was left unchanged regardless of the version installed. Now: - if `wheel` is not already installed, then the same versions will be installed as before, except these versions are pinned and will now not change unexpectedly after future `wheel` releases. - if `wheel` is already installed, then it's upgraded/downgraded to the target version as needed. Partly addresses #1000, though this change only helps builds where the pip/setuptools/wheel install flow is triggered (currently only new apps or ones where Python was purged or pip was not the correct version). Since the wheel version is now known, it's output to the build log to ease debugging and for parity with pip/setuptools. The rest of #1000 will be fixed in later commits.
179 lines
6.6 KiB
Bash
Executable File
179 lines
6.6 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"
|
|
|
|
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" != "$PYPY_27" ]; then
|
|
puts-warn "Could not find that Pypy version. Did you mean" "${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" != "$PYPY_36" ]; then
|
|
puts-warn "Could not find that Pypy version. Did you mean" "${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
|
|
FRESH_PYTHON=true
|
|
|
|
hash -r
|
|
fi
|
|
|
|
PIP_VERSION='20.0.2'
|
|
SETUPTOOLS_VERSION='39.0.1'
|
|
WHEEL_VERSION='0.34.2'
|
|
|
|
if [[ "${PYTHON_VERSION}" == ${PY34}* ]]; then
|
|
# Python 3.4 support was dropped in pip 19.2+ and wheel 0.34.0+.
|
|
PIP_VERSION='19.1.1'
|
|
WHEEL_VERSION='0.33.6'
|
|
fi
|
|
|
|
if [[ -f "$BUILD_DIR/Pipfile" ]]; then
|
|
# The buildpack is pinned to old pipenv, which requires older pip.
|
|
PIP_VERSION='9.0.2'
|
|
fi
|
|
|
|
# Heroku uses the get-pip utility maintained by the Python community to vendor Pip.
|
|
# https://github.com/pypa/get-pip
|
|
GETPIP_URL="https://lang-python.s3.amazonaws.com/etc/get-pip.py"
|
|
GETPIP_PY="${TMPDIR:-/tmp}/get-pip.py"
|
|
|
|
if ! curl -s "${GETPIP_URL}" -o "$GETPIP_PY" &> /dev/null; then
|
|
mcount "failure.python.get-pip"
|
|
echo "Failed to pull down get-pip"
|
|
exit 1
|
|
fi
|
|
|
|
# If a new Python has been installed or Pip isn't up to date:
|
|
if [ "$FRESH_PYTHON" ] || [[ ! $(pip --version) == *${PIP_VERSION}* ]]; then
|
|
|
|
puts-step "Installing pip ${PIP_VERSION}, setuptools ${SETUPTOOLS_VERSION} and wheel ${WHEEL_VERSION}"
|
|
|
|
# Remove old installations.
|
|
rm -fr /app/.heroku/python/lib/python*/site-packages/pip-*
|
|
rm -fr /app/.heroku/python/lib/python*/site-packages/setuptools-*
|
|
|
|
/app/.heroku/python/bin/python "$GETPIP_PY" pip=="${PIP_VERSION}" "setuptools==${SETUPTOOLS_VERSION}" "wheel==${WHEEL_VERSION}" &> /dev/null
|
|
fi
|
|
|
|
set -e
|
|
hash -r
|