Commits

Kevin Chan committed 6b709fa

Updated bin scripts.

Comments (0)

Files changed (6)

bin/initialize_models.sh

 if [ $delete_migrations -eq 1 ]; then
     for app in $apps
     do
-        find "$PROJECT_DIR/migrations/$app" -name '[0-9]*' -exec rm {} \; \
-        && echo "# deleted old migration data for $app"
+        migration_dir="$PROJECT_DIR/migrations/$app"
+        if [ -d "$migration_dir" ]; then
+            find "$migration_dir" -name '[0-9]*' -exec rm {} \; \
+                && echo "# deleted old migration data for $app"
+        else
+            echo >&2 "### cannot find migration directory: $migration_dir"
+        fi
     done
     echo
 fi

bin/project.config.template

 DEFAULT_TEST_VERBOSITY=2
 
 # use nose/django-nose as test runner instead of built-in Django default
-USE_NOSE=0
+USE_NOSE=1
+
+# filter junk output (filters out setup and teardown reporting if
+# verbosity > 1)
+FILTER_TEST_OUTPUT=1
 
 # use test server (use custom test server ports defined below for live
 # servers)
 # Script to run tests using Django or nose test runner.
 #
 # * created: 2013-07-20 Kevin Chan <kefin@makedostudio.com>
-# * updated: 2013-09-18 kchan
+# * updated: 2013-10-27 kchan
 
 ########################################################################
 myname=$(basename "$0")
 #   -s | --use-live-server    # use live server (to run selenium tests)
 #                             # * with custom ports defined in
 #                             #   project.config
-#   -N | --use-nose           # set USE_NOSE to 1
+#   -N | --nose               # set USE_NOSE to 1
 #                             # * this will run tests use the nose
 #                             #   test runner instead of the Django
 #                             #   default.
-#   -D | --use-default        # use the default (Django) test runner
-#   -n | --nose OPTION        # set option for nose test runner
+#   -D | --django             # use the default Django test runner
+#   -n | --nose-opt OPTION    # set option for nose test runner
 #                             # * can be specified multiple times
 #                             # * nose options only apply whtn
 #                             #   USE_NOSE is set to 1 in project.config.
+#   -j | --filter             # filter junk output
+#   -J | --no-filter          # do not filter
+#   -c | --coverage           # report code coverage for apps
 #
 # Wrapper script around Django default rest runner to perform tests.
 # * if tests are not specified, script will run the following  default
 GREP="grep"
 SED="sed"
 AWK="awk"
-<<<<<<< local
-=======
-KILLSIG="-2"
->>>>>>> other
+PYTHON="python"
 
 show_version=0
 use_live_server="${USE_LIVE_SERVER-0}"
 test_runner_opts=
 nose_opts=
 tests=
+filter="${FILTER_TEST_OUTPUT-0}"
+coverage=0
 
-<<<<<<< local
 # set default test runner
 if [ "X$USE_NOSE" = "X1" ]; then
     test_runner="nose"
     test_runner="django"
 fi
 
-=======
->>>>>>> other
 # default live server ports (if TEST_SERVER_PORT is not specified)
 DEFAULT_TEST_SERVER_PORT="9006-9010"
 TEST_SERVER_URL="localhost:${TEST_SERVER_PORT-DEFAULT_TEST_SERVER_PORT}"
 while [ $# -gt 0 ]
 do
     case "$1" in
-        -\?|-h|-help|--help)
-            usage
-            ;;
         -v|--verbosity)
             shift
             case "$1" in
             ;;
         -d|--start-display)
             start_display=1
-<<<<<<< local
             ;;
-        -N|--use-nose)
+        -N|--nose)
             test_runner="nose"
             ;;
-        -D|--use-default)
+        -D|--django)
             test_runner="django"
             ;;
-        -n|--nose)
+        -n|--nose-opt)
             shift
-            nose_opts="$nost_opts $1"
-=======
->>>>>>> other
+            nose_opts="$nose_opts $1"
+            ;;
+        -j|--filter|--filter-junk|--no-junk)
+            filter=1
+            ;;
+        -J|--no-filter|--no-filter-junk)
+            filter=0
+            ;;
+        -c|--coverage)
+            coverage=1
+            ;;
+        -C|--no-coverage)
+            coverage=0
             ;;
         --version)
             show_version=1
             ;;
