Skip to content
Snippets Groups Projects
Commit f888a818 authored by Noah Zoschke's avatar Noah Zoschke
Browse files

reset to whats in slug-compiler python language pack

parent 53f25fc8
No related branches found
No related tags found
No related merge requests found
...@@ -18,36 +18,4 @@ set a `LANGUAGE_PACK_URL` config var with a fully authenticated URL to this repo ...@@ -18,36 +18,4 @@ set a `LANGUAGE_PACK_URL` config var with a fully authenticated URL to this repo
$ heroku config:add LANGUAGE_PACK_URL=https://nzoschke:XXXXXXX@github.com/heroku/language-pack-python.git $ heroku config:add LANGUAGE_PACK_URL=https://nzoschke:XXXXXXX@github.com/heroku/language-pack-python.git
On next push, slug-compiler will use this LP instead of the built-in one. On next push, slug-compiler will use this LP instead of the built-in one.
\ No newline at end of file
Compile Hooks
-------------
The PLP uses a Makefile for user-controlled hooks into slug compilation. If
present, the `make environment` rule will be eval'd in the compile script, allowing
user-defined exports.
A sample Makefile
(<a href="https://github.com/heroku/language-pack-python/raw/master/test/canary_django/Makefile">raw</a>)
to force a re-build of every pip package is:
environment:
export PIP_OPTS=--upgrade
Django settings.py
------------------
The PLP injects code into `settings.py` to alias every Heroku database URL
config var. Every variable of the format `${NAME}_URL => postgres://` will be
added to the `settings.DATABASES` hash.
On an app with both a shared SHARED_DATABASE_URL and a dedicated
HEROKU_POSTGRESQL_RED_URL that is promoted to DATABASE_URL, `settings.DATABASES`
will be:
{
'DATABASE': {'ENGINE': 'psycopg2', 'NAME': 'dedicated', ...},
'HEROKU_POSTGRESQL_RED': {'ENGINE': 'psycopg2', 'NAME': 'dedicated', ...},
'SHARED': {'ENGINE': 'psycopg2', 'NAME': 'shared', ...},
'default': {'ENGINE': 'psycopg2', 'NAME': 'dedicated', ...},
}
These aliases can be referenced and further modified at the bottom of `settings.py`.
...@@ -19,9 +19,6 @@ function sed() { ...@@ -19,9 +19,6 @@ function sed() {
cd $BUILD_DIR cd $BUILD_DIR
# COMPILE HOOK: export build environment if specified
(make environment 2> /dev/null) && eval $(make environment)
# copy artifacts out of cache if exists # copy artifacts out of cache if exists
mkdir -p $CACHE_DIR mkdir -p $CACHE_DIR
for dir in $VIRTUALENV_DIRS; do for dir in $VIRTUALENV_DIRS; do
...@@ -40,14 +37,26 @@ if [ "$NAME" = "Python/Django" ]; then ...@@ -40,14 +37,26 @@ if [ "$NAME" = "Python/Django" ]; then
SETTINGS_FILE=$(ls **/settings.py | head -1) SETTINGS_FILE=$(ls **/settings.py | head -1)
echo " Injecting code into $SETTINGS_FILE to read from DATABASE_URL" echo " Injecting code into $SETTINGS_FILE to read from DATABASE_URL"
cat >>$SETTINGS_FILE <<EOF
$BIN_DIR/../opt/inject_dbs $SETTINGS_FILE _settings.py import os, urlparse
mv _settings.py $SETTINGS_FILE if os.environ.has_key('DATABASE_URL'):
urlparse.uses_netloc.append('postgres')
url = urlparse.urlparse(os.environ['DATABASE_URL'])
DATABASES['default'] = {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': url.path[1:],
'USER': url.username,
'PASSWORD': url.password,
'HOST': url.hostname,
'PORT': url.port,
}
EOF
fi fi
echo "-----> Installing dependencies using pip version $(pip --version | awk '{print $2}')" echo "-----> Installing dependencies using pip version $(pip --version | awk '{print $2}')"
PIP_DOWNLOAD_CACHE=$PIP_DOWNLOAD_CACHE bin/pip install -r requirements.txt ${PIP_OPTS} | sed -u 's/^/ /' PIP_DOWNLOAD_CACHE=$PIP_DOWNLOAD_CACHE bin/pip install -r requirements.txt | sed -u 's/^/ /'
virtualenv --relocatable .
# store new artifacts in cache # store new artifacts in cache
for dir in $VIRTUALENV_DIRS; do for dir in $VIRTUALENV_DIRS; do
......
#!/usr/bin/env bash #!/usr/bin/env bash
# bin/detect <build-dir> # bin/name <build-dir>
BUILD_DIR=$1 BUILD_DIR=$1
[ -f $BUILD_DIR/requirements.txt ] || exit 1 # fail fast if no requirements.txt
function abort() {
echo $1 1>&2
exit 1
}
[ -f $BUILD_DIR/requirements.txt ] || abort "fatal: Not a Python app (no requirements.txt)"
# 'Python/Django' if there is a [mysite]/settings.py file present; otherwise 'Python' # 'Python/Django' if there is a [mysite]/settings.py file present; otherwise 'Python'
ls $BUILD_DIR/**/settings.py &> /dev/null && echo Python/Django || echo Python ls $BUILD_DIR/**/settings.py &> /dev/null && echo Python/Django || echo Python
\ No newline at end of file
##########
# BEGIN HEROKU PYTHON/DJANGO LANGUAGE PACK
# Dynamically set DATABASES from ENV vars
import os, re, urlparse
urlparse.uses_netloc.append("postgres")
key_re = re.compile(r"^(?P<name>[A-Z_]+)_URL$")
for k,v in os.environ.items():
url = urlparse.urlparse(v)
matches = key_re.match(k)
if not matches or url.scheme != "postgres":
continue
DATABASES[matches.group("name")] = {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": url.path[1:],
"USER": url.username,
"PASSWORD": url.password,
"HOST": url.hostname,
"PORT": url.port,
}
# alias "default" to DATABASE_URL
if DATABASES["DATABASE"]:
DATABASES["default"] = DATABASES["DATABASE"]
#
# END HEROKU PYTHON/DJANGO LANGUAGE PACK
##########
#!/usr/bin/env python2.7
import os
import sys
from lib2to3 import pygram, pytree
from lib2to3.pgen2 import driver, parse
BIN_DIR = os.path.dirname(__file__)
def find(node, leaf):
if node == leaf:
return node
for c in node.children:
if find(c, leaf):
return find(c, leaf)
if __name__ == "__main__":
if len(sys.argv) != 3:
print "usage: %s settings_file target_file" % sys.argv[0]
sys.exit(1)
src = sys.argv[1]
dest = sys.argv[2]
patch = os.path.join(BIN_DIR, "dbs.py.src")
drv = driver.Driver(pygram.python_grammar, pytree.convert)
try:
root = drv.parse_file(src)
except parse.ParseError, e:
print "fatal: could not parse file as Python"
sys.exit(1)
node = find(root, pytree.Leaf(1, "DATABASES")) # Find node for DATABASES = { ... }
if not node:
print "fatal: could not find DATABASES = stmt"
sys.exit(1)
end = node.parent.next_sibling # calculate adjacent sibling
with open(src) as _src:
head = [_src.next() for x in xrange(end.lineno)]
tail = [l for x,l in enumerate(_src)]
with open(patch) as _patch:
body = [l for x,l in enumerate(_patch)]
with open(dest, "w") as _dest:
_dest.writelines(head)
_dest.writelines(body)
_dest.writelines(tail)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment