compile 15.2 KB
Newer Older
Kenneth Reitz's avatar
v14  
Kenneth Reitz committed
1
#!/usr/bin/env bash
Noah Zoschke's avatar
Noah Zoschke committed
2

3
# The Heroku Python Buildpack. This script accepts parameters for a build
Kenneth Reitz's avatar
Kenneth Reitz committed
4 5
# directory, a cache directory, and a directory for app environment variables.

6 7
# Warning: there are a few hacks in this script to accommodate excellent builds
# on Heroku. No guarantee for external compatibility is made. However,
Kenneth Reitz's avatar
Kenneth Reitz committed
8 9 10
# everything should work fine outside of the Heroku environment, if the
# environment is setup correctly.

11
# Usage:
Kenneth Reitz's avatar
Kenneth Reitz committed
12
#
13
#     $ bin/compile <build-dir> <cache-dir> <env-path>
Kenneth Reitz's avatar
Kenneth Reitz committed
14 15

# Fail fast and fail hard.
Noah Zoschke's avatar
Noah Zoschke committed
16
set -eo pipefail
Noah Zoschke's avatar
Noah Zoschke committed
17

Kenneth Reitz's avatar
Kenneth Reitz committed
18
# Boostrap the Buildpack Standard Library.
Kenneth Reitz's avatar
Kenneth Reitz committed
19 20 21
export BPLOG_PREFIX="buildpack.python"
export BUILDPACK_LOG_FILE=${BUILDPACK_LOG_FILE:-/dev/null}

22 23
[ "$BUILDPACK_XTRACE" ] && set -o xtrace

Kenneth Reitz's avatar
Kenneth Reitz committed
24 25
# Prepend proper path for old-school virtualenv hackery.
# This may not be neccessary.
Kenneth Reitz's avatar
test  
Kenneth Reitz committed
26
export PATH=:/usr/local/bin:$PATH
Kenneth Reitz's avatar
Kenneth Reitz committed
27

Kenneth Reitz's avatar
Kenneth Reitz committed
28
# Setup Path variables, for later use in the Buildpack.
Kenneth Reitz's avatar
Kenneth Reitz committed
29 30
BIN_DIR=$(cd "$(dirname "$0")"; pwd) # absolute path
ROOT_DIR=$(dirname "$BIN_DIR")
Noah Zoschke's avatar
Noah Zoschke committed
31 32
BUILD_DIR=$1
CACHE_DIR=$2
Kenneth Reitz's avatar
Kenneth Reitz committed
33
ENV_DIR=$3
34

Kenneth Reitz's avatar
Kenneth Reitz committed
35
# Export Path variables, for use in sub-scripts.
Kenneth Reitz's avatar
Kenneth Reitz committed
36 37
export BUILD_DIR CACHE_DIR ENV_DIR

Kenneth Reitz's avatar
Kenneth Reitz committed
38 39 40 41
# Set the Buildpack's internet target for downloading Python distributions.
# The user can provide BUILDPACK_VENDOR_URL to specify a custom target.
# Note: this is designed for non-Heroku use, as it does not use the user-provided
# environment variable mechanism (the ENV_DIR).
42 43 44
VENDOR_URL="https://lang-python.s3.amazonaws.com/$STACK"
if [[ -n ${BUILDPACK_VENDOR_URL:-} ]]; then
    VENDOR_URL="$BUILDPACK_VENDOR_URL"
45 46
elif [[ -n ${USE_STAGING_BINARIES} ]]; then
    VENDOR_URL="$USE_STAGING_BINARIES/$STACK"
47 48 49
fi
export VENDOR_URL

Casey's avatar
Casey committed
50 51 52
# Default Python Versions
# shellcheck source=bin/default_pythons
source "$BIN_DIR/default_pythons"
Kenneth Reitz's avatar
Kenneth Reitz committed
53