+        -\?|-h|-help|--help)
+            usage
+            ;;
         *)
             tests="$tests $1"
             ;;
 
 check_dir "$PROJECT_DIR"
 
+# if show version, display version and exit
+
 if [ $show_version -ne 0 ]; then
-    python "$MANAGE_SCRIPT" test --version
+    "$PYTHON" "$MANAGE_SCRIPT" test --version
     exit
 fi
 
-test_runner_opts="$test_runner_opts --verbosity=$verbosity"
 
-if [ "X$tests" = "X" ]; then
-    tests=$(echo "$DEFAULT_TESTS" | sed -e '/^$/d;s/^/ /')
-fi
+# setup test runner parameters and support fuctions/services
 
 if [ -f "$VIRTUALENV_DIR/bin/activate" ]; then
     . "$VIRTUALENV_DIR/bin/activate"
 fi
 
+if [ "X$tests" = "X" ]; then
+    tests=$(echo "$DEFAULT_TESTS" | sed -e '/^$/d' -e '/^[-#]..*/d' -e 's/^/ /')
+fi
+
+if [ $coverage -ne 0 ]; then
+    nose_opts="$nose_opts --with-coverage --cover-inclusive"
+    for t in $tests
+    do
+        pkg=$(echo "$t" | cut -d':' -f1)
+        nose_opts="$nose_opts --cover-package=$pkg"
+    done
+fi
+
+case "$test_runner" in
+    nose)
+        USE_NOSE=1
+        NOSE_ARGS=$(trim "$nose_opts")
+        ;;
+    *)
+        USE_NOSE=0
+        NOSE_ARGS=
+        ;;
+esac
+
+test_runner_opts="$test_runner_opts --verbosity=$verbosity"
+
 if [ $use_live_server -ne 0 ]; then
     test_runner_opts="$test_runner_opts --liveserver=$TEST_SERVER_URL"
 fi
 
+test_runner_opts=$(trim "$test_runner_opts")
+
+# * create temp file
+
+tmpfile=$(mktemp -q "/tmp/${myname}.XXXXXX")
+[ $? -ne 0 ] && error "Can't create temp file, exiting..."
+cleanup()
+{
+    rm -f "$tmpfile"
+}
+trap "cleanup" EXIT
+
+# * function to start or stop display server
+
+display_setup()
+{
+    if [ $start_display -ne 0 ] && [ -x "$DISPLAY_CONTROL" ]; then
+        case "$1" in
+            start)
+                echo "# starting display..."
+                "$DISPLAY_CONTROL" start
+                echo
+                ;;
+            stop)
+                echo
+                echo "# stopping display..."
+                "$DISPLAY_CONTROL" stop
+                ;;
+        esac
+    fi
+}
+
+# * function to filter out setup and teardown details from output
+
+filter_output()
+{
+    local _verbosity="$1"
+    local _input="$2"
+
+    if [ -f "$_input" ]; then
+        if [ "$_verbosity" -gt 1 ]; then
+
+            "$AWK" '
+BEGIN {
+    state = "output";
+    print "";
+}
+/^Creating test database/ {
+    state = "no-output";
+    next;
+}
+/^Installed [0-9][0-9]* object\(s\) from [0-9][0-9]* fixture\(s\)/ {
+    state = "output";
+    next;
+}
+/^Destroying (old )?test database/ {
+    next;
+}
+state == "output" {
+    print;
+}
+END {
+    print "";
+}' <"$_input"
+
+        else
+
+            "$AWK" '
+BEGIN {
+    state = "output";
+    print "";
+}
+/^Type ["'\'']*yes["'\'']* if you would like to try deleting the test database/ {
+    next;
+}
+/^Creating test database/ {
+    next;
+}
+/^Destroying (old )?test database/ {
+    next;
+}
+state == "output" {
+    print;
+}
+END {
+    print "";
+}' <"$_input"
+
+        fi
+    fi
+}
+
+# * print commands for reference
+
+echo
 echo "$DIVIDER"
