mirror of
https://github.com/kennethreitz/heroku-buildpack-python.git
synced 2026-06-05 23:10:16 +00:00
Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c5d7991468 | |||
| c4404694e1 | |||
| e914736956 | |||
| 23833dda9b | |||
| 15573b9d3f | |||
| 86661c1cda | |||
| 9cbace7f76 | |||
| 74cb870488 | |||
| ae9b83f07c | |||
| d70c681c32 | |||
| c312d917a1 | |||
| 5d2ecd2f1f | |||
| a1e1dbd865 | |||
| 12f28894ce | |||
| 538ef6e378 | |||
| 1588ea44b2 | |||
| 3cc9098e25 | |||
| 436e945a91 | |||
| f9b83a4e95 | |||
| b1f8bf9f5e | |||
| 7af5175942 | |||
| c24a9096de | |||
| 36d27c46ed | |||
| 713fa36bca | |||
| 20249f9672 | |||
| 8b55e73f77 | |||
| 2058b3c5bf | |||
| 4eb17eb9a9 | |||
| 7138b7afb2 | |||
| fe9b9401d3 | |||
| 8c870cabfb | |||
| b8182c077a | |||
| fbbdadd347 | |||
| b54faf36f5 | |||
| a0dc2a6f33 | |||
| f775fca31c | |||
| efebff4ce8 | |||
| 94b2ab43a5 | |||
| a21dbc2da1 | |||
| cf5a9d26d1 | |||
| ef4772b87a | |||
| ffda318476 | |||
| 6aff0d0197 | |||
| b9ebd33703 | |||
| 61e17df22d | |||
| b88d0ad800 | |||
| 7e24f94164 | |||
| 3a239aa71a | |||
| 0e1ae7a798 | |||
| 133c308796 | |||
| 7ea8c861a2 | |||
| 20e0af2bf4 | |||
| 5d0ed4e7cd | |||
| 144629d7dc | |||
| cf36e8c7cb | |||
| 233df5d59d | |||
| 375796063b | |||
| d8a70de8a8 | |||
| f1ee7fc04f | |||
| e8585fb4a7 | |||
| e10cc01f7e | |||
| 79d6db74b1 | |||
| 69d607a76e | |||
| 2c03d89213 | |||
| 11bf9833da | |||
| d2d37255d5 | |||
| bea5b4919e |
@@ -0,0 +1,6 @@
|
||||
language: python
|
||||
python:
|
||||
- 2.7
|
||||
script: make tests
|
||||
notifications:
|
||||
email: false
|
||||
@@ -1,3 +1,25 @@
|
||||
## v8
|
||||
|
||||
Features:
|
||||
|
||||
* Disable Django collectstatic with `$DISABLE_COLLECTSTATIC` + [user_env_compile](http://devcenter.heroku.com/articles/labs-user-env-compile).
|
||||
|
||||
Bugfixes:
|
||||
|
||||
* Don't disbable injection for new Django apps.
|
||||
* Inform user of July 1, 2012 deprecation of Django injection.
|
||||
|
||||
## v7
|
||||
|
||||
Features:
|
||||
|
||||
* Full removal of Django setting injection for new apps.
|
||||
* Automatic execution of collectstatic.
|
||||
* Suppress collectstatic errors via env SILENCE_COLLECTSTATIC.
|
||||
* Increase settings.py search depth to 3.
|
||||
* Search recursively from included requirements.txt files.
|
||||
|
||||
|
||||
## v6 (03/23/2012)
|
||||
|
||||
Features:
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
tests:
|
||||
./bin/test
|
||||
|
||||
|
||||
docs:
|
||||
mkdir -p site
|
||||
shocco -t 'Python Buildpack Compiler' ./bin/compile > site/index.html
|
||||
shocco -t 'Django Buildpack Compiler' ./bin/steps/django > site/django.html
|
||||
shocco -t 'Python Buildpack Detector' ./bin/detect > site/detect.html
|
||||
shocco -t 'Pylibmc Buildpack Compiler' ./bin/steps/pylibmc > site/pylibmc.html
|
||||
shocco -t 'Python Buildpack Changelog' ./Changelog.md > site/changelog.html
|
||||
|
||||
site: docs
|
||||
cd site && git add -A && git commit -m 'update' && git push heroku master
|
||||
|
||||
@@ -4,6 +4,8 @@ Heroku buildpack: Python
|
||||
This is a [Heroku buildpack](http://devcenter.heroku.com/articles/buildpacks) for Python apps.
|
||||
It uses [virtualenv](http://www.virtualenv.org/) and [pip](http://www.pip-installer.org/).
|
||||
|
||||
[](http://travis-ci.org/heroku/heroku-buildpack-python)
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
@@ -31,6 +33,10 @@ Example usage:
|
||||
Successfully installed Flask Werkzeug Jinja2
|
||||
Cleaning up...
|
||||
|
||||
You can also add it to upcoming builds of an existing application:
|
||||
|
||||
$ heroku config:add BUILDPACK_URL=git@github.com:heroku/heroku-buildpack-python.git
|
||||
|
||||
The buildpack will detect your app as Python if it has the file `requirements.txt` in the root. It will detect your app as Python/Django if there is an additional `settings.py` in a project subdirectory.
|
||||
|
||||
It will use virtualenv and pip to install your dependencies, vendoring a copy of the Python runtime into your slug. The `bin/`, `include/` and `lib/` directories will be cached between builds to allow for faster pip install time.
|
||||
|
||||
+45
-24
@@ -1,22 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script serves as the
|
||||
# [**Python Buildpack**](https://github.com/heroku/heroku-buildpack-python)
|
||||
# compiler.
|
||||
#
|
||||
# A [buildpack](http://devcenter.heroku.com/articles/buildpacks) is an
|
||||
# This script serves as the
|
||||
# [**Python Buildpack**](https://github.com/heroku/heroku-buildpack-python)
|
||||
# compiler.
|
||||
#
|
||||
# A [buildpack](http://devcenter.heroku.com/articles/buildpacks) is an
|
||||
# adapter between a Python application and Heroku's runtime.
|
||||
|
||||
#
|
||||
# You can intreract with the Heroku API directly with [heroku.py](https://github.com/heroku/heroku.py/).
|
||||
#
|
||||
# See also: [Release history](/changelog.html), [Detection](/detect.html).
|
||||
#
|
||||
# ## Usage
|
||||
# Compiling an app into a slug is simple:
|
||||
#
|
||||
#
|
||||
# $ bin/compile <build-dir> <cache-dir>
|
||||
|
||||
|
||||
# ## Assumptions
|
||||
#
|
||||
#
|
||||
# This buildpack makes the following assumptions:
|
||||
#
|
||||
#
|
||||
# - The desired Python VM is available on the base system.
|
||||
# - Library dependencies are available on the base system.
|
||||
# - Django applications should not require any platform-specific configuration.
|
||||
@@ -55,12 +59,13 @@ LEGACY_VIRTUALENV_TRIGGER="lib/python2.7"
|
||||
PYTHON_VERSION="2.7.2"
|
||||
PYTHON_EXE="python2.7"
|
||||
|
||||
# The slug compiler doesn't do a very good job of sanitizing environment variables.
|
||||
# Sanitizing environment variables.
|
||||
unset GIT_DIR
|
||||
unset PYTHON_HOME
|
||||
unset PYTHONPATH
|
||||
|
||||
# We'll need to send these statics to other scripts we `source`.
|
||||
export PIP_DOWNLOAD_CACHE
|
||||
export BUILD_DIR
|
||||
export PIP_DOWNLOAD_CACHE BUILD_DIR CACHE_DIR BIN_DIR
|
||||
|
||||
# Syntax sugar.
|
||||
indent() {
|
||||
@@ -81,13 +86,16 @@ function puts-warn (){
|
||||
}
|
||||
|
||||
# ## Build Time
|
||||
#
|
||||
#
|
||||
|
||||
# Switch to the repo's context.
|
||||
cd $BUILD_DIR
|
||||
|
||||
# Experimental pre_compile hook.
|
||||
source $BIN_DIR/steps/hooks/pre_compile
|
||||
|
||||
# ### Sanity Checks
|
||||
#
|
||||
#
|
||||
# Just a little peace of mind.
|
||||
|
||||
# If no requirements given, assume `setup.py develop`.
|
||||
@@ -99,8 +107,6 @@ fi
|
||||
# ### The Cache
|
||||
mkdir -p $CACHE_DIR
|
||||
|
||||
# Create set-aside `.heroku` folder.
|
||||
mkdir -p .heroku
|
||||
|
||||
# Nice defaults.
|
||||
LEGACY_VIRTUALENV=false
|
||||
@@ -129,12 +135,23 @@ for dir in $CACHED_DIRS; do
|
||||
cp -R $CACHE_DIR/$dir . &> /dev/null || true
|
||||
done
|
||||
|
||||
set +e
|
||||
# Create set-aside `.heroku` folder.
|
||||
mkdir .heroku &> /dev/null
|
||||
HEROKU_DIR_STATUS=$?
|
||||
|
||||
# TODO: This is a new app, disable injection.
|
||||
# [ $HEROKU_DIR_STATUS -eq 0 ] && {
|
||||
#TODO: touch .heroku/injection_disabled
|
||||
# }
|
||||
set -e
|
||||
|
||||
|
||||
# ### Virtualenv Setup
|
||||
#
|
||||
|
||||
# Create the virtualenv. Rebuild if corrupt.
|
||||
# TODO: Bootstrap a bottled Python VM...
|
||||
# TODO: Bootstrap a bottled Python VM...
|
||||
|
||||
set +e
|
||||
puts-step "Preparing Python interpreter ($PYTHON_VERSION)"
|
||||
@@ -155,7 +172,7 @@ echo "$OUT" | indent
|
||||
|
||||
set -e
|
||||
|
||||
# Pylibmc support.
|
||||
# Pylibmc support.
|
||||
# See [`bin/steps/pylibmc`](pylibmc.html).
|
||||
source $BIN_DIR/steps/pylibmc
|
||||
|
||||
@@ -169,16 +186,16 @@ if (grep -Fiq "hg+" requirements.txt) then
|
||||
fi
|
||||
|
||||
# Install dependencies with Pip.
|
||||
puts-step "Installing dependencies using Pip version $(pip --version | awk '{print $2}')"
|
||||
puts-step "Installing dependencies using pip version $(pip --version | awk '{print $2}')"
|
||||
pip install --use-mirrors -r requirements.txt --src ./.heroku/src | indent
|
||||
|
||||
# Do additional application hackery if applications appears to be a Django app.
|
||||
# Optionally, disable all Django-specific changes with `DISABLE_INJECTION` env.
|
||||
#
|
||||
#
|
||||
# See [`bin/steps/django`](django.html).
|
||||
|
||||
if [ "$NAME" = "Python/Django" ] && ! [ "$DISABLE_INJECTION" ]; then
|
||||
source $BIN_DIR/steps/django
|
||||
if [ "$NAME" = "Python/Django" ]; then
|
||||
source $BIN_DIR/steps/django/init
|
||||
fi
|
||||
|
||||
# Make Virtualenv's paths relative for portability.
|
||||
@@ -196,9 +213,13 @@ set -e
|
||||
|
||||
# Store new artifacts in cache.
|
||||
for dir in $CACHED_DIRS; do
|
||||
|
||||
rm -rf $CACHE_DIR/$dir
|
||||
cp -R $dir $CACHE_DIR/
|
||||
done
|
||||
|
||||
# ### Fin.
|
||||
# ### Fin.
|
||||
|
||||
# Experimental post_compile hook.
|
||||
source $BIN_DIR/steps/hooks/post_compile
|
||||
|
||||
# <a href="http://github.com/heroku/heroku-buildpack-python"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://d3nwyuy0nl342s.cloudfront.net/img/7afbc8b248c68eb468279e8c17986ad46549fb71/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub"></a>
|
||||
+39
-8
@@ -1,15 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script serves as the
|
||||
# [**Python Buildpack**](https://github.com/heroku/heroku-buildpack-python)
|
||||
# detector.
|
||||
#
|
||||
# A [buildpack](http://devcenter.heroku.com/articles/buildpacks) is an
|
||||
# This script serves as the
|
||||
# [**Python Buildpack**](https://github.com/heroku/heroku-buildpack-python)
|
||||
# detector.
|
||||
#
|
||||
# A [buildpack](http://devcenter.heroku.com/articles/buildpacks) is an
|
||||
# adapter between a Python application and Heroku's runtime.
|
||||
|
||||
# ## Usage
|
||||
# Compiling an app into a slug is simple:
|
||||
#
|
||||
#
|
||||
# $ bin/detect <build-dir> <cache-dir>
|
||||
|
||||
BUILD_DIR=$1
|
||||
@@ -25,9 +25,40 @@ if [ ! -f $BUILD_DIR/requirements.txt ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# `Python/Django` if `**/settings.py` is present and `django` exists in
|
||||
# `Python/Django` if `**/settings.py` is present and `django` exists in
|
||||
# `requirements.txt`.
|
||||
#
|
||||
# Otherwise, `Python`.
|
||||
|
||||
ls $BUILD_DIR/**/settings.py &> /dev/null && (grep -Fiq "django" $BUILD_DIR/requirements.txt) && echo Python/Django || echo Python
|
||||
array=""
|
||||
list_requirements() {
|
||||
IFS_BAK=$IFS
|
||||
IFS="
|
||||
"
|
||||
requirement_file=$1
|
||||
reqs=$(cat $requirement_file)
|
||||
for req in $reqs; do
|
||||
if [[ $req == -r* ]]; then
|
||||
new_req=$(echo $req | cut -d" " -f2)
|
||||
if [[ $new_req == $1 ]]; then
|
||||
continue
|
||||
fi
|
||||
directory=$(dirname $requirement_file)
|
||||
if [[ ! $array == *$directory/$new_req* ]]; then
|
||||
list_requirements "$directory/$new_req"
|
||||
fi
|
||||
array="$array $directory/$new_req"
|
||||
else
|
||||
echo $req;
|
||||
fi
|
||||
|
||||
done
|
||||
IFS=$IFS_BAK
|
||||
IFS_BAK=
|
||||
}
|
||||
|
||||
|
||||
SETTINGS_FILE=$(find $BUILD_DIR/. -maxdepth 2 -type f -name 'settings.py' | head -1)
|
||||
|
||||
|
||||
[ -n "$SETTINGS_FILE" ] && ( list_requirements $BUILD_DIR/requirements.txt | grep -Fiq "django" ) && echo Python/Django || echo Python
|
||||
+1
-1
@@ -21,7 +21,7 @@ EOF
|
||||
|
||||
[ "$NAME" = "Python/Django" ] || exit 0
|
||||
|
||||
MANAGE_FILE=$(cd $BUILD_DIR && find . -maxdepth 2 -type f -name 'manage.py' | head -1)
|
||||
MANAGE_FILE=$(cd $BUILD_DIR && find . -maxdepth 3 -type f -name 'manage.py' | head -1)
|
||||
MANAGE_FILE=${MANAGE_FILE:2}
|
||||
PROJECT=$(dirname $MANAGE_FILE)
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script serves as the Django build step of the
|
||||
# [**Python Buildpack**](https://github.com/heroku/heroku-buildpack-python)
|
||||
# compiler.
|
||||
#
|
||||
# A [buildpack](http://devcenter.heroku.com/articles/buildpacks) is an
|
||||
# adapter between a Python application and Heroku's runtime.
|
||||
#
|
||||
# This script is invoked by [`bin/compile`](/).
|
||||
|
||||
# ## Sanity Checks
|
||||
#
|
||||
|
||||
# Reject a Django app that appears to be packaged incorrectly.
|
||||
if [ -f settings.py ]; then
|
||||
echo " ! Django app must be in a package subdirectory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "-----> Injecting Django settings..."
|
||||
|
||||
|
||||
SETTINGS_FILE=$(find . -maxdepth 2 -type f -name 'settings.py' | head -1)
|
||||
PROJECT=$(dirname $SETTINGS_FILE)
|
||||
|
||||
echo "Injecting code into $SETTINGS_FILE to read from DATABASE_URL" | indent
|
||||
|
||||
cat >>$SETTINGS_FILE <<EOF
|
||||
|
||||
import os
|
||||
import sys
|
||||
import urlparse
|
||||
|
||||
# Register database schemes in URLs.
|
||||
urlparse.uses_netloc.append('postgres')
|
||||
urlparse.uses_netloc.append('mysql')
|
||||
|
||||
try:
|
||||
|
||||
# Check to make sure DATABASES is set in settings.py file.
|
||||
# If not default to {}
|
||||
|
||||
if 'DATABASES' not in locals():
|
||||
DATABASES = {}
|
||||
|
||||
if 'DATABASE_URL' in os.environ:
|
||||
url = urlparse.urlparse(os.environ['DATABASE_URL'])
|
||||
|
||||
# Ensure default database exists.
|
||||
DATABASES['default'] = DATABASES.get('default', {})
|
||||
|
||||
# Update with environment configuration.
|
||||
DATABASES['default'].update({
|
||||
'NAME': url.path[1:],
|
||||
'USER': url.username,
|
||||
'PASSWORD': url.password,
|
||||
'HOST': url.hostname,
|
||||
'PORT': url.port,
|
||||
})
|
||||
if url.scheme == 'postgres':
|
||||
DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
|
||||
|
||||
if url.scheme == 'mysql':
|
||||
DATABASES['default']['ENGINE'] = 'django.db.backends.mysql'
|
||||
except Exception:
|
||||
print 'Unexpected error:', sys.exc_info()
|
||||
|
||||
EOF
|
||||
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set +e
|
||||
|
||||
# Syntax sugar.
|
||||
indent() {
|
||||
RE="s/^/ /"
|
||||
[ $(uname) == "Darwin" ] && sed -l "$RE" || sed -u "$RE"
|
||||
}
|
||||
|
||||
|
||||
# Check if collectstatic is configured.
|
||||
python $MANAGE_FILE collectstatic --help &> /dev/null && RUN_COLLECTSTATIC=true
|
||||
|
||||
# Don't raise errors if SILENCE_COLLECTSTATIC is set.
|
||||
|
||||
echo "-----> Collecting static files"
|
||||
set -e
|
||||
|
||||
# Compile assets if collectstatic appears to be kosher.
|
||||
if [ "$RUN_COLLECTSTATIC" ]; then
|
||||
python $MANAGE_FILE collectstatic --noinput | indent
|
||||
|
||||
[ $? -ne 0 ] && {
|
||||
echo " ! Error running manage.py collectstatic. More info:"
|
||||
echo " http://devcenter.heroku.com/articles/django-assets"
|
||||
# exit 1
|
||||
}
|
||||
|
||||
else
|
||||
echo " ! Django collecstatic is not configured. Learn more:"
|
||||
echo " http://devcenter.heroku.com/articles/django-assets"
|
||||
fi
|
||||
|
||||
echo
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SETTINGS_FILE=$(find . -maxdepth 3 -type f -name 'settings.py' | head -1)
|
||||
PROJECT=$(dirname $SETTINGS_FILE)
|
||||
MANAGE_FILE=$(find . -maxdepth 3 -type f -name 'manage.py' | head -1)
|
||||
MANAGE_FILE=${MANAGE_FILE:2}
|
||||
|
||||
# Disable injection for new applications.
|
||||
if [ -f .heroku/injection_disabled ]; then
|
||||
DISABLE_INJECTION=1
|
||||
fi
|
||||
|
||||
export SETTINGS_FILE MANAGE_FILE PROJECT DISABLE_INJECTION
|
||||
|
||||
if [ ! "$DISABLE_INJECTION" ]; then
|
||||
source $BIN_DIR/steps/django/injection
|
||||
echo " ! Notice: settings injection will be deprecated for all new Django "
|
||||
echo " ! apps starting on July 1, 2012. Learn more:"
|
||||
echo " ! https://devcenter.heroku.com/articles/django-injection"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if [ ! "$DISABLE_COLLECTSTATIC" ]; then
|
||||
source $BIN_DIR/steps/django/collectstatic
|
||||
fi
|
||||
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script serves as the Django injection build step of the
|
||||
# [**Python Buildpack**](https://github.com/heroku/heroku-buildpack-python)
|
||||
# compiler.
|
||||
#
|
||||
# A [buildpack](http://devcenter.heroku.com/articles/buildpacks) is an
|
||||
# adapter between a Python application and Heroku's runtime.
|
||||
#
|
||||
# This script is invoked by [`bin/compile`](/).
|
||||
|
||||
# ## Sanity Checks
|
||||
#
|
||||
|
||||
# Syntax sugar.
|
||||
indent() {
|
||||
RE="s/^/ /"
|
||||
[ $(uname) == "Darwin" ] && sed -l "$RE" || sed -u "$RE"
|
||||
}
|
||||
|
||||
echo "-----> Installing dj-database-url..."
|
||||
pip install --use-mirrors dj-database-url>=0.2.0 | indent
|
||||
|
||||
echo "-----> Injecting Django settings..."
|
||||
|
||||
SETTINGS_FILE=$(find . -maxdepth 2 -type f -name 'settings.py' | head -1)
|
||||
PROJECT=$(dirname $SETTINGS_FILE)
|
||||
|
||||
echo "Injecting code into $SETTINGS_FILE to read from DATABASE_URL" | indent
|
||||
|
||||
cat >>$SETTINGS_FILE <<EOF
|
||||
|
||||
import dj_database_url
|
||||
|
||||
DATABASES = {'default': dj_database_url.config(default='postgres://')}
|
||||
EOF
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -f bin/post_compile ]; then
|
||||
echo "-----> Running post-compile hook"
|
||||
chmod +x bin/post_compile
|
||||
bin/post_compile
|
||||
fi
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -f bin/pre_compile ]; then
|
||||
echo "-----> Running pre-compile hook"
|
||||
chmod +x bin/pre_compile
|
||||
bin/pre_compile
|
||||
fi
|
||||
Regular → Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user