Casey Faist's avatar
Casey Faist committed
54
# Supported Python Branches
Casey Faist's avatar
Casey Faist committed
55
PY38="python-3.8"
Casey Faist's avatar
Casey Faist committed
56 57 58
PY37="python-3.7"
PY36="python-3.6"
PY35="python-3.5"
Casey Faist's avatar
Casey Faist committed
59
PY34="python-3.4"
Casey Faist's avatar
Casey Faist committed
60 61
PY27="python-2.7"

Kenneth Reitz's avatar
Kenneth Reitz committed
62
# Which stack is used (for binary downloading), if none is provided (e.g. outside of Heroku)?
63
DEFAULT_PYTHON_STACK="cedar-14"
Kenneth Reitz's avatar
Kenneth Reitz committed
64
# If pip doesn't match this version (the version we install), run the installer.
Kenneth Reitz's avatar
9.0.2  
Kenneth Reitz committed
65
PIP_UPDATE="9.0.2"
Kenneth Reitz's avatar
Kenneth Reitz committed
66

Casey's avatar
Casey committed
67
export DEFAULT_PYTHON_STACK PIP_UPDATE
Casey Faist's avatar
Casey Faist committed
68
export PY37 PY36 PY35 PY27 PY34
Noah Zoschke's avatar
Noah Zoschke committed
69

Kenneth Reitz's avatar
Kenneth Reitz committed
70 71 72 73
# Common Problem Warnings:
# This section creates a temporary file in which to stick the output of `pip install`.
# The `warnings` subscript then greps through this for common problems and guides
# the user towards resolution of known issues.
Kenneth Reitz's avatar
Kenneth Reitz committed
74 75
WARNINGS_LOG=$(mktemp)
export WARNINGS_LOG
76
export RECOMMENDED_PYTHON_VERSION=$DEFAULT_PYTHON_VERSION
Kenneth Reitz's avatar
Kenneth Reitz committed
77

Kenneth Reitz's avatar
Kenneth Reitz committed
78 79
# The buildpack ships with a few executable tools (e.g. pip-grep, etc).
# This installs them into the path, so we can execute them directly.
Kenneth Reitz's avatar
Kenneth Reitz committed
80
export PATH=$PATH:$ROOT_DIR/vendor/:$ROOT_DIR/vendor/pip-pop
81

Kenneth Reitz's avatar
Kenneth Reitz committed
82 83 84
# Set environment variables if they weren't set by the platform.
# Note: this is legacy, for a deprecated build system known as Anvil.
# This can likely be removed, with caution.
Pierre Dulac's avatar
Pierre Dulac committed
85
[ ! "$SLUG_ID" ] && SLUG_ID="defaultslug"
Kenneth Reitz's avatar
Kenneth Reitz committed
86
[ ! "$REQUEST_ID" ] && REQUEST_ID=$SLUG_ID
87
[ ! "$STACK" ] && STACK=$DEFAULT_PYTHON_STACK
Kenneth Reitz's avatar
Kenneth Reitz committed
88

Kenneth Reitz's avatar
Kenneth Reitz committed
89 90 91 92
# Sanitize externally-provided environment variables:
# The following environment variables are either problematic or simply unneccessary
# for the buildpack to have knowledge of, so we unset them, to keep the environment
# as clean and pristine as possible.
Tero Vuotila's avatar
Tero Vuotila committed
93
unset GIT_DIR PYTHONHOME PYTHONPATH
94
unset RECEIVE_DATA RUN_KEY BUILD_INFO DEPLOY LOG_TOKEN
95
unset CYTOKINE_LOG_FILE GEM_PATH
Kenneth Reitz's avatar
Kenneth Reitz committed
96

Kenneth Reitz's avatar
Kenneth Reitz committed
97
# Import the utils script, which contains helper functions used throughout the buildpack.
Kenneth Reitz's avatar
Kenneth Reitz committed
98 99
# shellcheck source=bin/utils
source "$BIN_DIR/utils"
Kenneth Reitz's avatar
Kenneth Reitz committed
100