-echo "# python $MANAGE_SCRIPT test $test_runner_opts $tests"
+
+# * export environ settings
+
+export_vars="
+VIRTUALENV_BIN_DIR
+DISPLAY
+DISPLAY_STARTED
+TEST_VERBOSITY
+USE_NOSE
+"
+
+cleanup_exports()
+{
+    unset $export_vars
+}
+trap "cleanup_exports" EXIT
+
+VIRTUALENV_BIN_DIR="$VIRTUALENV_DIR/bin"
+DISPLAY="$XVFB_DISPLAY"
+DISPLAY_STARTED="$start_display"
+TEST_VERBOSITY="$verbosity"
+USE_NOSE="$USE_NOSE"
+NOSE_ARGS="$NOSE_ARGS"
+
+echo "# exports:"
+echo export VIRTUALENV_BIN_DIR=\"$VIRTUALENV_DIR/bin\"
+echo export DISPLAY=\"$XVFB_DISPLAY\"
+echo export DISPLAY_STARTED=\"$start_display\"
+echo export TEST_VERBOSITY=\"$verbosity\"
+echo export USE_NOSE=\"$USE_NOSE\"
+
+export $export_vars
+
+# FiXME: empty NOSE_ARGS makes nose behave strangely so we only export
+# NOSE_ARGS if they are not empty.
+if [ "X$NOSE_ARGS" != "X" ]; then
+    echo export NOSE_ARGS=\"$NOSE_ARGS\"
+    export NOSE_ARGS
+fi
+
+echo "# test runner: $test_runner"
+if [ "X$nose_opts" != "X" ]; then
+    if [ "X$test_runner" = "Xnose" ]; then
+        echo "# nose options:"
+        nost_opts=$(trim "$nose_opts")
+        fold_args $nose_opts
+        echo
+     else
+        echo "# nose options ignored (test runner is $test_runner)"
+    fi
+fi
+
+if [ "$test_runner" != "nose" ]; then
+    if [ $coverage -ne 0 ]; then
+        echo "# coverage option is only available with nose tests"
+    fi
+fi
+
+echo "# test command:"
+echo "$PYTHON $MANAGE_SCRIPT test \\"
+fold_args $test_runner_opts
+echo " \\"
+fold_args $tests
+
+echo
 echo "$DIVIDER"
 echo
 
-export VIRTUALENV_BIN_DIR="$VIRTUALENV_DIR/bin"
-export DISPLAY="$XVFB_DISPLAY"
-export DISPLAY_STARTED="$start_display"
-export TEST_VERBOSITY="$verbosity"
 
-<<<<<<< local
-case "$test_runner" in
-    nose)
-        export USE_NOSE=1
-        if [ "X$nose_opts" != "X" ]; then
-            export NOSE_ARGS="$nose_opts"
-        fi
-        ;;
-    *)
-        export USE_NOSE=0
-        ;;
-esac
+# run tests
 
-=======
->>>>>>> other
-if [ $start_display -ne 0 ] && [ -x "$DISPLAY_CONTROL" ]; then
-    echo "# starting display..."
-    "$DISPLAY_CONTROL" start
-    echo
+display_setup "start"
+
+if [ "$filter" -eq 1 ]; then
+    {
+        echo ""
+        echo "yes" | "$PYTHON" "$MANAGE_SCRIPT" test $test_runner_opts $tests
+        echo ""
+    } >"$tmpfile"
+    filter_output "$verbosity" "$tmpfile"
+else
+    "$PYTHON" "$MANAGE_SCRIPT" test $test_runner_opts $tests
 fi
 
-python "$MANAGE_SCRIPT" test $test_runner_opts $tests
-
-if [ $start_display -ne 0 ] && [ -x "$DISPLAY_CONTROL" ]; then
-    echo
-    echo "# stopping display..."
-    "$DISPLAY_CONTROL" stop
-fi
+display_setup "stop"
 
 exit

bin/special_install.sh

