mirror of
https://github.com/kennethreitz/heroku-buildpack-python.git
synced 2026-06-05 23:10:16 +00:00
Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9504ffd2e | |||
| 96822983ed | |||
| f9d5c0010d | |||
| 9b1a69a1b3 | |||
| 58dd638fb6 | |||
| ead59ac7ff | |||
| ac8fd555b8 | |||
| f825896c4e | |||
| fcf696b835 | |||
| a98ef91566 | |||
| e67235f906 | |||
| b1690e9f47 | |||
| b250300b74 | |||
| 096709dcf7 | |||
| ff8945c0c2 | |||
| 4e78b5d57c | |||
| b74a41395e | |||
| c550143a59 | |||
| 838f4c125b | |||
| 0020aae078 | |||
| 63651e042f | |||
| c0609a881c | |||
| ef4696a922 | |||
| 6c612a7fb1 | |||
| f91f4ee4ce | |||
| eea9a7fd0f | |||
| 215a3e3670 | |||
| 4505968fcb | |||
| 37d1474bee | |||
| 40167d83f6 | |||
| 64fb396b73 | |||
| eb6ee49dfe | |||
| 64abfb2978 | |||
| 12d1cbb3be | |||
| 7817aa3fc3 | |||
| ae56342a81 | |||
| 3e49aeb940 | |||
| a91a5427de | |||
| ab69658efb | |||
| dfbe8ddaf5 | |||
| 60b9d1a562 | |||
| 3fa3f15d35 | |||
| a510c47b26 | |||
| 1972e6094e | |||
| 84ac34b1d4 | |||
| 7c4f55bc32 | |||
| eabe71d578 | |||
| 95fca53d38 | |||
| ff4f677435 | |||
| cba3201ac2 | |||
| ac29db32f8 | |||
| e83576f6b4 | |||
| 43600f25a5 | |||
| f508bd538d | |||
| bc7e34dbad | |||
| 419ef47996 | |||
| c1f6679dd7 | |||
| de81e41336 | |||
| 99c1027cb2 | |||
| 46d3d2b042 | |||
| 7b4f16145b | |||
| a165deadfb | |||
| b64897a0b7 | |||
| fc6698e597 | |||
| 6fa6feb75d | |||
| 81874dad47 |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"productTag": "a1aB0000000MR0RIAW",
|
||||
"issueTypeLabels": { "gus: story": "USER STORY", "gus: bug": "BUG P3" },
|
||||
"defaultBuild": "Heroku Unscheduled",
|
||||
"statusWhenClosed": "CLOSED"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
labels:
|
||||
- "c: dependencies"
|
||||
|
||||
- package-ecosystem: "bundler"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
labels:
|
||||
- "c: dependencies"
|
||||
@@ -1,7 +0,0 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: check-yaml
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
+9
-8
@@ -1,8 +1,8 @@
|
||||
language: minimal
|
||||
dist: bionic
|
||||
dist: focal
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- main
|
||||
|
||||
script:
|
||||
- make test STACK="${STACK}" TEST_CMD="${TEST_CMD}"
|
||||
@@ -12,14 +12,13 @@ jobs:
|
||||
- name: Bash linting (shellcheck)
|
||||
script: make check
|
||||
- name: Hatchet integration tests
|
||||
if: env(TRAVIS_PULL_REQUEST_SLUG) = env(TRAVIS_REPO_SLUG)
|
||||
if: env(HEROKU_API_USER) IS present AND env(HEROKU_API_KEY) IS present
|
||||
language: ruby
|
||||
rvm:
|
||||
- 2.6.6
|
||||
- 2.7
|
||||
before_script:
|
||||
- gem install bundler -v 1.16.2
|
||||
script:
|
||||
- bundle exec hatchet ci:setup
|
||||
script:
|
||||
- PARALLEL_SPLIT_TEST_PROCESSES=11 bundle exec parallel_split_test spec/hatchet/
|
||||
|
||||
env:
|
||||
@@ -35,10 +34,12 @@ env:
|
||||
- STACK=heroku-18 TEST_CMD=test/run-deps
|
||||
- STACK=heroku-18 TEST_CMD=test/run-versions
|
||||
- STACK=heroku-18 TEST_CMD=test/run-features
|
||||
|
||||
- STACK=heroku-20 TEST_CMD=test/run-deps
|
||||
- STACK=heroku-20 TEST_CMD=test/run-versions
|
||||
- STACK=heroku-20 TEST_CMD=test/run-features
|
||||
global:
|
||||
- HATCHET_RETRIES=3
|
||||
- IS_RUNNING_ON_CI=true
|
||||
- HATCHET_APP_LIMIT=80
|
||||
- HATCHET_DEPLOY_STRATEGY=git
|
||||
- secure: yjtlPE5FbVxTKnjUy/tZUBgSEf4qADD3QOxtgziuid73S0U/1IEXlMGFULsQzIjtlHKmHeywZqpVVEpthIH4RuT7uoX1Pb7SSM/g0T8fT3VoEFbFK1uYl0oZQbUS4Klxv9tPiumj8if3m6ULEGIz1X0wZcMOC0tMLwVCnwmap0E=
|
||||
- secure: ZeFTHWwnpIKE9nAqs88ocmiQh7bKce84lilGm5J23nf3N6V4wNyLwqlkvsM008WGBCaOg9AUx7ZunasT0ANsR5gLP3eV2UUg7ILdRgV2Gy13eNRFheC4PHdN92RqQ3aKoqlIv2K999xlhVjod0NzhkQQXB6PddfQINbuU7ks6As=
|
||||
|
||||
+149
-98
@@ -1,9 +1,63 @@
|
||||
# Python Buildpack Changelog
|
||||
|
||||
# Master
|
||||
## Unreleased
|
||||
|
||||
|
||||
# 174 (2020-07-30)
|
||||
## v184 (2020-10-21)
|
||||
|
||||
- Vendor buildpack-stdlib instead of fetching from S3 (#1100).
|
||||
- Fix metric names for metrics emitted within `sub_env` (#1099).
|
||||
|
||||
## v183 (2020-10-12)
|
||||
|
||||
- Add support for Heroku-20 (#968).
|
||||
|
||||
## v182 (2020-10-06)
|
||||
|
||||
- Python 3.9.0 is now available (CPython) (#1090).
|
||||
- Migrate from the `lang-python` S3 bucket to `heroku-buildpack-python` (#1089).
|
||||
- Remove `vendor/shunit2` (#1086).
|
||||
- Replace `BUILDPACK_VENDOR_URL` and `USE_STAGING_BINARIES` with `BUILDPACK_S3_BASE_URL` (#1085).
|
||||
|
||||
## v181 (2020-09-29)
|
||||
|
||||
- PyPy 2.7 and 3.6, version 7.3.2 are now available (Note: PyPy support is in beta) (#1081).
|
||||
|
||||
## v180 (2020-09-24)
|
||||
|
||||
- Python 3.8.6 is now available (CPython) (#1072).
|
||||
|
||||
## v179 (2020-09-23)
|
||||
|
||||
- Remove duplicate pipenv metric event (#1070).
|
||||
- Emit metrics for how the Python version was chosen for an app (#1069).
|
||||
- Emit Python version metric events for all builds, not just clean installs (#1066).
|
||||
|
||||
## v178 (2020-09-07)
|
||||
|
||||
- Python 3.5.10 is now available (CPython) (#1062).
|
||||
|
||||
## v177 (2020-08-18)
|
||||
|
||||
- Python 3.6.12 and 3.7.9 are now available (CPython) (#1054).
|
||||
- The default Python version for new apps is now 3.6.12 (previously 3.6.11) (#1054).
|
||||
|
||||
## v176 (2020-08-12)
|
||||
|
||||
- Rebuild the Python 3.4.10 archives with the correct version of Python (#1048).
|
||||
- Fix the security update version check message for apps using PyPy (#1040).
|
||||
- Remove `vendor/test-utils` (#1043).
|
||||
|
||||
## v175 (2020-08-05)
|
||||
|
||||
- Update pip from 20.0.2 to 20.1.1 for Python 2.7 and Python 3.5+ (#1030).
|
||||
- Update setuptools from 39.0.1 to: (#1024)
|
||||
- 44.1.1 for Python 2.7
|
||||
- 43.0.0 for Python 3.4
|
||||
- 47.1.1 for Python 3.5+
|
||||
- Switch the `heroku-buildpack-python` repository default branch from `master` to `main` (#1029).
|
||||
|
||||
## v174 (2020-07-30)
|
||||
|
||||
- For repeat builds, also manage the installed versions of setuptools/wheel, rather than just that of pip (#1007).
|
||||
- Install an explicit version of wheel rather than the latest release at the time (#1007).
|
||||
@@ -12,87 +66,85 @@
|
||||
- Install pip using itself rather than `get-pip.py` (#1007).
|
||||
- Disable pip's version check + cache when installing pip/setuptools/wheel (#1007).
|
||||
- Install setuptools from PyPI rather than a vendored copy (#1007).
|
||||
- Reduce the number of environment variables exposed to `bin/{pre,post}_compile` and other subprocesses (#1011)
|
||||
- Reduce the number of environment variables exposed to `bin/{pre,post}_compile` and other subprocesses (#1011).
|
||||
|
||||
# 173 (2020-07-21)
|
||||
## v173 (2020-07-21)
|
||||
|
||||
- Python 3.8.5 is now available (CPython)
|
||||
- Python 3.8.5 is now available (CPython).
|
||||
|
||||
# 172 (2020-07-17)
|
||||
## v172 (2020-07-17)
|
||||
|
||||
- Python 3.8.4 is now available (CPython)
|
||||
- Python 3.8.4 is now available (CPython).
|
||||
|
||||
# 171 (2020-07-07)
|
||||
## v171 (2020-07-07)
|
||||
|
||||
- Python 3.6.11 and 3.7.8 are now available (CPython).
|
||||
|
||||
# 170 (2020-05-19)
|
||||
## v170 (2020-05-19)
|
||||
|
||||
- Python 2.7.18, 3.5.9, 3.7.7 and 3.8.3 are now available (CPython).
|
||||
- PyPy 2.7 and 3.6, version 7.3.1 are now available (Note: PyPy support is in beta)
|
||||
- Docs: Fix explanation of runtime.txt generation when using pipenv
|
||||
- Bugfix: Correctly detect Python version when using a `python_version` of `3.8` in `Pipfile.lock`
|
||||
- PyPy 2.7 and 3.6, version 7.3.1 are now available (Note: PyPy support is in beta).
|
||||
- Docs: Fix explanation of runtime.txt generation when using pipenv.
|
||||
- Bugfix: Correctly detect Python version when using a `python_version` of `3.8` in `Pipfile.lock`.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# 169 (2020-04-22)
|
||||
## v169 (2020-04-22)
|
||||
|
||||
- Add a Hatchet test for python 3.8.2
|
||||
- Set Code Owners to @heroku/langauges
|
||||
- Bugfix: Caching on subsequent redeploys
|
||||
- Update tests to support latest version of Python
|
||||
|
||||
# 168 (2020-04-06)
|
||||
## v168 (2020-04-06)
|
||||
|
||||
- Doc: Update Readme with version numbers
|
||||
- update Code Owners to include the Heroku Buildpack Maintainers team
|
||||
- Deprecation warning: BUILD_WITH_GEO_LIBRARIES is now deprecated. See warning for details.
|
||||
- Deprecation warning: `BUILD_WITH_GEO_LIBRARIES` is now deprecated. See warning for details.
|
||||
- Clean up build log output
|
||||
- Update Python versions in README to match docs
|
||||
- Django version detection fixed, link updated
|
||||
|
||||
# 167 (2020-03-26)
|
||||
## v167 (2020-03-26)
|
||||
|
||||
- Add failcase for cache busting
|
||||
- Bugfix: Clearing pip dependencies
|
||||
|
||||
# 166 (2020-03-05)
|
||||
## v166 (2020-03-05)
|
||||
|
||||
- Correct ftp to https in vendored file
|
||||
- Warn for Django 1.11 approaching EOL, provide link to roadmap
|
||||
|
||||
# 165 (2020-02-27)
|
||||
## v165 (2020-02-27)
|
||||
|
||||
- Python 3.8.2 now available.
|
||||
|
||||
# 164 (2020-02-20)
|
||||
## v164 (2020-02-20)
|
||||
|
||||
- Update requirements.txt builds to use Pip 20.0.2
|
||||
- Download get-pip.py to tmpdir instead of root dir
|
||||
|
||||
# 163 (2019-12-23)
|
||||
## v163 (2019-12-23)
|
||||
|
||||
- New pythons released:
|
||||
Python 3.8.1, 3.7.6, 3.6.10 (CPython)
|
||||
Beta Release: Pypy 2.7 and 3.6, version 7.2.0
|
||||
|
||||
# 162 (2019-12-06)
|
||||
## v162 (2019-12-06)
|
||||
|
||||
- Bug fix: fragile sqlite3 install
|
||||
|
||||
# 161 (2019-12-2)
|
||||
## v161 (2019-12-2)
|
||||
|
||||
- Bug fix: Sqlite3 version bump
|
||||
|
||||
# 160 (2019-10-23)
|
||||
## v160 (2019-10-23)
|
||||
|
||||
- Bugfix: Pipenv no longer installs twice in CI
|
||||
|
||||
# 159 (2019-10-22)
|
||||
## v159 (2019-10-22)
|
||||
|
||||
- Python 2.7.17 now available on Heroku 18 and 16.
|
||||
|
||||
# 158 (2019-10-21)
|
||||
## v158 (2019-10-21)
|
||||
|
||||
- Python 3.7.5 and 3.8.0 now available on Heroku 18 and 16.
|
||||
- Add support for Python 3.8 branch
|
||||
@@ -100,11 +152,11 @@
|
||||
- Test Improvements
|
||||
- Add support for staging binary testing
|
||||
|
||||
# 157 (2019-09-18)
|
||||
## v157 (2019-09-18)
|
||||
|
||||
- Typo fixes
|
||||
|
||||
# 156 (2019-09-12)
|
||||
## v156 (2019-09-12)
|
||||
|
||||
- Python 3.6.9 and 3.7.4 now available.
|
||||
|
||||
@@ -112,125 +164,125 @@
|
||||
- Build utility and documentation updates
|
||||
- Bump Hatchet tests to point at new default python version.
|
||||
|
||||
# 155 (2019-08-22)
|
||||
## v155 (2019-08-22)
|
||||
|
||||
add docs and make target for heroku-18 bob builds
|
||||
|
||||
# 154 (2019-07-17)
|
||||
## v154 (2019-07-17)
|
||||
|
||||
Fix python 3.5.7 formula actually building 3.7.2
|
||||
|
||||
# 153 (2019-06-21)
|
||||
## v153 (2019-06-21)
|
||||
|
||||
Hotfix for broken heroku-16 deploys
|
||||
|
||||
# 152 (2019-04-04)
|
||||
## v152 (2019-04-04)
|
||||
|
||||
Python 3.7.3 now available.
|
||||
|
||||
# 151 (2019-03-21)
|
||||
## v151 (2019-03-21)
|
||||
|
||||
Python 3.5.7 and 3.4.10 now available on all Heroku stacks.
|
||||
|
||||
# 150 (2019-03-13)
|
||||
## v150 (2019-03-13)
|
||||
|
||||
Python 2.7.16 now available on all Heroku stacks.
|
||||
|
||||
# 149 (2019-03-04)
|
||||
## v149 (2019-03-04)
|
||||
|
||||
Hotfix for broken Cedar 14 deploys
|
||||
|
||||
# 148 (2019-02-21)
|
||||
## v148 (2019-02-21)
|
||||
|
||||
No user facing changes, improving internal metrics
|
||||
|
||||
# 147 (2019-02-07)
|
||||
## v147 (2019-02-07)
|
||||
|
||||
Python 3.7.2 and 3.6.8 now available on all Heroku stacks.
|
||||
|
||||
# 146 (2018-11-11)
|
||||
## v146 (2018-11-11)
|
||||
|
||||
Python 3.7.1, 3.6.7, 3.5.6 and 3.4.9 now available on all Heroku stacks.
|
||||
|
||||
# 145 (2018-11-08)
|
||||
## v145 (2018-11-08)
|
||||
|
||||
Testing and tooling expanded to better support new runtimes
|
||||
|
||||
# 144 (2018-10-10)
|
||||
## v144 (2018-10-10)
|
||||
|
||||
Switch to cautious upgrade for Pipenv install to ensure the pinned pip version
|
||||
is used with Pipenv
|
||||
|
||||
# 143 (2018-10-09)
|
||||
## v143 (2018-10-09)
|
||||
|
||||
Add support for detecting SLUGIFY_USES_TEXT_UNIDECODE, which is required to
|
||||
Add support for detecting `SLUGIFY_USES_TEXT_UNIDECODE`, which is required to
|
||||
install Apache Airflow version 1.10 or higher.
|
||||
|
||||
# 142 (2018-10-08)
|
||||
## v142 (2018-10-08)
|
||||
|
||||
Improvements to Python install messaging
|
||||
|
||||
# 139, 140, 141
|
||||
## v139, 140, 141
|
||||
|
||||
No user-facing changes, documenting for version clarity
|
||||
|
||||
# 138 (2018-08-01)
|
||||
## v138 (2018-08-01)
|
||||
|
||||
Use stack image SQLite3 instead of vendoring
|
||||
|
||||
# 137 (2018-07-17)
|
||||
## v137 (2018-07-17)
|
||||
|
||||
Prevent 3.7.0 from appearing as unsupported in buildpack messaging.
|
||||
|
||||
# 136 (2018-06-28)
|
||||
## v136 (2018-06-28)
|
||||
|
||||
Upgrade to 3.6.6 and support 3.7.0 on all runtimes.
|
||||
|
||||
# 135 (2018-05-29)
|
||||
## v135 (2018-05-29)
|
||||
|
||||
Upgrade Pipenv to v2018.5.18.
|
||||
|
||||
# 134 (2018-05-02)
|
||||
## v134 (2018-05-02)
|
||||
|
||||
Default to 3.6.5, bugfixes.
|
||||
|
||||
# 133
|
||||
## v133
|
||||
|
||||
Fixes for Pip 10 release.
|
||||
|
||||
# 132
|
||||
## v132
|
||||
|
||||
Improve pip installation, with the release of v9.0.2.
|
||||
|
||||
# 131
|
||||
## v131
|
||||
|
||||
Fix bug with pip.
|
||||
|
||||
# 130
|
||||
## v130
|
||||
|
||||
Better upgrade strategy for pip.
|
||||
|
||||
# 129
|
||||
## v129
|
||||
|
||||
Don't upgrade pip (from v128).
|
||||
|
||||
# 128
|
||||
## v128
|
||||
|
||||
Upgrade pip, pin to Pipenv v11.8.2.
|
||||
|
||||
# 127
|
||||
## v127
|
||||
|
||||
Pin to Pipenv v11.7.1.
|
||||
|
||||
# 126
|
||||
## v126
|
||||
|
||||
Bugfixes.
|
||||
|
||||
# 125
|
||||
## v125
|
||||
|
||||
Bugfixes.
|
||||
|
||||
# 124
|
||||
## v124
|
||||
|
||||
Update buildpack to automatically install `[dev-packages]` during Heroku CI Pipenv builds.
|
||||
|
||||
@@ -239,101 +291,101 @@ Update buildpack to automatically install `[dev-packages]` during Heroku CI Pipe
|
||||
- No longer warn if there is no `Procfile`.
|
||||
- Update Pipenv's "3.6" runtime specifier to point to "3.6.4".
|
||||
|
||||
# 123
|
||||
## v123
|
||||
|
||||
Update gunicorn `init.d` script to allow overrides.
|
||||
|
||||
# 122
|
||||
## v122
|
||||
|
||||
Update default Python to v3.6.4.
|
||||
|
||||
# 121
|
||||
## v121
|
||||
|
||||
Update default Python to v3.6.3.
|
||||
|
||||
# 120
|
||||
## v120
|
||||
|
||||
Use `$ pipenv --deploy`.
|
||||
|
||||
# 119
|
||||
## v119
|
||||
|
||||
Improvements to Pipenv support, warning on unsupported Python versions.
|
||||
|
||||
- We now warn when a user is not using latest 2.x or 3.x Python.
|
||||
- Heroku now supports `[requires]` `python_full_version` in addition to `python_version`.
|
||||
|
||||
# 118
|
||||
## v118
|
||||
|
||||
Improvements to Pipenv support.
|
||||
|
||||
# 117
|
||||
## v117
|
||||
|
||||
Bug fix.
|
||||
|
||||
# 116
|
||||
## v116
|
||||
|
||||
Vendoring improvements.
|
||||
|
||||
- Geos libraries should work on Heroku-16 now.
|
||||
- The libffi/libmemcached vendoring step is now skipped on Heroku-16 (since they are installed in the base image).
|
||||
|
||||
# 115
|
||||
## v115
|
||||
|
||||
Revert a pull request.
|
||||
|
||||
- No longer using `sub_env` for `pip install` step.
|
||||
|
||||
# 114
|
||||
## v114
|
||||
|
||||
- Bugfixes.
|
||||
|
||||
Blacklisting `PYTHONHOME` and `PYTHONPATH` for older apps. Upgrades to nltk support.
|
||||
|
||||
# 113
|
||||
## v113
|
||||
|
||||
Updates to Pipenv support.
|
||||
|
||||
# 112
|
||||
## v112
|
||||
|
||||
Bugfix.
|
||||
|
||||
- Fixed grep output bug.
|
||||
|
||||
# 111
|
||||
## v111
|
||||
|
||||
Linting, bugfixes.
|
||||
|
||||
# 110
|
||||
## v110
|
||||
|
||||
Update default Python to 3.6.2.
|
||||
|
||||
# 109
|
||||
## v109
|
||||
|
||||
Update Default Python to 3.6.1, bugfixes.
|
||||
|
||||
- Fixed automatic pip uninstall of dependencies removed from requirements.txt.
|
||||
|
||||
# 108
|
||||
## v108
|
||||
|
||||
Fix output for collectstatic step.
|
||||
|
||||
# 107
|
||||
## v107
|
||||
|
||||
Bugfix for C dependency installation.
|
||||
|
||||
# 106
|
||||
## v106
|
||||
|
||||
Don't install packages that could mess up packaging.
|
||||
Don't install packages that could mess up packaging.
|
||||
|
||||
- The Python buildpack will automatically remove `six`, `pyparsing`, `appdirs`,
|
||||
`setuptools`, and `distribute` from a `requirements.txt` file now, as these
|
||||
packages are provided by the Python buildpack.
|
||||
|
||||
# 105
|
||||
## v105
|
||||
|
||||
Improvements to output messaging.
|
||||
Improvements to output messaging.
|
||||
|
||||
# 104
|
||||
## v104
|
||||
|
||||
General improvements.
|
||||
|
||||
@@ -343,52 +395,52 @@ General improvements.
|
||||
|
||||
[395]: https://github.com/heroku/heroku-buildpack-python/pull/395
|
||||
|
||||
## 103
|
||||
## v103
|
||||
|
||||
Bug fixes and improvements.
|
||||
|
||||
- Fix for Pipenv.
|
||||
- Fix for Heroku CI.
|
||||
- Improve handling of WEB_CONCURRENCY when using multiple buildpacks.
|
||||
- Adjust environment variables set during the build to more closely match those in the dyno environment (DYNO is now available, STACK is not).
|
||||
- Improve handling of `WEB_CONCURRENCY` when using multiple buildpacks.
|
||||
- Adjust environment variables set during the build to more closely match those in the dyno environment (`DYNO` is now available, `STACK` is not).
|
||||
- Restore the build cache prior to running bin/pre_compile.
|
||||
|
||||
## 102
|
||||
## v102
|
||||
|
||||
Buildpack code cleanup.
|
||||
|
||||
- Improved messaging around NLTK.
|
||||
|
||||
## 101
|
||||
## v101
|
||||
|
||||
Updated setuptools installation method.
|
||||
|
||||
- Improved pipenv support.
|
||||
|
||||
## 100
|
||||
## v100
|
||||
|
||||
Preliminary pipenv support.
|
||||
|
||||
## 99
|
||||
## v99
|
||||
|
||||
Cleanup.
|
||||
|
||||
## 98
|
||||
## v98
|
||||
|
||||
Official NLTK support and other improvements.
|
||||
|
||||
- Support for `nltk.txt` file for declaring corpora to be downloaded.
|
||||
- Leading zeros for auto-set WEB_CONCURRENCY.
|
||||
- Leading zeros for auto-set `WEB_CONCURRENCY`.
|
||||
|
||||
## 97
|
||||
## v97
|
||||
|
||||
Improved egg-link functionality.
|
||||
|
||||
## 96
|
||||
## v96
|
||||
|
||||
Bugfix.
|
||||
|
||||
## 95
|
||||
## v95
|
||||
|
||||
Improved output support.
|
||||
|
||||
@@ -424,7 +476,7 @@ Fixed bug with editable pip installations.
|
||||
|
||||
Updated default Python 2.7.13.
|
||||
|
||||
- Python 2.7.13 uses UCS-4 build, more compatibile with linux wheels.
|
||||
- Python 2.7.13 uses UCS-4 build, more compatible with linux wheels.
|
||||
- Updated setuptools to v32.1.0.
|
||||
|
||||
## v86
|
||||
@@ -450,7 +502,7 @@ Support for Heroku CI.
|
||||
|
||||
## v82 (2016-08-22)
|
||||
|
||||
Update to library detection mechnisms (pip-pop).
|
||||
Update to library detection mechanisms (pip-pop).
|
||||
|
||||
- Updated setuptools to v25.5.0
|
||||
|
||||
@@ -524,7 +576,7 @@ Revert to v66.
|
||||
|
||||
## v68 (2015-10-12)
|
||||
|
||||
Fixed .heroku/venv error with modern apps.
|
||||
Fixed `.heroku/venv` error with modern apps.
|
||||
|
||||
## v67 (2015-10-12)
|
||||
|
||||
@@ -549,7 +601,6 @@ Updated Pip and Setuptools.
|
||||
- Setuptools updated to v18.3.2
|
||||
- Pip updated to v7.1.2
|
||||
|
||||
|
||||
## v62 (2015-08-07)
|
||||
|
||||
Updated Pip and Setuptools.
|
||||
|
||||
+27
-45
@@ -1,68 +1,50 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.0.3.1)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
concurrent-ruby (1.1.6)
|
||||
diff-lcs (1.3)
|
||||
diff-lcs (1.4.4)
|
||||
erubis (2.7.0)
|
||||
excon (0.73.0)
|
||||
heroics (0.0.25)
|
||||
excon (0.78.0)
|
||||
heroics (0.1.1)
|
||||
erubis (~> 2.0)
|
||||
excon
|
||||
moneta
|
||||
multi_json (>= 1.9.2)
|
||||
heroku_hatchet (5.0.3)
|
||||
heroku_hatchet (7.3.3)
|
||||
excon (~> 0)
|
||||
minitest-retry (~> 0.1.9)
|
||||
platform-api (~> 2)
|
||||
repl_runner (~> 0.0.3)
|
||||
platform-api (~> 3)
|
||||
rrrretry (~> 1)
|
||||
thor (~> 0)
|
||||
thor (~> 1)
|
||||
threaded (~> 0)
|
||||
i18n (1.8.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
minitest (5.14.1)
|
||||
minitest-retry (0.1.9)
|
||||
minitest (>= 5.0)
|
||||
moneta (1.0.0)
|
||||
multi_json (1.14.1)
|
||||
parallel (1.19.1)
|
||||
parallel_split_test (0.7.0)
|
||||
multi_json (1.15.0)
|
||||
parallel (1.19.2)
|
||||
parallel_split_test (0.8.0)
|
||||
parallel (>= 0.5.13)
|
||||
rspec (>= 3.1.0)
|
||||
platform-api (2.2.0)
|
||||
heroics (~> 0.0.25)
|
||||
platform-api (3.0.0)
|
||||
heroics (~> 0.1.1)
|
||||
moneta (~> 1.0.0)
|
||||
rake (12.3.3)
|
||||
repl_runner (0.0.3)
|
||||
activesupport
|
||||
rate_throttle_client (~> 0.1.0)
|
||||
rake (13.0.1)
|
||||
rate_throttle_client (0.1.2)
|
||||
rrrretry (1.0.0)
|
||||
rspec (3.8.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-core (3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.1)
|
||||
rspec (3.9.0)
|
||||
rspec-core (~> 3.9.0)
|
||||
rspec-expectations (~> 3.9.0)
|
||||
rspec-mocks (~> 3.9.0)
|
||||
rspec-core (3.9.2)
|
||||
rspec-support (~> 3.9.3)
|
||||
rspec-expectations (3.9.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.0)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-mocks (3.9.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-retry (0.6.1)
|
||||
rspec-support (~> 3.9.0)
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-support (3.8.0)
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
rspec-support (3.9.3)
|
||||
thor (1.0.1)
|
||||
threaded (0.0.4)
|
||||
tzinfo (1.2.7)
|
||||
thread_safe (~> 0.1)
|
||||
zeitwerk (2.3.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
# These targets are not files
|
||||
.PHONY: check test buildenv-heroku-16 buildenv-heroku-18 tools
|
||||
.PHONY: check test builder-image buildenv deploy-runtimes tools
|
||||
|
||||
STACK ?= heroku-18
|
||||
STACKS ?= cedar-14 heroku-16 heroku-18 heroku-20
|
||||
TEST_CMD ?= test/run-versions && test/run-features && test/run-deps
|
||||
ENV_FILE ?= builds/dockerenv.default
|
||||
BUILDER_IMAGE_PREFIX := heroku-python-build
|
||||
|
||||
ifeq ($(STACK),cedar-14)
|
||||
# Cedar-14 doesn't have a build image varient.
|
||||
IMAGE_TAG := heroku/cedar:14
|
||||
STACK_IMAGE_TAG := heroku/cedar:14
|
||||
else
|
||||
# Converts a stack name of `heroku-NN` to its build Docker image tag of `heroku/heroku:NN-build`.
|
||||
IMAGE_TAG := heroku/$(subst -,:,$(STACK))-build
|
||||
STACK_IMAGE_TAG := heroku/$(subst -,:,$(STACK))-build
|
||||
endif
|
||||
|
||||
check:
|
||||
@@ -19,37 +22,42 @@ check:
|
||||
|
||||
test:
|
||||
@echo "Running tests using: STACK=$(STACK) TEST_CMD='$(TEST_CMD)'"
|
||||
@echo ""
|
||||
@docker run --rm -it -v $(PWD):/buildpack:ro -e "STACK=$(STACK)" "$(IMAGE_TAG)" bash -c 'cp -r /buildpack /buildpack_test && cd /buildpack_test && $(TEST_CMD)'
|
||||
@echo ""
|
||||
|
||||
buildenv-heroku-16:
|
||||
@echo "Creating build environment (heroku-16)..."
|
||||
@echo
|
||||
@docker build --pull -f $(shell pwd)/builds/heroku-16.Dockerfile -t python-buildenv-heroku-16 .
|
||||
@docker run --rm -it -v $(PWD):/buildpack:ro -e "STACK=$(STACK)" "$(STACK_IMAGE_TAG)" bash -c 'cp -r /buildpack /buildpack_test && cd /buildpack_test && $(TEST_CMD)'
|
||||
@echo
|
||||
|
||||
builder-image:
|
||||
@echo "Generating binary builder image for $(STACK)..."
|
||||
@echo
|
||||
@docker build --pull -f builds/$(STACK).Dockerfile -t "$(BUILDER_IMAGE_PREFIX)-$(STACK)" .
|
||||
@echo
|
||||
|
||||
buildenv: builder-image
|
||||
@echo "Starting build environment for $(STACK)..."
|
||||
@echo
|
||||
@echo "Usage..."
|
||||
@echo
|
||||
@echo " $$ export AWS_ACCESS_KEY_ID=foo AWS_SECRET_ACCESS_KEY=bar # Optional unless deploying"
|
||||
@echo " $$ bob build runtimes/python-2.7.13"
|
||||
@echo " $$ bob deploy runtimes/python-2.7.13"
|
||||
@echo " $$ bob build runtimes/python-X.Y.Z"
|
||||
@echo
|
||||
@docker run -it --rm python-buildenv-heroku-16
|
||||
@docker run --rm -it --env-file="$(ENV_FILE)" -v $(PWD)/builds:/app/builds "$(BUILDER_IMAGE_PREFIX)-$(STACK)" bash
|
||||
|
||||
buildenv-heroku-18:
|
||||
@echo "Creating build environment (heroku-18)..."
|
||||
deploy-runtimes:
|
||||
ifndef RUNTIMES
|
||||
$(error No runtimes specified! Use: "make deploy-runtimes RUNTIMES='python-X.Y.Z ...' [STACKS='heroku-18 ...'] [ENV_FILE=...]")
|
||||
endif
|
||||
@echo "Using: RUNTIMES='$(RUNTIMES)' STACKS='$(STACKS)' ENV_FILE='$(ENV_FILE)'"
|
||||
@echo
|
||||
@docker build --pull -f $(shell pwd)/builds/heroku-18.Dockerfile -t python-buildenv-heroku-18 .
|
||||
@echo
|
||||
@echo "Usage..."
|
||||
@echo
|
||||
@echo " $$ export AWS_ACCESS_KEY_ID=foo AWS_SECRET_ACCESS_KEY=bar # Optional unless deploying"
|
||||
@echo " $$ bob build runtimes/python-2.7.13"
|
||||
@echo " $$ bob deploy runtimes/python-2.7.13"
|
||||
@echo
|
||||
@docker run -it --rm python-buildenv-heroku-18
|
||||
@set -eu; for stack in $(STACKS); do \
|
||||
$(MAKE) builder-image STACK=$${stack}; \
|
||||
for runtime in $(RUNTIMES); do \
|
||||
echo "Generating/deploying $${runtime} for $${stack}..."; \
|
||||
echo; \
|
||||
docker run --rm -it --env-file="$(ENV_FILE)" "$(BUILDER_IMAGE_PREFIX)-$${stack}" bob deploy "runtimes/$${runtime}"; \
|
||||
echo; \
|
||||
done; \
|
||||
done
|
||||
|
||||
tools:
|
||||
git clone https://github.com/kennethreitz/pip-pop.git
|
||||
mv pip-pop/bin/* vendor/pip-pop/
|
||||
rm -fr pip-pop
|
||||
rm -rf pip-pop
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Heroku Buildpack: Python
|
||||
|
||||
[](https://travis-ci.org/heroku/heroku-buildpack-python)
|
||||
[](https://travis-ci.com/heroku/heroku-buildpack-python)
|
||||
|
||||
This is the official [Heroku buildpack](https://devcenter.heroku.com/articles/buildpacks) for Python apps.
|
||||
|
||||
@@ -16,7 +16,7 @@ See it in Action
|
||||
$ ls
|
||||
my-application requirements.txt runtime.txt
|
||||
|
||||
$ git push heroku master
|
||||
$ git push heroku main
|
||||
Counting objects: 4, done.
|
||||
Delta compression using up to 8 threads.
|
||||
Compressing objects: 100% (2/2), done.
|
||||
@@ -26,7 +26,7 @@ remote: Compressing source files... done.
|
||||
remote: Building source:
|
||||
remote:
|
||||
remote: -----> Python app detected
|
||||
remote: -----> Installing python-3.7.4
|
||||
remote: -----> Installing python
|
||||
remote: -----> Installing pip
|
||||
remote: -----> Installing SQLite3
|
||||
remote: -----> Installing requirements with pip
|
||||
@@ -44,7 +44,7 @@ A `requirements.txt` must be present at the root of your application's repositor
|
||||
|
||||
To specify your python version, you also need a `runtime.txt` file - unless you are using the default Python runtime version.
|
||||
|
||||
Current default Python Runtime: Python 3.6.9
|
||||
Current default Python Runtime: Python 3.6.12
|
||||
|
||||
Alternatively, you can provide a `setup.py` file, or a `Pipfile`.
|
||||
Using `pipenv` will generate `runtime.txt` at build time if one of the field `python_version` or `python_full_version` is specified in the `requires` section of your `Pipfile`.
|
||||
@@ -62,9 +62,10 @@ Specify a Python Runtime
|
||||
|
||||
Supported runtime options include:
|
||||
|
||||
- `python-3.8.5`
|
||||
- `python-3.7.8`
|
||||
- `python-3.6.11`
|
||||
- `python-3.9.0`
|
||||
- `python-3.8.6`
|
||||
- `python-3.7.9`
|
||||
- `python-3.6.12`
|
||||
- `python-2.7.18`
|
||||
|
||||
## Tests
|
||||
|
||||
+28
-17
@@ -15,10 +15,8 @@
|
||||
# Fail fast and fail hard.
|
||||
set -eo pipefail
|
||||
|
||||
# Boostrap the Buildpack Standard Library.
|
||||
# Disable unused env var warning since shellcheck doesn't know about the stdlib.
|
||||
# shellcheck disable=2034
|
||||
BPLOG_PREFIX="buildpack.python"
|
||||
# Used by buildpack-stdlib's metrics features.
|
||||
export BPLOG_PREFIX="buildpack.python"
|
||||
export BUILDPACK_LOG_FILE=${BUILDPACK_LOG_FILE:-/dev/null}
|
||||
|
||||
[ "$BUILDPACK_XTRACE" ] && set -o xtrace
|
||||
@@ -37,23 +35,27 @@ ENV_DIR=$3
|
||||
# Export Path variables, for use in sub-scripts.
|
||||
export BUILD_DIR CACHE_DIR ENV_DIR
|
||||
|
||||
# Set the Buildpack's internet target for downloading Python distributions.
|
||||
# The user can provide BUILDPACK_VENDOR_URL to specify a custom target.
|
||||
# Set the base URL for downloading buildpack assets like Python runtimes.
|
||||
# The user can provide BUILDPACK_S3_BASE_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).
|
||||
VENDOR_URL="https://lang-python.s3.amazonaws.com/$STACK"
|
||||
if [[ -n ${BUILDPACK_VENDOR_URL:-} ]]; then
|
||||
VENDOR_URL="$BUILDPACK_VENDOR_URL"
|
||||
elif [[ -n ${USE_STAGING_BINARIES} ]]; then
|
||||
VENDOR_URL="$USE_STAGING_BINARIES/$STACK"
|
||||
if [[ "${STACK}" == "cedar-14" ]]; then
|
||||
# Since Cedar-14 is EOL on 2020-11-02 it's not worth migrating it to the new bucket.
|
||||
DEFAULT_S3_BASE_URL='https://lang-python.s3.amazonaws.com'
|
||||
else
|
||||
DEFAULT_S3_BASE_URL='https://heroku-buildpack-python.s3.amazonaws.com'
|
||||
fi
|
||||
export VENDOR_URL
|
||||
S3_BASE_URL="${BUILDPACK_S3_BASE_URL:-${DEFAULT_S3_BASE_URL}}"
|
||||
# This has to be exported since it's used by the geo-libs step which is run in a subshell.
|
||||
# TODO: Stop exporting once the geo-libs step is removed or no longer uses `sub_env`.
|
||||
export S3_BASE_URL
|
||||
|
||||
# Default Python Versions
|
||||
# shellcheck source=bin/default_pythons
|
||||
source "$BIN_DIR/default_pythons"
|
||||
|
||||
# Supported Python Branches
|
||||
PY39="python-3.9"
|
||||
PY38="python-3.8"
|
||||
PY37="python-3.7"
|
||||
PY36="python-3.6"
|
||||
@@ -137,6 +139,10 @@ export LIBRARY_PATH=/app/.heroku/vendor/lib:/app/.heroku/python/lib:$LIBRARY_PAT
|
||||
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
|
||||
|
||||
# Global pip options (https://pip.pypa.io/en/stable/user_guide/#environment-variables).
|
||||
# Disable pip's warnings about EOL Python since we show our own.
|
||||
export PIP_NO_PYTHON_VERSION_WARNING=1
|
||||
|
||||
# The Application Code
|
||||
# --------------------
|
||||
|
||||
@@ -185,7 +191,7 @@ source "$BIN_DIR/steps/hooks/pre_compile"
|
||||
# continue to use that version of Python in perpituity (warnings will be raised if
|
||||
# they are out–of–date).
|
||||
if [ -f "$CACHE_DIR/.heroku/python-version" ]; then
|
||||
DEFAULT_PYTHON_VERSION=$(cat "$CACHE_DIR/.heroku/python-version")
|
||||
CACHED_PYTHON_VERSION=$(cat "$CACHE_DIR/.heroku/python-version")
|
||||
fi
|
||||
|
||||
# We didn't always record the stack version. This code is in place because of that.
|
||||
@@ -202,9 +208,14 @@ fi
|
||||
# shellcheck source=bin/steps/pipenv-python-version
|
||||
source "$BIN_DIR/steps/pipenv-python-version"
|
||||
|
||||
# If no runtime was provided by the user, assume the default Python runtime version.
|
||||
if [ ! -f runtime.txt ]; then
|
||||
echo "$DEFAULT_PYTHON_VERSION" > runtime.txt
|
||||
if [[ -f runtime.txt ]]; then
|
||||
mcount "version.reason.python.specified"
|
||||
elif [[ -n "${CACHED_PYTHON_VERSION:-}" ]]; then
|
||||
mcount "version.reason.python.cached"
|
||||
echo "${CACHED_PYTHON_VERSION}" > runtime.txt
|
||||
else
|
||||
mcount "version.reason.python.default"
|
||||
echo "${DEFAULT_PYTHON_VERSION}" > runtime.txt
|
||||
fi
|
||||
|
||||
# Create the directory for .profile.d, if it doesn't exist.
|
||||
@@ -300,7 +311,7 @@ mtime "nltk.download.time" "${start}"
|
||||
# and copying it into the proper place (the logical place to do this was early, but it must be done here).
|
||||
# In CI, $BUILD_DIR is /app.
|
||||
if [[ ! "$BUILD_DIR" == "/app" ]]; then
|
||||
rm -fr "$BUILD_DIR/.heroku/src"
|
||||
rm -rf "$BUILD_DIR/.heroku/src"
|
||||
deep-cp /app/.heroku/src "$BUILD_DIR/.heroku/src"
|
||||
fi
|
||||
|
||||
|
||||
+8
-7
@@ -5,12 +5,13 @@
|
||||
# the env vars to subprocesses.
|
||||
# shellcheck disable=2034
|
||||
|
||||
DEFAULT_PYTHON_VERSION="python-3.6.11"
|
||||
LATEST_38="python-3.8.5"
|
||||
LATEST_37="python-3.7.8"
|
||||
LATEST_36="python-3.6.11"
|
||||
LATEST_35="python-3.5.9"
|
||||
DEFAULT_PYTHON_VERSION="python-3.6.12"
|
||||
LATEST_39="python-3.9.0"
|
||||
LATEST_38="python-3.8.6"
|
||||
LATEST_37="python-3.7.9"
|
||||
LATEST_36="python-3.6.12"
|
||||
LATEST_35="python-3.5.10"
|
||||
LATEST_34="python-3.4.10"
|
||||
LATEST_27="python-2.7.18"
|
||||
PYPY_36="pypy3.6-7.3.1"
|
||||
PYPY_27="pypy2.7-7.3.1"
|
||||
LATEST_PYPY_36="pypy3.6-7.3.2"
|
||||
LATEST_PYPY_27="pypy2.7-7.3.2"
|
||||
|
||||
+5
-2
@@ -10,7 +10,7 @@
|
||||
# This script is invoked by [`bin/compile`](/).
|
||||
|
||||
# The location of the pre-compiled cryptography binary.
|
||||
VENDORED_GDAL="${VENDOR_URL}/libraries/vendor/gdal.tar.gz"
|
||||
VENDORED_GDAL="${S3_BASE_URL}/${STACK}/libraries/vendor/gdal.tar.gz"
|
||||
|
||||
PKG_CONFIG_PATH="/app/.heroku/vendor/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
|
||||
@@ -21,8 +21,11 @@ source "$BIN_DIR/utils"
|
||||
# If GDAL exists within requirements, use vendored gdal.
|
||||
if (pip-grep -s requirements.txt GDAL gdal pygdal &> /dev/null) then
|
||||
|
||||
if [ ! -f ".heroku/vendor/bin/gdalserver" ]; then
|
||||
if [[ ! -f ".heroku/vendor/bin/gdalserver" && "${STACK}" == 'heroku-20' ]]; then
|
||||
puts-warn "The buildpack's built-in GDAL functonality is not supported on Heroku-20."
|
||||
puts-warn "Please use this buildpack instead: https://github.com/heroku/heroku-geo-buildpack"
|
||||
|
||||
elif [[ ! -f ".heroku/vendor/bin/gdalserver" ]]; then
|
||||
puts-warn "The vendored GDAL package in the Heroku Python Buildpack now deprecated."
|
||||
puts-warn "To enable GDAL use an alternative buildpack is available here - https://github.com/heroku/heroku-geo-buildpack"
|
||||
|
||||
|
||||
+8
-5
@@ -10,9 +10,9 @@
|
||||
# This script is invoked by [`bin/compile`](/).
|
||||
|
||||
# The location of the pre-compiled cryptography binary.
|
||||
VENDORED_GDAL="${VENDOR_URL}/libraries/vendor/gdal.tar.gz"
|
||||
VENDORED_GEOS="${VENDOR_URL}/libraries/vendor/geos.tar.gz"
|
||||
VENDORED_PROJ="${VENDOR_URL}/libraries/vendor/proj.tar.gz"
|
||||
VENDORED_GDAL="${S3_BASE_URL}/${STACK}/libraries/vendor/gdal.tar.gz"
|
||||
VENDORED_GEOS="${S3_BASE_URL}/${STACK}/libraries/vendor/geos.tar.gz"
|
||||
VENDORED_PROJ="${S3_BASE_URL}/${STACK}/libraries/vendor/proj.tar.gz"
|
||||
|
||||
PKG_CONFIG_PATH="/app/.heroku/vendor/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
|
||||
@@ -20,8 +20,11 @@ PKG_CONFIG_PATH="/app/.heroku/vendor/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
# shellcheck source=bin/utils
|
||||
source "$BIN_DIR/utils"
|
||||
|
||||
# If GDAL exists within requirements, use vendored gdal.
|
||||
if [[ "$BUILD_WITH_GEO_LIBRARIES" ]]; then
|
||||
if [[ "$BUILD_WITH_GEO_LIBRARIES" && "${STACK}" == 'heroku-20' ]]; then
|
||||
puts-warn "The GDAL, GEOS and PROJ binaries and BUILD_WITH_GEO_LIBRARIES functonality is not supported on Heroku-20."
|
||||
puts-warn "Please use this buildpack for GDAL, GEOS and PROJ: https://github.com/heroku/heroku-geo-buildpack"
|
||||
puts-warn "To hide this message, unset the BUILD_WITH_GEO_LIBRARIES variable using: heroku config:unset BUILD_WITH_GEO_LIBRARIES"
|
||||
elif [[ "$BUILD_WITH_GEO_LIBRARIES" ]]; then
|
||||
mcount "buildvar.BUILD_WITH_GEO_LIBRARIES"
|
||||
|
||||
puts-warn "The GDAL, GEOS and PROJ binaries and BUILD_WITH_GEO_LIBRARIES functonality are now deprecated."
|
||||
|
||||
@@ -16,7 +16,7 @@ if [ ! "$SKIP_PIP_INSTALL" ]; then
|
||||
mcount "failure.bad-requirements"
|
||||
fi
|
||||
|
||||
rm -fr requirements-declared.txt
|
||||
rm -rf requirements-declared.txt
|
||||
|
||||
if [[ -s .heroku/python/requirements-stale.txt ]]; then
|
||||
puts-step "Uninstalling stale dependencies"
|
||||
|
||||
+1
-4
@@ -9,10 +9,7 @@ set -e
|
||||
if [[ -f Pipfile.lock ]]; then
|
||||
if [[ -f .heroku/python/Pipfile.lock.sha256 ]]; then
|
||||
if [[ $(openssl dgst -sha256 Pipfile.lock) == $(cat .heroku/python/Pipfile.lock.sha256) ]]; then
|
||||
# Measure that we're using Pipenv.
|
||||
mcount "tool.pipenv"
|
||||
|
||||
# Don't skip installation of there are git deps.
|
||||
# Don't skip installation if there are git deps.
|
||||
if ! grep -q 'git' Pipfile.lock; then
|
||||
echo "Skipping installation, as Pipfile.lock hasn't changed since last deploy." | indent
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ if [[ -f $BUILD_DIR/Pipfile ]]; then
|
||||
if [ "$PYTHON" = 3.8 ]; then
|
||||
echo "$LATEST_38" > "$BUILD_DIR/runtime.txt"
|
||||
fi
|
||||
if [ "$PYTHON" = 3.9 ]; then
|
||||
echo "$LATEST_39" > "$BUILD_DIR/runtime.txt"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ if [[ "$STACK" != "cedar-14" ]]; then
|
||||
fi
|
||||
|
||||
# The location of the pre-compiled libmemcached binary.
|
||||
VENDORED_MEMCACHED="${VENDOR_URL}/libraries/vendor/libmemcache.tar.gz"
|
||||
VENDORED_MEMCACHED="${S3_BASE_URL}/${STACK}/libraries/vendor/libmemcache.tar.gz"
|
||||
|
||||
# Syntax sugar.
|
||||
# shellcheck source=bin/utils
|
||||
|
||||
+28
-17
@@ -5,9 +5,10 @@ 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"
|
||||
VENDORED_PYTHON="${S3_BASE_URL}/${STACK}/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"
|
||||
|
||||
@@ -15,6 +16,12 @@ PYTHON_2_EOL_UPDATE="Python 2 has reached it's community EOL. Upgrade your Pytho
|
||||
|
||||
# check if runtime exists
|
||||
if curl --output /dev/null --silent --head --fail "$VENDORED_PYTHON"; then
|
||||
if [[ "$PYTHON_VERSION" == $PY39* ]]; then
|
||||
if [ "$PYTHON_VERSION" != "$LATEST_39" ]; then
|
||||
puts-warn "$SECURITY_UPDATE" "$LATEST_39"
|
||||
echo " Learn More: https://devcenter.heroku.com/articles/python-runtimes"
|
||||
fi
|
||||
fi
|
||||
if [[ "$PYTHON_VERSION" == $PY38* ]]; then
|
||||
# do things to alert the user of security release available
|
||||
if [ "$PYTHON_VERSION" != "$LATEST_38" ]; then
|
||||
@@ -51,11 +58,9 @@ if curl --output /dev/null --silent --head --fail "$VENDORED_PYTHON"; then
|
||||
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 [[ "$(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"
|
||||
@@ -63,15 +68,15 @@ if curl --output /dev/null --silent --head --fail "$VENDORED_PYTHON"; then
|
||||
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}?"
|
||||
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" != "$PYPY_36" ]; then
|
||||
puts-warn "Could not find that Pypy version. Did you mean" "${PYPY_36}?"
|
||||
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
|
||||
@@ -81,15 +86,17 @@ else
|
||||
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 -fr .heroku/python-stack .heroku/python-version .heroku/python .heroku/vendor .heroku/python .heroku/python-sqlite3-version
|
||||
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 -fr .heroku/python
|
||||
rm -rf .heroku/python
|
||||
else
|
||||
SKIP_INSTALL=1
|
||||
fi
|
||||
@@ -120,8 +127,6 @@ if [ ! "$SKIP_INSTALL" ]; then
|
||||
# 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"
|
||||
@@ -137,14 +142,20 @@ fi
|
||||
|
||||
set -e
|
||||
|
||||
PIP_VERSION='20.0.2'
|
||||
SETUPTOOLS_VERSION='39.0.1'
|
||||
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+ and wheel 0.34.0+.
|
||||
# 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:
|
||||
@@ -155,7 +166,7 @@ fi
|
||||
# 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_URL="${S3_BASE_URL}/common/${PIP_WHEEL_FILENAME}"
|
||||
PIP_WHEEL="${TMPDIR:-/tmp}/${PIP_WHEEL_FILENAME}"
|
||||
|
||||
if ! curl -sSf "${PIP_WHEEL_URL}" -o "$PIP_WHEEL"; then
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
shopt -s extglob
|
||||
shopt -s nullglob
|
||||
|
||||
# The standard library.
|
||||
if [[ ! -f /tmp/stdlib.sh ]]; then
|
||||
curl --retry 3 -s https://lang-common.s3.amazonaws.com/buildpack-stdlib/v8/stdlib.sh > /tmp/stdlib.sh
|
||||
fi
|
||||
# shellcheck source=/dev/null
|
||||
source /tmp/stdlib.sh
|
||||
# This is necessary since this script is sometimes sourced from
|
||||
# subshells that don't have the variables from bin/compile.
|
||||
# Remove this once we no longer wrap all the things in `sub_env`.
|
||||
BIN_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
ROOT_DIR=$(dirname "${BIN_DIR}")
|
||||
# shellcheck source=vendor/buildpack-stdlib_v8.sh
|
||||
source "${ROOT_DIR}/vendor/buildpack-stdlib_v8.sh"
|
||||
|
||||
if [ "$(uname)" == Darwin ]; then
|
||||
sed() { command sed -l "$@"; }
|
||||
|
||||
+61
-38
@@ -1,57 +1,80 @@
|
||||
# Python Buildpack Binaries
|
||||
|
||||
## Building the Docker Images
|
||||
|
||||
**After every change to your formulae, perform the following** from the root of the Git repository (not from `builds/`) to rebuild the images for each stack:
|
||||
|
||||
$ docker build --pull --tag heroku-python-build-cedar-14 --file $(pwd)/builds/cedar-14.Dockerfile .
|
||||
$ docker build --pull --tag heroku-python-build-heroku-16 --file $(pwd)/builds/heroku-16.Dockerfile .
|
||||
$ docker build --pull --tag heroku-python-build-heroku-18 --file $(pwd)/builds/heroku-18.Dockerfile .
|
||||
|
||||
## Using the Image
|
||||
|
||||
You can e.g. `bash` into each of the images you built using their tag:
|
||||
|
||||
docker run --rm -ti heroku-python-build-cedar-14 bash
|
||||
docker run --rm -ti heroku-python-build-heroku-16 bash
|
||||
docker run --rm -ti heroku-python-build-heroku-18 bash
|
||||
|
||||
You then have a shell where you can run `bob build`, `bob deploy`, and so forth. You can of course also invoke these programs directly with `docker run`:
|
||||
|
||||
docker run --rm -ti heroku-python-build-heroku-18 bob build runtimes/python-2.7.15
|
||||
|
||||
In order to `bob deploy`, AWS credentials must be set up, as well as name and prefix of your custom S3 bucket (unless you're deploying to the Heroku production buckets that are pre-defined in each `Dockerfile`); see next section for details.
|
||||
The binaries for this buildpack are built in Docker containers based on the Heroku stack image.
|
||||
|
||||
## Configuration
|
||||
|
||||
File `dockerenv.default` contains a list of required env vars; most of these have default values defined in `Dockerfile`. You can copy this file to a location outside the buildpack and modify it with the values you desire and pass its location with `--env-file`, or pass the env vars to `docker run` using `--env`.
|
||||
In order to publish binaries AWS credentials must be passed to the build container.
|
||||
If you are testing only the build (ie: `bob build`), these are optional.
|
||||
|
||||
Out of the box, each `Dockerfile` has the correct values predefined for `S3_BUCKET`, `S3_PREFIX`, and `S3_REGION`. If you're building your own packages, you'll likely want to change `S3_BUCKET` and `S3_PREFIX` to match your info. Instead of setting `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` into that file, you may also pass them to `docker run` through the environment, or explicitly using `--env`, in order to prevent accidental commits of credentials.
|
||||
In addition, unless you are building the official binaries for Heroku (which use the defaults
|
||||
specified in each `Dockerfile`), you will need to override `S3_BUCKET` and `S3_PREFIX` to
|
||||
match your own S3 bucket/use case.
|
||||
|
||||
### Passing AWS credentials to the container
|
||||
If you only need to set AWS credentials, you can do so by setting the environment variables
|
||||
`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` before calling the make commands.
|
||||
|
||||
If you want to deploy packages and thus need to pass `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`, you can either pass them explicitly, through your environment, or through an env file.
|
||||
For example:
|
||||
|
||||
#### Passing credentials explicitly
|
||||
```bash
|
||||
set +o history # Disable bash history
|
||||
export AWS_ACCESS_KEY_ID=...
|
||||
export AWS_SECRET_ACCESS_KEY=...
|
||||
set -o history # Re-enable bash history
|
||||
make ...
|
||||
```
|
||||
|
||||
docker run --rm -ti -e AWS_ACCESS_KEY_ID=... -e AWS_SECRET_ACCESS_KEY=... heroku-python-build-heroku-18 bash
|
||||
If you need to override the default S3 bucket, or would prefer not to use credentials via
|
||||
environment variables, then you need to instead use a Docker env file like so:
|
||||
|
||||
#### Passing credentials through the environment
|
||||
1. Copy the `builds/dockerenv.default` env file to a location outside the buildpack repository.
|
||||
2. Edit the new file, adding at a minimum the values for the variables
|
||||
`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` (see Docker
|
||||
[env-file documentation](https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file)).
|
||||
3. Pass the path of the file to the make commands using `ENV_FILE`. For example:
|
||||
|
||||
The two environment variables `AWS_ACCESS_KEY_ID`and `AWS_SECRET_ACCESS_KEY` are defined in `builds/dockerenv.default`, without values. This will cause Docker to "forward" values for these variables from the current environment, so you can pass them in:
|
||||
```bash
|
||||
make ... ENV_FILE=~/.dockerenv.python-buildpack
|
||||
```
|
||||
|
||||
AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... docker run --rm -ti --env-file=builds/dockerenv.default heroku-python-build-heroku-18 bash
|
||||
## Launching an interactive build environment
|
||||
|
||||
or
|
||||
To start an interactive version of the build environment (ideal for development) use the
|
||||
`buildenv` make target, passing in the desired `STACK` name. For example:
|
||||
|
||||
export AWS_ACCESS_KEY_ID=...
|
||||
export AWS_SECRET_ACCESS_KEY=...
|
||||
docker run --rm -ti --env-file=builds/dockerenv.default heroku-python-build-heroku-18 bash
|
||||
```bash
|
||||
make buildenv STACK=heroku-18
|
||||
```
|
||||
|
||||
#### Passing credentials through a separate env file
|
||||
This will create the builder docker image based on the latest image for that stack, and
|
||||
then start a bash shell where you can run `bob build`, `bob deploy`, and so forth.
|
||||
|
||||
This method is the easiest for users who want to build packages in their own S3 bucket, as they will have to adjust the `S3_BUCKET` and `S3_PREFIX` environment variable values anyway from their default values.
|
||||
The `builds/` directory is bind-mounted into the running container, so local build formula
|
||||
changes will appear there immediately without the need to rebuild the image.
|
||||
|
||||
For this method, it is important to keep the credentials file in a location outside the buildpack, so that your credentials aren't accidentally committed. Copy `builds/dockerenv.default` **to a safe location outside the buildpack directory**, and insert your values for `AWS_ACCESS_KEY_ID`and `AWS_SECRET_ACCESS_KEY`.
|
||||
## Bulk deploying runtimes
|
||||
|
||||
docker run --rm -ti --env-file=../SOMEPATHOUTSIDE/s3.env heroku-python-build-heroku-18 bash
|
||||
When a new Python version is released, binaries have to be generated for multiple stacks.
|
||||
To automate this, use the `deploy-runtimes` make target, which will ensure the builder
|
||||
image is up to date, and then run `bob deploy` for each runtime-stack combination.
|
||||
|
||||
The build formula name(s) are passed using `RUNTIMES`, like so:
|
||||
|
||||
```bash
|
||||
make deploy-runtimes RUNTIMES='python-X.Y.Z'
|
||||
```
|
||||
|
||||
By default this will deploy to all supported stacks (see `STACKS` in `Makefile`),
|
||||
but this can be overridden using `STACKS`:
|
||||
|
||||
```bash
|
||||
make deploy-runtimes RUNTIMES='python-X.Y.Z' STACKS='heroku-16 heroku-18'
|
||||
```
|
||||
|
||||
Multiple runtimes can also be specified (useful for when adding a new stack), like so:
|
||||
|
||||
```bash
|
||||
make deploy-runtimes RUNTIMES='python-A.B.C python-X.Y.Z' STACKS='heroku-20'
|
||||
```
|
||||
|
||||
Note: Both `RUNTIMES` and `STACKS` are space delimited.
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
FROM heroku/cedar:14
|
||||
|
||||
WORKDIR /app
|
||||
ENV WORKSPACE_DIR="/app/builds" \
|
||||
S3_BUCKET="lang-python" \
|
||||
S3_PREFIX="cedar-14/" \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
STACK="cedar-14"
|
||||
|
||||
RUN apt-get update && apt-get install -y python-pip libsqlite3-dev realpath && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
|
||||
libsqlite3-dev \
|
||||
python3-pip \
|
||||
realpath \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt /app/
|
||||
RUN pip install -r /app/requirements.txt
|
||||
# Can't use `--disable-pip-version-check --no-cache-dir` since not supported by Ubuntu 14.04's pip.
|
||||
RUN pip3 install -r /app/requirements.txt
|
||||
|
||||
COPY . /app
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Since no values are specified here, these variables will be read from the environment at run time:
|
||||
# https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file
|
||||
AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY
|
||||
S3_BUCKET
|
||||
S3_PREFIX
|
||||
S3_REGION
|
||||
|
||||
# Uncomment these if you need to override the default S3 bucket and/or path prefixes.
|
||||
# S3_BUCKET
|
||||
# S3_PREFIX
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
FROM heroku/heroku:16-build
|
||||
|
||||
WORKDIR /app
|
||||
ENV WORKSPACE_DIR="/app/builds" \
|
||||
S3_BUCKET="lang-python" \
|
||||
S3_BUCKET="heroku-buildpack-python" \
|
||||
S3_PREFIX="heroku-16/" \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
STACK="heroku-16"
|
||||
|
||||
RUN apt-get update && apt-get install -y python-pip libsqlite3-dev && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
|
||||
libsqlite3-dev \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt /app/
|
||||
RUN pip install --disable-pip-version-check --no-cache-dir -r /app/requirements.txt
|
||||
RUN pip3 install --disable-pip-version-check --no-cache-dir -r /app/requirements.txt
|
||||
|
||||
COPY . /app
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
FROM heroku/heroku:18-build
|
||||
|
||||
WORKDIR /app
|
||||
ENV WORKSPACE_DIR="/app/builds" \
|
||||
S3_BUCKET="lang-python" \
|
||||
S3_BUCKET="heroku-buildpack-python" \
|
||||
S3_PREFIX="heroku-18/" \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
STACK="heroku-18"
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y python-pip-whl=9.0.1-2 python-pip=9.0.1-2 python-setuptools python-wheel libsqlite3-dev && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
|
||||
libsqlite3-dev \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt /app/
|
||||
RUN pip install --disable-pip-version-check --no-cache-dir -r /app/requirements.txt
|
||||
RUN pip3 install --disable-pip-version-check --no-cache-dir -r /app/requirements.txt
|
||||
|
||||
COPY . /app
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
FROM heroku/heroku:20-build
|
||||
|
||||
ENV WORKSPACE_DIR="/app/builds" \
|
||||
S3_BUCKET="heroku-buildpack-python" \
|
||||
S3_PREFIX="heroku-20/" \
|
||||
STACK="heroku-20"
|
||||
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
|
||||
libsqlite3-dev \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt /app/
|
||||
RUN pip3 install --disable-pip-version-check --no-cache-dir -r /app/requirements.txt
|
||||
|
||||
COPY . /app
|
||||
@@ -19,4 +19,4 @@ make install
|
||||
|
||||
# Cleanup
|
||||
cd ..
|
||||
rm -fr sqlite
|
||||
rm -rf sqlite
|
||||
|
||||
@@ -13,11 +13,11 @@ dep_version=${dep_formula##*"/${dep_name}-"} # "subtract" our name from full ver
|
||||
dep_package=${dep_name}-v${dep_version} # it's always "pypy2-…"
|
||||
dep_dirname=${dep_package}-linux64
|
||||
dep_archive_name=${dep_dirname}.tar.bz2
|
||||
dep_url=https://bitbucket.org/pypy/pypy/downloads/${dep_archive_name}
|
||||
dep_url="https://downloads.python.org/pypy/${dep_archive_name}"
|
||||
|
||||
echo "Building PyPy…"
|
||||
echo "${dep_url}"
|
||||
|
||||
curl -L "${dep_url}" | tar jx -C "${OUT_PREFIX}" --strip-components 1 # extract to $OUT_PREFIX, drop the first directory level, which is the archive name
|
||||
curl -fL "${dep_url}" | tar jx -C "${OUT_PREFIX}" --strip-components 1 # extract to $OUT_PREFIX, drop the first directory level, which is the archive name
|
||||
|
||||
ln "$OUT_PREFIX/bin/pypy" "$OUT_PREFIX/bin/python"
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
source $(dirname $0)/pypy2.7
|
||||
@@ -13,11 +13,11 @@ dep_version=${dep_formula##*"/${dep_name}-"} # "subtract" our name from full ver
|
||||
dep_package=${dep_name}${dep_version_prefix:-}-v${dep_version}${dep_version_suffix:-}
|
||||
dep_dirname=${dep_package}-linux64
|
||||
dep_archive_name=${dep_dirname}.tar.bz2
|
||||
dep_url=https://bitbucket.org/pypy/pypy/downloads/${dep_archive_name}
|
||||
dep_url="https://downloads.python.org/pypy/${dep_archive_name}"
|
||||
|
||||
echo "Building PyPy3…"
|
||||
echo "${dep_url}"
|
||||
|
||||
curl -L "${dep_url}" | tar jx -C "${OUT_PREFIX}" --strip-components 1 # extract to $OUT_PREFIX, drop the first directory level, which is the archive name
|
||||
curl -fL "${dep_url}" | tar jx -C "${OUT_PREFIX}" --strip-components 1 # extract to $OUT_PREFIX, drop the first directory level, which is the archive name
|
||||
|
||||
ln "$OUT_PREFIX/bin/pypy3" "$OUT_PREFIX/bin/python"
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
source $(dirname $0)/pypy3.6
|
||||
@@ -1,27 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
OUT_PREFIX=$1
|
||||
BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
|
||||
export BIN_DIR
|
||||
|
||||
# shellcheck source=bin/utils
|
||||
source "$BIN_DIR/steps/sqlite3"
|
||||
|
||||
sqlite3_version
|
||||
echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
|
||||
sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
|
||||
|
||||
echo "Building Python…"
|
||||
SOURCE_TARBALL='https://python.org/ftp/python/2.7.17/Python-2.7.17.tgz'
|
||||
curl -L $SOURCE_TARBALL | tar xz
|
||||
mv Python-2.7.17 src
|
||||
cd src
|
||||
|
||||
./configure --prefix=$OUT_PREFIX --enable-unicode=ucs4 --with-ensurepip=no
|
||||
make
|
||||
make install
|
||||
|
||||
# Remove unneeded test directories, similar to the official Docker Python images:
|
||||
# https://github.com/docker-library/python
|
||||
find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' +
|
||||
source $(dirname $0)/python2
|
||||
|
||||
@@ -1,27 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
OUT_PREFIX=$1
|
||||
BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
|
||||
export BIN_DIR
|
||||
|
||||
# shellcheck source=bin/utils
|
||||
source "$BIN_DIR/steps/sqlite3"
|
||||
|
||||
sqlite3_version
|
||||
echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
|
||||
sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
|
||||
|
||||
echo "Building Python…"
|
||||
SOURCE_TARBALL='https://python.org/ftp/python/2.7.18/Python-2.7.18.tgz'
|
||||
curl -L $SOURCE_TARBALL | tar xz
|
||||
mv Python-2.7.18 src
|
||||
cd src
|
||||
|
||||
./configure --prefix=$OUT_PREFIX --enable-unicode=ucs4 --with-ensurepip=no
|
||||
make
|
||||
make install
|
||||
|
||||
# Remove unneeded test directories, similar to the official Docker Python images:
|
||||
# https://github.com/docker-library/python
|
||||
find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' +
|
||||
source $(dirname $0)/python2
|
||||
|
||||
@@ -1,32 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
OUT_PREFIX=$1
|
||||
BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
|
||||
export BIN_DIR
|
||||
|
||||
# shellcheck source=bin/utils
|
||||
source "$BIN_DIR/steps/sqlite3"
|
||||
|
||||
sqlite3_version
|
||||
echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
|
||||
sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
|
||||
|
||||
echo "Building Python…"
|
||||
SOURCE_TARBALL='https://python.org/ftp/python/3.7.2/Python-3.7.2.tgz'
|
||||
curl -L $SOURCE_TARBALL | tar xz
|
||||
mv Python-3.7.2 src
|
||||
cd src
|
||||
|
||||
./configure --prefix=$OUT_PREFIX --with-ensurepip=no
|
||||
make
|
||||
make install
|
||||
|
||||
# Remove unneeded test directories, similar to the official Docker Python images:
|
||||
# https://github.com/docker-library/python
|
||||
find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' +
|
||||
|
||||
# Remove spare /
|
||||
LOCATION=${OUT_PREFIX%?}
|
||||
|
||||
ln $LOCATION/bin/python3 $LOCATION/bin/python
|
||||
source $(dirname $0)/python3
|
||||
|
||||
@@ -1,32 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
OUT_PREFIX=$1
|
||||
BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
|
||||
export BIN_DIR
|
||||
|
||||
# shellcheck source=bin/utils
|
||||
source "$BIN_DIR/steps/sqlite3"
|
||||
|
||||
sqlite3_version
|
||||
echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
|
||||
sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
|
||||
|
||||
echo "Building Python…"
|
||||
SOURCE_TARBALL='https://python.org/ftp/python/3.4.9/Python-3.4.9.tgz'
|
||||
curl -L $SOURCE_TARBALL | tar xz
|
||||
mv Python-3.4.9 src
|
||||
cd src
|
||||
|
||||
./configure --prefix=$OUT_PREFIX --with-ensurepip=no
|
||||
make
|
||||
make install
|
||||
|
||||
# Remove unneeded test directories, similar to the official Docker Python images:
|
||||
# https://github.com/docker-library/python
|
||||
find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' +
|
||||
|
||||
# Remove spare /
|
||||
LOCATION=${OUT_PREFIX%?}
|
||||
|
||||
ln $LOCATION/bin/python3 $LOCATION/bin/python
|
||||
source $(dirname $0)/python3
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
source $(dirname $0)/python3
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
source $(dirname $0)/python3
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
source $(dirname $0)/python3
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
source $(dirname $0)/python3
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build Path: /app/.heroku/python/
|
||||
|
||||
source $(dirname $0)/python3
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get install software-properties-common
|
||||
curl --fail --retry 3 --retry-delay 1 --connect-timeout 3 --max-time 30 https://cli-assets.heroku.com/install-ubuntu.sh | sh
|
||||
Regular → Executable
+4
-4
@@ -14,9 +14,9 @@ case "$choice" in
|
||||
* ) exit 1;;
|
||||
esac
|
||||
|
||||
originMaster=$(git rev-parse origin/master)
|
||||
echo "Tagging commit $originMaster with $newVersion... "
|
||||
git tag "$newVersion" "${originMaster:?}"
|
||||
originMain=$(git rev-parse origin/main)
|
||||
echo "Tagging commit $originMain with $newVersion... "
|
||||
git tag "$newVersion" "${originMain:?}"
|
||||
git push origin refs/tags/$newVersion
|
||||
|
||||
heroku buildpacks:publish "$BP_NAME" "$newVersion"
|
||||
@@ -31,7 +31,7 @@ if [ $(git tag | grep -q latest-version) ]; then
|
||||
echo "Updating latest-version tag"
|
||||
git tag -d latest-version
|
||||
git push origin :latest-version
|
||||
git tag latest-version "${originMaster:?}"
|
||||
git tag latest-version "${originMain:?}"
|
||||
git push --tags
|
||||
fi
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- - "./repos/python/python-getting-started"
|
||||
- master
|
||||
- main
|
||||
- - "./repos/python/python_default"
|
||||
- ca947f69027b2a30be5d26f9a42f25e54f4d7a1a
|
||||
|
||||
+5
-2
@@ -1,3 +1,6 @@
|
||||
# Dependencies for generating/publishing Python binaries.
|
||||
bob-builder==0.0.19
|
||||
|
||||
# Sub-dependencies of bob-builder.
|
||||
boto==2.49.0
|
||||
docopt==0.6.2
|
||||
bob-builder==0.0.17
|
||||
boto==2.48.0
|
||||
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
python-3.6.6
|
||||
+1
-1
@@ -6,4 +6,4 @@ verify_ssl = true
|
||||
requests = "*"
|
||||
|
||||
[requires]
|
||||
python_full_version = "3.6.3"
|
||||
python_full_version = "3.7.8"
|
||||
|
||||
+2
-15
@@ -1,24 +1,11 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "22a052f4d1cfe6518b2f236fe45c3208c587a9ab1323bdd390632e27278b541e"
|
||||
},
|
||||
"host-environment-markers": {
|
||||
"implementation_name": "cpython",
|
||||
"implementation_version": "3.6.3",
|
||||
"os_name": "posix",
|
||||
"platform_machine": "x86_64",
|
||||
"platform_python_implementation": "CPython",
|
||||
"platform_release": "16.7.0",
|
||||
"platform_system": "Darwin",
|
||||
"platform_version": "Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64",
|
||||
"python_full_version": "3.6.3",
|
||||
"python_version": "3.6",
|
||||
"sys_platform": "darwin"
|
||||
"sha256": "8a36860f0f9cb55716222098062cea5c5e0f8127cafb9d0c694de327bac9fbc0"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_full_version": "3.6.3"
|
||||
"python_full_version": "3.7.8"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
pypy2.7-7.2.0
|
||||
pypy2.7-7.3.2
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
pypy2.7-7.3.1
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
pypy3.6-7.2.0
|
||||
pypy3.6-7.3.2
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
pypy3.6-7.3.1
|
||||
-1
@@ -1 +0,0 @@
|
||||
requests
|
||||
-1
@@ -1 +0,0 @@
|
||||
python-2.7.99
|
||||
-1
@@ -1 +0,0 @@
|
||||
requests
|
||||
@@ -1 +0,0 @@
|
||||
flask
|
||||
-1
@@ -1 +0,0 @@
|
||||
python-3.4.99
|
||||
@@ -1 +0,0 @@
|
||||
flask
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
python-3.5.9
|
||||
python-3.5.10
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
flask
|
||||
-1
@@ -1 +0,0 @@
|
||||
python-3.5.99
|
||||
@@ -1 +0,0 @@
|
||||
flask
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
python-3.6.8
|
||||
python-3.6.12
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
flask
|
||||
-1
@@ -1 +0,0 @@
|
||||
python-3.6.99
|
||||
@@ -1 +0,0 @@
|
||||
requests
|
||||
+1
-1
@@ -1 +1 @@
|
||||
python-3.6.7
|
||||
python-3.6.11
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
python-3.7.2
|
||||
python-3.7.9
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
flask
|
||||
-1
@@ -1 +0,0 @@
|
||||
python-3.7.99
|
||||
@@ -1 +0,0 @@
|
||||
requests
|
||||
+1
-1
@@ -1 +1 @@
|
||||
python-3.7.1
|
||||
python-3.7.8
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
python-3.8.2
|
||||
python-3.8.6
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
flask
|
||||
@@ -1 +0,0 @@
|
||||
requests
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
python-3.8.0
|
||||
python-3.8.5
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
python-3.9.0
|
||||
+1
@@ -0,0 +1 @@
|
||||
python-3.9.0
|
||||
@@ -1 +0,0 @@
|
||||
flask
|
||||
Vendored
+15
-17
@@ -21,16 +21,13 @@ testGEOS() {
|
||||
local env_dir="$(mktmpdir)"
|
||||
echo '1' > "${env_dir}/BUILD_WITH_GEO_LIBRARIES"
|
||||
compile 'geos' '' "${env_dir}"
|
||||
assertCaptured "geos"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testGEOSDeprecation() {
|
||||
local env_dir="$(mktmpdir)"
|
||||
echo '1' > "${env_dir}/BUILD_WITH_GEO_LIBRARIES"
|
||||
compile 'geos' '' "${env_dir}"
|
||||
assertCaptured " ! The GDAL, GEOS and PROJ binaries and BUILD_WITH_GEO_LIBRARIES functonality are now deprecated.
|
||||
! An alternative buildpack to enable GDAL, GEOS and PROJ use is available here - https://github.com/heroku/heroku-geo-buildpack"
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
assertCaptured " ! The GDAL, GEOS and PROJ binaries and BUILD_WITH_GEO_LIBRARIES functonality is not supported on Heroku-20."
|
||||
else
|
||||
assertCaptured " ! The GDAL, GEOS and PROJ binaries and BUILD_WITH_GEO_LIBRARIES functonality are now deprecated."
|
||||
fi
|
||||
# This should assertCapturedError on Heroku-20, but the test doesn't actually
|
||||
# install anything that uses GEOS so succeeds (see W-8145375)
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
@@ -43,7 +40,9 @@ testNLTK() {
|
||||
echo 'ignore::RuntimeWarning' > "${env_dir}/PYTHONWARNINGS"
|
||||
compile 'nltk' '' "${env_dir}"
|
||||
assertCaptured "[nltk_data] Downloading package city_database" "STD_ERR"
|
||||
assertCapturedSuccess
|
||||
# Can't use `assertCapturedSuccess` since the NLTK downloader outputs all
|
||||
# progress/status messages to stderr (W-8146040).
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
|
||||
testPsycopg2() {
|
||||
@@ -53,17 +52,16 @@ testPsycopg2() {
|
||||
}
|
||||
|
||||
testPysqlite() {
|
||||
# pysqlite does not support Python 3 (since the sqlite3 stdlib can be used there),
|
||||
# so we have to test with Python 2, which we've not made available for Heroku-20.
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "pysqlite"
|
||||
assertCaptured "pysqlite"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testSqliteInstall() {
|
||||
compile "pythonDefault"
|
||||
assertNotCaptured "Sqlite3 failed to install."
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testCffi() {
|
||||
compile "cffi"
|
||||
assertCaptured "cffi"
|
||||
|
||||
+37
-14
@@ -33,7 +33,9 @@ testStackChange() {
|
||||
testSetupPy() {
|
||||
compile "setup-py"
|
||||
assertCaptured "maya"
|
||||
assertCapturedSuccess
|
||||
# Can't use `assertCapturedSuccess` since stderr contains:
|
||||
# "cp: cannot stat '/tmp/build_*/requirements.txt': No such file or directory" (W-7924941)
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
|
||||
testStandardRequirements() {
|
||||
@@ -44,30 +46,49 @@ testStandardRequirements() {
|
||||
|
||||
testPipenv() {
|
||||
compile "pipenv"
|
||||
assertCaptured "Installing pip 9.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCapturedSuccess
|
||||
assertCaptured "Installing pip 9.0.2, setuptools 47.1.1 and wheel 0.34.2"
|
||||
# Can't use `assertCapturedSuccess` since stderr contains:
|
||||
# "cp: cannot stat '/tmp/build_*/requirements.txt': No such file or directory" (W-7924941)
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
|
||||
testPipenvLock() {
|
||||
compile "pipenv-lock"
|
||||
assertCapturedSuccess
|
||||
# Can't use `assertCapturedSuccess` since stderr contains:
|
||||
# "cp: cannot stat '/tmp/build_*/requirements.txt': No such file or directory" (W-7924941)
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
|
||||
testPipenvVersion() {
|
||||
testPipenvPythonVersion3_6() {
|
||||
compile "pipenv-version"
|
||||
assertCaptured $DEFAULT_PYTHON_VERSION
|
||||
assertCapturedSuccess
|
||||
assertCaptured "Installing ${LATEST_36}"
|
||||
# Can't use `assertCapturedSuccess` since stderr contains:
|
||||
# "cp: cannot stat '/tmp/build_*/requirements.txt': No such file or directory" (W-7924941)
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
|
||||
testPipenvVersion2() {
|
||||
testPipenvPythonVersion2_7() {
|
||||
# Python 2.7 is EOL, so it has not been built for Heroku-20.
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "pipenv-version2"
|
||||
assertCaptured $LATEST_27
|
||||
assertCapturedSuccess
|
||||
assertCaptured "Installing ${LATEST_27}"
|
||||
# Can't use `assertCapturedSuccess` since stderr contains:
|
||||
# "cp: cannot stat '/tmp/build_*/requirements.txt': No such file or directory" (W-7924941)
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
testPipenvFullVersion() {
|
||||
|
||||
testPipenvPythonFullVersion() {
|
||||
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
||||
if [[ "${STACK}" = "cedar-14" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "pipenv-full-version"
|
||||
assertCaptured "3.6.3"
|
||||
assertCapturedSuccess
|
||||
assertCaptured "3.7.8"
|
||||
# Can't use `assertCapturedSuccess` since stderr contains:
|
||||
# "cp: cannot stat '/tmp/build_*/requirements.txt': No such file or directory" (W-7924941)
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
|
||||
testNoRequirements() {
|
||||
@@ -95,6 +116,7 @@ testHooks() {
|
||||
local expected_env_vars=(
|
||||
_
|
||||
BIN_DIR
|
||||
BPLOG_PREFIX
|
||||
BUILD_DIR
|
||||
BUILDPACK_LOG_FILE
|
||||
CACHE_DIR
|
||||
@@ -108,14 +130,15 @@ testHooks() {
|
||||
LIBRARY_PATH
|
||||
OLDPWD
|
||||
PATH
|
||||
PIP_NO_PYTHON_VERSION_WARNING
|
||||
PKG_CONFIG_PATH
|
||||
PROFILE_PATH
|
||||
PWD
|
||||
PYTHONUNBUFFERED
|
||||
S3_BASE_URL
|
||||
SHLVL
|
||||
SOME_APP_CONFIG_VAR
|
||||
STACK
|
||||
VENDOR_URL
|
||||
)
|
||||
if [[ "${STACK}" == "cedar-14" || "${STACK}" == "heroku-16" ]]; then
|
||||
# Remove "OLDPWD" from expected_env_vars since for bash <4.4 it's not exported to subshells:
|
||||
|
||||
+186
-151
@@ -4,219 +4,254 @@
|
||||
# shellcheck source=bin/default_pythons
|
||||
source "bin/default_pythons"
|
||||
|
||||
testPythonDefault() {
|
||||
updateVersion "pythonDefault" $DEFAULT_PYTHON_VERSION
|
||||
compile "pythonDefault"
|
||||
assertCaptured $DEFAULT_PYTHON_VERSION
|
||||
testPythonVersionUnspecified() {
|
||||
compile "python_version_unspecified"
|
||||
assertCaptured "Installing ${DEFAULT_PYTHON_VERSION}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython2() {
|
||||
updateVersion "python2" $LATEST_27
|
||||
echo $LATEST_27 > "runtime.txt"
|
||||
compile "python2"
|
||||
assertCaptured $LATEST_27
|
||||
if [[ $(date "+%Y") > "2019" ]]; then
|
||||
assertCaptured "python-2-7-eol-faq";
|
||||
else
|
||||
assertNotCaptured "python-2-7-eol-faq";
|
||||
fi
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
testPython2_7() {
|
||||
# Python 2.7 is EOL, so it has not been built for Heroku-20.
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python2"
|
||||
assertCaptured "Installing ${LATEST_27}"
|
||||
assertCaptured "python-2-7-eol-faq";
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 44.1.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython2_warn() {
|
||||
compile "python2_warn"
|
||||
assertCaptured "python-2.7.15"
|
||||
if [[ $(date "+%Y") > "2019" ]]; then
|
||||
assertCaptured "python-2-7-eol-faq";
|
||||
else
|
||||
assertNotCaptured "python-2-7-eol-faq";
|
||||
fi
|
||||
assertCaptured "Only the latest version"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython2_fail() {
|
||||
compile "python2_fail"
|
||||
assertCaptured "Aborting"
|
||||
assertCapturedError
|
||||
testPython2_7_warn() {
|
||||
# Python 2.7 is EOL, so it has not been built for Heroku-20.
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python2_warn"
|
||||
assertCaptured "Installing python-2.7.15"
|
||||
assertCaptured "python-2-7-eol-faq";
|
||||
assertCaptured "Only the latest version"
|
||||
assertCaptured "${LATEST_27}"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_4() {
|
||||
compile "python3_4"
|
||||
assertCaptured $LATEST_34
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 19.1.1, setuptools 39.0.1 and wheel 0.33.6"
|
||||
# if cedar 14 and legacy binaries, fail. if cedar 14 and staging, succeed.
|
||||
if [[ ! -n $USE_STAGING_BINARIES ]] && [[ $STACK == "cedar-14" ]]; then
|
||||
assertCapturedError
|
||||
# if heroku 18 and legacy binaries, succeed. if heroku 18 and staging, fail.
|
||||
elif [[ -n $USE_STAGING_BINARIES ]] && [[ $STACK == "heroku-18" ]]; then
|
||||
assertCapturedError
|
||||
else
|
||||
# all else succeed
|
||||
assertCapturedSuccess
|
||||
# Python 3.4 is EOL, so it has not been built for Heroku-20.
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_4"
|
||||
assertCaptured "Installing ${LATEST_34}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 19.1.1, setuptools 43.0.0 and wheel 0.33.6"
|
||||
assertCaptured "Installing SQLite3"
|
||||
# Can't use `assertCapturedSuccess` since Pip outputs a Python 3.4 EOL warning to stderr,
|
||||
# and the newest Pip that works on Python 3.4 doesn't support `PIP_NO_PYTHON_VERSION_WARNING`.
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
|
||||
testPython3_4_warn() {
|
||||
compile "python3_4_warn"
|
||||
assertCaptured "python-3.4.9"
|
||||
assertCaptured "security update!"
|
||||
# if heroku 18 and legacy binaries, succeed. if heroku 18 and staging, fail.
|
||||
if [[ -n $USE_STAGING_BINARIES ]] && [[ $STACK == "heroku-18" ]]; then
|
||||
assertCapturedError
|
||||
else
|
||||
# all else succeed
|
||||
assertCapturedSuccess
|
||||
# Python 3.4 is EOL, so it has not been built for Heroku-20.
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
testPython3_4_fail() {
|
||||
compile "python3_4_fail"
|
||||
assertCaptured "Aborting"
|
||||
assertCapturedError
|
||||
compile "python3_4_warn"
|
||||
assertCaptured "Installing python-3.4.9"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "${LATEST_34}"
|
||||
# Can't use `assertCapturedSuccess` since Pip outputs a Python 3.4 EOL warning to stderr,
|
||||
# and the newest Pip that works on Python 3.4 doesn't support `PIP_NO_PYTHON_VERSION_WARNING`.
|
||||
assertCapturedSuccessWithStdErr
|
||||
}
|
||||
|
||||
testPython3_5() {
|
||||
# Python 3.5 is EOL, so it has not been built for Heroku-20.
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_5"
|
||||
assertCaptured $LATEST_35
|
||||
assertCaptured "Installing ${LATEST_35}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_5_warn() {
|
||||
# Python 3.5 is EOL, so it has not been built for Heroku-20.
|
||||
if [[ $STACK == "heroku-20" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_5_warn"
|
||||
assertCaptured "python-3.5.6"
|
||||
assertCaptured "Installing python-3.5.6"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "${LATEST_35}"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_5_fail() {
|
||||
compile "python3_5_fail"
|
||||
assertCaptured "Aborting"
|
||||
assertCapturedError
|
||||
}
|
||||
|
||||
testPython3_6() {
|
||||
updateVersion "python3_6" $LATEST_36
|
||||
compile "python3_6"
|
||||
assertCaptured $LATEST_36
|
||||
assertCaptured "Installing ${LATEST_36}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_6_warn() {
|
||||
compile "python3_6_warn"
|
||||
assertCaptured "python-3.6.7"
|
||||
assertCaptured "Installing python-3.6.11"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "${LATEST_36}"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_7() {
|
||||
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
||||
if [[ "${STACK}" = "cedar-14" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_7"
|
||||
assertCaptured "Installing ${LATEST_37}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_6_fail() {
|
||||
compile "python3_6_fail"
|
||||
assertCaptured "Aborting"
|
||||
assertCapturedError
|
||||
}
|
||||
|
||||
testPython3_7() {
|
||||
updateVersion "python3_7" $LATEST_37
|
||||
compile "python3_7"
|
||||
if [[ $STACK = "cedar-14" ]]; then
|
||||
assertCapturedError
|
||||
else
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured $LATEST_37
|
||||
assertCaptured "Installing pip 20.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
fi
|
||||
}
|
||||
|
||||
testPython3_7_warn() {
|
||||
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
||||
if [[ "${STACK}" = "cedar-14" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_7_warn"
|
||||
if [[ $STACK = "cedar-14" ]]; then
|
||||
assertCapturedError
|
||||
else
|
||||
assertCaptured "python-3.7.1"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
fi
|
||||
}
|
||||
|
||||
testPython3_7_fail() {
|
||||
compile "python3_7_fail"
|
||||
assertCaptured "Aborting"
|
||||
assertCapturedError
|
||||
}
|
||||
|
||||
testPython3_7_warn() {
|
||||
compile "python3_8_warn"
|
||||
if [[ $STACK = "cedar-14" ]]; then
|
||||
assertCapturedError
|
||||
else
|
||||
assertCaptured "python-3.8.0"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
fi
|
||||
assertCaptured "Installing python-3.7.8"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "${LATEST_37}"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_8() {
|
||||
updateVersion "python3_8" $LATEST_38
|
||||
compile "python3_8"
|
||||
if [[ $STACK = "cedar-14" ]]; then
|
||||
assertCapturedError
|
||||
else
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured $LATEST_38
|
||||
assertCaptured "Installing pip 20.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
||||
if [[ "${STACK}" = "cedar-14" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_8"
|
||||
assertCaptured "Installing ${LATEST_38}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_8_fail() {
|
||||
compile "python3_8_fail"
|
||||
testPython3_8_warn() {
|
||||
# Python 3.7+ requires newer libssl than is present on Cedar-14.
|
||||
if [[ "${STACK}" = "cedar-14" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_8_warn"
|
||||
assertCaptured "Installing python-3.8.5"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "${LATEST_38}"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_9() {
|
||||
# Cedar-14 is EOL, so we're not building new major Python versions for it.
|
||||
if [[ "${STACK}" = "cedar-14" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_9"
|
||||
assertCaptured "Installing ${LATEST_39}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
||||
assertCaptured "Installing SQLite3"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPython3_9_warn() {
|
||||
# Cedar-14 is EOL, so we're not building new major Python versions for it.
|
||||
if [[ "${STACK}" = "cedar-14" ]]; then
|
||||
return
|
||||
fi
|
||||
# Can't test the version warning until there is at least one old version of Python 3.9.
|
||||
if [[ "${LATEST_39}" = "python-3.9.0" ]]; then
|
||||
return
|
||||
fi
|
||||
compile "python3_9_warn"
|
||||
assertCaptured "Installing python-3.9.0"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "${LATEST_39}"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPythonVersionInvalid() {
|
||||
compile "python_version_invalid"
|
||||
assertCaptured "Requested runtime (python-3.8.99) is not available for this stack"
|
||||
assertCaptured "Aborting"
|
||||
assertCapturedError
|
||||
}
|
||||
|
||||
testPypy3_6() {
|
||||
compile "pypy3_6"
|
||||
if [[ $STACK = "cedar-14" ]]; then
|
||||
assertCapturedError
|
||||
else
|
||||
assertCaptured "Installing pypy"
|
||||
assertCaptured "$PYPY_36"
|
||||
assertCaptured "Installing pip 20.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCapturedSuccess
|
||||
fi
|
||||
assertCaptured "Installing ${LATEST_PYPY_36}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 47.1.1 and wheel 0.34.2"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPypy3_6_warn() {
|
||||
compile "pypy3_6_warn"
|
||||
assertCaptured "Installing pypy3.6-7.3.1"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "${LATEST_PYPY_36}"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPypy2_7() {
|
||||
compile "pypy2_7"
|
||||
if [[ $STACK = "cedar-14" ]]; then
|
||||
assertCapturedError
|
||||
else
|
||||
assertCaptured "Installing pypy"
|
||||
assertCaptured "$PYPY_27"
|
||||
assertCaptured "Installing pip 20.0.2, setuptools 39.0.1 and wheel 0.34.2"
|
||||
assertCapturedSuccess
|
||||
fi
|
||||
assertCaptured "Installing ${LATEST_PYPY_27}"
|
||||
assertNotCaptured "security update"
|
||||
assertCaptured "Installing pip 20.1.1, setuptools 44.1.1 and wheel 0.34.2"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testPypy2_7_warn() {
|
||||
compile "pypy2_7_warn"
|
||||
assertCaptured "Installing pypy2.7-7.3.1"
|
||||
assertCaptured "security update!"
|
||||
assertCaptured "${LATEST_PYPY_27}"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
testStickyPythonVersion() {
|
||||
local cache_dir="$(mktmpdir)"
|
||||
compile "python3_6_warn" "$cache_dir"
|
||||
assertCaptured "Installing python-3.6.11"
|
||||
assertCapturedSuccess
|
||||
compile "python_version_unspecified" "$cache_dir"
|
||||
assertNotCaptured "Installing python"
|
||||
assertCaptured "security update!"
|
||||
assertCapturedSuccess
|
||||
# Whilst this file seems like an implementation detail (so something that should
|
||||
# not be tested), we must guarantee the filename remains consistent for backwards
|
||||
# compatibility across buildpack versions for already-built apps.
|
||||
assertFile "python-3.6.11" ".heroku/python-version"
|
||||
}
|
||||
|
||||
testPythonVersionChange() {
|
||||
local cache_dir="$(mktmpdir)"
|
||||
compile "python3_6_warn" "$cache_dir"
|
||||
assertCaptured "Installing python-3.6.11"
|
||||
assertCapturedSuccess
|
||||
compile "python3_6" "$cache_dir"
|
||||
assertCaptured "Found python-3.6.11, removing"
|
||||
assertCapturedSuccess
|
||||
}
|
||||
|
||||
pushd $(dirname 0) >/dev/null
|
||||
|
||||
+21
-13
@@ -56,11 +56,6 @@ resetCapture()
|
||||
unset rtrn # deprecated
|
||||
}
|
||||
|
||||
updateVersion()
|
||||
{
|
||||
echo "$2" > "test/fixtures/${1}/runtime.txt"
|
||||
}
|
||||
|
||||
assertCapturedEquals()
|
||||
{
|
||||
assertEquals "$@" "$(cat ${STD_OUT})"
|
||||
@@ -85,12 +80,20 @@ assertNotCaptured()
|
||||
assertCapturedSuccess()
|
||||
{
|
||||
assertEquals "Captured exit code -" "0" "${RETURN}"
|
||||
# assertEquals "STD_ERR -" "" "$(cat ${STD_ERR})"
|
||||
assertEquals "STD_ERR -" "" "$(cat ${STD_ERR})"
|
||||
|
||||
if [ $RETURN -ne 0 -a -z "$(cat ${STD_ERR})" ]; then
|
||||
# Failing exit code but stderr was empty. Display stdout to help debugging.
|
||||
cat $STD_OUT
|
||||
echo
|
||||
if [ $RETURN -ne 0 -o -n "$(cat ${STD_ERR})" ]; then
|
||||
debug
|
||||
fi
|
||||
}
|
||||
|
||||
assertCapturedSuccessWithStdErr()
|
||||
{
|
||||
assertEquals "Captured exit code -" "0" "${RETURN}"
|
||||
assertNotEquals "STD_ERR -" "" "$(cat ${STD_ERR})"
|
||||
|
||||
if [ ${RETURN} -ne 0 ]; then
|
||||
debug
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -151,9 +154,14 @@ _assertContains()
|
||||
|
||||
debug()
|
||||
{
|
||||
cat $STD_OUT
|
||||
echo '^^^^^^'
|
||||
cat $STD_ERR
|
||||
echo
|
||||
echo '### STD_OUT ###'
|
||||
cat "${STD_OUT}"
|
||||
echo
|
||||
echo '### STD_ERR ###'
|
||||
cat "${STD_ERR}"
|
||||
echo
|
||||
echo
|
||||
}
|
||||
|
||||
assertContains()
|
||||
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# From:
|
||||
# https://raw.githubusercontent.com/heroku/buildpack-stdlib/v8/stdlib.sh
|
||||
|
||||
# Buildpack defaults
|
||||
# ---------------
|
||||
|
||||
export BUILDPACK_LOG_FILE="${BUILDPACK_LOG_FILE:-/dev/null}"
|
||||
|
||||
# Standard Output
|
||||
# ---------------
|
||||
|
||||
# Buildpack Steps.
|
||||
puts_step() {
|
||||
if [[ "$*" == "-" ]]; then
|
||||
read -r output
|
||||
else
|
||||
output=$*
|
||||
fi
|
||||
echo -e "\\e[1m\\e[36m=== $output\\e[0m"
|
||||
unset output
|
||||
}
|
||||
|
||||
# Buildpack Error.
|
||||
puts_error() {
|
||||
if [[ "$*" == "-" ]]; then
|
||||
read -r output
|
||||
else
|
||||
output=$*
|
||||
fi
|
||||
echo -e "\\e[1m\\e[31m=!= $output\\e[0m"
|
||||
}
|
||||
|
||||
# Buildpack Warning.
|
||||
puts_warn() {
|
||||
if [[ "$*" == "-" ]]; then
|
||||
read -r output
|
||||
else
|
||||
output=$*
|
||||
fi
|
||||
echo -e "\\e[1m\\e[33m=!= $output\\e[0m"
|
||||
}
|
||||
|
||||
# Is verbose set?
|
||||
is_verbose() {
|
||||
if [[ -n $BUILDPACK_VERBOSE ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Buildpack Verbose.
|
||||
puts_verbose() {
|
||||
if is_verbose; then
|
||||
if [[ "$*" == "-" ]]; then
|
||||
read -r output
|
||||
else
|
||||
output=$*
|
||||
fi
|
||||
echo "$output"
|
||||
unset output
|
||||
fi
|
||||
}
|
||||
|
||||
# Buildpack Utilities
|
||||
# -------------------
|
||||
|
||||
# Usage: $ set-env key value
|
||||
# NOTICE: Expects PROFILE_PATH & EXPORT_PATH to be set!
|
||||
set_env() {
|
||||
# TODO: automatically create profile path directory if it doesn't exist.
|
||||
echo "export $1=$2" >> "$PROFILE_PATH"
|
||||
echo "export $1=$2" >> "$EXPORT_PATH"
|
||||
}
|
||||
|
||||
# Usage: $ set-default-env key value
|
||||
# NOTICE: Expects PROFILE_PATH & EXPORT_PATH to be set!
|
||||
set_default_env() {
|
||||
echo "export $1=\${$1:-$2}" >> "$PROFILE_PATH"
|
||||
echo "export $1=\${$1:-$2}" >> "$EXPORT_PATH"
|
||||
}
|
||||
|
||||
# Usage: $ un-set-env key
|
||||
# NOTICE: Expects PROFILE_PATH to be set!
|
||||
un_set_env() {
|
||||
echo "unset $1" >> "$PROFILE_PATH"
|
||||
}
|
||||
|
||||
# Usage: $ _env-blacklist pattern
|
||||
# Outputs a regex of default blacklist env vars.
|
||||
_env_blacklist() {
|
||||
local regex=${1:-''}
|
||||
if [ -n "$regex" ]; then
|
||||
regex="|$regex"
|
||||
fi
|
||||
echo "^(PATH|GIT_DIR|CPATH|CPPATH|LD_PRELOAD|LIBRARY_PATH$regex)$"
|
||||
}
|
||||
|
||||
# Usage: $ export-env ENV_DIR WHITELIST BLACKLIST
|
||||
# Exports the environment variables defined in the given directory.
|
||||
export_env() {
|
||||
local env_dir=${1:-$ENV_DIR}
|
||||
local whitelist=${2:-''}
|
||||
local blacklist
|
||||
blacklist="$(_env_blacklist "$3")"
|
||||
if [ -d "$env_dir" ]; then
|
||||
# Environment variable names won't contain characters affected by:
|
||||
# shellcheck disable=SC2045
|
||||
for e in $(ls "$env_dir"); do
|
||||
echo "$e" | grep -E "$whitelist" | grep -qvE "$blacklist" &&
|
||||
export "$e=$(cat "$env_dir/$e")"
|
||||
:
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage: $ sub-env command
|
||||
# Runs a subshell of specified command with user-provided config.
|
||||
# NOTICE: Expects ENV_DIR to be set. WHITELIST & BLACKLIST are optional.
|
||||
# Examples:
|
||||
# WHITELIST=${2:-''}
|
||||
# BLACKLIST=${3:-'^(GIT_DIR|PYTHONHOME|LD_LIBRARY_PATH|LIBRARY_PATH|PATH)$'}
|
||||
sub_env() {
|
||||
(
|
||||
# TODO: Fix https://github.com/heroku/buildpack-stdlib/issues/37
|
||||
# shellcheck disable=SC2153
|
||||
export_env "$ENV_DIR" "$WHITELIST" "$BLACKLIST"
|
||||
|
||||
"$@"
|
||||
)
|
||||
}
|
||||
|
||||
# Logging
|
||||
# -------
|
||||
|
||||
# Notice: These functions expect BPLOG_PREFIX and BUILDPACK_LOG_FILE to be defined (BUILDPACK_LOG_FILE can point to /dev/null if not provided by the buildpack).
|
||||
# Example: BUILDPACK_LOG_FILE=${BUILDPACK_LOG_FILE:-/dev/null}; BPLOG_PREFIX="buildpack.go"
|
||||
|
||||
# Returns now, in milleseconds. Useful for logging.
|
||||
# Example: $ let start=$(nowms); sleep 30; mtime "glide.install.time" "${start}"
|
||||
nowms() {
|
||||
date +%s%3N
|
||||
}
|
||||
|
||||
# Log arbitrary data to the logfile (e.g. a packaging file).
|
||||
# Usage: $ bplog "$(<${vendorJSON})
|
||||
bplog() {
|
||||
echo -n "${@}" | awk 'BEGIN {printf "msg=\""; f="%s"} {gsub(/"/, "\\\"", $0); printf f, $0} {if (NR == 1) f="\\n%s" } END { print "\"" }' >> "${BUILDPACK_LOG_FILE}"
|
||||
}
|
||||
|
||||
# Measures time elapsed for a specific build step.
|
||||
# Usage: $ let start=$(nowms); mtime "glide.install.time" "${start}"
|
||||
# https://github.com/heroku/engineering-docs/blob/master/guides/logs-as-data.md#distributions-measure
|
||||
mtime() {
|
||||
local key="${BPLOG_PREFIX}.${1}"
|
||||
local start="${2}"
|
||||
local end="${3:-$(nowms)}"
|
||||
echo "${key} ${start} ${end}" | awk '{ printf "measure#%s=%.3f\n", $1, ($3 - $2)/1000 }' >> "${BUILDPACK_LOG_FILE}"
|
||||
}
|
||||
|
||||
# Logs a count for a specific built step.
|
||||
# Usage: $ mcount "tool.govendor"
|
||||
# https://github.com/heroku/engineering-docs/blob/master/guides/logs-as-data.md#counting-count
|
||||
mcount() {
|
||||
local k="${BPLOG_PREFIX}.${1}"
|
||||
local v="${2:-1}"
|
||||
echo "count#${k}=${v}" >> "${BUILDPACK_LOG_FILE}"
|
||||
}
|
||||
|
||||
# Logs a measure for a specific build step.
|
||||
# Usage: $ mmeasure "tool.installed_dependencies" 42
|
||||
# https://github.com/heroku/engineering-docs/blob/master/guides/logs-as-data.md#distributions-measure
|
||||
mmeasure() {
|
||||
local k="${BPLOG_PREFIX}.${1}"
|
||||
local v="${2}"
|
||||
echo "measure#${k}=${v}" >> "${BUILDPACK_LOG_FILE}"
|
||||
}
|
||||
|
||||
# Logs a unuique measurement build step.
|
||||
# Usage: $ munique "versions.count" 2.7.13
|
||||
# https://github.com/heroku/engineering-docs/blob/master/guides/logs-as-data.md#uniques-unique
|
||||
munique() {
|
||||
local k="${BPLOG_PREFIX}.${1}"
|
||||
local v="${2}"
|
||||
echo "unique#${k}=${v}" >> "${BUILDPACK_LOG_FILE}"
|
||||
}
|
||||
|
||||
# Measures when an exit path to the buildpack is reached, given a name, then exits 1.
|
||||
# Usage: $ mcount-exi "binExists"
|
||||
mcount_exit() {
|
||||
mcount "error.${1}"
|
||||
exit 1
|
||||
}
|
||||
Vendored
-1048
File diff suppressed because it is too large
Load Diff
Vendored
-204
@@ -1,204 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# taken from
|
||||
# https://github.com/ryanbrainard/heroku-buildpack-testrunner/blob/master/lib/test_utils.sh
|
||||
|
||||
oneTimeSetUp()
|
||||
{
|
||||
TEST_SUITE_CACHE="$(mktemp -d ${SHUNIT_TMPDIR}/test_suite_cache.XXXX)"
|
||||
}
|
||||
|
||||
oneTimeTearDown()
|
||||
{
|
||||
rm -rf ${TEST_SUITE_CACHE}
|
||||
}
|
||||
|
||||
setUp()
|
||||
{
|
||||
OUTPUT_DIR="$(mktemp -d ${SHUNIT_TMPDIR}/output.XXXX)"
|
||||
STD_OUT="${OUTPUT_DIR}/stdout"
|
||||
STD_ERR="${OUTPUT_DIR}/stderr"
|
||||
BUILD_DIR="${OUTPUT_DIR}/build"
|
||||
CACHE_DIR="${OUTPUT_DIR}/cache"
|
||||
mkdir -p ${OUTPUT_DIR}
|
||||
mkdir -p ${BUILD_DIR}
|
||||
mkdir -p ${CACHE_DIR}
|
||||
}
|
||||
|
||||
tearDown()
|
||||
{
|
||||
rm -rf ${OUTPUT_DIR}
|
||||
}
|
||||
|
||||
capture()
|
||||
{
|
||||
resetCapture
|
||||
|
||||
LAST_COMMAND="$@"
|
||||
|
||||
"$@" >${STD_OUT} 2>${STD_ERR}
|
||||
RETURN=$?
|
||||
rtrn=${RETURN} # deprecated
|
||||
}
|
||||
|
||||
resetCapture()
|
||||
{
|
||||
if [ -f ${STD_OUT} ]; then
|
||||
rm ${STD_OUT}
|
||||
fi
|
||||
|
||||
if [ -f ${STD_ERR} ]; then
|
||||
rm ${STD_ERR}
|
||||
fi
|
||||
|
||||
unset LAST_COMMAND
|
||||
unset RETURN
|
||||
unset rtrn # deprecated
|
||||
}
|
||||
|
||||
detect()
|
||||
{
|
||||
capture ${BUILDPACK_HOME}/bin/detect ${BUILD_DIR}
|
||||
}
|
||||
|
||||
compile()
|
||||
{
|
||||
capture ${BUILDPACK_HOME}/bin/compile ${BUILD_DIR} ${CACHE_DIR}
|
||||
}
|
||||
|
||||
release()
|
||||
{
|
||||
capture ${BUILDPACK_HOME}/bin/release ${BUILD_DIR}
|
||||
}
|
||||
|
||||
assertCapturedEquals()
|
||||
{
|
||||
assertEquals "$@" "$(cat ${STD_OUT})"
|
||||
}
|
||||
|
||||
assertCapturedNotEquals()
|
||||
{
|
||||
assertNotEquals "$@" "$(cat ${STD_OUT})"
|
||||
}
|
||||
|
||||
assertCaptured()
|
||||
{
|
||||
assertFileContains "$@" "${STD_OUT}"
|
||||
}
|
||||
|
||||
assertNotCaptured()
|
||||
{
|
||||
assertFileNotContains "$@" "${STD_OUT}"
|
||||
}
|
||||
|
||||
assertCapturedSuccess()
|
||||
{
|
||||
assertEquals "Expected captured exit code to be 0; was <${RETURN}>" "0" "${RETURN}"
|
||||
assertEquals "Expected STD_ERR to be empty; was <$(cat ${STD_ERR})>" "" "$(cat ${STD_ERR})"
|
||||
}
|
||||
|
||||
# assertCapturedError [[expectedErrorCode] expectedErrorMsg]
|
||||
assertCapturedError()
|
||||
{
|
||||
if [ $# -gt 1 ]; then
|
||||
expectedErrorCode=${1}
|
||||
shift
|
||||
fi
|
||||
|
||||
expectedErrorMsg=${1:-""}
|
||||
|
||||
if [ -z ${expectedErrorCode} ]; then
|
||||
assertTrue "Expected captured exit code to be greater than 0; was <${RETURN}>" "[ ${RETURN} -gt 0 ]"
|
||||
else
|
||||
assertTrue "Expected captured exit code to be <${expectedErrorCode}>; was <${RETURN}>" "[ ${RETURN} -eq ${expectedErrorCode} ]"
|
||||
fi
|
||||
|
||||
assertFileContains "Expected STD_OUT to contain error <${expectedErrorMsg}>" "${expectedErrorMsg}" "${STD_OUT}"
|
||||
assertEquals "STD_ERR should always be empty" "" "$(cat ${STD_ERR})"
|
||||
}
|
||||
|
||||
assertAppDetected()
|
||||
{
|
||||
expectedAppType=${1?"Must provide app type"}
|
||||
|
||||
assertCapturedSuccess
|
||||
assertEquals "${expectedAppType}" "$(cat ${STD_OUT})"
|
||||
}
|
||||
|
||||
assertNoAppDetected()
|
||||
{
|
||||
assertEquals "1" "${RETURN}"
|
||||
assertEquals "no" "$(cat ${STD_OUT})"
|
||||
assertEquals "" "$(cat ${STD_ERR})"
|
||||
}
|
||||
|
||||
_assertContains()
|
||||
{
|
||||
if [ 5 -eq $# ]; then
|
||||
msg=$1
|
||||
shift
|
||||
elif [ ! 4 -eq $# ]; then
|
||||
fail "Expected 4 or 5 parameters; Receieved $# parameters"
|
||||
fi
|
||||
|
||||
needle=$1
|
||||
haystack=$2
|
||||
expectation=$3
|
||||
haystack_type=$4
|
||||
|
||||
case "${haystack_type}" in
|
||||
"file") grep -q -F -e "${needle}" ${haystack} ;;
|
||||
"text") echo "${haystack}" | grep -q -F -e "${needle}" ;;
|
||||
esac
|
||||
|
||||
if [ "${expectation}" != "$?" ]; then
|
||||
case "${expectation}" in
|
||||
0) default_msg="Expected <${haystack}> to contain <${needle}>" ;;
|
||||
1) default_msg="Did not expect <${haystack}> to contain <${needle}>" ;;
|
||||
esac
|
||||
|
||||
fail "${msg:-${default_msg}}"
|
||||
fi
|
||||
}
|
||||
|
||||
assertContains()
|
||||
{
|
||||
_assertContains "$@" 0 "text"
|
||||
}
|
||||
|
||||
assertNotContains()
|
||||
{
|
||||
_assertContains "$@" 1 "text"
|
||||
}
|
||||
|
||||
assertFileContains()
|
||||
{
|
||||
_assertContains "$@" 0 "file"
|
||||
}
|
||||
|
||||
assertFileNotContains()
|
||||
{
|
||||
_assertContains "$@" 1 "file"
|
||||
}
|
||||
|
||||
command_exists () {
|
||||
type "$1" > /dev/null 2>&1 ;
|
||||
}
|
||||
|
||||
assertFileMD5()
|
||||
{
|
||||
expectedHash=$1
|
||||
filename=$2
|
||||
|
||||
if command_exists "md5sum"; then
|
||||
md5_cmd="md5sum ${filename}"
|
||||
expected_md5_cmd_output="${expectedHash} ${filename}"
|
||||
elif command_exists "md5"; then
|
||||
md5_cmd="md5 ${filename}"
|
||||
expected_md5_cmd_output="MD5 (${filename}) = ${expectedHash}"
|
||||
else
|
||||
fail "no suitable MD5 hashing command found on this system"
|
||||
fi
|
||||
|
||||
assertEquals "${expected_md5_cmd_output}" "`${md5_cmd}`"
|
||||
}
|
||||
Reference in New Issue
Block a user