Kenneth Reitz's avatar
Kenneth Reitz committed
101 102
# Import the warnings script, which contains the `pip install` user warning mechanisms
# (mentioned and explained above)
Kenneth Reitz's avatar
Kenneth Reitz committed
103 104
# shellcheck source=bin/warnings
source "$BIN_DIR/warnings"
Kenneth Reitz's avatar
Kenneth Reitz committed
105

Kenneth Reitz's avatar
Kenneth Reitz committed
106 107 108 109
# Make the directory in which we will create symlinks from the temporary build directory
# to `/app`.
# Symlinks are required, since Python is not a portable installation.
# More on this topic later.
David Zülke's avatar
David Zülke committed
110
mkdir -p /app/.heroku
Kenneth Reitz's avatar
Kenneth Reitz committed
111

Kenneth Reitz's avatar
Kenneth Reitz committed
112 113 114
# This buildpack programatically generates (or simply copies) a number of files for
# buildpack machinery: an export script, and a number of `.profile.d` scripts. This
# section declares the locations of those files and targets.
115
PROFILE_PATH="$BUILD_DIR/.profile.d/python.sh"
Kenneth Reitz's avatar
Kenneth Reitz committed
116
EXPORT_PATH="$BIN_DIR/../export"
117
GUNICORN_PROFILE_PATH="$BUILD_DIR/.profile.d/python.gunicorn.sh"
118
WEB_CONCURRENCY_PROFILE_PATH="$BUILD_DIR/.profile.d/WEB_CONCURRENCY.sh"
119

120
# We'll need to send these statics to other scripts we `source`.
Kenneth Reitz's avatar
Kenneth Reitz committed
121
export BUILD_DIR CACHE_DIR BIN_DIR PROFILE_PATH EXPORT_PATH
122

Kenneth Reitz's avatar
Kenneth Reitz committed
123 124 125 126 127
# Python Environment Variables
# Set Python-specific environment variables, for running Python within the buildpack.
# Notes on each variable included.

# PATH is relatively obvious, we need to be able to execute 'python'.
David Zülke's avatar
David Zülke committed
128
export PATH=/app/.heroku/python/bin:/app/.heroku/vendor/bin:$PATH
Kenneth Reitz's avatar
Kenneth Reitz committed
129
# Tell Python to not buffer it's stdin/stdout.
Kenneth Reitz's avatar
test  
Kenneth Reitz committed
130
export PYTHONUNBUFFERED=1
Kenneth Reitz's avatar
Kenneth Reitz committed
131
# Set the locale to a well-known and expected standard.
132
export LANG=en_US.UTF-8
Kenneth Reitz's avatar
Kenneth Reitz committed
133 134 135
# `~/.heroku/vendor` is an place where the buildpack may stick pre-build binaries for known
# C dependencies (e.g. libmemcached on cedar-14). This section configures Python (GCC, more specifically)
# and pip to automatically include these paths when building binaries.
David Zülke's avatar
David Zülke committed
136 137 138 139 140
export C_INCLUDE_PATH=/app/.heroku/vendor/include:/app/.heroku/python/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=/app/.heroku/vendor/include:/app/.heroku/python/include:$CPLUS_INCLUDE_PATH
export LIBRARY_PATH=/app/.heroku/vendor/lib:/app/.heroku/python/lib:$LIBRARY_PATH
export LD_LIBRARY_PATH=/app/.heroku/vendor/lib:/app/.heroku/python/lib:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH=/app/.heroku/vendor/lib/pkg-config:/app/.heroku/python/lib/pkg-config:$PKG_CONFIG_PATH
Kenneth Reitz's avatar
Kenneth Reitz committed
141

Kenneth Reitz's avatar
Kenneth Reitz committed
142 143 144
# The Application Code
# --------------------