+#!/bin/sh
+#
+# Script to install packages using custom configurations that normal
+# 'pip install' doesn't know how to deal with.
+#
+
+########################################################################
+# add special installation configurations here...
+#
+# * be sure to add installation commands in an "if .. fi" block
+#   using the following convention:
+#
+#   if [ "$_package" = "PACKAGE_NAME" ]; then
+#       ...
+#       [do install]
+#       ...
+#   fi
+#
+
+### [special install commands : begin]
+special_install()
+{
+    local _package="$1"
+
+    if [ "$_package" = "pyyaml" ]; then
+
+        # NOTE:
+        # --with-libyaml install option causes error with pyyaml:
+        # gcc: error: ext/_yaml.c: No such file or directory
+        #
+
+        # cd "$SRC_DIR"case
+        # TARGET="xi-libyaml"
+        # if [ ! -d "$TARGET" ] || [ ! -z "$reinstall" ]; then
+        #     rm -rf "$TARGET"
+        #     mkdir "$TARGET"
+        #     cd "$TARGET"
+        #     wget "https://bitbucket.org/xi/libyaml/get/default.tar.gz"
+        #     tar -xvzf "default.tar.gz"
+        #     src=$(find . -type d -name "${TARGET}-*")
+        #     echo "# $TARGET source extracted to: $src"
+        #     if [ ! -z "$src" ] && [ -d "$src" ]; then
+        #         cd "$src"
+        #         [ ! -f "configure" ] && ./bootstrap
+        #         ./configure --prefix="$VIRTUALENV_DIR"
+        #         make
+        #         make install
+        #     else
+        #         echo "### Unable to find $TARGET source directory"
+        #     fi
+        # fi
+
+        # install PyYAML
+        # PyYAML is a YAML parser and emitter for the Python programming language.
+
+        # cd "$SRC_DIR"
+        # PYYAML_PKG_NAME="PyYAML-3.10"
+        # PYYAML="${PYYAML_PKG_NAME}.tar.gz"
+        # if [ ! -d "$PYYAML_PKG_NAME" ] || [ ! -z "$reinstall" ]; then
+        #     [ -f "$PYYAML" ] && rm -rf "$PYYAML"
+        #     [ -d "$PYYAML_PKG_NAME" ] && rm -rf "$PYYAML_PKG_NAME"
+        #     wget "http://pyyaml.org/download/pyyaml/$PYYAML"
+        #     tar -xvzf "$PYYAML"
+        #     cd "$PYYAML_PKG_NAME"
+        #     python setup.py --with-libyaml install --prefix="$VIRTUALENV_DIR"
+        #     python setup.py test
+        # fi
+
+        repo="https://bitbucket.org/xi/pyyaml/get/default.tar.gz"
+        pip_special_install "$_package" "$repo"
+    fi
+
+    if [ "$_package" = "uuid" ]; then
+        section "# installing uuid ..."
+        cd "$SRC_DIR"
+        UUID_PKG_NAME="uuid-1.30"
+        UUID="${UUID_PKG_NAME}.tar.gz"
+        installed=$(is_installed "$_package")
+        if [ "X$installed" != "X" ] && [ "X$reinstall" = "X" ]; then
+            log "# uuid already installed: $installed"
+        else
+            {
+                [ -f "$UUID" ] && rm -rf "$UUID"
+                [ -d "$UUID_PKG_NAME" ] && rm -rf "$UUID_PKG_NAME"
+                log "downloading $_package"
+                wget -q "https://pypi.python.org/packages/source/u/uuid/${UUID}#md5=639b310f1fe6800e4bf8aa1dd9333117"
+                tar -xvzf "$UUID"
+                cd "$UUID_PKG_NAME"
+                python setup.py install --prefix="$VIRTUALENV_DIR"
+            } | prefix_output "> "
+        fi
+        cd "$BASE_DIR"
+    fi
+
+    if [ "$_package" = "minipylib" ]; then
+        repo="https://bitbucket.org/kchan/minipylib/get/default.tar.gz"
+        pip_special_install "$_package" "$repo"
+    fi
+
+    if [ "$_package" = "pil" ]; then
+        cd "$VIRTUALENV_DIR"
+        if [ ! -f "./lib/libz.so" ] \
+            && [ -f "/usr/lib/x86_64-linux-gnu/libz.so" ]; then
+            ln -s "/usr/lib/x86_64-linux-gnu/libz.so" "./lib/" \
+                && log "# copied libz.so to $VIRTUALENV_DIR/lib"
+        fi
+        if [ ! -f "./lib/libjpeg.so" ] \
+            && [ -f "/usr/lib/x86_64-linux-gnu/libjpeg.so" ]; then
+            ln -s "/usr/lib/x86_64-linux-gnu/libjpeg.so" "./lib/" \
+                && log "# copied libjpeg.so to $VIRTUALENV_DIR/lib"
+        fi
+        if [ ! -f "./lib/libfreetype.so" ] \
+            && [ -f "/usr/lib/x86_64-linux-gnu/libfreetype.so" ]; then
+            ln -s "/usr/lib/x86_64-linux-gnu/libfreetype.so" "./lib/" \
+                && log "# copied libfreetype.so to $VIRTUALENV_DIR/lib"
+        fi
+        repo="PIL"
+        pip_special_install "$_package" "$repo"
+        cd "$BASE_DIR"
+    fi
+
+    if [ "$_package" = "django-garage" ]; then
+        repo="https://bitbucket.org/kchan/django-garage/get/tip.tar.gz"
+        pip_special_install "$_package" "$repo"
+    fi
+
+    if [ "$_package" = "django-filebrowser" ]; then
+        repo="https://bitbucket.org/kchan/django-filebrowser-no-grappelli-and-uploadify/get/master.tar.bz2"
+        pip_special_install "$_package" "$repo"
+    fi
+
+    if [ "$_package" = "django-registration" ]; then
+        #
+        # OLD:
+        # pip install $reinstall $quiet django-registration --install-option="--prefix=$VIRTUALENV_DIR"
+        #
+        # NOTE:
+        # * install forked version of django-registration with fixes that
+        #   are compatible with Django 1.5.
+        # * use django-registration fork (original has been placed in private repo by James Bennett).
+        # * use "trapeze/django-registration"
+        # * "kchan/django-registration" is a fork of "trapeze/django-registation"
+        # REGISTRATION="https://bitbucket.org/trapeze/django-registration/get/default.tar.gz"
+        #
+        repo="https://bitbucket.org/kchan/django-registration/get/cbv.tar.gz"
+        pip_special_install "$_package" "$repo"
+    fi
+
+    if [ "$_package" = "django-hitcount" ]; then
+        # NOTE: add "-e" as pip options to install python egg
+        repo="git://github.com/thornomad/django-hitcount.git#egg=django-hitcount"
+        pip_special_install "$_package" "$repo" "-e"
+    fi
+
+    if [ "$_package" = "django-threadedcomments" ]; then
+        # pip install $reinstall $quiet https://github.com/HonzaKral/django-threadedcomments/archive/master.zip
+        # use forked version from mbartlett's bitbucket account:
+        repo="https://bitbucket.org/markbartlett/django-threadedcomments/get/tip.tar.gz"
+        pip_special_install "$_package" "$repo"
+    fi
+
+    if [ "$_package" = "django-annoying" ]; then
+        repo="https://bitbucket.org/Stavros/django-annoying/get/tip.tar.gz"
+        pip_special_install "$_package" "$repo"
+    fi
+
+    if [ "$_package" = "django-picklefield" ]; then
+        # NOTE: add "-e" as pip options to install python egg
+        repo="git://github.com/gintas/django-picklefield.git#egg=django-picklefield"
+        pip_special_install "$_package" "$repo" "-e"
+    fi
+
+    if [ "$_package" = "nose-ignore-docstring" ]; then
+        # NOTE: add "-e" as pip options to install python egg
+        # * this is a fork of the original repo at
+        #   https://github.com/schlamar/nose-ignore-docstring
+        repo="git://github.com/kefin/nose-ignore-docstring.git#egg=nose-ignore-docstring"
+        pip_special_install "$_package" "$repo" "-e"
+    fi
+
+    if [ "$_package" = "minipy" ]; then
+        section "# installing minipy ... (manually)"
+        minipy_repo_dir="$SRC_DIR/minipy"
+        cd "$SRC_DIR"
+        MINIPY_REPO="ssh://hg@bitbucket.org/kchan/minipy"
+        {
+            if [ "X$reinstall" != "X" ]; then
+                rm -rf "$minipy_repo_dir"
+            fi
+            if [ ! -d "$minipy_repo_dir" ]; then
+                hg clone "$MINIPY_REPO" "$minipy_repo_dir" && \
+                    {
+                    cd "$minipy_repo_dir"
+                    python setup.py install --prefix="$VIRTUALENV_DIR" $quiet
+                }
+            else
+                cd "$minipy_repo_dir"
+                hg pull -u $quiet
+                python setup.py install --prefix="$VIRTUALENV_DIR" $quiet
+            fi
+        } | prefix_output "> "
+        cd "$BASE_DIR"
+    fi
+
+    if [ "$_package" = "chromedriver" ]; then
+        section "# installing chromedriver ..."
+        src_dir="$SRC_DIR"
+        cd "$SRC_DIR"
+        CHROMEDRIVER="https://chromedriver.googlecode.com/files/chromedriver_linux64_2.1.zip"
+        {
+            src="chromedriver"
+            dst="$VIRTUALENV_DIR/bin/chromedriver"
+            if [ "X$reinstall" != "X" ]; then
+                rm -rf "$src" "$dst" "$CHROMEDRIVER"
+            fi
+            if [ ! -f "$src" ]; then
+                wget "$CHROMEDRIVER" && \
+                    unzip "${src}"*.zip && \
+                    cp "$src" "$dst" && \
+                    log "# installed $dst"
+            else
+                if [ ! -f "$dst" ]; then
+                    cp "$src" "$dst" && \
+                    log "# installed $dst"
+                fi
+            fi
+        } | prefix_output "> "
+    fi
+}
+### [special install commands : end]
+
+
+
+### [check special installs : begin]
+check_special_install()
+{
+    local _package="$1"
+
+    case "$_package" in
+        chromedriver)
+            # check if chromedriver is installed
+            dst="$VIRTUALENV_DIR/bin/chromedriver"
+            [ -f "$dst" ] && echo "true" || echo "false"
+            ;;
+        *)
+            echo "false"
+            ;;
+    esac
+}
+### [check special installs : end]
+
+
+
+########################################################################
+
+# OBSOLETE PACKAGES/COMMANDS/COMMENTS
+
+#pip install $reinstall $quiet django-crispy-forms --install-option="--prefix=$VIRTUALENV_DIR"
+#pip install $reinstall $quiet django-tagging --install-option="--prefix=$VIRTUALENV_DIR"
+
+# MISC UNUSED PACKAGES
+# if [ "X$(lookup_data 'django-notification')" != "X" ]; then
+#     section "# installing django-notification ..."
+#     NOTIFICATION="git+https://github.com/pinax/django-notification.git#egg=django-notification"
+#     pip install $reinstall $quiet --install-option="--prefix=$VIRTUALENV_DIR" -e "$NOTIFICATION"
+# fi
+
+# if [ "X$(lookup_data 'django-tastypie')" != "X" ]; then
+#     section "# installing django-tastypie ..."
+#     # NOTE:
+#     # * latest version of tastypie still has some compatibility issues
+#     #   with Django 1.5.
+#     # * we can still use it for the website but some scripts (in tools) like
+#     #   import_users.py will fail because of import errors.
+#     # TASTYPIE="git://github.com/ntucker/django-tastypie.git@django1.5#egg=django-tastypie"
+#     # pip install $reinstall $quiet --install-option="--prefix=$VIRTUALENV_DIR" -e "$TASTYPIE"
+#     pip install $reinstall $quiet django-tastypie --install-option="--prefix=$VIRTUALENV_DIR"
+# fi

