diff --git a/Readme.md b/Readme.md index 2badee1dd1a82dc74923ced1611f1adbe9c4758c..c86b5f7cfec551ab85c4b113fa2a385541391477 100644 --- a/Readme.md +++ b/Readme.md @@ -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 -On next push, slug-compiler will use this LP instead of the built-in one. - -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`. +On next push, slug-compiler will use this LP instead of the built-in one. \ No newline at end of file diff --git a/bin/compile b/bin/compile index 505d22974817bf51c255bdd9ab9a39cb6a2f4b64..6076095cfc040a473a3dc29391019698ea7313db 100755 --- a/bin/compile +++ b/bin/compile @@ -19,9 +19,6 @@ function sed() { 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 mkdir -p $CACHE_DIR for dir in $VIRTUALENV_DIRS; do @@ -40,14 +37,26 @@ if [ "$NAME" = "Python/Django" ]; then SETTINGS_FILE=$(ls **/settings.py | head -1) echo " Injecting code into $SETTINGS_FILE to read from DATABASE_URL" + + cat >>$SETTINGS_FILE <<EOF - $BIN_DIR/../opt/inject_dbs $SETTINGS_FILE _settings.py - mv _settings.py $SETTINGS_FILE +import os, urlparse +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 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/^/ /' -virtualenv --relocatable . +PIP_DOWNLOAD_CACHE=$PIP_DOWNLOAD_CACHE bin/pip install -r requirements.txt | sed -u 's/^/ /' # store new artifacts in cache for dir in $VIRTUALENV_DIRS; do diff --git a/bin/detect b/bin/detect index 17597c053f6bb6eec62106d99b817099b4ffd141..37252b59d8f62710909671c5adeaf49410242b88 100755 --- a/bin/detect +++ b/bin/detect @@ -1,14 +1,8 @@ #!/usr/bin/env bash -# bin/detect <build-dir> +# bin/name <build-dir> BUILD_DIR=$1 - -function abort() { - echo $1 1>&2 - exit 1 -} - -[ -f $BUILD_DIR/requirements.txt ] || abort "fatal: Not a Python app (no requirements.txt)" +[ -f $BUILD_DIR/requirements.txt ] || exit 1 # fail fast if no requirements.txt # '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 diff --git a/opt/dbs.py.src b/opt/dbs.py.src deleted file mode 100644 index 6d2fc5c817a534d0cbc5f2adc1db1307a9b6fa5a..0000000000000000000000000000000000000000 --- a/opt/dbs.py.src +++ /dev/null @@ -1,31 +0,0 @@ - -########## -# 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 -########## diff --git a/opt/inject_dbs b/opt/inject_dbs deleted file mode 100755 index 09b7fef1eeb372a1b5f68b667a6eb8c65a5b17fa..0000000000000000000000000000000000000000 --- a/opt/inject_dbs +++ /dev/null @@ -1,49 +0,0 @@ -#!/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)