Kenneth Reitz's avatar
Kenneth Reitz committed
145
# Switch to the repo's context.
Kenneth Reitz's avatar
Kenneth Reitz committed
146
cd "$BUILD_DIR"
Noah Zoschke's avatar
Noah Zoschke committed
147

Kenneth Reitz's avatar
Kenneth Reitz committed
148 149 150 151 152 153 154 155 156 157
# The Cache
# ---------

# The workflow for the Python Buildpack's cache is as follows:
#
# - `~/.heroku/{known-paths}` are copied from the cache into the slug.
# - The build is executed, modifying `~/.heroku/{known-paths}`.
# - Once the build is complete, `~/.heroku/{known-paths}` is copied back into the cache.

# Create the cache directory, if it doesn't exist.
Kenneth Reitz's avatar
Kenneth Reitz committed
158
mkdir -p "$CACHE_DIR"
159 160 161 162

# Restore old artifacts from the cache.
mkdir -p .heroku

Kenneth Reitz's avatar
Kenneth Reitz committed
163
# The Python installation.
Kenneth Reitz's avatar
Kenneth Reitz committed
164
cp -R "$CACHE_DIR/.heroku/python" .heroku/ &> /dev/null || true
Kenneth Reitz's avatar
Kenneth Reitz committed
165
# A plain text file which contains the current stack being used (used for cache busting).
Kenneth Reitz's avatar
Kenneth Reitz committed
166
cp -R "$CACHE_DIR/.heroku/python-stack" .heroku/ &> /dev/null || true
Kenneth Reitz's avatar
Kenneth Reitz committed
167
# A plain text file which contains the current python version being used (used for cache busting).
Kenneth Reitz's avatar
Kenneth Reitz committed
168
cp -R "$CACHE_DIR/.heroku/python-version" .heroku/ &> /dev/null || true
169 170
# A plain text file which contains the current sqlite3 version being used (used for cache busting).
cp -R "$CACHE_DIR/.heroku/python-sqlite3-version" .heroku/ &> /dev/null || true
Kenneth Reitz's avatar
Kenneth Reitz committed
171
# Any pre-compiled binaries, provided by the buildpack.
Kenneth Reitz's avatar
Kenneth Reitz committed
172
cp -R "$CACHE_DIR/.heroku/vendor" .heroku/ &> /dev/null || true
Kenneth Reitz's avatar
Kenneth Reitz committed
173
# "editable" installations of code repositories, via pip or pipenv.
Kenneth Reitz's avatar
Kenneth Reitz committed
174 175
if [[ -d "$CACHE_DIR/.heroku/src" ]]; then
  cp -R "$CACHE_DIR/.heroku/src" .heroku/ &> /dev/null || true
176 177
fi

Kenneth Reitz's avatar
Kenneth Reitz committed
178 179 180 181 182
# The pre_compile hook. Customers rely on this. Don't remove it.
# This part of the code is used to allow users to customize their build experience
# without forking the buildpack by providing a `bin/pre_compile` script, which gets
# run inline with the buildpack automatically.

Kenneth Reitz's avatar
Kenneth Reitz committed
183 184
# shellcheck source=bin/steps/hooks/pre_compile
source "$BIN_DIR/steps/hooks/pre_compile"
Kenneth Reitz's avatar
hooks  
Kenneth Reitz committed
185

Kenneth Reitz's avatar
Kenneth Reitz committed
186 187 188
# Sticky runtimes. If there was a previous build, and it used a given version of Python,
# continue to use that version of Python in perpituity (warnings will be raised if
# they are out–of–date).
Kenneth Reitz's avatar
Kenneth Reitz committed
189 190
if [ -f "$CACHE_DIR/.heroku/python-version" ]; then
  DEFAULT_PYTHON_VERSION=$(cat "$CACHE_DIR/.heroku/python-version")
Kenneth Reitz's avatar
bpwatch  
Kenneth Reitz committed
191
fi
Kenneth Reitz's avatar
Kenneth Reitz committed
192