bin/update_models.sh

 # Script to update db models for web dev environment
 #
 # * created: 2013-04-30 Kevin Chan <kefin@makedostudio.com>
-# * updated: 2013-06-12 kchan
+# * updated: 2013-10-18 kchan
 
 ########################################################################
 myname=$(basename "$0")
 usage()
 {
     cat <<EOF
-# Usage: $myname [options] fixture-data-files
+# Usage: $myname [options] [apps]
 #   -h | --help             # display usage and exit
 #   -a | --apps APPS        # specify apps to initialize
 #   -s | --schemamigration-options OPTIONS  # options to pass to south when running schemamigration
 #
 # Script to update db models for web dev environment
 # * if apps are not specified, script will update default list of apps:
+# * NOTE: the latest version of this script no longer loads fixtures
+#   any arguments suppled are considered apps to be updated.
 EOF
     echo "$APPS" | sed -e '/^$/d;s/^/#   /'
     exit 1
             shift
             moptions="$moptions $1"
             ;;
+        --*|-*)
+            error "unknown option: $1"
+            ;;
         *)
-            data_files="$data_files $1"
+            apps="$apps $1"
+            #data_files="$data_files $1"
             ;;
     esac
     shift
     . "$VIRTUALENV_DIR/bin/activate"
 fi
 
