Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Arbitrary Python Versions #64

Merged
merged 7 commits into from

1 participant

Kenneth Reitz
Kenneth Reitz
Owner

This provides support for arbitrary versions of Python on Heroku.

Support for (officially):

  • python-2.7.3
  • python-3.3.0

Unofficially:

  • pypy-1.7
  • pypy-1.8
  • pypy-1.9
  • python-2.4.4
  • python-2.4.5
  • python-2.4.6
  • python-2.5.0
  • python-2.5.1
  • python-2.5.2
  • python-2.5.3
  • python-2.5.4
  • python-2.6.0
  • python-2.6.1
  • python-2.6.2
  • python-2.6.3
  • python-2.6.4
  • python-2.6.5
  • python-2.6.6
  • python-2.7.0
  • python-2.7.1
  • python-2.7.2
  • python-2.7.3
  • python-3.1.0
  • python-3.1.1
  • python-3.1.2
  • python-3.1.3
  • python-3.1.4
  • python-3.1.5
  • python-3.2.0
  • python-3.2.1
  • python-3.2.2
  • python-3.2.3

These builds are provided by https://github.com/kennethreitz/python-versions

Kenneth Reitz kennethreitz merged commit ca3b380 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
81 bin/compile
View
@@ -44,17 +44,14 @@ CACHE_DIR=$2
# The detected application type (`Python`|`Python/Django`).
NAME=$($BIN_DIR/detect $BUILD_DIR)
-# Where to store the Pip download cache.
+# Where to store the pip download cache.
CACHED_DIRS=".heroku"
PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE:-$CACHE_DIR/pip_downloads}
# Static configurations for virtualenv caches.
-LEGACY_VIRTUALENV_LOC="."
-MODERN_VIRTUALENV_LOC=".heroku/venv"
-LEGACY_VIRTUALENV_DIRS="bin include lib"
-LEGACY_VIRTUALENV_TRIGGER="lib/python2.7"
-PROFILE_PATH="$1/.profile.d/python.sh"
-
+VIRTUALENV_LOC=".heroku/venv"
+LEGACY_TRIGGER="lib/python2.7"
+PROFILE_PATH="$BUILD_DIR/.profile.d/python.sh"
# Python version. This will be used in the future to specify custom Pythons.
PYTHON_VERSION="2.7.2"
@@ -66,6 +63,7 @@ unset GIT_DIR PYTHONHOME PYTHONPATH LD_LIBRARY_PATH LIBRARY_PATH
# We'll need to send these statics to other scripts we `source`.
export PIP_DOWNLOAD_CACHE BUILD_DIR CACHE_DIR BIN_DIR PROFILE_PATH
+# Syntax sugar.
source $BIN_DIR/utils
# ## Build Time
@@ -77,10 +75,6 @@ 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`.
if [ ! -f requirements.txt ]; then
puts-step "No requirements.txt provided; assuming dist package."
@@ -91,29 +85,8 @@ fi
mkdir -p $CACHE_DIR
[ ! "$(ls -A $CACHE_DIR)" ] && export FRESH_APP=1
-
-# Nice defaults.
-VIRTUALENV_LOC=$MODERN_VIRTUALENV_LOC
-VIRTUALENV_DIRS=$MODERN_VIRTUALENV_LOC
-
-# Support "old-style" virtualenvs.
-if [ -d $CACHE_DIR/$LEGACY_VIRTUALENV_TRIGGER ]; then
- LEGACY_VIRTUALENV=true
- VIRTUALENV_LOC=$LEGACY_VIRTUALENV_LOC
- VIRTUALENV_DIRS=$LEGACY_VIRTUALENV_DIRS
- CACHED_DIRS=$LEGACY_VIRTUALENV_DIRS
-
- # Warn for a checked-in virtualenv.
- if [ -d "lib" ] || [ -d "bin" ]; then
- puts-warn "You have a virtualenv checked in. You should ignore the appropriate paths in your repo. See http://devcenter.heroku.com/articles/gitignore for more info.";
- fi
-
- # Reject a conflicting checked-in virtualenv.
- if [ -f "lib/python2.7" ]; then
- puts-warn "Checked-in virtualenv conflict."
- exit 1;
- fi
-fi
+# Purge "old-style" virtualenvs.
+[ -d $CACHE_DIR/$LEGACY_TRIGGER ] && rm -fr $CACHE_DIR/*
# Restore old artifacts from the cache.
for dir in $CACHED_DIRS; do
@@ -123,12 +96,6 @@ 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
# Buildpack profile init script
@@ -152,13 +119,12 @@ OUT=$(virtualenv --python $PYTHON_EXE --distribute --never-download --prompt='(v
then echo " ! CLEAN_VIRTUALENV set, rebuilding virtualenv."
else echo " ! Virtualenv corrupt, rebuilding."
fi
- for dir in $VIRTUALENV_DIRS; do
- rm -fr $dir &> /dev/null || true
- done
+
+ rm -fr $VIRTUALENV_LOC &> /dev/null || true
+
OUT=$(virtualenv --python $PYTHON_EXE --distribute --never-download --prompt='(venv) ' $VIRTUALENV_LOC )
}
echo "$OUT" | cleanup | indent
-
set -e
# Pylibmc support.
@@ -177,13 +143,9 @@ fi
puts-step "Installing dependencies using pip ($(pip --version | awk '{print $2}'))"
pip install --use-mirrors -r requirements.txt --exists-action=w --src=./.heroku/src | cleanup | 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).
-
+# Django collectstatic support.
if [ "$NAME" = "Python/Django" ]; then
- source $BIN_DIR/steps/django/init
+ source $BIN_DIR/steps/django
fi
# Make Virtualenv's paths relative for portability.
@@ -206,16 +168,15 @@ for dir in $CACHED_DIRS; do
done
# Set context environment variables.
-if [ ! -n "$LEGACY_VIRTUALENV" ]; then
- set-env PATH '$HOME/.heroku/venv/bin:$PATH'
- set-default-env PYTHONUNBUFFERED true
- set-default-env LIBRARY_PATH /app/.heroku/vendor/lib
- set-default-env LD_LIBRARY_PATH /app/.heroku/vendor/lib
- set-default-env LANG en_US.UTF-8
- set-default-env PYTHONHASHSEED random
- set-default-env PYTHONHOME /app/.heroku/venv/
- set-default-env PYTHONPATH /app/
-fi
+set-env PATH '$HOME/.heroku/venv/bin:$PATH'
+set-default-env PYTHONUNBUFFERED true
+set-default-env LIBRARY_PATH /app/.heroku/vendor/lib
+set-default-env LD_LIBRARY_PATH /app/.heroku/vendor/lib
+set-default-env LANG en_US.UTF-8
+set-default-env PYTHONHASHSEED random
+set-default-env PYTHONHOME /app/.heroku/venv/
+set-default-env PYTHONPATH /app/
+
# ### Fin.
41 bin/detect
View
@@ -19,46 +19,11 @@ if [ ! -f $BUILD_DIR/requirements.txt ] && [ ! -f $BUILD_DIR/setup.py ]; then
exit 1
fi
-# If only `setup.py`, assume that the app is not Django.
-if [ ! -f $BUILD_DIR/requirements.txt ]; then
- echo Python
- exit 0
-fi
-
-# `Python/Django` if `**/settings.py` is present and `django` exists in
-# `requirements.txt`.
+# `Python/Django` if `**/settings.py` is present.
#
# Otherwise, `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)
+SETTINGS_FILE=$(find $BUILD_DIR/. -maxdepth 3 -type f -name 'settings.py' | head -1)
-[ -n "$SETTINGS_FILE" ] && ( list_requirements $BUILD_DIR/requirements.txt | grep -Fiq "django" ) && echo Python/Django || echo Python
+[ -n "$SETTINGS_FILE" ] && echo Python/Django || echo Python
37 bin/steps/django
View
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+# Syntax sugar.
+indent() {
+ RE="s/^/ /"
+ [ $(uname) == "Darwin" ] && sed -l "$RE" || sed -u "$RE"
+}
+
+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}
+
+
+if [ ! "$DISABLE_COLLECTSTATIC" ]; then
+ set +e
+
+ # Check if collectstatic is configured properly.
+ python $MANAGE_FILE collectstatic --dry-run --noinput &> /dev/null && RUN_COLLECTSTATIC=true
+
+ # Compile assets if collectstatic appears to be kosher.
+ if [ "$RUN_COLLECTSTATIC" ]; then
+
+ echo "-----> Collecting static files"
+ python $MANAGE_FILE collectstatic --noinput 2>&1 | sed '/^Copying/d;/^$/d;/^ /d' | indent
+
+ [ $? -ne 0 ] && {
+ echo " ! Error running manage.py collectstatic. More info:"
+ echo " http://devcenter.heroku.com/articles/django-assets"
+ }
+ fi
+
+ echo
+
+
+fi
+
28 bin/steps/django/collectstatic
View
@@ -1,28 +0,0 @@
-#!/usr/bin/env bash
-
-set +e
-
-# Syntax sugar.
-indent() {
- RE="s/^/ /"
- [ $(uname) == "Darwin" ] && sed -l "$RE" || sed -u "$RE"
-}
-
-
-# Check if collectstatic is configured properly.
-python $MANAGE_FILE collectstatic --dry-run --noinput &> /dev/null && RUN_COLLECTSTATIC=true
-
-# Compile assets if collectstatic appears to be kosher.
-if [ "$RUN_COLLECTSTATIC" ]; then
-
- echo "-----> Collecting static files"
- python $MANAGE_FILE collectstatic --noinput 2>&1 | sed '/^Copying/d;/^$/d;/^ /d' | indent
-
- [ $? -ne 0 ] && {
- echo " ! Error running manage.py collectstatic. More info:"
- echo " http://devcenter.heroku.com/articles/django-assets"
- }
-fi
-
-echo
-
32 bin/steps/django/init
View
@@ -1,32 +0,0 @@
-#!/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}
-
-if [ "$FRESH_APP" ]; then
- # Legacy Django injection for existing applications.
- touch .heroku/injection_disabled
-fi
-
-# Disable injection for new applications.
-if [ -f .heroku/injection_disabled ]; then
- DISABLE_INJECTION=1
-fi
-
-if [ -f .heroku/collectstatic_disabled ]; then
- DISABLE_COLLECTSTATIC=1
-fi
-
-export SETTINGS_FILE MANAGE_FILE PROJECT DISABLE_INJECTION
-
-if [ ! "$DISABLE_INJECTION" ]; then
- # Legacy Django injection for existing applications.
- source $BIN_DIR/steps/django/injection
-fi
-
-if [ ! "$DISABLE_COLLECTSTATIC" ]; then
- source $BIN_DIR/steps/django/collectstatic
-fi
-
47 bin/steps/django/injection
View
@@ -1,47 +0,0 @@
-#!/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 "-----> Injecting legacy Django settings..."
-echo " ! WARNING: Settings injection will be fully deprecated on January 1, 2013. More info:"
-echo " ! https://devcenter.heroku.com/articles/django-injection "
-
-
-echo "-----> Installing dj-database-url..."
-pip install --use-mirrors 'dj-database-url>=0.2.0' | indent
-
-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
-
-if 'DATABASES' not in locals():
- DATABASES = {}
-
-if not 'default' in DATABASES:
- DATABASES['default'] = {}
-
-DATABASES['default'].update(dj_database_url.config(default='postgres://'))
-
-EOF
-
Something went wrong with that request. Please try again.