Kenneth Reitz's avatar
Kenneth Reitz committed
193
# We didn't always record the stack version. This code is in place because of that.
Kenneth Reitz's avatar
Kenneth Reitz committed
194 195
if [ -f "$CACHE_DIR/.heroku/python-stack" ]; then
  CACHED_PYTHON_STACK=$(cat "$CACHE_DIR/.heroku/python-stack")
196
else
197
  CACHED_PYTHON_STACK=$STACK
198 199
fi

Kenneth Reitz's avatar
Kenneth Reitz committed
200 201
export CACHED_PYTHON_STACK

202
# Pipenv Python version support.
Kenneth Reitz's avatar
Kenneth Reitz committed
203 204 205
# Detect the version of Python requested from a Pipfile (e.g. python_version or python_full_version).
# Convert it to a runtime.txt file.

Kenneth Reitz's avatar
Kenneth Reitz committed
206 207
# shellcheck source=bin/steps/pipenv-python-version
source "$BIN_DIR/steps/pipenv-python-version"
208

Kenneth Reitz's avatar
Kenneth Reitz committed
209
# If no runtime was provided by the user, assume the default Python runtime version.
Kenneth Reitz's avatar
Kenneth Reitz committed
210
if [ ! -f runtime.txt ]; then
Kenneth Reitz's avatar
Kenneth Reitz committed
211
  echo "$DEFAULT_PYTHON_VERSION" > runtime.txt
Kenneth Reitz's avatar
Kenneth Reitz committed
212 213
fi

Kenneth Reitz's avatar
Kenneth Reitz committed
214
# Create the directory for .profile.d, if it doesn't exist.
Kenneth Reitz's avatar
Kenneth Reitz committed
215
mkdir -p "$(dirname "$PROFILE_PATH")"
Kenneth Reitz's avatar
Kenneth Reitz committed
216
# Create the directory for editable source code installation, if it doesn't exist.
David Zülke's avatar
David Zülke committed
217
mkdir -p /app/.heroku/src
Kenneth Reitz's avatar
Kenneth Reitz committed
218

Kenneth Reitz's avatar
Kenneth Reitz committed
219 220 221 222
# On Heroku CI, builds happen in `/app`. Otherwise, on the Heroku platform,
# they occur in a temp directory. Beacuse Python is not portable, we must create
# symlinks to emulate that we are operating in `/app` during the build process.
# This is (hopefully obviously) because apps end up running from `/app` in production.
David Zülke's avatar
David Zülke committed
223
if [[ $BUILD_DIR != '/app' ]]; then
224 225
    # python expects to reside in /app, so set up symlinks
    # we will not remove these later so subsequent buildpacks can still invoke it
Kenneth Reitz's avatar
Kenneth Reitz committed
226 227
    ln -nsf "$BUILD_DIR/.heroku/python" /app/.heroku/python
    ln -nsf "$BUILD_DIR/.heroku/vendor" /app/.heroku/vendor
228
    # Note: .heroku/src is copied in later.
229 230
fi

Kenneth Reitz's avatar
Kenneth Reitz committed
231 232
# Download / Install Python, from pre-build binaries available on Amazon S3.
# This step also bootstraps pip / setuptools.
233
(( start=$(nowms) ))
Kenneth Reitz's avatar
Kenneth Reitz committed
234 235
# shellcheck source=bin/steps/python
source "$BIN_DIR/steps/python"
Kenneth Reitz's avatar
Kenneth Reitz committed
236
mtime "python.install.time" "${start}"
237

Kenneth Reitz's avatar
Kenneth Reitz committed
238
# Install Pipenv dependencies, if a Pipfile was provided.
Kenneth Reitz's avatar
Kenneth Reitz committed
239
# shellcheck source=bin/steps/pipenv
Kenneth Reitz's avatar
Kenneth Reitz committed
240
source "$BIN_DIR/steps/pipenv"
241 242