+
+# create temp file
+tmpfile=$(mktemp -q "/tmp/${myname}.XXXXXX")
+[ $? -ne 0 ] && error "Can't create temp file, exiting..."
+touch "$tmpfile"
+cleanup()
+{
+    rm -f "$tmpfile"
+}
+trap "cleanup" EXIT
+
+
+# functions
+
+NO_MIGRATIONS="You cannot use --auto on an app with no migrations. Try --initial."
+
+no_migrations_error()
+{
+    local _input="$1"
+    result=$(egrep -c "$NO_MIGRATIONS" "$_input")
+    [ "$result" -gt 0 ] && echo 1 || echo 0
+}
+
+TABLE_EXISTS="DatabaseError: relation \".+\" already exists"
+
+table_exists()
+{
+    local _input="$1"
+    result=$(egrep -c "$TABLE_EXISTS" "$_input")
+    [ "$result" -gt 0 ] && echo 1 || echo 0
+}
+
+
 # run initial syncdb for default models
 python "$MANAGE_SCRIPT" syncdb --noinput
 
-
 # set up schemamigration and migrate using South
 for app in $apps
 do
     echo $DIVIDER
 
     echo "# running schemamigration for $app..."
-    if [ "X$soptions" != "X" ]; then
-        echo "# south schemamigration options: $soptions"
-        python "$MANAGE_SCRIPT" schemamigration "$app" $soptions
+    {
+        if [ "X$soptions" != "X" ]; then
+            echo "# south schemamigration options: $soptions"
+            python "$MANAGE_SCRIPT" schemamigration "$app" $soptions
+        else
+            python "$MANAGE_SCRIPT" schemamigration "$app" --auto
+        fi
+    } >"$tmpfile" 2>&1
+
+    if [ $(no_migrations_error "$tmpfile") -eq 1 ]; then
+        echo "# $app has no migrations: initializing ..."
+        python "$MANAGE_SCRIPT" schemamigration "$app" --initial
     else
