Anonymous avatar Anonymous committed 4bd2cb3 Merge

Branch merge.

Comments (0)

Files changed (15)

 Getting Started
 ---------------
 
-This release contains all the relevant shell scripts in the scripts
+This release contains all the relevant shell scripts in the bin
 directory, and a fully working Django example project in ``mysite``.
 You can copy files from it as needed to your own projects. To get
 the example environment working, do the following:
 
-1. Copy scripts/initenv_example to scripts/initenv.
-2. Edit scripts/initenv, set ``PROJECT_ROOT`` and save the file.
-3. Use ``source scripts/initenv`` to load django-environments into
+1. Copy bin/initenv_example to bin/initenv.
+2. Edit bin/initenv, set ``PROJECT_ROOT`` and save the file.
+3. Use ``source bin/initenv`` to load django-environments into
    your shell. If you left in the djenv command, you will see the
    environment settings immediately.
 4. For fun, you could do a ``cp -rpv mysite foo`` from the top
    completion.
 5. For automatic initialization of django-environments when using
    virtualenv with virtualenvwrapper, you can either
-   ``source <path-to-project>/scripts/initenv`` from ``bin/postactivate``,
+   ``source <path-to-project>/bin/initenv`` from ``bin/postactivate``,
    or simply use your initenv's contents inside postactivate.
    Alternatively, you may also symlink ``bin/postactivate`` to your
    initenv script.
 * ``runserver``
                 perform ``django-admin.py runserver <port>``, using
                 settings.LOCAL_SERVER_PORT if defined (see also
-                scripts/create_apache_vhost_conf.sh).
+                bin/create_apache_vhost_conf.sh).
 * ``pipup``
                 call ``pip install`` with the appropriate file listing
                 the project's requirements.
 * ``djexit``
                 leave the current Django project.
 
-See ``scripts/djenvlib`` for the more information.
+See ``bin/djenvlib`` for the more information.
 
 Compatibility with virtualenv
 -----------------------------
 ----------------------------------------------------------
 
 If you want your WSGI setup done as quickly as possible, activate an
-environment - either directly via your ``scripts/initenv`` or through
-virtualenv - and execute ``scripts/setup_local_wsgi.sh <environment>``, e.g.::
+environment - either directly via your ``bin/initenv`` or through
+virtualenv - and execute ``bin/setup_local_wsgi.sh <environment>``, e.g.::
 
-    $ scripts/setup_local_wsgi.sh staging
+    $ bin/setup_local_wsgi.sh staging
 
 This will create a ``deploy/local.wsgi`` symbolic link to staging.wsgi and
 will create a ``settings/env/local.py`` with default contents for a given
   filenames are used to determine which settings to import. If
   your Apache configuration allows it, you could use symlinks
   instead of copies.
-* The scripts directory contains the shell scripts intended to be
+* The bin directory contains the shell scripts intended to be
   sourced with the ``source`` command, unless they have a '.sh'
   extension.
 

bin/create_apache_vhost_conf.sh

+#!/bin/sh
+#
+# Generates Apache named virtual host configuration for reverse
+# proxying runserver instances, to be included from your Apache
+# configuration.
+#
+# This way, you can have unlimited Django runserver instances running
+# at the same time, each one listening on a different port as specified
+# in the settings. This makes life easier when working with multiple
+# Django projects simultaneously, but it also allows comparison between
+# different settings within a single Django project, for instance the
+# performance of two different database backends.
+#
+# Either set settings.LOCAL_SERVER_PORT to the port you want to use
+# for a given Django project (in settings/generic.py), and optionally
+# overrule settings.LOCAL_SERVER_PORT in a specific environment
+# settings file, like settings/env/dev_postgresql.py. (It's a good
+# idea to have a port numbering strategy ready before you start, just
+# like with BASIC line numbers: 7000-7099 project A, 7100-7199 project
+# B and so on.)
+#
+# By default, the generated virtual hosts will have the naming formats
+# 'django_project_id.local' and 'settings_id.django_project_id.local'.
+# By defining environment variable $DOMAIN you can change the domain
+# postfix to anything you like, for instance
+# 'development.myorganization.dom'.
+#
+# Steps to get this working:
+#
+# 1. Run this script and save the output to a file, for instance
+#    create_apache_vhost_conf.sh > $PROJECT_ROOT/deploy/vhosts-development.conf
+#    (It's good idea to do this in a VCS hook to always keep it up-to-date.)
+#
+# 2. Include the configuration file in your Apache configuration:
+#    Include /Users/spanky/repos/myproject/deploy/vhosts-development.conf
+#
+# 3. Restart Apache.
+#
+# 4. For each of the generated virtual hosts you wish to use, add
+#    the host name to the localhost entry in /etc/hosts:
+#    127.0.0.1 localhost django_project_id.local
+#
+#    Or, even better: use a DNS server that supports wildcards! This
+#    way you simply have to make sure that *.development.myorganization.dom
+#    points to 127.0.0.1, and you're done.
+#
+# 5. Use 'djenv django_project_id settings_id', followed by 'runserver'
+#    to have a Django server listening at the port you specified in the
+#    settings. Note you will have to use the 'runserver' function as
+#    provided by django-environments to have the server actually listen
+#    on settings.LOCAL_SERVER_PORT.
+#
+# 6. Go to the appropriate URL, e.g.
+#    http://settings_id.django_project_id.local/ and admire your work.
+
+domain=local
+[ ! -z "$DOMAIN" ] && domain=$DOMAIN
+
+# The root of the project should exist, of course
+[ -z "$PROJECT_ROOT" ] && \
+    echo "Variable \$PROJECT_ROOT not set or empty" 1>&2 && exit 1
+[ ! -d "$PROJECT_ROOT" ] && \
+     echo "Variable \$PROJECT_ROOT does not point to a readable directory" 1>&2 && exit 1
+
+cd `dirname $0`
+
+echo '# >>>' Generated django-environments virtual host config start
+echo
+echo NameVirtualHost 127.0.0.1:*
+echo
+
+for django_project_dir in $PROJECT_ROOT/*; do
+
+    # Generic settings
+    if [ -f "$django_project_dir/settings.py" -o \
+         -d "$django_project_dir/settings" ]; then
+        django_project=`basename $django_project_dir`
+
+        echo '#' $django_project
+        export PYTHONPATH=`dirname $django_project_dir`
+        export DJANGO_SETTINGS_MODULE=$django_project.settings
+        port=`get_django_setting LOCAL_SERVER_PORT 8000`
+
+        cat << EOF
+<VirtualHost 127.0.0.1:*>
+    ServerName $django_project.$domain
+    RewriteEngine On
+    RewriteRule ^/(.*) http://localhost:$port/\$1 [P]
+</VirtualHost>
+EOF
+
+        # Environment settings
+        for settings in $django_project_dir/settings/env/[a-z0-9_]*py; do
+            if [ `basename $settings` = "__init__.py" -o ! -f "$settings" ]; then
+                continue
+            fi
+
+            django_project_dir=`echo $settings | sed "s#/settings/env/.*py##"`
+            django_project=`basename $django_project_dir`
+            django_settings=`echo $settings | sed "s#$PROJECT_ROOT/##" | sed "s#[a-z0-9_]*/settings/env/#settings.env.#" | sed 's#.py$##'`
+            django_settings_id=`echo $django_settings | sed "s#.*\\.##"`
+
+            echo '#' $django_project $django_settings
+
+            export PYTHONPATH=`dirname $django_project_dir`
+            export DJANGO_SETTINGS_MODULE=$django_project.$django_settings
+            port=`get_django_setting LOCAL_SERVER_PORT 8000`
+
+            cat << EOF
+<VirtualHost 127.0.0.1:*>
+    ServerName $django_settings_id.$django_project.$domain
+    RewriteEngine On
+    RewriteRule ^/(.*) http://localhost:$port/\$1 [P]
+</VirtualHost>
+EOF
+        done
+
+        echo
+    fi
+done
+
+echo '# <<<' Generated django-environments virtual host config end