# Uninstall removed dependencies with Pip.
Kenneth Reitz's avatar
Kenneth Reitz committed
243 244
# The buildpack will automatically remove any declared dependencies (in requirements.txt)
# that were explicitly removed. This machinery is a bit complex, but it is not complicated.
245
(( start=$(nowms) ))
246 247 248 249
# shellcheck source=bin/steps/pip-uninstall
source "$BIN_DIR/steps/pip-uninstall"
mtime "pip.uninstall.time" "${start}"

250
# If no requirements.txt file given, assume `setup.py develop` is intended.
Kenneth Reitz's avatar
Kenneth Reitz committed
251 252 253
# This allows for people to ship a setup.py application to Heroku
# (which is rare, but I vouch that it should work!)

Kenneth Reitz's avatar
Kenneth Reitz committed
254
if [ ! -f requirements.txt ] && [ ! -f Pipfile ]; then
255 256 257
  echo "-e ." > requirements.txt
fi

Kenneth Reitz's avatar
Kenneth Reitz committed
258
# Fix egg-links.
Kenneth Reitz's avatar
Kenneth Reitz committed
259 260
# Because we're installing things into a different path than we're running them (temp dir vs app dir),
# We must re-write all of Python's eggpath links to target the proper directory.
Kenneth Reitz's avatar
Kenneth Reitz committed
261 262
# shellcheck source=bin/steps/eggpath-fix
source "$BIN_DIR/steps/eggpath-fix"
Kenneth Reitz's avatar
Kenneth Reitz committed
263

264
# Mercurial support.
Kenneth Reitz's avatar
Kenneth Reitz committed
265 266
# If a customer appears to be using mercurial for dependency resolution, we install it first.
# Note: this only applies to pip, not pipenv. This can likely be removed, over time. Measure it first.
Kenneth Reitz's avatar
Kenneth Reitz committed
267 268
# shellcheck source=bin/steps/mercurial
source "$BIN_DIR/steps/mercurial"
269

Kenneth Reitz's avatar
Kenneth Reitz committed
270
# Pylibmc support.
Kenneth Reitz's avatar
Kenneth Reitz committed
271
# On cedar-14, libmemcached was not available. The buildpack provides its own version, instead.
Kenneth Reitz's avatar
Kenneth Reitz committed
272 273
# shellcheck source=bin/steps/pylibmc
source "$BIN_DIR/steps/pylibmc"
274

Kenneth Reitz's avatar
Kenneth Reitz committed
275 276
# Support for Geo libraries. This is deprecated functionality, only functional on cedar-14.
# It is undocumented.
Kenneth Reitz's avatar
Kenneth Reitz committed
277
# shellcheck source=bin/steps/geo-libs
Kenneth Reitz's avatar
Kenneth Reitz committed
278
sub_env "$BIN_DIR/steps/geo-libs"
Kenneth Reitz's avatar
Kenneth Reitz committed
279

Kenneth Reitz's avatar
GDAL  
Kenneth Reitz committed
280
# GDAL support.
Kenneth Reitz's avatar
Kenneth Reitz committed
281
# This is part of the Geo support.
Kenneth Reitz's avatar
Kenneth Reitz committed
282 283
# shellcheck source=bin/steps/gdal
source "$BIN_DIR/steps/gdal"
Kenneth Reitz's avatar
GDAL  
Kenneth Reitz committed
284

285 286 287 288 289 290 291 292 293 294
# SQLite3 support.
# This sets up and installs sqlite3 dev headers and the sqlite3 binary but not the
# libsqlite3-0 library since that exists on the stack image.
# Note: This only applies to Python 2.7.15+ and Python 3.6.6+
(( start=$(nowms) ))
# shellcheck source=bin/steps/sqlite3
source "$BIN_DIR/steps/sqlite3"
buildpack_sqlite3_install
mtime "sqlite3.install.time" "${start}"

Kenneth Reitz's avatar
Kenneth Reitz committed
295 296 297 298
# pip install
# -----------