-        python "$MANAGE_SCRIPT" schemamigration "$app" --auto
+        cat "$tmpfile"
     fi
 
     echo
     if [ "X$moptions" != "X" ]; then
         echo "# south migration options: $moptions"
     fi
-    python "$MANAGE_SCRIPT" migrate "$app" $moptions
-done
+    python "$MANAGE_SCRIPT" migrate "$app" $moptions > "$tmpfile" 2>&1
 
-
-# load data supplied on command line
-for f in $data_files
-do
-    if [ -f "$f" ]; then
-        echo
-        echo "# loading data: $f"
-        python "$MANAGE_SCRIPT" loaddata "$f"
+    if [ $(table_exists "$tmpfile") -eq 1 ]; then
+        echo "# database table already exists: running migrate --fake ..."
+        python "$MANAGE_SCRIPT" migrate "$app" --fake
+    else
+        cat "$tmpfile"
     fi
 done
 
+
+### OBSOLETE (begin)
+
+# load data supplied on command line
+# for f in $data_files
+# do
+#     if [ -f "$f" ]; then
+#         echo
+#         echo "# loading data: $f"
+#         python "$MANAGE_SCRIPT" loaddata "$f"
+#     fi
+# done
+
+### OBSOLETE (end)
+
 exit
 # helper functions for scripts
 #
 # * created: 2012-02-05 Kevin Chan <kefin@makedostudio.com>
-# * updated: 2013-07-06 kchan
+# * updated: 2013-10-26 kchan
 
 ########################################################################
 myname=$(basename "$0")
     done
 }
 
+# trim whitespace at beginning and end of string
+
+trim()
+{
+    echo $1 | sed -e 's/^  *//' -e 's/  *$//'
+}
+
+# fold arguments with backslash (\) at end of lines except last
+
+fold_args()
+{
+    echo "$@" \
+        | tr "\\n" " " \
+        | sed -e '/^  *$/d' \
+        | sed -e 's/  */:::/g' -e 's/:::$//' -e 's/:::\([^:][^:]*\)/ \\\
+\1/g' | sed -e 's/^/    /'
+}
+
 
 DIVIDER="########################################################################"
 
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.