bin/deinitenv_generic

+#
+# Deinitialize the settings environment
+#
+# Should be sourced with the 'source' command, e.g. 'source deinitenv'.
+#
+# The source command can be performed within virtualenvwrapper's
+# bin/predeactivate, or you could just copy the following lines
+# to bin/predeactivate. Alternatively, you may also symlink
+# bin/predeactivate to (a custom version of) this file.
+
+djexit

bin/djenv.mercurial

+#
+# Mercurial utilities for django-environments
+# 
+
+hgbaseport=7100
+
+# Start hg server in daemon mode and open first argument in browser
+function hgserve() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+
+    local tmpdir=$PROJECT_ROOT/tmp
+    [ ! -d $tmpdir ] && mkdir $tmpdir
+    hgpidfile=$tmpdir/hgserve.pid
+
+    # Determine port number
+    local numhash=`basename $PROJECT_ROOT | openssl md5 | sed 's/[^0-9]//g'`
+    hgport=`expr $hgbaseport + ${numhash:0:2}`
+
+    # See if the server is alive - start it if not
+    kill -0 `cat $hgpidfile 2>&1` > /dev/null 2>&1
+    if [ ! $? -eq 0 ]; then
+        cwd=`pwd`
+        cdroot
+        hg serve --port $hgport --daemon \
+            --pid-file $PROJECT_ROOT/tmp/hgserve.pid
+        sleep 0.5
+        cd $cwd
+    fi
+
+    [ ! "$1" = "--no-open" ] && run_open http://localhost:$hgport/$1
+}
+
+# Browse files in tip
+function hgbrowse() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    hgserve --no-open
+
+    path=file/tip`echo \`pwd\` | sed "s#$PROJECT_ROOT##"`
+    [ ! -z "$1" ] && path=$path/$1
+
+    run_open http://localhost:$hgport/$path
+}
+
+# System-independent open
+function run_open() {
+    if which xdg-open; then xdg-open "$@"
+    else open "$@"; fi
+}
+
+# Shut down hg server
+function hgkill() {
+    kill -9 `cat "$hgpidfile" 2>&1` > /dev/null 2>&1
+    if [ ! $? -eq 0 ]; then
+        echo Server not running or other error 2>&1
+    fi
+}
+
+# Runs an hg command on all hg repositories in the externals directory,
+# e.g. 'hgexternals pull -u'
+function hgexternals() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    for external in $PROJECT_ROOT/externals/*; do
+        if [ -d $external/.hg ]; then
+            echo `basename $external`:
+            _IFS=$IFS
+            IFS='' # magic
+            hg -R $external $*
+            IFS=$_IFS
+            echo
+        fi
+    done
+}
+
+# Pull and update the project and all Mercurial externals
+function hgfetchall() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    hg -R $PROJECT_ROOT pull -u
+    echo
+    hgexternals pull -u
+}
+
+# List all .orig files
+function hgfindorig() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    find -H $PROJECT_ROOT -name \*.orig
+}
+
+# Remove all .orig files
+function hgremoveorig() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    find -H $PROJECT_ROOT -name \*.orig -print -delete
+}
+
+# Clean up
+function _djenv_mercurial_cleanup () {
+    # Stop server
+    hgkill 2>&1 > /dev/null
+    # Clean environment
+    unset hgport
+}
+
+_djenv_register_cleanup _djenv_mercurial_cleanup 
+#
+# django-environments initialization script
+#
+# Instead of editing the file, it's better to set the following
+# variable in your own initenv script or virtualenv bin/postactivate,
+# and source this file (order does not matter).
+#
+# PROJECT_ROOT is the path to the root of the entire project, i.e.
+# the directory containing the one or more 'Django projects'.
+#
+# PROJECT_ROOT=/Users/joe/projects/myproject
+
+# Not to be called directly, see djenv below
+function _djenv_init() {
+    DJANGO_PROJECT=$1
+    DJANGO_SETTINGS=$2
+
+    # The root of the project should exist, of course
+    [ -z "$PROJECT_ROOT" ] && \
+        echo "Variable \$PROJECT_ROOT not set or empty" 1>&2 && return 1
+    [ ! -d "$PROJECT_ROOT" ] && \
+         echo "Variable \$PROJECT_ROOT does not point to a readable directory" 1>&2 && return 1
+
+    # Check Django project as well
+    [ -z "$DJANGO_PROJECT" ] && \
+        echo "Argument \$DJANGO_PROJECT not set or empty" 1>&2 && return 1
+    [ ! -d "$PROJECT_ROOT/$DJANGO_PROJECT" ] && \
+        echo "Argument \$DJANGO_PROJECT does not identify a readable directory within $PROJECT_ROOT" 1>&2 && \
+        return 1
+
+    # If no particular settings are defined, just use the "base" settings
+    _OLD_DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
+    if [ ! -z "$DJANGO_SETTINGS" ]; then
+        DJANGO_SETTINGS_MODULE=$DJANGO_PROJECT.$DJANGO_SETTINGS
+    else
+        DJANGO_SETTINGS_MODULE=$DJANGO_PROJECT.settings
+    fi
+
+    # Set the PYTHONPATH to include PROJECT_ROOT
+    _OLD_PYTHONPATH=$PYTHONPATH
+    PYTHONPATH=$PROJECT_ROOT:$PYTHONPATH
+
+    export PROJECT_ROOT DJANGO_PROJECT PYTHONPATH DJANGO_SETTINGS_MODULE
+
+    # Test settings import
+    python -c "import $DJANGO_SETTINGS_MODULE" > /dev/null 2>&1
+    if [ ! "$?" -eq 0 ]; then
+        echo "Error importing settings $DJANGO_SETTINGS_MODULE (PYTHONPATH: $PYTHONPATH)" 1>&2
+        python -c "import $DJANGO_SETTINGS_MODULE"
+        return 1
+    fi
+
+    # Test if the definitions in the settings match ours
+
+    if [ ! -z "`get_django_setting :`" ]; then
+        echo "Current Django settings generate output - debugging print statements maybe?" 1>&2
+    else
+        [ "$PROJECT_ROOT" != "`get_django_setting PROJECT_ROOT`" ] && \
+            echo "\$PROJECT_ROOT in Django settings is different from shell" 1>&2 && \
+            echo "\$PROJECT_ROOT: $PROJECT_ROOT" 1>&2 && \
+            echo "settings.PROJECT_ROOT: `get_django_setting PROJECT_ROOT`" 1>&2 && \
+            return 1
+        [ "$DJANGO_PROJECT" != "`get_django_setting DJANGO_PROJECT`" ] && \
+            echo "\$DJANGO_PROJECT in Django settings is different from shell" 1>&2 && \
+            return 1
+        [ "$PROJECT_ROOT/$DJANGO_PROJECT" != "`get_django_setting DJANGO_PROJECT_DIR`" ] && \
+            echo "\$DJANGO_PROJECT_DIR in Django settings is different from \$PROJECT_ROOT/\$DJANGO_PROJECT" 1>&2 && 
+            return 1
+    fi
+
+    # We're good - let's set the prompt
+    _OLD_DJENV_PS1=$PS1
+    PS1=[$DJANGO_PROJECT]$PS1
+
+    # Show environment info
+    if [ ! -z "$SHOW_DJANGO_ENVIRONMENT" ]; then
+        if [ "$SHOW_DJANGO_ENVIRONMENT" = "yes" ]; then
+            echo Welcome to $DJANGO_PROJECT. Environment info:
+            djenv
+            echo
+            if [ "$SHOW_DJANGO_ENVIRONMENT" = "settings" ]; then
+                echo Django settings:
+                PAGER=cat python -c "import $DJANGO_SETTINGS_MODULE; help($DJANGO_SETTINGS_MODULE)" | grep -v "^$"
+                echo
+            fi
+        fi
+    fi
+
+    # Check non-critical settings
+    local dirs dir
+    for dirs in TEMPLATE_DIRS FIXTURE_DIRS; do
+        eval `import_django_settings $dirs`
+        envname=DJANGO_$dirs
+        for dir in ${!envname}; do
+            [ ! -d $dir ] && echo "Warning: \"$dir\" in settings.$dirs is not a valid directory"
+        done
+    done
+
+    return 0
+}
+
+# Register cleanup hook
+function _djenv_register_cleanup() {
+    local func
+    for func in $*; do
+        if [ -z "$DJENV_CLEANUP_FUNCTIONS" ]; then
+            DJENV_CLEANUP_FUNCTIONS=$func
+        else
+            DJENV_CLEANUP_FUNCTIONS=$DJENV_CLEANUP_FUNCTIONS:$func
+        fi
+    done
+}
+
+# Some useful functions
+
+# Exit current project
+function djexit() {
+    [ -z "$DJANGO_PROJECT" ] && return 1
+
+    # Restore prompt
+    if [ ! -z "$_OLD_DJENV_PS1" ]; then
+        PS1=$_OLD_DJENV_PS1
+        unset _OLD_DJENV_PS1
+    fi
+
+    # Restore django settings
+    if [ ! -z "$_OLD_DJANGO_SETTINGS_MODULE" ]; then
+        DJANGO_SETTINGS_MODULE=$_OLD_DJANGO_SETTINGS_MODULE
+    else
+        unset DJANGO_SETTINGS_MODULE
+    fi
+
+    # Restore python path
+    if [ ! -z "$_OLD_PYTHONPATH" ]; then
+        PYTHONPATH=$_OLD_PYTHONPATH
+    else
+        unset PYTHONPATH
+    fi
+
+    # Call the registerd cleanup functions
+    _IFS=$IFS
+    IFS=:
+    local func
+    for func in $DJENV_CLEANUP_FUNCTIONS; do
+        $func
+    done
+    IFS=$_IFS
+}
+
+# Change django project
+# Example:
+# djenv # Print current environment settings
+# or
+# djenv mysite # Use default settings
+# or
+# djenv mysite settings.env.local # Use specific settins
+function djenv() {
+    # Environment info
+    if [ -z "$1" ]; then
+        echo PROJECT_ROOT: \'$PROJECT_ROOT\'
+        echo DJANGO_PROJECT: \'$DJANGO_PROJECT\'
+        echo DJANGO_SETTINGS_MODULE: \'$DJANGO_SETTINGS_MODULE\'
+        echo PYTHONPATH: \'$PYTHONPATH\'
+        return
+    fi
+
+    # Help
+    if [ "$1" = "-h" -o "$1" = "--help" ]; then
+        echo "Usage: djenv [DJANGO_PROJECT [DJANGO_SETTINGS]]"
+        return
+    fi
+
+    # Check $PROJECT_ROOT
+    if [ -z "$PROJECT_ROOT" ]; then
+        echo "Variable \$PROJECT_ROOT not set or empty" 1>&2
+        return 1
+    fi
+
+    # Exit current environment (if any)
+    djexit
+
+    # Initialize
+    _djenv_init $*
+
+    # On error, use djexit for cleanup
+    [ ! $? -eq 0 ] && djexit && return 1
+
+    # Change working directory
+    cdjango
+
+    return 0
+}
+
+# Get a django setting from the current or specified settings module
+# Experimental.
+#
+# Example:
+# LC=`get_django_setting LANGUAGE_CODE` && echo $LC
+#
+# Returns the second argument if setting cannot be found. Be aware
+# that the settings file should not print anything to stdout for
+# this to work!
+function get_django_setting() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    [ -z "$DJANGO_SETTINGS_MODULE" ] && echo "No \$DJANGO_SETTINGS_MODULE" 1>&2 && return 1
+    [ -z "$1" ] && echo "Usage: get_django_setting <setting-name> [default-value] [settings-module]" 1>&2 && return 1
+    local settings_module
+    if [ ! -z "$3" ]; then
+        settings_module=$3
+    else
+        settings_module=$DJANGO_SETTINGS_MODULE
+    fi
+    python << EOF
+import $settings_module as settings
+
+try:
+    print settings.__dict__['$1']
+except KeyError:
+    print '$2'
+EOF
+}
+
+# Import django settings into the shell environment
+# Experimental.
+#
+# When using, set $IFS to empty (this is needed because we eval
+# the output of the python-generated shell script code):
+# IFS=''
+#
+# Then use the function as follows:
+# eval `import_django_settings` # all settings
+# or
+# eval `import_django_settings ADMIN` # all settings starting with 'ADMIN'
+#
+# Tuples and lists items are separated with newlines, so set $IFS
+# to newline to get to those:
+# IFS='
+# '
+# Note that all variables are prefixed with value of $prefix, 'DJANGO_'.
+function import_django_settings() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    [ -z "$DJANGO_SETTINGS_MODULE" ] && echo "No \$DJANGO_SETTINGS_MODULE" 1>&2 && return 1
+
+    prefix=DJANGO_
+    python << EOF
+import $DJANGO_SETTINGS_MODULE as settings
+from types import TupleType, ListType, DictType
+
+def escape(value):
+    return str(value).replace('"', '\\\\"')
+
+settings = settings.__dict__.items()
+settings.sort()
+for name, value in settings:
+    if name.find('__') == -1 and name.find('$1') == 0:
+        if type(value) in (TupleType, ListType):
+            print '$prefix%s="' % name
+            for item in value:
+                print escape(item)
+            print '"'
+        elif type(value) == DictType:
+            print '$prefix%s="' % name
+            for name, value in value.items():
+                print '%s:%s' % (name, escape(value))
+            print '"'
+        else:
+            print '$prefix%s="%s"' % (name, escape(value))
+EOF
+}
+
+# Change directory to project root
+function cdroot() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    cd $PROJECT_ROOT/$1
+}
+
+# Install dependencies for a python environment (first argument);
+# the file with the dependencies should be in the requirements
+# directory and should have the format 'libs-<environment>.txt'
+function pipup() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    [ -z "$1" ] && echo "Usage: pipup <requirements-identifier> [pip options]" 1>&2 && return 1
+    local requirements=$1
+    shift
+    pip install --requirement=$PROJECT_ROOT/requirements/libs-$requirements.txt $*
+}
+
+# Use compileall to compile all .py files - handy for web server
+# environments where the server user often has no write access to the
+# .pyc files / directories
+function pycompile() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    python -c "import compileall; compileall.compile_dir('$PROJECT_ROOT')"
+    removeorphanpycs
+}
+
+# Remove .pyc files without a corresponding .py
+function removeorphanpycs() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    local pyc
+    for pyc in `find -H $PROJECT_ROOT -name \*.pyc`; do
+        [ -f  `echo $pyc | sed 's/c$//'` ] || rm -v $pyc
+    done
+}
+
+# Change directory to Django project
+function cdjango () {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    [ -z "$DJANGO_PROJECT" ] && echo "No \$DJANGO_PROJECT" 1>&2 && return 1
+    cd $PROJECT_ROOT/$DJANGO_PROJECT/$1
+}
+
+# Forget manage.py, django-admin.py respects our settings!
+function djadmin() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    django-admin.py $*
+}
+
+# Run development server on settings.LOCAL_SERVER_PORT
+function runserver() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    [ -z "$DJANGO_PROJECT" ] && echo "No \$DJANGO_PROJECT" 1>&2 && return 1
+    django-admin.py runserver `get_django_setting LOCAL_SERVER_PORT` $*
+}
+
+# Run test server on settings.LOCAL_SERVER_PORT
+function testserver() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    [ -z "$DJANGO_PROJECT" ] && echo "No \$DJANGO_PROJECT" 1>&2 && return 1
+    django-admin.py testserver --addrport=`get_django_setting LOCAL_SERVER_PORT` $*
+}
+
+# Export functions that are not solely intended for interactive use
+export -f get_django_setting import_django_settings
+
+# Clean up the environment
+function _djenv_cleanup () {
+    unset DJANGO_PROJECT DJANGO_SETTINGS \
+        _OLD_DJANGO_SETTINGS_MODULE _OLD_PYTHONPATH \
+        DJANGO_TEMPLATE_DIRS DJANGO_FIXTURE_DIRS
+}
+
+# Use _djenv_register_cleanup to register your own cleanup functions
+_djenv_register_cleanup _djenv_cleanup
+
+#
+# Tab completion
+#
+
+function show_django_projects() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    (cd $PROJECT_ROOT; for f in */settings/__init__.py; do echo $f; done) | \
+        sed 's#/settings/__init__.py##' | sort
+}
+
+function show_django_settings() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    (cd $PROJECT_ROOT/$1; for f in settings/env/*.py; do echo $f; done) | \
+        grep -v '/__init__.py$' | sed 's#settings/env/#settings.env.#' | \
+        sed 's#\.py$##' | sort
+}
+
+_django_projects_complete() {
+    local current="${COMP_WORDS[COMP_CWORD]}"
+    local previous="${COMP_WORDS[COMP_CWORD - 1]}"
+
+    if [ $COMP_CWORD -eq 1 ]; then
+        COMPREPLY=($(compgen -W "`show_django_projects`" -- ${current}))
+    elif [ $COMP_CWORD -eq 2 ]; then
+        COMPREPLY=( $(compgen -W "`show_django_settings $previous`" -- ${current}) )
+    fi
+}
+
+_cdroot_complete() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    COMPREPLY=($(cdroot && compgen -d -- "${2}" ))
+}
+
+_cdjango_complete() {
+    [ -z "$DJANGO_PROJECT" ] && echo "No \$DJANGO_PROJECT" 1>&2 && return 1
+    COMPREPLY=($(cdjango && compgen -d -- "${2}" ))
+}
+
+function show_pip_environments() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    (cd $PROJECT_ROOT/requirements; for f in libs-*.txt; do echo $f; done) | \
+        sed 's#libs-##' | sed 's#.txt##' | sort
+}
+
+_pipup_complete() {
+    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
+    COMPREPLY=($(compgen -W "`show_pip_environments`" -- "${2}" ))
+}
+
+complete -o nospace -F _cdroot_complete -S/ cdroot
+complete -o nospace -F _cdjango_complete -S/ cdjango
+complete -F _django_projects_complete djenv
+complete -F _pipup_complete pipup

bin/initenv_example

+#
+# Initialize the settings environment
+#
+# Should be sourced with the 'source' command, e.g. 'source initenv'
+#
+# The source command can be performed within virtualenvwrapper's
+# bin/postdeactivate, or you could just copy the following lines
+# to bin/postdeactivate. Alternatively, you may also symlink
+# bin/postdeactivate to (a custom version of) this file.
+
+# The root of the project, i.e. the directory containing your Django projects
+# PROJECT_ROOT=/Users/joe/projects/myproject
+PROJECT_ROOT=$HOME/repos/django-environments
+# Debugging output: 'yes' shows basic info, 'settings' all settings
+SHOW_DJANGO_ENVIRONMENT=yes
+
+source $PROJECT_ROOT/bin/djenvlib
+
+# Switch environment to Django project mysite, using development settings
+djenv mysite settings.env.development
+
+# Domain for virtual host configuration - optional (see
+# bin/create_apache_vhost_conf.sh)
+#export DOMAIN=local.mysite.org
+
+# For your convenience: these two lines help greatly when using pip
+# with virtualenv, see http://pip.openplans.org/
+#export PIP_REQUIRE_VIRTUALENV=true PIP_RESPECT_VIRTUALENV=true

bin/run_in_env_wrapper.sh

+#!/bin/sh
+#
+# Standard environment wrapper for other scripts
+#
+# To be called from another script that sets the following correctly:
+# - PROJECT_ROOT
+# - DJANGO_PROJECT
+# - DJANGO_SETTINGS
+# - VIRTUAL_ENV (optional)
+
+APP_HOME=`dirname $0` # Make sure we can refer back to this location
+
+# Update PATH
+PATH=$APP_HOME:$PATH
+
+# Update PYTHONPATH
+PYTHONPATH=$PROJECT_ROOT/apps:$PYTHONPATH
+
+# Check for help request
+if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    echo "Usage: `basename $0` <command> [args...]"
+    echo
+    echo "Where <command> is any of the following:"
+    for file in $APP_HOME/*; do
+        [ -x $file -a `basename $file` != `basename $0` ] && echo "    "`basename $file`
+    done
+    exit
+fi
+
+# Check if arguments supplied
+[ -z "$1" ] && echo "Usage: `basename $0` <command> [args...]" 1>&2 && exit 1
+
+# Check if command exists as an executable file
+[ ! -x $APP_HOME/$1 ] && echo "`basename $0`: $1 not found!" && exit 1
+
+# Set python environment
+[ -f $VIRTUAL_ENV/bin/activate ] && source $VIRTUAL_ENV/bin/activate
+
+# Set django environment
+source $PROJECT_ROOT/bin/djenvlib
+
+# Set DJANGO_PROJECT and DJANGO_SETTINGS to empty so djenv doesn't think
+# we're already in an active environment (which it will try to exit first):
+DJANGO_PROJECT= DJANGO_SETTINGS= djenv $DJANGO_PROJECT $DJANGO_SETTINGS
+
+# Execute command
+$*

bin/setup_local_wsgi.sh

+#!/bin/sh
+#
+# Generates deploy/local.wsgi and settings/env/local.py for a given
+# environment
+#
+# To be run in an activated django-environment environment, i.e.
+# $PROJECT_ROOT and $DJANGO_PROJECT must be set correctly.
+
+env=$1
+local=local # Identifier for local configuration
+
+# Check arguments
+[ -z "$env" ] && echo "Usage: $0 <environment>" 1>&2 && exit 1
+
+# The root of the project should exist, of course
+[ -z "$PROJECT_ROOT" ] && \
+    echo "Variable \$PROJECT_ROOT not set or empty" 1>&2 && exit 1
+[ ! -d "$PROJECT_ROOT" ] && \
+     echo "Variable \$PROJECT_ROOT does not point to a readable directory" 1>&2 && exit 1
+
+# Check Django project as well
+[ -z "$DJANGO_PROJECT" ] && \
+    echo "Variable \$DJANGO_PROJECT not set or empty" 1>&2 && exit 1
+[ ! -d "$PROJECT_ROOT/$DJANGO_PROJECT" ] && \
+    echo "Variable \$DJANGO_PROJECT does not identify a readable directory within $PROJECT_ROOT" 1>&2 && \
+    exit 1
+
+# WSGI symlink
+
+deploy_dir=$PROJECT_ROOT/$DJANGO_PROJECT/deploy
+wsgi_target=$deploy_dir/$env.wsgi
+wsgi_local=$deploy_dir/$local.wsgi
+[ ! -f "$wsgi_target" ] && echo "$wsgi_target not found - exiting" 1>&2 && exit 1
+
+rm -f $wsgi_local
+ln -s $env.wsgi $wsgi_local
+[ ! $? -eq 0 ] && echo "Error creating symlink $wsgi_local" 1>&2 && exit 1
+echo "Link $local.wsgi to $wsgi_target created" 1>&2
+
+# Settings python file
+
+settings_dir=$PROJECT_ROOT/$DJANGO_PROJECT/settings/env
+settings_target=$settings_dir/$env.py
+settings_local=$PROJECT_ROOT/$DJANGO_PROJECT/settings/env/$local.py
+[ ! -f "$settings_target" ] && echo "$settings_target not found - exiting" 1>&2 && exit 1
+
+cat > $settings_local << EOF
+from $env import *
+
+# You can set stuff you don't wish to store anywhere else here, like:
+# DATABASES['default']['PASSWORD'] = 'secret'
+EOF
+echo "$settings_local created" 1>&2

scripts/create_apache_vhost_conf.sh

-#!/bin/sh
-#
-# Generates Apache named virtual host configuration for reverse
-# proxying runserver instances, to be included from your Apache
-# configuration.
-#
-# This way, you can have unlimited Django runserver instances running
-# at the same time, each one listening on a different port as specified
-# in the settings. This makes life easier when working with multiple
-# Django projects simultaneously, but it also allows comparison between
-# different settings within a single Django project, for instance the
-# performance of two different database backends.
-#
-# Either set settings.LOCAL_SERVER_PORT to the port you want to use
-# for a given Django project (in settings/generic.py), and optionally
-# overrule settings.LOCAL_SERVER_PORT in a specific environment
-# settings file, like settings/env/dev_postgresql.py. (It's a good
-# idea to have a port numbering strategy ready before you start, just
-# like with BASIC line numbers: 7000-7099 project A, 7100-7199 project
-# B and so on.)
-#
-# By default, the generated virtual hosts will have the naming formats
-# 'django_project_id.local' and 'settings_id.django_project_id.local'.
-# By defining environment variable $DOMAIN you can change the domain
-# postfix to anything you like, for instance
-# 'development.myorganization.dom'.
-#
-# Steps to get this working:
-#
-# 1. Run this script and save the output to a file, for instance
-#    create_apache_vhost_conf.sh > $PROJECT_ROOT/deploy/vhosts-development.conf
-#    (It's good idea to do this in a VCS hook to always keep it up-to-date.)
-#
-# 2. Include the configuration file in your Apache configuration:
-#    Include /Users/spanky/repos/myproject/deploy/vhosts-development.conf
-#
-# 3. Restart Apache.
-#
-# 4. For each of the generated virtual hosts you wish to use, add
-#    the host name to the localhost entry in /etc/hosts:
-#    127.0.0.1 localhost django_project_id.local
-#
-#    Or, even better: use a DNS server that supports wildcards! This
-#    way you simply have to make sure that *.development.myorganization.dom
-#    points to 127.0.0.1, and you're done.
-#
-# 5. Use 'djenv django_project_id settings_id', followed by 'runserver'
-#    to have a Django server listening at the port you specified in the
-#    settings. Note you will have to use the 'runserver' function as
-#    provided by django-environments to have the server actually listen
-#    on settings.LOCAL_SERVER_PORT.
-#
-# 6. Go to the appropriate URL, e.g.
-#    http://settings_id.django_project_id.local/ and admire your work.
-
-domain=local
-[ ! -z "$DOMAIN" ] && domain=$DOMAIN
-
-# The root of the project should exist, of course
-[ -z "$PROJECT_ROOT" ] && \
-    echo "Variable \$PROJECT_ROOT not set or empty" 1>&2 && exit 1
-[ ! -d "$PROJECT_ROOT" ] && \
-     echo "Variable \$PROJECT_ROOT does not point to a readable directory" 1>&2 && exit 1
-
-cd `dirname $0`
-
-echo '# >>>' Generated django-environments virtual host config start
-echo
-echo NameVirtualHost 127.0.0.1:*
-echo
-
-for django_project_dir in $PROJECT_ROOT/*; do
-
-    # Generic settings
-    if [ -f "$django_project_dir/settings.py" -o \
-         -d "$django_project_dir/settings" ]; then
-        django_project=`basename $django_project_dir`
-
-        echo '#' $django_project
-        export PYTHONPATH=`dirname $django_project_dir`
-        export DJANGO_SETTINGS_MODULE=$django_project.settings
-        port=`get_django_setting LOCAL_SERVER_PORT 8000`
-
-        cat << EOF
-<VirtualHost 127.0.0.1:*>
-    ServerName $django_project.$domain
-    RewriteEngine On
-    RewriteRule ^/(.*) http://localhost:$port/\$1 [P]
-</VirtualHost>
-EOF
-
-        # Environment settings
-        for settings in $django_project_dir/settings/env/[a-z0-9_]*py; do
-            if [ `basename $settings` = "__init__.py" -o ! -f "$settings" ]; then
-                continue
-            fi
-
-            django_project_dir=`echo $settings | sed "s#/settings/env/.*py##"`
-            django_project=`basename $django_project_dir`
-            django_settings=`echo $settings | sed "s#$PROJECT_ROOT/##" | sed "s#[a-z0-9_]*/settings/env/#settings.env.#" | sed 's#.py$##'`
-            django_settings_id=`echo $django_settings | sed "s#.*\\.##"`
-
-            echo '#' $django_project $django_settings
-
-            export PYTHONPATH=`dirname $django_project_dir`
-            export DJANGO_SETTINGS_MODULE=$django_project.$django_settings
-            port=`get_django_setting LOCAL_SERVER_PORT 8000`
-
-            cat << EOF
-<VirtualHost 127.0.0.1:*>
-    ServerName $django_settings_id.$django_project.$domain
-    RewriteEngine On
-    RewriteRule ^/(.*) http://localhost:$port/\$1 [P]
-</VirtualHost>
-EOF
-        done
-
-        echo
-    fi
-done
-
-echo '# <<<' Generated django-environments virtual host config end

scripts/deinitenv_generic

-#
-# Deinitialize the settings environment
-#
-# Should be sourced with the 'source' command, e.g. 'source deinitenv'.
-#
-# The source command can be performed within virtualenvwrapper's
-# bin/predeactivate, or you could just copy the following lines
-# to bin/predeactivate. Alternatively, you may also symlink
-# bin/predeactivate to (a custom version of) this file.
-
-djexit

scripts/djenv.mercurial

-#
-# Mercurial utilities for django-environments
-# 
-
-hgbaseport=7100
-
-# Start hg server in daemon mode and open first argument in browser
-function hgserve() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-
-    local tmpdir=$PROJECT_ROOT/tmp
-    [ ! -d $tmpdir ] && mkdir $tmpdir
-    hgpidfile=$tmpdir/hgserve.pid
-
-    # Determine port number
-    local numhash=`basename $PROJECT_ROOT | openssl md5 | sed 's/[^0-9]//g'`
-    hgport=`expr $hgbaseport + ${numhash:0:2}`
-
-    # See if the server is alive - start it if not
-    kill -0 `cat $hgpidfile 2>&1` > /dev/null 2>&1
-    if [ ! $? -eq 0 ]; then
-        cwd=`pwd`
-        cdroot
-        hg serve --port $hgport --daemon \
-            --pid-file $PROJECT_ROOT/tmp/hgserve.pid
-        sleep 0.5
-        cd $cwd
-    fi
-
-    [ ! "$1" = "--no-open" ] && run_open http://localhost:$hgport/$1
-}
-
-# Browse files in tip
-function hgbrowse() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    hgserve --no-open
-
-    path=file/tip`echo \`pwd\` | sed "s#$PROJECT_ROOT##"`
-    [ ! -z "$1" ] && path=$path/$1
-
-    run_open http://localhost:$hgport/$path
-}
-
-# System-independent open
-function run_open() {
-    if which xdg-open; then xdg-open "$@"
-    else open "$@"; fi
-}
-
-# Shut down hg server
-function hgkill() {
-    kill -9 `cat "$hgpidfile" 2>&1` > /dev/null 2>&1
-    if [ ! $? -eq 0 ]; then
-        echo Server not running or other error 2>&1
-    fi
-}
-
-# Runs an hg command on all hg repositories in the externals directory,
-# e.g. 'hgexternals pull -u'
-function hgexternals() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    for external in $PROJECT_ROOT/externals/*; do
-        if [ -d $external/.hg ]; then
-            echo `basename $external`:
-            _IFS=$IFS
-            IFS='' # magic
-            hg -R $external $*
-            IFS=$_IFS
-            echo
-        fi
-    done
-}
-
-# Pull and update the project and all Mercurial externals
-function hgfetchall() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    hg -R $PROJECT_ROOT pull -u
-    echo
-    hgexternals pull -u
-}
-
-# List all .orig files
-function hgfindorig() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    find -H $PROJECT_ROOT -name \*.orig
-}
-
-# Remove all .orig files
-function hgremoveorig() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    find -H $PROJECT_ROOT -name \*.orig -print -delete
-}
-
-# Clean up
-function _djenv_mercurial_cleanup () {
-    # Stop server
-    hgkill 2>&1 > /dev/null
-    # Clean environment
-    unset hgport
-}
-
-_djenv_register_cleanup _djenv_mercurial_cleanup 

scripts/djenvlib

-#
-# django-environments initialization script
-#
-# Instead of editing the file, it's better to set the following
-# variable in your own initenv script or virtualenv bin/postactivate,
-# and source this file (order does not matter).
-#
-# PROJECT_ROOT is the path to the root of the entire project, i.e.
-# the directory containing the one or more 'Django projects'.
-#
-# PROJECT_ROOT=/Users/joe/projects/myproject
-
-# Not to be called directly, see djenv below
-function _djenv_init() {
-    DJANGO_PROJECT=$1
-    DJANGO_SETTINGS=$2
-
-    # The root of the project should exist, of course
-    [ -z "$PROJECT_ROOT" ] && \
-        echo "Variable \$PROJECT_ROOT not set or empty" 1>&2 && return 1
-    [ ! -d "$PROJECT_ROOT" ] && \
-         echo "Variable \$PROJECT_ROOT does not point to a readable directory" 1>&2 && return 1
-
-    # Check Django project as well
-    [ -z "$DJANGO_PROJECT" ] && \
-        echo "Argument \$DJANGO_PROJECT not set or empty" 1>&2 && return 1
-    [ ! -d "$PROJECT_ROOT/$DJANGO_PROJECT" ] && \
-        echo "Argument \$DJANGO_PROJECT does not identify a readable directory within $PROJECT_ROOT" 1>&2 && \
-        return 1
-
-    # If no particular settings are defined, just use the "base" settings
-    _OLD_DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
-    if [ ! -z "$DJANGO_SETTINGS" ]; then
-        DJANGO_SETTINGS_MODULE=$DJANGO_PROJECT.$DJANGO_SETTINGS
-    else
-        DJANGO_SETTINGS_MODULE=$DJANGO_PROJECT.settings
-    fi
-
-    # Set the PYTHONPATH to include PROJECT_ROOT
-    _OLD_PYTHONPATH=$PYTHONPATH
-    PYTHONPATH=$PROJECT_ROOT:$PYTHONPATH
-
-    export PROJECT_ROOT DJANGO_PROJECT PYTHONPATH DJANGO_SETTINGS_MODULE
-
-    # Test settings import
-    python -c "import $DJANGO_SETTINGS_MODULE" > /dev/null 2>&1
-    if [ ! "$?" -eq 0 ]; then
-        echo "Error importing settings $DJANGO_SETTINGS_MODULE (PYTHONPATH: $PYTHONPATH)" 1>&2
-        python -c "import $DJANGO_SETTINGS_MODULE"
-        return 1
-    fi
-
-    # Test if the definitions in the settings match ours
-
-    if [ ! -z "`get_django_setting :`" ]; then
-        echo "Current Django settings generate output - debugging print statements maybe?" 1>&2
-    else
-        [ "$PROJECT_ROOT" != "`get_django_setting PROJECT_ROOT`" ] && \
-            echo "\$PROJECT_ROOT in Django settings is different from shell" 1>&2 && \
-            echo "\$PROJECT_ROOT: $PROJECT_ROOT" 1>&2 && \
-            echo "settings.PROJECT_ROOT: `get_django_setting PROJECT_ROOT`" 1>&2 && \
-            return 1
-        [ "$DJANGO_PROJECT" != "`get_django_setting DJANGO_PROJECT`" ] && \
-            echo "\$DJANGO_PROJECT in Django settings is different from shell" 1>&2 && \
-            return 1
-        [ "$PROJECT_ROOT/$DJANGO_PROJECT" != "`get_django_setting DJANGO_PROJECT_DIR`" ] && \
-            echo "\$DJANGO_PROJECT_DIR in Django settings is different from \$PROJECT_ROOT/\$DJANGO_PROJECT" 1>&2 && 
-            return 1
-    fi
-
-    # We're good - let's set the prompt
-    _OLD_DJENV_PS1=$PS1
-    PS1=[$DJANGO_PROJECT]$PS1
-
-    # Show environment info
-    if [ ! -z "$SHOW_DJANGO_ENVIRONMENT" ]; then
-        if [ "$SHOW_DJANGO_ENVIRONMENT" = "yes" ]; then
-            echo Welcome to $DJANGO_PROJECT. Environment info:
-            djenv
-            echo
-            if [ "$SHOW_DJANGO_ENVIRONMENT" = "settings" ]; then
-                echo Django settings:
-                PAGER=cat python -c "import $DJANGO_SETTINGS_MODULE; help($DJANGO_SETTINGS_MODULE)" | grep -v "^$"
-                echo
-            fi
-        fi
-    fi
-
-    # Check non-critical settings
-    local dirs dir
-    for dirs in TEMPLATE_DIRS FIXTURE_DIRS; do
-        eval `import_django_settings $dirs`
-        envname=DJANGO_$dirs
-        for dir in ${!envname}; do
-            [ ! -d $dir ] && echo "Warning: \"$dir\" in settings.$dirs is not a valid directory"
-        done
-    done
-
-    return 0
-}
-
-# Register cleanup hook
-function _djenv_register_cleanup() {
-    local func
-    for func in $*; do
-        if [ -z "$DJENV_CLEANUP_FUNCTIONS" ]; then
-            DJENV_CLEANUP_FUNCTIONS=$func
-        else
-            DJENV_CLEANUP_FUNCTIONS=$DJENV_CLEANUP_FUNCTIONS:$func
-        fi
-    done
-}
-
-# Some useful functions
-
-# Exit current project
-function djexit() {
-    [ -z "$DJANGO_PROJECT" ] && return 1
-
-    # Restore prompt
-    if [ ! -z "$_OLD_DJENV_PS1" ]; then
-        PS1=$_OLD_DJENV_PS1
-        unset _OLD_DJENV_PS1
-    fi
-
-    # Restore django settings
-    if [ ! -z "$_OLD_DJANGO_SETTINGS_MODULE" ]; then
-        DJANGO_SETTINGS_MODULE=$_OLD_DJANGO_SETTINGS_MODULE
-    else
-        unset DJANGO_SETTINGS_MODULE
-    fi
-
-    # Restore python path
-    if [ ! -z "$_OLD_PYTHONPATH" ]; then
-        PYTHONPATH=$_OLD_PYTHONPATH
-    else
-        unset PYTHONPATH
-    fi
-
-    # Call the registerd cleanup functions
-    _IFS=$IFS
-    IFS=:
-    local func
-    for func in $DJENV_CLEANUP_FUNCTIONS; do
-        $func
-    done
-    IFS=$_IFS
-}
-
-# Change django project
-# Example:
-# djenv # Print current environment settings
-# or
-# djenv mysite # Use default settings
-# or
-# djenv mysite settings.env.local # Use specific settins
-function djenv() {
-    # Environment info
-    if [ -z "$1" ]; then
-        echo PROJECT_ROOT: \'$PROJECT_ROOT\'
-        echo DJANGO_PROJECT: \'$DJANGO_PROJECT\'
-        echo DJANGO_SETTINGS_MODULE: \'$DJANGO_SETTINGS_MODULE\'
-        echo PYTHONPATH: \'$PYTHONPATH\'
-        return
-    fi
-
-    # Help
-    if [ "$1" = "-h" -o "$1" = "--help" ]; then
-        echo "Usage: djenv [DJANGO_PROJECT [DJANGO_SETTINGS]]"
-        return
-    fi
-
-    # Check $PROJECT_ROOT
-    if [ -z "$PROJECT_ROOT" ]; then
-        echo "Variable \$PROJECT_ROOT not set or empty" 1>&2
-        return 1
-    fi
-
-    # Exit current environment (if any)
-    djexit
-
-    # Initialize
-    _djenv_init $*
-
-    # On error, use djexit for cleanup
-    [ ! $? -eq 0 ] && djexit && return 1
-
-    # Change working directory
-    cdjango
-
-    return 0
-}
-
-# Get a django setting from the current or specified settings module
-# Experimental.
-#
-# Example:
-# LC=`get_django_setting LANGUAGE_CODE` && echo $LC
-#
-# Returns the second argument if setting cannot be found. Be aware
-# that the settings file should not print anything to stdout for
-# this to work!
-function get_django_setting() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    [ -z "$DJANGO_SETTINGS_MODULE" ] && echo "No \$DJANGO_SETTINGS_MODULE" 1>&2 && return 1
-    [ -z "$1" ] && echo "Usage: get_django_setting <setting-name> [default-value] [settings-module]" 1>&2 && return 1
-    local settings_module
-    if [ ! -z "$3" ]; then
-        settings_module=$3
-    else
-        settings_module=$DJANGO_SETTINGS_MODULE
-    fi
-    python << EOF
-import $settings_module as settings
-
-try:
-    print settings.__dict__['$1']
-except KeyError:
-    print '$2'
-EOF
-}
-
-# Import django settings into the shell environment
-# Experimental.
-#
-# When using, set $IFS to empty (this is needed because we eval
-# the output of the python-generated shell script code):
-# IFS=''
-#
-# Then use the function as follows:
-# eval `import_django_settings` # all settings
-# or
-# eval `import_django_settings ADMIN` # all settings starting with 'ADMIN'
-#
-# Tuples and lists items are separated with newlines, so set $IFS
-# to newline to get to those:
-# IFS='
-# '
-# Note that all variables are prefixed with value of $prefix, 'DJANGO_'.
-function import_django_settings() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    [ -z "$DJANGO_SETTINGS_MODULE" ] && echo "No \$DJANGO_SETTINGS_MODULE" 1>&2 && return 1
-
-    prefix=DJANGO_
-    python << EOF
-import $DJANGO_SETTINGS_MODULE as settings
-from types import TupleType, ListType, DictType
-
-def escape(value):
-    return str(value).replace('"', '\\\\"')
-
-settings = settings.__dict__.items()
-settings.sort()
-for name, value in settings:
-    if name.find('__') == -1 and name.find('$1') == 0:
-        if type(value) in (TupleType, ListType):
-            print '$prefix%s="' % name
-            for item in value:
-                print escape(item)
-            print '"'
-        elif type(value) == DictType:
-            print '$prefix%s="' % name
-            for name, value in value.items():
-                print '%s:%s' % (name, escape(value))
-            print '"'
-        else:
-            print '$prefix%s="%s"' % (name, escape(value))
-EOF
-}
-
-# Change directory to project root
-function cdroot() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    cd $PROJECT_ROOT/$1
-}
-
-# Install dependencies for a python environment (first argument);
-# the file with the dependencies should be in the requirements
-# directory and should have the format 'libs-<environment>.txt'
-function pipup() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    [ -z "$1" ] && echo "Usage: pipup <requirements-identifier> [pip options]" 1>&2 && return 1
-    local requirements=$1
-    shift
-    pip install --requirement=$PROJECT_ROOT/requirements/libs-$requirements.txt $*
-}
-
-# Use compileall to compile all .py files - handy for web server
-# environments where the server user often has no write access to the
-# .pyc files / directories
-function pycompile() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    python -c "import compileall; compileall.compile_dir('$PROJECT_ROOT')"
-    removeorphanpycs
-}
-
-# Remove .pyc files without a corresponding .py
-function removeorphanpycs() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    local pyc
-    for pyc in `find -H $PROJECT_ROOT -name \*.pyc`; do
-        [ -f  `echo $pyc | sed 's/c$//'` ] || rm -v $pyc
-    done
-}
-
-# Change directory to Django project
-function cdjango () {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    [ -z "$DJANGO_PROJECT" ] && echo "No \$DJANGO_PROJECT" 1>&2 && return 1
-    cd $PROJECT_ROOT/$DJANGO_PROJECT/$1
-}
-
-# Forget manage.py, django-admin.py respects our settings!
-function djadmin() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    django-admin.py $*
-}
-
-# Run development server on settings.LOCAL_SERVER_PORT
-function runserver() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    [ -z "$DJANGO_PROJECT" ] && echo "No \$DJANGO_PROJECT" 1>&2 && return 1
-    django-admin.py runserver `get_django_setting LOCAL_SERVER_PORT` $*
-}
-
-# Run test server on settings.LOCAL_SERVER_PORT
-function testserver() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    [ -z "$DJANGO_PROJECT" ] && echo "No \$DJANGO_PROJECT" 1>&2 && return 1
-    django-admin.py testserver --addrport=`get_django_setting LOCAL_SERVER_PORT` $*
-}
-
-# Export functions that are not solely intended for interactive use
-export -f get_django_setting import_django_settings
-
-# Clean up the environment
-function _djenv_cleanup () {
-    unset DJANGO_PROJECT DJANGO_SETTINGS \
-        _OLD_DJANGO_SETTINGS_MODULE _OLD_PYTHONPATH \
-        DJANGO_TEMPLATE_DIRS DJANGO_FIXTURE_DIRS
-}
-
-# Use _djenv_register_cleanup to register your own cleanup functions
-_djenv_register_cleanup _djenv_cleanup
-
-#
-# Tab completion
-#
-
-function show_django_projects() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    (cd $PROJECT_ROOT; for f in */settings/__init__.py; do echo $f; done) | \
-        sed 's#/settings/__init__.py##' | sort
-}
-
-function show_django_settings() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    (cd $PROJECT_ROOT/$1; for f in settings/env/*.py; do echo $f; done) | \
-        grep -v '/__init__.py$' | sed 's#settings/env/#settings.env.#' | \
-        sed 's#\.py$##' | sort
-}
-
-_django_projects_complete() {
-    local current="${COMP_WORDS[COMP_CWORD]}"
-    local previous="${COMP_WORDS[COMP_CWORD - 1]}"
-
-    if [ $COMP_CWORD -eq 1 ]; then
-        COMPREPLY=($(compgen -W "`show_django_projects`" -- ${current}))
-    elif [ $COMP_CWORD -eq 2 ]; then
-        COMPREPLY=( $(compgen -W "`show_django_settings $previous`" -- ${current}) )
-    fi
-}
-
-_cdroot_complete() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    COMPREPLY=($(cdroot && compgen -d -- "${2}" ))
-}
-
-_cdjango_complete() {
-    [ -z "$DJANGO_PROJECT" ] && echo "No \$DJANGO_PROJECT" 1>&2 && return 1
-    COMPREPLY=($(cdjango && compgen -d -- "${2}" ))
-}
-
-function show_pip_environments() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    (cd $PROJECT_ROOT/requirements; for f in libs-*.txt; do echo $f; done) | \
-        sed 's#libs-##' | sed 's#.txt##' | sort
-}
-
-_pipup_complete() {
-    [ -z "$PROJECT_ROOT" ] && echo "No \$PROJECT_ROOT" 1>&2 && return 1
-    COMPREPLY=($(compgen -W "`show_pip_environments`" -- "${2}" ))
-}
-
-complete -o nospace -F _cdroot_complete -S/ cdroot
-complete -o nospace -F _cdjango_complete -S/ cdjango
-complete -F _django_projects_complete djenv
-complete -F _pipup_complete pipup

scripts/initenv_example

-#
-# Initialize the settings environment
-#
-# Should be sourced with the 'source' command, e.g. 'source initenv'
-#
-# The source command can be performed within virtualenvwrapper's
-# bin/postdeactivate, or you could just copy the following lines
-# to bin/postdeactivate. Alternatively, you may also symlink
-# bin/postdeactivate to (a custom version of) this file.
-
-# The root of the project, i.e. the directory containing your Django projects
-# PROJECT_ROOT=/Users/joe/projects/myproject
-PROJECT_ROOT=$HOME/repos/django-environments
-# Debugging output: 'yes' shows basic info, 'settings' all settings
-SHOW_DJANGO_ENVIRONMENT=yes
-
-source $PROJECT_ROOT/scripts/djenvlib
-
-# Switch environment to Django project mysite, using development settings
-djenv mysite settings.env.development
-
-# Domain for virtual host configuration - optional (see
-# scripts/create_apache_vhost_conf.sh)
-#export DOMAIN=local.mysite.org
-
-# For your convenience: these two lines help greatly when using pip
-# with virtualenv, see http://pip.openplans.org/
-#export PIP_REQUIRE_VIRTUALENV=true PIP_RESPECT_VIRTUALENV=true

scripts/run_in_env_wrapper.sh

-#!/bin/sh
-#
-# Standard environment wrapper for other scripts
-#
-# To be called from another script that sets the following correctly:
-# - PROJECT_ROOT
-# - DJANGO_PROJECT
-# - DJANGO_SETTINGS
-# - VIRTUAL_ENV (optional)
-
-APP_HOME=`dirname $0` # Make sure we can refer back to this location
-
-# Update PATH
-PATH=$APP_HOME:$PATH
-
-# Update PYTHONPATH
-PYTHONPATH=$PROJECT_ROOT/apps:$PYTHONPATH
-
-# Check for help request
-if [ "$1" = "-h" -o "$1" = "--help" ]; then
-    echo "Usage: `basename $0` <command> [args...]"
-    echo
-    echo "Where <command> is any of the following:"
-    for file in $APP_HOME/*; do
-        [ -x $file -a `basename $file` != `basename $0` ] && echo "    "`basename $file`
-    done
-    exit
-fi
-
-# Check if arguments supplied
-[ -z "$1" ] && echo "Usage: `basename $0` <command> [args...]" 1>&2 && exit 1
-
-# Check if command exists as an executable file
-[ ! -x $APP_HOME/$1 ] && echo "`basename $0`: $1 not found!" && exit 1
-
-# Set python environment
-[ -f $VIRTUAL_ENV/bin/activate ] && source $VIRTUAL_ENV/bin/activate
-
-# Set django environment
-source $PROJECT_ROOT/scripts/djenvlib
-
-# Set DJANGO_PROJECT and DJANGO_SETTINGS to empty so djenv doesn't think
-# we're already in an active environment (which it will try to exit first):
-DJANGO_PROJECT= DJANGO_SETTINGS= djenv $DJANGO_PROJECT $DJANGO_SETTINGS
-
-# Execute command
-$*

scripts/setup_local_wsgi.sh

-#!/bin/sh
-#
-# Generates deploy/local.wsgi and settings/env/local.py for a given
-# environment
-#
-# To be run in an activated django-environment environment, i.e.
-# $PROJECT_ROOT and $DJANGO_PROJECT must be set correctly.
-
-env=$1
-local=local # Identifier for local configuration
-
-# Check arguments
-[ -z "$env" ] && echo "Usage: $0 <environment>" 1>&2 && exit 1
-
-# The root of the project should exist, of course
-[ -z "$PROJECT_ROOT" ] && \
-    echo "Variable \$PROJECT_ROOT not set or empty" 1>&2 && exit 1
-[ ! -d "$PROJECT_ROOT" ] && \
-     echo "Variable \$PROJECT_ROOT does not point to a readable directory" 1>&2 && exit 1
-
-# Check Django project as well
-[ -z "$DJANGO_PROJECT" ] && \
-    echo "Variable \$DJANGO_PROJECT not set or empty" 1>&2 && exit 1
-[ ! -d "$PROJECT_ROOT/$DJANGO_PROJECT" ] && \
-    echo "Variable \$DJANGO_PROJECT does not identify a readable directory within $PROJECT_ROOT" 1>&2 && \
-    exit 1
-
-# WSGI symlink
-
-deploy_dir=$PROJECT_ROOT/$DJANGO_PROJECT/deploy
-wsgi_target=$deploy_dir/$env.wsgi
-wsgi_local=$deploy_dir/$local.wsgi
-[ ! -f "$wsgi_target" ] && echo "$wsgi_target not found - exiting" 1>&2 && exit 1
-
-rm -f $wsgi_local
-ln -s $env.wsgi $wsgi_local
-[ ! $? -eq 0 ] && echo "Error creating symlink $wsgi_local" 1>&2 && exit 1
-echo "Link $local.wsgi to $wsgi_target created" 1>&2
-
-# Settings python file
-
-settings_dir=$PROJECT_ROOT/$DJANGO_PROJECT/settings/env
-settings_target=$settings_dir/$env.py
-settings_local=$PROJECT_ROOT/$DJANGO_PROJECT/settings/env/$local.py
-[ ! -f "$settings_target" ] && echo "$settings_target not found - exiting" 1>&2 && exit 1
-
-cat > $settings_local << EOF
-from $env import *
-
-# You can set stuff you don't wish to store anywhere else here, like:
-# DATABASES['default']['PASSWORD'] = 'secret'
-EOF
-echo "$settings_local created" 1>&2
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.