# Install dependencies with pip (where the magic happens).
299
(( start=$(nowms) ))
Kenneth Reitz's avatar
Kenneth Reitz committed
300 301
# shellcheck source=bin/steps/pip-install
source "$BIN_DIR/steps/pip-install"
302 303
mtime "pip.install.time" "${start}"

Kenneth Reitz's avatar
Kenneth Reitz committed
304
# Support for NLTK corpora.
Kenneth Reitz's avatar
Kenneth Reitz committed
305 306 307
# Note: this may only work on Python 2.7. I don't think many customers use this functionality,
# and it should probably be undocumented.
# (there's an import error on 3.6 that should hopefully be fixed upstream at some point)
308
(( start=$(nowms) ))
Kenneth Reitz's avatar
Kenneth Reitz committed
309
sub_env "$BIN_DIR/steps/nltk"
Kenneth Reitz's avatar
Kenneth Reitz committed
310
mtime "nltk.download.time" "${start}"
Kenneth Reitz's avatar
Kenneth Reitz committed
311

Kenneth Reitz's avatar
Kenneth Reitz committed
312 313
# Support for editable installations. Here, we are copying pip–created src directory,
# and copying it into the proper place (the logical place to do this was early, but it must be done here).
Kenneth Reitz's avatar
Kenneth Reitz committed
314 315
# In CI, $BUILD_DIR is /app.
if [[ ! "$BUILD_DIR" == "/app" ]]; then
David Zülke's avatar
David Zülke committed
316 317
  rm -fr "$BUILD_DIR/.heroku/src"
  deep-cp /app/.heroku/src "$BUILD_DIR/.heroku/src"
Kenneth Reitz's avatar
Kenneth Reitz committed
318 319
fi

Kenneth Reitz's avatar
Kenneth Reitz committed
320

Kenneth Reitz's avatar
Kenneth Reitz committed
321
# Django collectstatic support.
Kenneth Reitz's avatar
Kenneth Reitz committed
322 323 324 325
# The buildpack automatically runs collectstatic for Django applications.
# This is the cause for the majority of build failures on the Python platform.
# These failures are intentional — if collectstatic (which can be tricky, at times) fails,
# your build fails.
326
(( start=$(nowms) ))
Kenneth Reitz's avatar
Kenneth Reitz committed
327
sub_env "$BIN_DIR/steps/collectstatic"
Kenneth Reitz's avatar
Kenneth Reitz committed
328
mtime "collectstatic.time" "${start}"
329

Kenneth Reitz's avatar
Kenneth Reitz committed
330 331 332 333

# Progamatically create .profile.d script for application runtime environment variables.

# Set the PATH to include Python / pip / pipenv / etc.
Kenneth Reitz's avatar
Kenneth Reitz committed
334
set_env PATH "\$HOME/.heroku/python/bin:\$PATH"
Kenneth Reitz's avatar
Kenneth Reitz committed
335
# Tell Python to run in unbuffered mode.
Kenneth Reitz's avatar
Kenneth Reitz committed
336
set_env PYTHONUNBUFFERED true
Kenneth Reitz's avatar
Kenneth Reitz committed
337
# Tell Python where it lives.
338
set_env PYTHONHOME "\$HOME/.heroku/python"
Kenneth Reitz's avatar
Kenneth Reitz committed
339
# Set variables for C libraries.
340 341
set_env LIBRARY_PATH "\$HOME/.heroku/vendor/lib:\$HOME/.heroku/python/lib:\$LIBRARY_PATH"
set_env LD_LIBRARY_PATH "\$HOME/.heroku/vendor/lib:\$HOME/.heroku/python/lib:\$LD_LIBRARY_PATH"
Kenneth Reitz's avatar
Kenneth Reitz committed
342
# Locale.
Kenneth Reitz's avatar
Kenneth Reitz committed
343
set_default_env LANG en_US.UTF-8
Kenneth Reitz's avatar
Kenneth Reitz committed
344
# The Python hash seed is set to random.
Kenneth Reitz's avatar
Kenneth Reitz committed
345
set_default_env PYTHONHASHSEED random
Kenneth Reitz's avatar
Kenneth Reitz committed
346
# Tell Python to look for Python modules in the /app dir. Don't change this.
347 348
set_default_env PYTHONPATH "\$HOME"

