@@ -103,16 +103,16 @@ mkdir -p "$CACHE_DIR/.heroku"
103
103
mkdir -p .heroku
104
104
105
105
# The Python installation.
106
- cp -R " $CACHE_DIR /.heroku/python" .heroku/ & > /dev/null || true
106
+ cp -R " $CACHE_DIR /.heroku/python" .heroku/ & > /dev/null || true
107
107
# A plain text file which contains the current stack being used (used for cache busting).
108
- cp -R " $CACHE_DIR /.heroku/python-stack" .heroku/ & > /dev/null || true
108
+ cp -R " $CACHE_DIR /.heroku/python-stack" .heroku/ & > /dev/null || true
109
109
# A plain text file which contains the current python version being used (used for cache busting).
110
- cp -R " $CACHE_DIR /.heroku/python-version" .heroku/ & > /dev/null || true
110
+ cp -R " $CACHE_DIR /.heroku/python-version" .heroku/ & > /dev/null || true
111
111
# A plain text file which contains the current sqlite3 version being used (used for cache busting).
112
- cp -R " $CACHE_DIR /.heroku/python-sqlite3-version" .heroku/ & > /dev/null || true
112
+ cp -R " $CACHE_DIR /.heroku/python-sqlite3-version" .heroku/ & > /dev/null || true
113
113
# "editable" installations of code repositories, via pip or pipenv.
114
114
if [[ -d " $CACHE_DIR /.heroku/src" ]]; then
115
- cp -R " $CACHE_DIR /.heroku/src" .heroku/ & > /dev/null || true
115
+ cp -R " $CACHE_DIR /.heroku/src" .heroku/ & > /dev/null || true
116
116
fi
117
117
118
118
# The pre_compile hook. Customers rely on this. Don't remove it.
@@ -124,47 +124,47 @@ source "${BUILDPACK_DIR}/bin/steps/hooks/pre_compile"
124
124
# Sticky runtimes. If there was a previous build, and it used a given version of Python,
125
125
# continue to use that version of Python in perpetuity.
126
126
if [[ -f " $CACHE_DIR /.heroku/python-version" ]]; then
127
- CACHED_PYTHON_VERSION=$( cat " $CACHE_DIR /.heroku/python-version" )
127
+ CACHED_PYTHON_VERSION=$( cat " $CACHE_DIR /.heroku/python-version" )
128
128
fi
129
129
130
130
# We didn't always record the stack version. This code is in place because of that.
131
131
if [[ -f " $CACHE_DIR /.heroku/python-stack" ]]; then
132
- CACHED_PYTHON_STACK=$( cat " $CACHE_DIR /.heroku/python-stack" )
132
+ CACHED_PYTHON_STACK=$( cat " $CACHE_DIR /.heroku/python-stack" )
133
133
else
134
- CACHED_PYTHON_STACK=$STACK
134
+ CACHED_PYTHON_STACK=$STACK
135
135
fi
136
136
137
137
# TODO: Move this into a new package manager handling implementation when adding Poetry support.
138
138
# We intentionally don't mention `setup.py` here since it's being removed soon.
139
139
if [[ ! -f requirements.txt && ! -f Pipfile && ! -f setup.py ]]; then
140
- puts-warn
141
- puts-warn " Error: Couldn't find any supported Python package manager files."
142
- puts-warn
143
- puts-warn " A Python app on Heroku must have either a 'requirements.txt' or"
144
- puts-warn " 'Pipfile' package manager file in the root directory of its"
145
- puts-warn " source code."
146
- puts-warn
147
- puts-warn " Currently the root directory of your app contains:"
148
- puts-warn
149
- # TODO: Overhaul logging helpers so they can handle prefixing multi-line strings, and switch to them.
150
- # shellcheck disable=SC2012 # Using `ls` instead of `find` is absolutely fine for this use case.
151
- ls -1 --indicator-style=slash " ${BUILD_DIR} " | sed ' s/^/ ! /'
152
- puts-warn
153
- puts-warn " If your app already has a package manager file, check that it:"
154
- puts-warn
155
- puts-warn " 1. Is in the top level directory (not a subdirectory)."
156
- puts-warn " 2. Has the correct spelling (the filenames are case-sensitive)."
157
- puts-warn " 3. Isn't listed in '.gitignore' or '.slugignore'."
158
- puts-warn
159
- puts-warn " Otherwise, add a package manager file to your app. If your app has"
160
- puts-warn " no dependencies, then create an empty 'requirements.txt' file."
161
- puts-warn
162
- puts-warn " For help with using Python on Heroku, see:"
163
- puts-warn " https://devcenter.heroku.com/articles/getting-started-with-python"
164
- puts-warn " https://devcenter.heroku.com/articles/python-support"
165
- puts-warn
166
- meta_set " failure_reason" " package-manager-not-found"
167
- exit 1
140
+ puts-warn
141
+ puts-warn " Error: Couldn't find any supported Python package manager files."
142
+ puts-warn
143
+ puts-warn " A Python app on Heroku must have either a 'requirements.txt' or"
144
+ puts-warn " 'Pipfile' package manager file in the root directory of its"
145
+ puts-warn " source code."
146
+ puts-warn
147
+ puts-warn " Currently the root directory of your app contains:"
148
+ puts-warn
149
+ # TODO: Overhaul logging helpers so they can handle prefixing multi-line strings, and switch to them.
150
+ # shellcheck disable=SC2012 # Using `ls` instead of `find` is absolutely fine for this use case.
151
+ ls -1 --indicator-style=slash " ${BUILD_DIR} " | sed ' s/^/ ! /'
152
+ puts-warn
153
+ puts-warn " If your app already has a package manager file, check that it:"
154
+ puts-warn
155
+ puts-warn " 1. Is in the top level directory (not a subdirectory)."
156
+ puts-warn " 2. Has the correct spelling (the filenames are case-sensitive)."
157
+ puts-warn " 3. Isn't listed in '.gitignore' or '.slugignore'."
158
+ puts-warn
159
+ puts-warn " Otherwise, add a package manager file to your app. If your app has"
160
+ puts-warn " no dependencies, then create an empty 'requirements.txt' file."
161
+ puts-warn
162
+ puts-warn " For help with using Python on Heroku, see:"
163
+ puts-warn " https://devcenter.heroku.com/articles/getting-started-with-python"
164
+ puts-warn " https://devcenter.heroku.com/articles/python-support"
165
+ puts-warn
166
+ meta_set " failure_reason" " package-manager-not-found"
167
+ exit 1
168
168
fi
169
169
170
170
# Pipenv Python version support.
173
173
source " ${BUILDPACK_DIR} /bin/steps/pipenv-python-version"
174
174
175
175
if [[ -f runtime.txt ]]; then
176
- # PYTHON_VERSION_SOURCE may have already been set by the pipenv-python-version step.
177
- # TODO: Refactor this and stop pipenv-python-version using runtime.txt as an API.
178
- PYTHON_VERSION_SOURCE=${PYTHON_VERSION_SOURCE:- " runtime.txt" }
179
- puts-step " Using Python version specified in ${PYTHON_VERSION_SOURCE} "
180
- meta_set " python_version_reason" " specified"
176
+ # PYTHON_VERSION_SOURCE may have already been set by the pipenv-python-version step.
177
+ # TODO: Refactor this and stop pipenv-python-version using runtime.txt as an API.
178
+ PYTHON_VERSION_SOURCE=${PYTHON_VERSION_SOURCE:- " runtime.txt" }
179
+ puts-step " Using Python version specified in ${PYTHON_VERSION_SOURCE} "
180
+ meta_set " python_version_reason" " specified"
181
181
elif [[ -n " ${CACHED_PYTHON_VERSION:- } " ]]; then
182
- puts-step " No Python version was specified. Using the same version as the last build: ${CACHED_PYTHON_VERSION} "
183
- echo " To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes"
184
- meta_set " python_version_reason" " cached"
185
- echo " ${CACHED_PYTHON_VERSION} " > runtime.txt
182
+ puts-step " No Python version was specified. Using the same version as the last build: ${CACHED_PYTHON_VERSION} "
183
+ echo " To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes"
184
+ meta_set " python_version_reason" " cached"
185
+ echo " ${CACHED_PYTHON_VERSION} " > runtime.txt
186
186
else
187
- puts-step " No Python version was specified. Using the buildpack default: ${DEFAULT_PYTHON_VERSION} "
188
- echo " To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes"
189
- meta_set " python_version_reason" " default"
190
- echo " ${DEFAULT_PYTHON_VERSION} " > runtime.txt
187
+ puts-step " No Python version was specified. Using the buildpack default: ${DEFAULT_PYTHON_VERSION} "
188
+ echo " To use a different version, see: https://devcenter.heroku.com/articles/python-runtimes"
189
+ meta_set " python_version_reason" " default"
190
+ echo " ${DEFAULT_PYTHON_VERSION} " > runtime.txt
191
191
fi
192
192
193
193
# Create the directory for .profile.d, if it doesn't exist.
@@ -201,11 +201,11 @@ mkdir -p /app/.heroku/src
201
201
# This is (hopefully obviously) because apps end up running from `/app` in production.
202
202
# Realpath is used to support use-cases where one of the locations is a symlink to the other.
203
203
if [[ " $( realpath " ${BUILD_DIR} " ) " != " $( realpath /app) " ]]; then
204
- # python expects to reside in /app, so set up symlinks
205
- # we will not remove these later so subsequent buildpacks can still invoke it
206
- ln -nsf " $BUILD_DIR /.heroku/python" /app/.heroku/python
207
- ln -nsf " $BUILD_DIR /.heroku/vendor" /app/.heroku/vendor
208
- # Note: .heroku/src is copied in later.
204
+ # python expects to reside in /app, so set up symlinks
205
+ # we will not remove these later so subsequent buildpacks can still invoke it
206
+ ln -nsf " $BUILD_DIR /.heroku/python" /app/.heroku/python
207
+ ln -nsf " $BUILD_DIR /.heroku/vendor" /app/.heroku/vendor
208
+ # Note: .heroku/src is copied in later.
209
209
fi
210
210
211
211
# Download / Install Python, from pre-build binaries available on Amazon S3.
@@ -221,10 +221,10 @@ source "${BUILDPACK_DIR}/bin/steps/pipenv"
221
221
# This allows for people to ship a setup.py application to Heroku
222
222
223
223
if [[ ! -f requirements.txt ]] && [[ ! -f Pipfile ]]; then
224
- meta_set " setup_py_only" " true"
225
- echo " -e ." > requirements.txt
224
+ meta_set " setup_py_only" " true"
225
+ echo " -e ." > requirements.txt
226
226
else
227
- meta_set " setup_py_only" " false"
227
+ meta_set " setup_py_only" " false"
228
228
fi
229
229
230
230
# SQLite3 support.
@@ -251,11 +251,10 @@ meta_time "nltk_downloader_duration" "${nltk_downloader_start_time}"
251
251
# In CI, $BUILD_DIR is /app.
252
252
# Realpath is used to support use-cases where one of the locations is a symlink to the other.
253
253
if [[ " $( realpath " ${BUILD_DIR} " ) " != " $( realpath /app) " ]]; then
254
- rm -rf " $BUILD_DIR /.heroku/src"
255
- deep-cp /app/.heroku/src " $BUILD_DIR /.heroku/src"
254
+ rm -rf " $BUILD_DIR /.heroku/src"
255
+ deep-cp /app/.heroku/src " $BUILD_DIR /.heroku/src"
256
256
fi
257
257
258
-
259
258
# Django collectstatic support.
260
259
# The buildpack automatically runs collectstatic for Django applications.
261
260
# This is the cause for the majority of build failures on the Python platform.
@@ -265,7 +264,6 @@ collectstatic_start_time=$(nowms)
265
264
sub_env " ${BUILDPACK_DIR} /bin/steps/collectstatic"
266
265
meta_time " django_collectstatic_duration" " ${collectstatic_start_time} "
267
266
268
-
269
267
# Programmatically create .profile.d script for application runtime environment variables.
270
268
271
269
# Set the PATH to include Python / pip / pipenv / etc.
@@ -286,7 +284,7 @@ set_default_env PYTHONPATH "\$HOME"
286
284
287
285
# Python expects to be in /app, if at runtime, it is not, set
288
286
# up symlinks… this can occur when the subdir buildpack is used.
289
- cat << EOT >> "$PROFILE_PATH "
287
+ cat << EOT >>"$PROFILE_PATH "
290
288
if [[ \$ HOME != "/app" ]]; then
291
289
mkdir -p /app/.heroku
292
290
ln -nsf "\$ HOME/.heroku/python" /app/.heroku/python
298
296
# (such as `/tmp/build_<hash>`) back to `/app`. This is not done during the build itself, since later
299
297
# buildpacks still need the build time paths.
300
298
if [[ " ${BUILD_DIR} " != " /app" ]]; then
301
- cat << EOT >> "$PROFILE_PATH "
299
+ cat << EOT >>"$PROFILE_PATH "
302
300
find .heroku/python/lib/python*/site-packages/ -type f -and \( -name '*.egg-link' -or -name '*.pth' -or -name '__editable___*_finder.py' \) -exec sed -i -e 's#${BUILD_DIR} #/app#' {} \+
303
301
EOT
304
302
fi
@@ -320,9 +318,9 @@ rm -rf "$CACHE_DIR/.heroku/src"
320
318
mkdir -p " $CACHE_DIR /.heroku"
321
319
cp -R .heroku/python " $CACHE_DIR /.heroku/"
322
320
cp -R .heroku/python-version " $CACHE_DIR /.heroku/"
323
- cp -R .heroku/python-stack " $CACHE_DIR /.heroku/" & > /dev/null || true
321
+ cp -R .heroku/python-stack " $CACHE_DIR /.heroku/" & > /dev/null || true
324
322
if [[ -d .heroku/src ]]; then
325
- cp -R .heroku/src " $CACHE_DIR /.heroku/" & > /dev/null || true
323
+ cp -R .heroku/src " $CACHE_DIR /.heroku/" & > /dev/null || true
326
324
fi
327
325
328
326
meta_time " total_duration" " ${compile_start_time} "
0 commit comments