David Zülke's avatar
David Zülke committed
349
# Python expects to be in /app, if at runtime, it is not, set
Kenneth Reitz's avatar
Kenneth Reitz committed
350
# up symlinks… this can occur when the subdir buildpack is used.
351
cat <<EOT >> "$PROFILE_PATH"
David Zülke's avatar
David Zülke committed
352 353 354 355
if [[ \$HOME != "/app" ]]; then
    mkdir -p /app/.heroku
    ln -nsf "\$HOME/.heroku/python" /app/.heroku/python
    ln -nsf "\$HOME/.heroku/vendor" /app/.heroku/vendor
356 357
fi
EOT
Kenneth Reitz's avatar
Kenneth Reitz committed
358

359
# Install sane-default script for $WEB_CONCURRENCY and $FORWARDED_ALLOW_IPS.
Kenneth Reitz's avatar
Kenneth Reitz committed
360 361
cp "$ROOT_DIR/vendor/WEB_CONCURRENCY.sh" "$WEB_CONCURRENCY_PROFILE_PATH"
cp "$ROOT_DIR/vendor/python.gunicorn.sh" "$GUNICORN_PROFILE_PATH"
Kenneth Reitz's avatar
Kenneth Reitz committed
362

Kenneth Reitz's avatar
Kenneth Reitz committed
363
# Experimental post_compile hook. Don't remove this.
Kenneth Reitz's avatar
Kenneth Reitz committed
364 365
# shellcheck source=bin/steps/hooks/post_compile
source "$BIN_DIR/steps/hooks/post_compile"
Kenneth Reitz's avatar
Kenneth Reitz committed
366

Kenneth Reitz's avatar
Kenneth Reitz committed
367
# Fix egg-links, again.
Kenneth Reitz's avatar
Kenneth Reitz committed
368 369
# shellcheck source=bin/steps/eggpath-fix2
source "$BIN_DIR/steps/eggpath-fix2"
370

Kenneth Reitz's avatar
Kenneth Reitz committed
371
# Store new artifacts in the cache.
Kenneth Reitz's avatar
Kenneth Reitz committed
372 373 374 375 376 377 378 379 380 381 382
rm -rf "$CACHE_DIR/.heroku/python"
rm -rf "$CACHE_DIR/.heroku/python-version"
rm -rf "$CACHE_DIR/.heroku/python-stack"
rm -rf "$CACHE_DIR/.heroku/vendor"
rm -rf "$CACHE_DIR/.heroku/src"

mkdir -p "$CACHE_DIR/.heroku"
cp -R .heroku/python "$CACHE_DIR/.heroku/"
cp -R .heroku/python-version "$CACHE_DIR/.heroku/"
cp -R .heroku/python-stack "$CACHE_DIR/.heroku/" &> /dev/null || true
cp -R .heroku/vendor "$CACHE_DIR/.heroku/" &> /dev/null || true
Kenneth Reitz's avatar
Kenneth Reitz committed
383
if [[ -d .heroku/src ]]; then
Kenneth Reitz's avatar
Kenneth Reitz committed
384
  cp -R .heroku/src "$CACHE_DIR/.heroku/" &> /dev/null || true
Kenneth Reitz's avatar
Kenneth Reitz committed
385
fi
Kenneth Reitz's avatar
Kenneth Reitz committed
386 387

# Measure the size of the Python installation.
Kenneth Reitz's avatar
Kenneth Reitz committed
388
# shellcheck disable=SC2119
Kenneth Reitz's avatar
Kenneth Reitz committed
389
mmeasure 'python.size' "$(measure-size)"