summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--acore.json5
-rw-r--r--acore.sh7
-rw-r--r--apps/bash_shared/common.sh23
-rw-r--r--apps/bash_shared/includes.sh22
-rwxr-xr-xapps/compiler/1-clean.sh5
-rwxr-xr-xapps/compiler/2-configure.sh5
-rwxr-xr-xapps/compiler/3-build.sh5
-rwxr-xr-xapps/compiler/compiler.sh74
-rw-r--r--apps/compiler/includes/functions.sh12
-rw-r--r--apps/db_assembler/db_assembler.sh64
-rw-r--r--apps/installer/includes/functions.sh116
-rw-r--r--apps/installer/includes/includes.sh26
-rw-r--r--apps/installer/main.sh101
-rw-r--r--apps/startup-scripts/simple-restarter9
-rwxr-xr-xbin/acore4
-rwxr-xr-xbin/acore-compiler4
-rwxr-xr-xbin/acore-db-asm4
-rwxr-xr-xbin/acore-db-export4
-rwxr-xr-xbin/acore-db-pendings4
-rwxr-xr-xbin/acore-installer4
-rw-r--r--deps/jsonpath/.gitignore5
-rw-r--r--deps/jsonpath/.travis.yml10
-rw-r--r--deps/jsonpath/CNAME1
-rw-r--r--deps/jsonpath/JSONPath.sh857
-rw-r--r--deps/jsonpath/LICENSE.APACHE215
-rw-r--r--deps/jsonpath/LICENSE.MIT24
-rw-r--r--deps/jsonpath/MANIFEST.in3
-rw-r--r--deps/jsonpath/README.md491
-rw-r--r--deps/jsonpath/_config.yml1
-rw-r--r--deps/jsonpath/all-tests.sh33
-rw-r--r--deps/jsonpath/package.json19
-rw-r--r--deps/jsonpath/setup.py31
-rw-r--r--deps/semver_bash/.gitignore4
-rw-r--r--deps/semver_bash/LICENSE26
-rw-r--r--deps/semver_bash/README.md31
-rw-r--r--deps/semver_bash/semver.sh130
-rw-r--r--deps/semver_bash/semver_test.sh151
-rwxr-xr-xinstall.sh10
38 files changed, 2178 insertions, 162 deletions
diff --git a/acore.json b/acore.json
new file mode 100644
index 0000000000..fa828e3f65
--- /dev/null
+++ b/acore.json
@@ -0,0 +1,5 @@
+{
+ "name" : "azerothcore-wotlk",
+ "version" : "2.0.0-dev",
+ "license" : "AGPL3"
+} \ No newline at end of file
diff --git a/acore.sh b/acore.sh
new file mode 100644
index 0000000000..ba247e009c
--- /dev/null
+++ b/acore.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+set -e
+
+CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+source "$CUR_PATH/apps/installer/main.sh"
diff --git a/apps/bash_shared/common.sh b/apps/bash_shared/common.sh
new file mode 100644
index 0000000000..7b42858057
--- /dev/null
+++ b/apps/bash_shared/common.sh
@@ -0,0 +1,23 @@
+function registerHooks() { hwc_event_register_hooks "$@"; }
+function runHooks() { hwc_event_run_hooks "$@"; }
+
+source "$AC_PATH_CONF/config.sh.dist" # "hack" to avoid missing conf variables
+
+if [ -f "$AC_PATH_CONF/config.sh" ]; then
+ source "$AC_PATH_CONF/config.sh" # should overwrite previous
+else
+ echo "NOTICE: file <$AC_PATH_CONF/config.sh> has not been found, you should create and configure it."
+fi
+
+#
+# Load modules
+#
+
+for entry in "$AC_PATH_MODULES/"*/include.sh
+do
+ if [ -e $entry ]; then
+ source $entry
+ fi
+done
+
+ACORE_VERSION=$("$AC_PATH_DEPS/jsonpath/JSONPath.sh" -f $AC_PATH_ROOT/acore.json -b '$.version') \ No newline at end of file
diff --git a/apps/bash_shared/includes.sh b/apps/bash_shared/includes.sh
index d90b4b451d..312b5ad19b 100644
--- a/apps/bash_shared/includes.sh
+++ b/apps/bash_shared/includes.sh
@@ -11,25 +11,5 @@ source "$AC_PATH_SHARED/defines.sh"
source "$AC_PATH_DEPS/hw-core/bash-lib-event/src/hooks.sh"
+source "$AC_PATH_SHARED/common.sh"
-function registerHooks() { hwc_event_register_hooks "$@"; }
-function runHooks() { hwc_event_run_hooks "$@"; }
-
-source "$AC_PATH_CONF/config.sh.dist" # "hack" to avoid missing conf variables
-
-if [ -f "$AC_PATH_CONF/config.sh" ]; then
- source "$AC_PATH_CONF/config.sh" # should overwrite previous
-else
- echo "NOTICE: file <$AC_PATH_CONF/config.sh> has not been found, you should create and configure it."
-fi
-
-#
-# Load modules
-#
-
-for entry in "$AC_PATH_MODULES/"*/include.sh
-do
- if [ -e $entry ]; then
- source $entry
- fi
-done
diff --git a/apps/compiler/1-clean.sh b/apps/compiler/1-clean.sh
deleted file mode 100755
index 558c093e3f..0000000000
--- a/apps/compiler/1-clean.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-
-CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-bash "$CURRENT_PATH/compiler.sh" 1
diff --git a/apps/compiler/2-configure.sh b/apps/compiler/2-configure.sh
deleted file mode 100755
index 0d59b1caac..0000000000
--- a/apps/compiler/2-configure.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-
-CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-bash "$CURRENT_PATH/compiler.sh" 2
diff --git a/apps/compiler/3-build.sh b/apps/compiler/3-build.sh
deleted file mode 100755
index 6956f82fd3..0000000000
--- a/apps/compiler/3-build.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-
-CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-bash "$CURRENT_PATH/compiler.sh" 3
diff --git a/apps/compiler/compiler.sh b/apps/compiler/compiler.sh
index cb89bfb705..388ad41a32 100755
--- a/apps/compiler/compiler.sh
+++ b/apps/compiler/compiler.sh
@@ -4,41 +4,67 @@ CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CURRENT_PATH/includes/includes.sh"
-function all() {
- comp_clean
- comp_configure
- comp_build
-}
-
function run_option() {
- if test "${comp_functions[$1-1]+'test'}"; then
+ re='^[0-9]+$'
+ if [[ $1 =~ $re ]] && test "${comp_functions[$1-1]+'test'}"; then
${comp_functions[$1-1]}
+ elif [ -n "$(type -t comp_$1)" ] && [ "$(type -t comp_$1)" = function ]; then
+ fun="comp_$1"
+ $fun
else
- echo "invalid option"
- fi
+ echo "invalid option, use --help option for the commands list"
+ fi
}
-comp_options=("Clean" "Configure" "Build" "All")
-comp_functions=("comp_clean" "comp_configure" "comp_build" "all")
+function comp_quit() {
+ exit 0
+}
-runHooks "ON_AFTER_OPTIONS" #you can create your custom options
+comp_options=(
+ "build: Configure and compile"
+ "clean: Clean build files"
+ "configure: Run CMake"
+ "compile: Compile only"
+ "all: clean, configure and compile"
+ "quit: Close this menu")
+comp_functions=(
+ "comp_build"
+ "comp_clean"
+ "comp_configure"
+ "comp_compile"
+ "comp_all"
+ "comp_quit")
-# push exit after custom options
-comp_options+=('Exit')
-comp_functions+=('exit 0')
+PS3='[ Please enter your choice ]: '
-# run option directly if specified in argument
-[ ! -z $1 ] && run_option $1 && exit 0
+runHooks "ON_AFTER_OPTIONS" #you can create your custom options
-PS3='[ Please enter your choice ]: '
-select opt in "${comp_options[@]}"
-do
- case $opt in
- 'Exit')
- break
+function _switch() {
+ _reply="$1"
+ _opt="$2"
+
+ case $_reply in
+ ""|"--help")
+ echo "Available commands:"
+ printf '%s\n' "${options[@]}"
;;
*)
- run_option $REPLY
+ run_option $_reply $_opt
;;
esac
+}
+
+
+while true
+do
+ # run option directly if specified in argument
+ [ ! -z $1 ] && _switch $@
+ [ ! -z $1 ] && exit 0
+
+ select opt in "${comp_options[@]}"
+ do
+ echo "==== ACORE COMPILER ===="
+ _switch $REPLY
+ break;
+ done
done
diff --git a/apps/compiler/includes/functions.sh b/apps/compiler/includes/functions.sh
index 4dfaa46038..947f9ff5fc 100644
--- a/apps/compiler/includes/functions.sh
+++ b/apps/compiler/includes/functions.sh
@@ -39,7 +39,7 @@ function comp_configure() {
}
-function comp_build() {
+function comp_compile() {
[ $MTHREADS == 0 ] && MTHREADS=`grep -c ^processor /proc/cpuinfo` && MTHREADS=$(($MTHREADS + 2))
echo "Using $MTHREADS threads"
@@ -55,3 +55,13 @@ function comp_build() {
runHooks "ON_AFTER_BUILD"
}
+
+function comp_build() {
+ comp_configure
+ comp_build
+}
+
+function comp_all() {
+ comp_clean
+ comp_build
+} \ No newline at end of file
diff --git a/apps/db_assembler/db_assembler.sh b/apps/db_assembler/db_assembler.sh
index 4b4c23e5b9..e1e1de240a 100644
--- a/apps/db_assembler/db_assembler.sh
+++ b/apps/db_assembler/db_assembler.sh
@@ -6,56 +6,70 @@ source "$CURRENT_PATH/includes/includes.sh"
cmdopt=$1
-while true
-do
-echo "===== DB ASSEMBLER MENU ====="
-PS3='Please enter your choice: '
+PS3='[Please enter your choice]: '
options=(
- "Assemble ALL" "Assemble only bases" "Assemble only updates" "Assemble only customs"
- "Quit"
- "Assemble & import ALL" "Assemble & import only bases" "Assemble & import only updates" "Assemble & import only customs"
+ "all: Assemble all" # 1
+ "bases: Assemble only bases" # 2
+ "updates: Assemble only updates" # 3
+ "customs: Assemble only customs" # 4
+ "import-all: Assemble & Import all" # 5
+ "import-bases: Assemble & Import only bases" # 6
+ "import-updates: Assemble & Import only updates" # 7
+ "import-customs: Assemble & Import only customs" # 8
+ "quit: Exit from this menu" # 9
)
function _switch() {
- case $1 in
- "Assemble ALL")
+ _reply="$1"
+ _opt="$2"
+
+ case $_reply in
+ ""|"all"|"1")
dbasm_run true true true
;;
- "Assemble only bases")
+ ""|"bases"|"2")
dbasm_run true false false
;;
- "Assemble only updates")
+ ""|"updates"|"3")
dbasm_run false true false
;;
- "Assemble only customs")
+ ""|"customs"|"4")
dbasm_run false false true
;;
- "Assemble & import ALL")
+ ""|"import-all"|"5")
dbasm_import true true true
;;
- "Assemble & import only bases")
+ ""|"import-bases"|"6")
dbasm_import true false false
;;
- "Assemble & import only updates")
+ ""|"import-updates"|"7")
dbasm_import false true false
;;
- "Assemble & import only customs")
+ ""|"import-customs"|"8")
dbasm_import false false true
;;
- "Quit")
+ ""|"quit"|"9")
echo "Goodbye!"
exit
;;
- *) echo invalid option;;
+ ""|"--help")
+ echo "Available commands:"
+ printf '%s\n' "${options[@]}"
+ ;;
+ *) echo "invalid option, use --help option for the commands list";;
esac
}
-# run option directly if specified in argument
-[ ! -z $1 ] && _switch "${options[$cmdopt-1]}" && exit 0
-
-select opt in "${options[@]}"
+while true
do
- _switch "$opt"
- break
-done
+ # run option directly if specified in argument
+ [ ! -z $1 ] && _switch $@
+ [ ! -z $1 ] && exit 0
+
+ select opt in "${options[@]}"
+ do
+ echo "===== DB ASSEMBLER MENU ====="
+ _switch $REPLY
+ break
+ done
done
diff --git a/apps/installer/includes/functions.sh b/apps/installer/includes/functions.sh
index 3aa0b6baf2..987fe5e3c8 100644
--- a/apps/installer/includes/functions.sh
+++ b/apps/installer/includes/functions.sh
@@ -44,10 +44,6 @@ function inst_cleanCompile() {
inst_compile
}
-function inst_assembleDb {
- dbasm_import true true true
-}
-
function inst_allInOne() {
inst_configureOS
inst_updateRepo
@@ -55,19 +51,66 @@ function inst_allInOne() {
inst_assembleDb
}
+function inst_getVersionBranch() {
+ local res="master"
+ local v="not-defined"
+ local MODULE_MAJOR=0
+ local MODULE_MINOR=0
+ local MODULE_PATCH=0
+ local MODULE_SPECIAL=0;
+ local ACV_MAJOR=0
+ local ACV_MINOR=0
+ local ACV_PATCH=0
+ local ACV_SPECIAL=0;
+ local curldata=$(curl -f --silent -H 'Cache-Control: no-cache' "$1" || echo "{}")
+ local parsed=$(echo "$curldata" | "$AC_PATH_DEPS/jsonpath/JSONPath.sh" -b '$.compatibility.*.[version,branch]')
+
+ semverParseInto "$ACORE_VERSION" ACV_MAJOR ACV_MINOR ACV_PATCH ACV_SPECIAL
+
+ if [[ ! -z "$parsed" ]]; then
+ readarray -t vers < <(echo "$parsed")
+ local idx
+ res="none"
+ # since we've the pair version,branch alternated in not associative and one-dimensional
+ # array, we've to simulate the association with length/2 trick
+ for idx in `seq 0 $((${#vers[*]}/2-1))`; do
+ semverParseInto "${vers[idx*2]}" MODULE_MAJOR MODULE_MINOR MODULE_PATCH MODULE_SPECIAL
+ if [[ $MODULE_MAJOR -eq $ACV_MAJOR && $MODULE_MINOR -le $ACV_MINOR ]]; then
+ res="${vers[idx*2+1]}"
+ v="${vers[idx*2]}"
+ fi
+ done
+ fi
+
+ echo "$v" "$res"
+}
+
function inst_module_search {
- search=""
+
+ local res="$1"
+ local idx=0;
+
if [ -z "$1" ]; then
echo "Type what to search or leave blank for full list"
read -p "Insert name: " res
-
- search="+$res"
fi
- echo "Searching ..."
+
+ local search="+$res"
+
+ echo "Searching $res..."
echo "";
- for i in `curl -s "https://api.github.com/search/repositories?q=org%3Aazerothcore${search}+fork%3Atrue+topic%3Acore-module+sort%3Astars&type=" | grep \"name\" | cut -d ':' -f 2-3|tr -d '",'`; do
- echo "-> $i";
+ readarray -t MODS < <(curl --silent "https://api.github.com/search/repositories?q=org%3Aazerothcore${search}+fork%3Atrue+topic%3Acore-module+sort%3Astars&type=" \
+ | "$AC_PATH_DEPS/jsonpath/JSONPath.sh" -b '$.items.*.name')
+ while (( ${#MODS[@]} > idx )); do
+ mod="${MODS[idx++]}"
+ read v b < <(inst_getVersionBranch "https://raw.githubusercontent.com/azerothcore/$mod/master/acore-module.json")
+
+ if [[ "$b" != "none" ]]; then
+ echo "-> $mod (tested with AC v$v)"
+ else
+ echo "-> $mod (no revision available for AC v$AC_VERSION, it could not work!)"
+ fi
done
echo "";
@@ -75,30 +118,50 @@ function inst_module_search {
}
function inst_module_install {
+ local res
if [ -z "$1" ]; then
echo "Type the name of the module to install"
read -p "Insert name: " res
+ else
+ res="$1"
fi
- git clone "https://github.com/azerothcore/$res" "$AC_PATH_ROOT/modules/$res" && echo "Done, please re-run compiling and db assembly. Read instruction on module repository for more information"
+ read v b < <(inst_getVersionBranch "https://raw.githubusercontent.com/azerothcore/$res/master/acore-module.json")
+
+ if [[ "$b" != "none" ]]; then
+ Joiner:add_repo "https://github.com/azerothcore/$res" "$res" "$b" && echo "Done, please re-run compiling and db assembly. Read instruction on module repository for more information"
+ else
+ echo "Cannot install $res module: it doesn't exists or no version compatible with AC v$ACORE_VERSION are available"
+ fi
echo "";
echo "";
}
function inst_module_update {
+ local res;
+ local _tmp;
+ local branch;
+ local p;
+
if [ -z "$1" ]; then
echo "Type the name of the module to update"
read -p "Insert name: " res
+ else
+ res="$1"
fi
- cd "$AC_PATH_ROOT/modules/$res"
+ _tmp=$PWD
- #git reset --hard master
- #git clean -f
- git pull origin master && echo "Done"
+ if [ -d "$J_PATH_MODULES/$res/" ]; then
+ cd "$J_PATH_MODULES/$res/"
+ branch=`git rev-parse --abbrev-ref HEAD`
- cd "../../"
+ Joiner:upd_repo "https://github.com/azerothcore/$res" "$res" "$branch" && echo "Done, please re-run compiling and db assembly" || echo "Cannot update"
+ cd $_tmp
+ else
+ echo "Cannot update! Path doesn't exist"
+ fi;
echo "";
echo "";
@@ -108,10 +171,29 @@ function inst_module_remove {
if [ -z "$1" ]; then
echo "Type the name of the module to remove"
read -p "Insert name: " res
+ else
+ res="$1"
fi
- rm -rf "$AC_PATH_ROOT/modules/$res" && echo "Done"
+ Joiner:remove "$res" && echo "Done, please re-run compiling" || echo "Cannot remove"
echo "";
echo "";
+}
+
+
+function inst_simple_restarter {
+ echo "Running $1 in background..."
+ bash "$AC_PATH_APPS/startup-scripts/simple-restarter" "$BINPATH" "$1" &
+}
+
+function inst_download_client_data {
+ path="$BINPATH/data"
+ if [ -e "$path/.git/" ]; then
+ # if exists , update
+ git --git-dir="$path/.git/" rev-parse && git --git-dir="$path/.git/" pull origin master | grep 'Already up-to-date.' && changed="no"
+ else
+ # otherwise clone
+ git clone "https://github.com/wowgaming/client-data" -c advice.detachedHead=0 -b master --depth=1 $path
+ fi
} \ No newline at end of file
diff --git a/apps/installer/includes/includes.sh b/apps/installer/includes/includes.sh
index 16ba795792..a0dad11cb5 100644
--- a/apps/installer/includes/includes.sh
+++ b/apps/installer/includes/includes.sh
@@ -1,9 +1,31 @@
-CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+[[ ${INSTALLER_GUARDYVAR:-} -eq 1 ]] && return || readonly INSTALLER_GUARDYVAR=1 # include it once
+
+CURRENT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd )
source "$CURRENT_PATH/../../bash_shared/includes.sh"
AC_PATH_INSTALLER="$AC_PATH_APPS/installer"
+
+J_VER_REQ="v0.8.3"
+J_PATH="$AC_PATH_APPS/drassil/joiner"
+J_PATH_MODULES="$AC_PATH_MODULES"
+
+#install/update and include joiner
+if [ ! -d "$J_PATH/.git" ]; then
+ git clone https://github.com/drassil/joiner "$J_PATH" -b master
+ git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" reset --hard "$J_VER_REQ"
+else
+ # legacy code, with new rev of joiner the update process is internally handled
+ _cur_branch=`git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" rev-parse --abbrev-ref HEAD`
+ _cur_ver=`git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" name-rev --tags --name-only $_cur_branch`
+ if [ "$_cur_ver" != "$J_VER_REQ" ]; then
+ git --git-dir="$J_PATH/.git" --work-tree="$J_PATH/" rev-parse && git --git-dir="$J_PATH/.git" --work-tree="$J_PATH/" fetch --tags origin master --quiet
+ git --git-dir="$J_PATH/.git/" --work-tree="$J_PATH/" reset --hard "$J_VER_REQ"
+ fi
+fi
+source "$AC_PATH_APPS/drassil/joiner/joiner.sh"
+
if [ -f "$AC_PATH_INSTALLER/config.sh" ]; then
source "$AC_PATH_INSTALLER/config.sh" # should overwrite previous
fi
@@ -11,4 +33,6 @@ fi
source "$AC_PATH_APPS/compiler/includes/includes.sh"
source "$AC_PATH_APPS/db_assembler/includes/includes.sh"
+source "$AC_PATH_DEPS/semver_bash/semver.sh"
+
source "$AC_PATH_INSTALLER/includes/functions.sh"
diff --git a/apps/installer/main.sh b/apps/installer/main.sh
index 44fc65efb0..e9ee7a3918 100644
--- a/apps/installer/main.sh
+++ b/apps/installer/main.sh
@@ -4,75 +4,90 @@ CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CURRENT_PATH/includes/includes.sh"
-cmdopt=$1
-
-while true
-do
-echo "===== INSTALLER SCRIPT ====="
-PS3='Please enter your choice: '
+PS3='[Please enter your choice]: '
options=(
- "First Installation" "Configure OS dep" "Update Repository" "Reset & Clean Repository"
- "Compile" "Clean & Compile" "Assemble & Import DB" "Module Search" "Module Install" "Module Update" "Module Remove"
- "Sub Menu >> Compiler" "Sub Menu >> DB Assembler"
- "Quit"
+ "init (i): First Installation" # 1
+ "install-deps (d): Configure OS dep" # 2
+ "pull (u): Update Repository" # 3
+ "reset (r): Reset & Clean Repository" # 4
+ "compiler (c): Run compiler tool" # 5
+ "db-assembler (a): Run db assembler tool" # 6
+ "module-search (ms): Module Search by keyword" # 7
+ "module-install (mi): Module Install by name" # 8
+ "module-update (mu): Module Update by name" # 9
+ "module-remove: (mr): Module Remove by name" # 10
+ "client-data: (gd): download client data from github repository (beta)" # 11
+ "run-worldserver (rw): execute a simple restarter for worldserver" # 12
+ "run-authserver (ra): execute a simple restarter for authserver" # 13
+ "quit: Exit from this menu" # 14
)
function _switch() {
- case $1 in
- "First Installation")
+ _reply="$1"
+ _opt="$2"
+
+ case $_reply in
+ ""|"i"|"init"|"1")
inst_allInOne
;;
- "Configure OS dep")
+ ""|"d"|"install-deps"|"2")
inst_configureOS
;;
- "Update Repository")
+ ""|"u"|"pull"|"3")
inst_updateRepo
;;
- "Reset & Clean Repository")
+ ""|"r"|"reset"|"4")
inst_resetRepo
;;
- "Compile")
- inst_compile
+ ""|"c"|"compiler"|"5")
+ bash "$AC_PATH_APPS/compiler/compiler.sh" $_opt
;;
- "Clean & Compile")
- inst_cleanCompile
+ ""|"a"|"db-assembler"|"6")
+ bash "$AC_PATH_APPS/db_assembler/db_assembler.sh" $_opt
;;
- "Assemble & Import DB")
- inst_assembleDb
+ ""|"ms"|"module-search"|"7")
+ inst_module_search "$_opt"
;;
- "Module Search")
- inst_module_search $2
+ ""|"mi"|"module-install"|"8")
+ inst_module_install "$_opt"
;;
- "Module Install")
- inst_module_install $2
+ ""|"mu"|"module-update"|"9")
+ inst_module_update "$_opt"
;;
- "Module Update")
- inst_module_update $2
+ ""|"mr"|"module-remove"|"10")
+ inst_module_remove "$_opt"
;;
- "Module Remove")
- inst_module_remove $2
+ ""|"gd"|"client-data"|"11")
+ inst_download_client_data
;;
- "Sub Menu >> Compiler")
- bash "$AC_PATH_APPS/compiler/compiler.sh"
+ ""|"rw"|"run-worldserver"|"12")
+ inst_simple_restarter worldserver
;;
- "Sub Menu >> DB Assembler")
- bash "$AC_PATH_APPS/db_assembler/db_assembler.sh"
+ ""|"ra"|"run-authserver"|"13")
+ inst_simple_restarter authserver
;;
- "Quit")
+ ""|"quit"|"14")
echo "Goodbye!"
exit
;;
- *) echo invalid option;;
+ ""|"--help")
+ echo "Available commands:"
+ printf '%s\n' "${options[@]}"
+ ;;
+ *) echo "invalid option, use --help option for the commands list";;
esac
}
-# run option directly if specified in argument
-[ ! -z $1 ] && _switch "${options[$cmdopt-1]}"
-[ ! -z $1 ] && exit 0
-
-select opt in "${options[@]}"
+while true
do
- _switch "$opt"
- break
-done
+ # run option directly if specified in argument
+ [ ! -z $1 ] && _switch $@ # old method: "${options[$cmdopt-1]}"
+ [ ! -z $1 ] && exit 0
+
+ select opt in "${options[@]}"
+ do
+ echo "==== ACORE DASHBOARD ===="
+ _switch $REPLY
+ break
+ done
done
diff --git a/apps/startup-scripts/simple-restarter b/apps/startup-scripts/simple-restarter
new file mode 100644
index 0000000000..084d1a1c92
--- /dev/null
+++ b/apps/startup-scripts/simple-restarter
@@ -0,0 +1,9 @@
+#PARAMETER 1: directory
+#PARAMETER 2: binary file
+
+_bin_path=$1
+_bin_file=$2
+while true
+do
+ cd "$_bin_path" && "./$_bin_file" &>/dev/null; echo "$_bin_file crashed (?), restarting..."
+done \ No newline at end of file
diff --git a/bin/acore b/bin/acore
index a9c10efb22..cd51f60d5d 100755
--- a/bin/acore
+++ b/bin/acore
@@ -1,3 +1,5 @@
#!/usr/bin/env bash
-source ./acore-installer \ No newline at end of file
+CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+source "$CUR_PATH/acore-installer" \ No newline at end of file
diff --git a/bin/acore-compiler b/bin/acore-compiler
index aa356deede..ba5311a12f 100755
--- a/bin/acore-compiler
+++ b/bin/acore-compiler
@@ -1,3 +1,5 @@
#!/usr/bin/env bash
-bash ../apps/compiler/compiler.sh \ No newline at end of file
+CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+source "$CUR_PATH/../apps/compiler/compiler.sh"
diff --git a/bin/acore-db-asm b/bin/acore-db-asm
index 7cc11c8ef8..962a70b233 100755
--- a/bin/acore-db-asm
+++ b/bin/acore-db-asm
@@ -1,3 +1,5 @@
#!/usr/bin/env bash
-bash ../apps/db_assembler/db_assembler.sh \ No newline at end of file
+CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+source "$CUR_PATH/../apps/db_assembler/db_assembler.sh"
diff --git a/bin/acore-db-export b/bin/acore-db-export
index 9a1f154586..11b8d6cba0 100755
--- a/bin/acore-db-export
+++ b/bin/acore-db-export
@@ -1,3 +1,5 @@
#!/usr/bin/env bash
-bash ../apps/db_exporter/db_exporter.sh \ No newline at end of file
+CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+source "$CUR_PATH/../apps/db_exporter/db_exporter.sh"
diff --git a/bin/acore-db-pendings b/bin/acore-db-pendings
index 569d161c63..6f8d62f9e6 100755
--- a/bin/acore-db-pendings
+++ b/bin/acore-db-pendings
@@ -1,3 +1,5 @@
#!/usr/bin/env bash
-bash ../apps/db_pendings/import.sh \ No newline at end of file
+CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+source "$CUR_PATH/../apps/db_pendings/import.sh"
diff --git a/bin/acore-installer b/bin/acore-installer
index c61d00458e..ef68e06150 100755
--- a/bin/acore-installer
+++ b/bin/acore-installer
@@ -1,3 +1,5 @@
#!/usr/bin/env bash
-bash ../apps/installer/main.sh \ No newline at end of file
+CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+source "$CUR_PATH/../apps/installer/main.sh"
diff --git a/deps/jsonpath/.gitignore b/deps/jsonpath/.gitignore
new file mode 100644
index 0000000000..36ed3d2069
--- /dev/null
+++ b/deps/jsonpath/.gitignore
@@ -0,0 +1,5 @@
+test/errlog
+test/outlog
+
+# vi .swp files
+.*.swp
diff --git a/deps/jsonpath/.travis.yml b/deps/jsonpath/.travis.yml
new file mode 100644
index 0000000000..acf1f26295
--- /dev/null
+++ b/deps/jsonpath/.travis.yml
@@ -0,0 +1,10 @@
+language: python
+
+addons:
+ apt:
+ packages:
+ - bash
+
+# Whatever the current shebang, replace with hardcoded shell
+script: >
+ ./all-tests.sh
diff --git a/deps/jsonpath/CNAME b/deps/jsonpath/CNAME
new file mode 100644
index 0000000000..4f3d0812c3
--- /dev/null
+++ b/deps/jsonpath/CNAME
@@ -0,0 +1 @@
+jsonpath.obdi.io \ No newline at end of file
diff --git a/deps/jsonpath/JSONPath.sh b/deps/jsonpath/JSONPath.sh
new file mode 100644
index 0000000000..a03752e130
--- /dev/null
+++ b/deps/jsonpath/JSONPath.sh
@@ -0,0 +1,857 @@
+#!/bin/bash
+
+# ---------------------------------------------------------------------------
+# GLOBALS
+# ---------------------------------------------------------------------------
+
+DEBUG=0
+INCLEMPTY=0
+NOCASE=0
+WHOLEWORD=0
+FILE=
+NO_HEAD=0
+NORMALIZE_SOLIDUS=0
+BRIEF=0
+PASSTHROUGH=0
+JSON=0
+PRINT=1
+MULTIPASS=0
+FLATTEN=0
+STDINFILE=/var/tmp/JSONPath.$$.stdin
+STDINFILE2=/var/tmp/JSONPath.$$.stdin2
+PASSFILE=/var/tmp/JSONPath.$$.pass1
+declare -a INDEXMATCH_QUERY
+
+# ---------------------------------------------------------------------------
+main() {
+# ---------------------------------------------------------------------------
+# It all starts here
+
+ parse_options "$@"
+
+ trap cleanup EXIT
+
+ if [[ $QUERY == *'?(@'* ]]; then
+ # This will be a multipass query
+
+ [[ -n $FILE ]] && STDINFILE=$FILE
+ [[ -z $FILE ]] && cat >$STDINFILE
+
+ while true; do
+ tokenize_path
+ create_filter
+
+ cat "$STDINFILE" | tokenize | parse | filter | indexmatcher >$PASSFILE
+
+ [[ $MULTIPASS -eq 1 ]] && {
+ # replace filter expression with index sequence
+ SET=$(sed -rn 's/.*,([0-9]+)[],].*/\1/p' $PASSFILE | tr '\n' ,)
+ SET=${SET%,}
+ QUERY=$(echo $QUERY | sed "s/?(@[^)]\+)/$SET/")
+ [[ $DEBUG -eq 1 ]] && echo "QUERY=$QUERY"
+ reset
+ continue
+ }
+
+ cat $PASSFILE | flatten | json | brief
+
+ break
+ done
+
+ else
+
+ tokenize_path
+ create_filter
+
+ if [[ $PASSTHROUGH -eq 1 ]]; then
+ JSON=1
+ flatten | json
+ elif [[ -z $FILE ]]; then
+ tokenize | parse | filter | indexmatcher | flatten | json | brief
+ else
+ cat "$FILE" | tokenize | parse | filter | indexmatcher | flatten | \
+ json | brief
+ fi
+
+ fi
+}
+
+# ---------------------------------------------------------------------------
+reset() {
+# ---------------------------------------------------------------------------
+
+ # Reset some vars
+ declare -a INDEXMATCH_QUERY
+ PATHTOKENS=
+ FILTER=
+ OPERATOR=
+ RHS=
+ MULTIPASS=0
+}
+
+# ---------------------------------------------------------------------------
+cleanup() {
+# ---------------------------------------------------------------------------
+
+ [[ -e "$PASSFILE" ]] && rm -f "$PASSFILE"
+ [[ -e "$STDINFILE2" ]] && rm -f "$STDINFILE2"
+ [[ -z "$FILE" && -e "$STDINFILE" ]] && rm -f "$STDINFILE"
+}
+
+# ---------------------------------------------------------------------------
+usage() {
+# ---------------------------------------------------------------------------
+
+ echo
+ echo "Usage: JSONPath.sh [-b] [j] [-h] [-f FILE] [pattern]"
+ echo
+ echo "pattern - the JSONPath query. Defaults to '$.*' if not supplied."
+ #echo "-s - Remove escaping of the solidus symbol (straight slash)."
+ echo "-b - Brief. Only show values."
+ echo "-j - JSON ouput."
+ echo "-u - Strip unnecessary leading path elements."
+ echo "-i - Case insensitive."
+ echo "-p - Pass-through to the JSON parser."
+ echo "-w - Match whole words only (for filter script expression)."
+ echo "-f FILE - Read a FILE instead of stdin."
+ #echo "-n - No-head. Do not show nodes that have no path (lines that start with [])."
+ echo "-h - This help text."
+ echo
+}
+
+# ---------------------------------------------------------------------------
+parse_options() {
+# ---------------------------------------------------------------------------
+
+ set -- "$@"
+ local ARGN=$#
+ while [ "$ARGN" -ne 0 ]
+ do
+ case $1 in
+ -h) usage
+ exit 0
+ ;;
+ -f) shift
+ FILE=$1
+ ;;
+ -i) NOCASE=1
+ ;;
+ -j) JSON=1
+ ;;
+ -n) NO_HEAD=1
+ ;;
+ -b) BRIEF=1
+ ;;
+ -u) FLATTEN=1
+ ;;
+ -p) PASSTHROUGH=1
+ ;;
+ -w) WHOLEWORD=1
+ ;;
+ -s) NORMALIZE_SOLIDUS=1
+ ;;
+ ?*) QUERY=$1
+ ;;
+ esac
+ shift 1
+ ARGN=$((ARGN-1))
+ done
+ [[ -z $QUERY ]] && QUERY='$.*'
+}
+
+# ---------------------------------------------------------------------------
+awk_egrep() {
+# ---------------------------------------------------------------------------
+ local pattern_string=$1
+
+ gawk '{
+ while ($0) {
+ start=match($0, pattern);
+ token=substr($0, start, RLENGTH);
+ print token;
+ $0=substr($0, start+RLENGTH);
+ }
+ }' pattern="$pattern_string"
+}
+
+# ---------------------------------------------------------------------------
+tokenize() {
+# ---------------------------------------------------------------------------
+# json parsing
+
+ local GREP
+ local ESCAPE
+ local CHAR
+
+ if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1
+ then
+ GREP='egrep -ao --color=never'
+ else
+ GREP='egrep -ao'
+ fi
+
+ if echo "test string" | egrep -o "test" >/dev/null 2>&1
+ then
+ ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+ CHAR='[^[:cntrl:]"\\]'
+ else
+ GREP=awk_egrep
+ ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+ CHAR='[^[:cntrl:]"\\\\]'
+ fi
+
+ local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
+ local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
+ local KEYWORD='null|false|true'
+ local SPACE='[[:space:]]+'
+
+ # Force zsh to expand $A into multiple words
+ local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')
+ if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi
+ $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
+ if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi
+}
+
+# ---------------------------------------------------------------------------
+tokenize_path () {
+# ---------------------------------------------------------------------------
+ local GREP
+ local ESCAPE
+ local CHAR
+
+ if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1
+ then
+ GREP='egrep -ao --color=never'
+ else
+ GREP='egrep -ao'
+ fi
+
+ if echo "test string" | egrep -o "test" >/dev/null 2>&1
+ then
+ CHAR='[^[:cntrl:]"\\]'
+ else
+ GREP=awk_egrep
+ #CHAR='[^[:cntrl:]"\\\\]'
+ fi
+
+ local WILDCARD='\*'
+ local WORD='[ A-Za-z0-9_-]*'
+ local INDEX="\\[$WORD(:$WORD){0,2}\\]"
+ local INDEXALL="\\[\\*\\]"
+ local STRING="[\\\"'][^[:cntrl:]\\\"']*[\\\"']"
+ local SET="\\[($WORD|$STRING)(,($WORD|$STRING))*\\]"
+ local FILTER='\?\(@[^)]+'
+ local DEEPSCAN="\\.\\."
+ local SPACE='[[:space:]]+'
+
+ # Force zsh to expand $A into multiple words
+ local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')
+ if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi
+ readarray -t PATHTOKENS < <( echo "$QUERY" | \
+ $GREP "$INDEX|$STRING|$WORD|$WILDCARD|$FILTER|$DEEPSCAN|$SET|$INDEXALL|." | \
+ egrep -v "^$SPACE$|^\\.$|^\[$|^\]$|^'$|^\\\$$|^\)$")
+ [[ $DEBUG -eq 1 ]] && {
+ echo "egrep -o '$INDEX|$STRING|$WORD|$WILDCARD|$FILTER|$DEEPSCAN|$SET|$INDEXALL|.'"
+ echo -n "TOKENISED QUERY="; echo "$QUERY" | \
+ $GREP "$INDEX|$STRING|$WORD|$WILDCARD|$FILTER|$DEEPSCAN|$SET|$INDEXALL|." | \
+ egrep -v "^$SPACE$|^\\.$|^\[$|^\]$|^'$|^\\\$$|^\)$"
+ }
+ if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi
+}
+
+# ---------------------------------------------------------------------------
+create_filter() {
+# ---------------------------------------------------------------------------
+# Creates the filter from the user's query.
+# Filter works in a single pass through the data, unless a filter (script)
+# expression is used, in which case two passes are required (MULTIPASS=1).
+
+ local len=${#PATHTOKENS[*]}
+
+ local -i i=0
+ local query="^\[" comma=
+ while [[ i -lt len ]]; do
+ case "${PATHTOKENS[i]}" in
+ '"') :
+ ;;
+ '..') query+="$comma[^]]*"
+ comma=
+ ;;
+ '[*]') query+="$comma[^,]*"
+ comma=","
+ ;;
+ '*') query+="$comma(\"[^\"]*\"|[0-9]+[^],]*)"
+ comma=","
+ ;;
+ '?(@'*) a=${PATHTOKENS[i]#?(@.}
+ elem="${a%%[<>=!]*}"
+ rhs="${a##*[<>=!]}"
+ a="${a#$elem}"
+ elem="${elem//./[\",.]+}" # Allows child node matching
+ operator="${a%$rhs}"
+ [[ -z $operator ]] && { operator="=="; rhs=; }
+ if [[ $rhs == *'"'* || $rhs == *"'"* ]]; then
+ case $operator in
+ '=='|'=') OPERATOR=
+ if [[ $elem == '?(@' ]]; then
+ # To allow search on @.property such as:
+ # $..book[?(@.title==".*Book 1.*")]
+ query+="$comma[0-9]+[],][[:space:]\"]*${rhs//\"/}"
+ else
+ # To allow search on @ (this node) such as:
+ # $..reviews[?(@==".*Fant.*")]
+ query+="$comma[0-9]+,\"$elem\"[],][[:space:]\"]*${rhs//\"/}"
+ fi
+ FILTER="$query"
+ ;;
+ '>='|'>') OPERATOR=">"
+ RHS="$rhs"
+ query+="$comma[0-9]+,\"$elem\"[],][[:space:]\"]*"
+ FILTER="$query"
+ ;;
+ '<='|'<') OPERATOR="<"
+ RHS="$rhs"
+ query+="$comma[0-9]+,\"$elem\"[],][[:space:]\"]*"
+ FILTER="$query"
+ ;;
+ esac
+ else
+ case $operator in
+ '=='|'=') OPERATOR=
+ query+="$comma[0-9]+,\"$elem\"[],][[:space:]\"]*$rhs"
+ FILTER="$query"
+ ;;
+ '>=') OPERATOR="-ge"
+ RHS="$rhs"
+ query+="$comma[0-9]+,\"$elem\"[],][[:space:]\"]*"
+ FILTER="$query"
+ ;;
+ '>') OPERATOR="-gt"
+ RHS="$rhs"
+ query+="$comma[0-9]+,\"$elem\"[],][[:space:]\"]*"
+ FILTER="$query"
+ ;;
+ '<=') OPERATOR="-le"
+ RHS="$rhs"
+ query+="$comma[0-9]+,\"$elem\"[],][[:space:]\"]*"
+ FILTER="$query"
+ ;;
+ '<') OPERATOR="-lt"
+ RHS="$rhs"
+ query+="$comma[0-9]+,\"$elem\"[],][[:space:]\"]*"
+ FILTER="$query"
+ esac
+ fi
+ MULTIPASS=1
+ ;;
+ "["*) if [[ ${PATHTOKENS[i]} =~ , ]]; then
+ a=${PATHTOKENS[i]#[}
+ a=${a%]}
+ if [[ $a =~ [[:alpha:]] ]]; then
+ # converts only one comma: s/("[^"]+),([^"]+")/\1`\2/g;s/"//g
+ #a=$(echo $a | sed 's/\([[:alpha:]]*\)/"\1"/g')
+ a=$(echo $a | sed -r "s/[\"']//g;s/([^,]*)/\"\1\"/g")
+ fi
+ query+="$comma(${a//,/|})"
+ elif [[ ${PATHTOKENS[i]} =~ : ]]; then
+ if ! [[ ${PATHTOKENS[i]} =~ [0-9][0-9] || ${PATHTOKENS[i]} =~ :] ]]
+ then
+ if [[ ${PATHTOKENS[i]#*:} =~ : ]]; then
+ INDEXMATCH_QUERY+=("${PATHTOKENS[i]}")
+ query+="$comma[^,]*"
+ else
+ # Index in the range of 0-9 can be handled by regex
+ query+="${comma}$(echo ${PATHTOKENS[i]} | \
+ awk '/:/ { a=substr($0,0,index($0,":")-1);
+ b=substr($0,index($0,":")+1,index($0,"]")-index($0,":")-1);
+ if(b>0) { print a ":" b-1 "]" };
+ if(b<=0) { print a ":]" } }' | \
+ sed 's/\([0-9]\):\([0-9]\)/\1-\2/;
+ s/\[:\([0-9]\)/[0-\1/;
+ s/\([0-9]\):\]/\1-9999999]/')"
+ fi
+ else
+ INDEXMATCH_QUERY+=("${PATHTOKENS[i]}")
+ query+="$comma[^,]*"
+ fi
+ else
+ a=${PATHTOKENS[i]#[}
+ a=${a%]}
+ if [[ $a =~ [[:alpha:]] ]]; then
+ a=$(echo $a | sed -r "s/[\"']//g;s/([^,]*)/\"\1\"/g")
+ else
+ [[ $i -gt 0 ]] && comma=","
+ fi
+ #idx=$(echo "${PATHTOKENS[i]}" | tr -d "[]")
+ query+="$comma$a"
+ fi
+ comma=","
+ ;;
+ *) PATHTOKENS[i]=${PATHTOKENS[i]//\'/\"}
+ query+="$comma\"${PATHTOKENS[i]//\"/}\""
+ comma=","
+ ;;
+ esac
+ i=i+1
+ done
+
+ [[ -z $FILTER ]] && FILTER="$query[],]"
+ [[ $DEBUG -eq 1 ]] && echo "FILTER=$FILTER"
+}
+
+# ---------------------------------------------------------------------------
+parse_array () {
+# ---------------------------------------------------------------------------
+# json parsing
+
+ local index=0
+ local ary=''
+ read -r token
+ case "$token" in
+ ']')
+ ;;
+ *)
+ while :
+ do
+ parse_value "$1" "$index"
+ index=$((index+1))
+ ary="$ary""$value"
+ read -r token
+ case "$token" in
+ ']') break ;;
+ ',') ary="$ary," ;;
+ *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
+ esac
+ read -r token
+ done
+ ;;
+ esac
+ value=
+ :
+}
+
+# ---------------------------------------------------------------------------
+parse_object () {
+# ---------------------------------------------------------------------------
+# json parsing
+
+ local key
+ local obj=''
+ read -r token
+ case "$token" in
+ '}')
+ ;;
+ *)
+ while :
+ do
+ case "$token" in
+ '"'*'"') key=$token ;;
+ *) throw "EXPECTED string GOT ${token:-EOF}" ;;
+ esac
+ read -r token
+ case "$token" in
+ ':') ;;
+ *) throw "EXPECTED : GOT ${token:-EOF}" ;;
+ esac
+ read -r token
+ parse_value "$1" "$key"
+ obj="$obj$key:$value"
+ read -r token
+ case "$token" in
+ '}') break ;;
+ ',') obj="$obj," ;;
+ *) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
+ esac
+ read -r token
+ done
+ ;;
+ esac
+ value=
+ :
+}
+
+# ---------------------------------------------------------------------------
+parse_value () {
+# ---------------------------------------------------------------------------
+# json parsing
+
+ local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0
+ case "$token" in
+ '{') parse_object "$jpath" ;;
+ '[') parse_array "$jpath" ;;
+ # At this point, the only valid single-character tokens are digits.
+ ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
+ *) value=$token
+ # if asked, replace solidus ("\/") in json strings with normalized value: "/"
+ [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g')
+ isleaf=1
+ [ "$value" = '""' ] && isempty=1
+ ;;
+ esac
+ [[ -z INCLEMPTY ]] && [ "$value" = '' ] && return
+ [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return
+
+ [ "$isleaf" -eq 1 ] && [ $isempty -eq 0 ] && print=1
+ [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value"
+ :
+}
+
+# ---------------------------------------------------------------------------
+flatten() {
+# ---------------------------------------------------------------------------
+# Take out
+
+ local path a prevpath pathlen
+
+ if [[ $FLATTEN -eq 1 ]]; then
+ cat >"$STDINFILE2"
+
+ highest=9999
+
+ while read line; do
+ a=${line#[};a=${a%%]*}
+ readarray -t path < <(grep -o "[^,]*"<<<"$a")
+ [[ -z $prevpath ]] && {
+ prevpath=("${path[@]}")
+ highest=$((${#path[*]}-1))
+ continue
+ }
+
+ pathlen=$((${#path[*]}-1))
+
+ for i in `seq 0 $pathlen`; do
+ [[ ${path[i]} != ${prevpath[i]} ]] && {
+ high=$i
+ break
+ }
+ done
+
+ [[ $high -lt $highest ]] && highest=$high
+
+ prevpath=("${path[@]}")
+ done <"$STDINFILE2"
+
+ if [[ $highest -gt 0 ]]; then
+ sed -r 's/\[(([0-9]+|"[^"]+")[],]){'$((highest))'}(.*)/[\3/' \
+ "$STDINFILE2"
+ else
+ cat "$STDINFILE2"
+ fi
+ else
+ cat
+ fi
+}
+
+# ---------------------------------------------------------------------------
+indexmatcher() {
+# ---------------------------------------------------------------------------
+# For double digit or greater indexes match each line individually
+# Single digit indexes are handled more efficiently by regex
+
+ local a b
+
+ [[ $DEBUG -eq 1 ]] && {
+ for i in `seq 0 $((${#INDEXMATCH_QUERY[*]}-1))`; do
+ echo "INDEXMATCH_QUERY[$i]=${INDEXMATCH_QUERY[i]}"
+ done
+ }
+
+ matched=1
+
+ step=
+ if [[ ${#INDEXMATCH_QUERY[*]} -gt 0 ]]; then
+ while read -r line; do
+ for i in `seq 0 $((${#INDEXMATCH_QUERY[*]}-1))`; do
+ [[ ${INDEXMATCH_QUERY[i]#*:} =~ : ]] && {
+ step=${INDEXMATCH_QUERY[i]##*:}
+ step=${step%]}
+ INDEXMATCH_QUERY[i]="${INDEXMATCH_QUERY[i]%:*}]"
+ }
+ q=${INDEXMATCH_QUERY[i]:1:-1} # <- strip '[' and ']'
+ a=${q%:*} # <- number before ':'
+ b=${q#*:} # <- number after ':'
+ [[ -z $b ]] && b=99999999999
+ readarray -t num < <( (grep -Eo ',[0-9]+[],]' | tr -d ,])<<<$line )
+ if [[ ${num[i]} -ge $a && ${num[i]} -lt $b && matched -eq 1 ]]; then
+ matched=1
+ [[ $i -eq $((${#INDEXMATCH_QUERY[*]}-1)) ]] && {
+ if [[ $step -gt 1 ]]; then
+ [[ $(((num[i]-a)%step)) -eq 0 ]] && {
+ [[ $DEBUG -eq 1 ]] && echo -n "($a,$b,${num[i]}) "
+ echo "$line"
+ }
+ else
+ [[ $DEBUG -eq 1 ]] && echo -n "($a,$b,${num[i]}) "
+ echo "$line"
+ fi
+ }
+ else
+ matched=0
+ continue
+ fi
+ done
+ matched=1
+ done
+ else
+ cat -
+ fi
+}
+
+# ---------------------------------------------------------------------------
+brief() {
+# ---------------------------------------------------------------------------
+# Only show the value
+
+ if [[ $BRIEF -eq 1 ]]; then
+ sed 's/^[^\t]*\t//;s/^"//;s/"$//;'
+ else
+ cat
+ fi
+}
+
+# ---------------------------------------------------------------------------
+json() {
+# ---------------------------------------------------------------------------
+# Turn output into JSON
+
+ local a tab=$(echo -e "\t")
+ local UP=1 DOWN=2 SAME=3
+ local prevpathlen=-1 prevpath=() path a
+ declare -a closers
+
+ if [[ $JSON -eq 0 ]]; then
+ cat -
+ else
+ while read -r line; do
+ a=${line#[};a=${a%%]*}
+ readarray -t path < <(grep -o "[^,]*"<<<"$a")
+ value=${line#*$tab}
+
+ # Not including the object itself (last item)
+ pathlen=$((${#path[*]}-1))
+
+ # General direction
+
+ direction=$SAME
+ [[ $pathlen -gt $prevpathlen ]] && direction=$DOWN
+ [[ $pathlen -lt $prevpathlen ]] && direction=$UP
+
+ # Handle jumps UP the tree (close previous paths)
+
+ [[ $prevpathlen != -1 ]] && {
+ for i in `seq 0 $((pathlen-1))`; do
+ [[ ${prevpath[i]} == ${path[i]} ]] && continue
+ [[ ${path[i]} != '"'* ]] && {
+ a=(${!arrays[*]})
+ [[ -n $a ]] && {
+ for k in `seq $((i+1)) ${a[-1]}`; do
+ arrays[k]=
+ done
+ }
+ a=(${!comma[*]})
+ [[ -n $a ]] && {
+ for k in `seq $((i+1)) ${a[-1]}`; do
+ comma[k]=
+ done
+ }
+ for j in `seq $((prevpathlen)) -1 $((i+2))`
+ do
+ arrays[j]=
+ [[ -n ${closers[j]} ]] && {
+ let indent=j*4
+ printf "\n%0${indent}s${closers[j]}" ""
+ unset closers[j]
+ comma[j]=
+ }
+ done
+ direction=$DOWN
+ break
+ }
+ direction=$DOWN
+ for j in `seq $((prevpathlen)) -1 $((i+1))`
+ do
+ arrays[j]=
+ [[ -n ${closers[j]} ]] && {
+ let indent=j*4
+ printf "\n%0${indent}s${closers[j]}" ""
+ unset closers[j]
+ comma[j]=
+ }
+ done
+ a=(${!arrays[*]})
+ [[ -n $a ]] && {
+ for k in `seq $i ${a[-1]}`; do
+ arrays[k]=
+ done
+ }
+ break
+ done
+ }
+
+ [[ $direction -eq $UP ]] && {
+ [[ $prevpathlen != -1 ]] && comma[prevpathlen]=
+ for i in `seq $((prevpathlen+1)) -1 $((pathlen+1))`
+ do
+ arrays[i]=
+ [[ -n ${closers[i]} ]] && {
+ let indent=i*4
+ printf "\n%0${indent}s${closers[i]}" ""
+ unset closers[i]
+ comma[i]=
+ }
+ done
+ a=(${!arrays[*]})
+ [[ -n $a ]] && {
+ for k in `seq $i ${a[-1]}`; do
+ arrays[k]=
+ done
+ }
+ }
+
+ # Opening braces (the path leading up to the key)
+
+ broken=
+ for i in `seq 0 $((pathlen-1))`; do
+ [[ -z $broken && ${prevpath[i]} == ${path[i]} ]] && continue
+ [[ -z $broken ]] && {
+ broken=$i
+ [[ $prevpathlen -ne -1 ]] && broken=$((i+1))
+ }
+ if [[ ${path[i]} == '"'* ]]; then
+ # Object
+ [[ $i -ge $broken ]] && {
+ let indent=i*4
+ printf "${comma[i]}%0${indent}s{\n" ""
+ closers[i]='}'
+ comma[i]=
+ }
+ let indent=(i+1)*4
+ printf "${comma[i]}%0${indent}s${path[i]}:\n" ""
+ comma[i]=",\n"
+ else
+ # Array
+ if [[ ${arrays[i]} != 1 ]]; then
+ let indent=i*4
+ printf "%0${indent}s" ""
+ echo "["
+ closers[i]=']'
+ arrays[i]=1
+ comma[i]=
+ else
+ let indent=(i+1)*4
+ printf "\n%0${indent}s${closers[i-1]}" ""
+ direction=$DOWN
+ comma[i+1]=",\n"
+ fi
+ fi
+ done
+
+ # keys & values
+
+ if [[ ${path[-1]} == '"'* ]]; then
+ # Object
+ [[ $direction -eq $DOWN ]] && {
+ let indent=pathlen*4
+ printf "${comma[pathlen]}%0${indent}s{\n" ""
+ closers[pathlen]='}'
+ comma[pathlen]=
+ }
+ let indent=(pathlen+1)*4
+ printf "${comma[pathlen]}%0${indent}s" ""
+ echo -n "${path[-1]}:$value"
+ comma[pathlen]=",\n"
+ else
+ # Array
+ [[ ${arrays[i]} != 1 ]] && {
+ let indent=(pathlen-0)*4
+ printf "%0${indent}s[\n" ""
+ closers[pathlen]=']'
+ comma[pathlen]=
+ arrays[i]=1
+ }
+ let indent=(pathlen+1)*4
+ printf "${comma[pathlen]}%0${indent}s" ""
+ echo -n "$value"
+ comma[pathlen]=",\n"
+ fi
+
+ prevpath=("${path[@]}")
+ prevpathlen=$pathlen
+ done
+
+ # closing braces
+
+ for i in `seq $((pathlen)) -1 0`
+ do
+ let indent=i*4
+ printf "\n%0${indent}s${closers[i]}" ""
+ done
+ echo
+ fi
+}
+
+# ---------------------------------------------------------------------------
+filter() {
+# ---------------------------------------------------------------------------
+# Apply the query filter
+
+ local a tab=$(echo -e "\t") v
+
+ [[ $NOCASE -eq 1 ]] && opts+="-i"
+ [[ $WHOLEWORD -eq 1 ]] && opts+=" -w"
+ if [[ -z $OPERATOR ]]; then
+ egrep $opts "$FILTER"
+ else
+ egrep $opts "$FILTER" | \
+ while read line; do
+ v=${line#*$tab}
+ case $OPERATOR in
+ '-ge') if awk '{exit !($1>=$2)}'<<<"$v $RHS";then echo "$line"; fi
+ ;;
+ '-gt') if awk '{exit !($1>$2) }'<<<"$v $RHS";then echo "$line"; fi
+ ;;
+ '-le') if awk '{exit !($1<=$2) }'<<<"$v $RHS";then echo "$line"; fi
+ ;;
+ '-lt') if awk '{exit !($1<$2) }'<<<"$v $RHS";then echo "$line"; fi
+ ;;
+ '>') v=${v#\"};v=${v%\"}
+ RHS=${RHS#\"};RHS=${RHS%\"}
+ [[ "$v" > "$RHS" ]] && echo "$line"
+ ;;
+ '<') v=${v#\"};v=${v%\"}
+ RHS=${RHS#\"};RHS=${RHS%\"}
+ [[ "$v" < "$RHS" ]] && echo "$line"
+ ;;
+ esac
+ done #< <(egrep $opts "$FILTER")
+ fi
+}
+
+# ---------------------------------------------------------------------------
+parse () {
+# ---------------------------------------------------------------------------
+# Parses json
+
+ read -r token
+ parse_value
+ read -r token
+ case "$token" in
+ '') ;;
+ *) throw "EXPECTED EOF GOT $token"
+ exit 1;;
+ esac
+}
+
+# ---------------------------------------------------------------------------
+throw() {
+# ---------------------------------------------------------------------------
+ echo "$*" >&2
+ exit 1
+}
+
+if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]);
+then
+ main "$@"
+fi
+
+# vi: expandtab sw=2 ts=2 \ No newline at end of file
diff --git a/deps/jsonpath/LICENSE.APACHE2 b/deps/jsonpath/LICENSE.APACHE2
new file mode 100644
index 0000000000..6366c04716
--- /dev/null
+++ b/deps/jsonpath/LICENSE.APACHE2
@@ -0,0 +1,15 @@
+Apache License, Version 2.0
+
+Copyright (c) 2011 Dominic Tarr
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/deps/jsonpath/LICENSE.MIT b/deps/jsonpath/LICENSE.MIT
new file mode 100644
index 0000000000..6eafbd734a
--- /dev/null
+++ b/deps/jsonpath/LICENSE.MIT
@@ -0,0 +1,24 @@
+The MIT License
+
+Copyright (c) 2011 Dominic Tarr
+
+Permission is hereby granted, free of charge,
+to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to
+deal in the Software without restriction, including
+without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom
+the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/deps/jsonpath/MANIFEST.in b/deps/jsonpath/MANIFEST.in
new file mode 100644
index 0000000000..b98f63d048
--- /dev/null
+++ b/deps/jsonpath/MANIFEST.in
@@ -0,0 +1,3 @@
+include README.md
+include LICENSE.MIT
+include LICENSE.APACHE2 \ No newline at end of file
diff --git a/deps/jsonpath/README.md b/deps/jsonpath/README.md
new file mode 100644
index 0000000000..5b770bc5d1
--- /dev/null
+++ b/deps/jsonpath/README.md
@@ -0,0 +1,491 @@
+# JSONPath.sh
+
+yo, so it's a JSONPath implementation written in Bash - and it probably only works in Bash.
+
+[![travis](https://secure.travis-ci.org/mclarkson/JSONPath.sh.png?branch=master)](https://travis-ci.org/mclarkson/JSONPath.sh)
+
+## Invocation
+
+ JSONPath.sh [-b] [-i] [-j] [-h] [-p] [-u] [-f FILE] [pattern]
+
+pattern
+> the JSONPath query. Defaults to '$.\*' if not supplied.
+
+-b
+> Brief output. Only show the values, not the path and key.
+
+-f FILE
+> Read a FILE instead of reading from standard input.
+
+-i
+> Case insensitive searching.
+
+-j
+> Output in JSON format, instead of JSON.sh format.
+
+-u
+> Strip unnecessary leading path elements.
+
+-p
+> Pass JSON.sh formatted data through to the JSON parser only. Useful after
+> JSON.sh data has been manipulated.
+
+-h
+> Show help text.
+
+## Requirements
+
+JSONPath.sh is a Bash script that uses the standard GNU tools: *bash*, *cat*, *sed*, *awk*, *grep*, and *seq*.
+
+## Installation
+
+Install with pip:
+
+* `sudo pip install git+https://github.com/mclarkson/JSONPath.sh#egg=JSONPath.sh`
+
+Install with npm:
+
+* `sudo npm install -g jsonpath.sh`
+
+Or copy the `JSONPath.sh` script to your PATH, for example:
+
+``` bash
+curl -O https://raw.githubusercontent.com/mclarkson/JSONPath.sh/master/JSONPath.sh
+chmod +x JSONPath.sh
+mv JSONPath.sh ~/bin
+```
+
+## Examples
+
+``` bash
+$ ./JSONPath.sh < package.json
+["name"] "JSONPath.sh"
+["version"] "0.0.0"
+["description"] "JSONPath implementation written in Bash"
+["homepage"] "http://github.com/mclarkson/JSONPath.sh"
+["repository","type"] "git"
+["repository","url"] "https://github.com/mclarkson/JSONPath.sh.git"
+["bin","JSONPath.sh"] "./JSONPath.sh"
+["author"] "Mark Clarkson <mark.clarkson@smorg.co.uk>"
+["scripts","test"] "./all-tests.sh"
+```
+
+more complex examples:
+
+*NPMJS.ORG EXAMPLES*
+
+``` bash
+# Number of downloads yesterday
+curl -s https://api.npmjs.org/downloads/point/last-day/jsonpath.sh | \
+ JSONPath.sh '$.downloads' -b
+
+# Show all versions
+curl registry.npmjs.org/express | ./JSONPath.sh '$.versions.*.version'
+
+# Show version 2.2.0
+./JSONPath.sh \
+ -f test/valid/npmjs.org.json \
+ '$.versions.["2.2.0"]'
+
+# Find versions 2.2.x (using a regular expression)
+# and show version and contributors
+./JSONPath.sh \
+ -f test/valid/npmjs.org.json \
+ '$..["2.2.*"].[version,contributors]'
+```
+*JSONPATH.ORG EXAMPLES*
+
+``` bash
+# The default query
+./JSONPath.sh \
+ -f test/valid/jsonpath.com.json \
+ '$.phoneNumbers[:1].type'
+
+# The same, but using a filter (script) expression
+# (This takes 2 passes through the data)
+./JSONPath.sh \
+ -f test/valid/jsonpath.com.json \
+ '$.phoneNumbers[?(@.type=iPhone)]'
+```
+
+*KUBERNETES EXAMPLES*
+
+``` bash
+# Show the NodePort of a service named bob
+# from a list of all services
+kubectl get svc -o json | JSONPath.sh \
+ '$..items[?(@.metadata.name==bob)].spec.ports[0].nodePort' -b
+
+# Or, more simply, show the NodePort of the service
+kubectl get svc bob -o json | JSONPath.sh '$..nodePort' -b
+
+# Get the port of the kubernetes-dashboard and output as json:
+kubectl get svc --all-namespaces -o json | JSONPath.sh -j -u \
+ '$.items[?(@.spec.selector.app=".*dashboard")]..ports[*].nodePort'
+```
+
+*DOCKER EXAMPLES*
+
+``` bash
+# Show Everything
+./JSONPath.sh -f test/valid/docker_stopped.json '$.*'
+
+# Look for an ip address (using case insensitive searching to start)
+./JSONPath.sh \
+ -f test/valid/docker_running.json \
+ /valid/docker_running.json -i '$..".*ip.*"'
+
+# Now get the IP address exactly
+./JSONPath.sh \
+ -f test/valid/docker_running.json \
+ '$.*.NetworkSettings.IPAddress' -b
+
+# Show all Mounts
+./JSONPath.sh \
+ -f test/valid/docker_stopped.json \
+ '$.[*].Mounts'
+
+# Show sources and destinations for all mounts
+./JSONPath.sh \
+ -f test/valid/docker_stopped.json \
+ '$.[*].Mounts[*].[Source,Destination]'
+
+# Use brief (-b) output to store mounts in an array for use in a loop
+readarray -t MNTS \
+ < <(./JSONPath.sh -b -f test/valid/docker_stopped.json '$.*.Mounts[*].[Source,Destination]')
+
+# the loop:
+for idx in `seq 0 $((${#MNTS[*]}/2-1))`; do
+ echo "'${MNTS[idx*2]}' is mounted on the host at '${MNTS[idx*2+1]}'"
+done
+```
+
+*GOESSNER.NET (EXPANDED) EXAMPLES*
+
+``` bash
+# dot-notation (my latest favourite book)
+./JSONPath.sh \
+ -f test/valid/goessner.net.expanded.json \
+ '$.store.book[16].title'
+
+# dot-notation with a node set
+./JSONPath.sh \
+ -f test/valid/goessner.net.expanded.json \
+ '$.store.book[4,6,16,22].title'
+
+# bracket-notation ('$[' needs escaping at the
+# command line, so bash doesn't think it's an
+# arithmetic expression)
+./JSONPath.sh \
+ -f test/valid/goessner.net.expanded.json \
+ "\$['store']['book'][16]['title']"
+
+# bracket-notation with an array slice and a set
+./JSONPath.sh \
+ -f test/valid/goessner.net.expanded.json \
+ "\$['store']['book'][14:25:2]['title','reviews']"
+
+# Mixed bracket- and dot- notation
+./JSONPath.sh \
+ -f test/valid/goessner.net.expanded.json \
+ "\$['store'].book[16].title"
+
+# Show all titles
+./JSONPath.sh \
+ -f test/valid/goessner.net.expanded.json \
+ '$..book[*].title'
+
+# All books with 'Book 1' somewhere in the title
+./JSONPath.sh \
+ -f test/valid/goessner.net.expanded.json \
+ -i '$..book[?(@.title==".*Book 1.*")].title'
+
+# All books with a price less than or equal to 4.20
+# Show both the title and the price and output in
+# JSON format but without redundant path elements.
+./JSONPath.sh -j -u \
+ -f test/valid/goessner.net.expanded.json \
+ '$.store.book[?(@.price<4.20)].[title,price]'
+
+# The following does not work yet (TODO)
+./JSONPath.sh \
+ -f test/valid/goessner.net.expanded.json \
+ '$.store.book[(@.length-1)].title'
+```
+
+## JSONPath patterns and extensions
+
+### Supported JSONPath options
+
+| JSONPath | Supported | Comment |
+| -----------------------|-----------|---------------------------------------------------------|
+| $ | Y | the root object/element (optional) |
+| @ | Y | the current object/element |
+| . or [] | Y | child operator. |
+| .. | Y | recusive descent. |
+| * | Y | wildcard. All objects/elements regardless their names. |
+| [] | Y | subscript operator. |
+| [,] | Y | node sets. |
+| ```[start:end:step]``` | Y | array slice operator. |
+| ?() | Y | applies a filter (script) expressions |
+| () | Y | script expression, using the underlying script engine. |
+
+### Searching for things
+
+"regex"
+
+Use a regular expression inside the JSONPath pattern.<br>
+Combine with '-i' for case insensitive search.<br>
+Combine with '-w' to match whole words only.
+
+Examples:
+
+Find every node key starting with 'ip':
+
+``` bash
+# These are all equivalent
+./JSONPath.sh -f test/valid/docker_running.json -i "$..['ip.*']"
+./JSONPath.sh -f test/valid/docker_running.json -i '$..["ip.*"]'
+./JSONPath.sh -f test/valid/docker_running.json -i '$.."ip.*"'
+./JSONPath.sh -f test/valid/docker_running.json -i "$..'ip.*'"
+```
+
+Restrict the previous search to the bridge object.
+
+``` bash
+./JSONPath.sh -f test/valid/docker_running.json -i "$..bridge.'ip.*'"
+```
+
+Show all book titles by authors starting with 'Doug'.
+
+``` bash
+# Show the title
+./JSONPath.sh -f test/valid/goessner.net.expanded.json -i \
+ "$..book[?(@.author==Doug)].title"
+
+# Show the author, title and rating (can be with or without double quotes)
+./JSONPath.sh -f test/valid/goessner.net.expanded.json -i \
+ '$..book[?(@.author="Doug")].["author","title",rating]'
+```
+
+### Modification
+
+A common task is to modify JSON data on-the-fly. Unix style 'one-liners' can be
+created to easily and logically modify JSON data.
+
+The key to data modification (that is: add, modify or deletion of data) is to
+modify the *JSON.sh* formatted data, then use the passthrough, '-p', option to
+output again as JSON. Sequence is:
+
+1. Read JSON data and output as *JSON.sh* data.
+2. Modify *JSON.sh* data using standard Unix tools.
+3. Pipe modified *JSON.sh* data to JSONPath.sh with passthrough option producing
+ JSON data again.
+
+For example: The following 'one-liner' will read a kubernetes deployment
+configuration (using 'kubectl get ...'), output it in *JSON.sh* format (using
+'JSONPath.sh'), change the number of replicas from the existing value to 5
+(using *sed*), output again in JSON (using 'JSONPath.sh -p'), then replace the
+original deployment with the newly changed one (using 'kubectl replace ...').
+
+```
+kubectl get deployment sample-deployment -o json | \
+JSONPath.sh | \
+sed 's/\["spec","replicas"\].*/["spec","replicas"]\t5/' | \
+JSONPath.sh -p | \
+kubectl replace deployment sample-deployment -f -
+```
+
+This allows you to reuse your Unix skills rather than learn new terse syntax
+or Domain Specific Language.
+
+### Re-injection
+
+This tool, JSONPath.sh, is really handy for handing json formatted
+data to other tools, and using pass-through mode (-p) comes in quite
+handy for creating complex queries and outputting in json.
+
+**Re-injection** allows the user to overcome the limitation
+of a single filter expression per invocation. To do this the first
+query, or set of queries, should output in JSON format using the
+'-j' option.
+
+**Usage Example**
+
+Show all books with a price greater than 4 that also have a 5 star
+rating (note that the first process in the pipeline outputs in json):
+
+```
+./JSONPath.sh -j -f test/valid/goessner.net.expanded.json \
+ '$..book[?(@.price>4)]' | ./JSONPath.sh \
+ '$..book[?(@.rating==5)].title'
+```
+
+**Pass-through mode** reads the standard output JSONPath.sh (or JSON.sh)
+produces and outputs JSON. This gives the user an opportunity to filter
+or modify the results:
+
+**Filtering Usage Example**
+
+Show all authors, without showing duplicates and output in JSON format.
+
+All authors with duplicates:
+
+```
+$ ./JSONPath.sh -f test/valid/goessner.net.expanded.json '$..author'
+... omitted ...
+["store","book",9,"author"] "James S. A. Corey"
+["store","book",10,"author"] "James S. A. Corey"
+["store","book",11,"author"] "James S. A. Corey"
+... 25 lines of output ...
+```
+
+Use standard unix tools to remove duplicates:
+
+```
+$ ./JSONPath.sh -f test/valid/goessner.net.expanded.json '$..author' \
+ | sort -k2 | uniq -f 1
+... 11 lines of output ...
+```
+
+And pipe (re-inject - 'cos it sounds cool) the output into JSONPath.sh:
+
+```
+$ ./JSONPath.sh -f test/valid/goessner.net.expanded.json '$..author' \
+ | sort -k2 | uniq -f 1 \
+ | ./JSONPath.sh -p
+{
+ "store":
+ {
+ "book":
+ [
+ {
+ "author":"Douglas E. Richards"
+ }
+ ,{
+ "author":"Evelyn Waugh"
+ }
+... JSON output with unique data ...
+```
+
+Use the '-u' option to flatten the output:
+
+```
+$ ./JSONPath.sh -f test/valid/goessner.net.expanded.json \
+ '$..author' \
+ | sort -k2 | uniq -f 1 \
+ | ./JSONPath.sh -p -u
+... JSON flattened output ...
+{
+ "book":
+ [
+ {
+ "author":"Douglas E. Richards"
+ },
+ {
+ "author":"Evelyn Waugh"
+ },
+```
+
+**Filter and Merge Usage Example**
+
+Different parts of JSON input, or entirely different JSON input, can be merged
+together with Unix 'sort' and output in json format.
+
+This is a complex kubernetes example that uses JSONPath.sh and standard Unix
+tools to output just the command, pod mounts, and container mounts (output from
+different parts of the tree) for the first matched kube-proxy pod.
+
+```
+# Get details of all pods
+kubectl get -n kube-system pods -o json >/tmp/kpod
+
+# Get the index of the first pod with name starting 'kube-proxy'
+idx=`JSONPath.sh -f /tmp/kpod '$.items[?(@.metadata.name=="kube-proxy.*")].apiVersion' \
+ | head -n1 | grep -o ',[0-9]\+,' | tr -d ,`
+
+# Get three subtrees using the index and merge them using sort
+# and then output in json format
+( JSONPath.sh -f /tmp/kpod '$.items['$idx'].spec.volumes'; \
+ JSONPath.sh -f /tmp/kpod '$.items['$idx']..volumeMounts'; \
+ JSONPath.sh -f /tmp/kpod '$.items['$idx']..containers[*].command'
+) | sort | JSONPath.sh -p -u
+```
+
+, which produces:
+
+```
+{
+ "containers":
+ [
+ {
+ "command":
+ [
+ "/usr/local/bin/kube-proxy",
+ "--kubeconfig=/var/lib/kube-proxy/kubeconfig.conf"
+ ],
+ "volumeMounts":
+ [
+ {
+ "mountPath":"/var/lib/kube-proxy",
+ "name":"kube-proxy"
+ },
+ {
+ "mountPath":"/var/run/secrets/kubernetes.io/serviceaccount",
+ "name":"kube-proxy-token-m9b6j",
+ "readOnly":true
+ }
+ ]
+ }
+ ],
+ "volumes":
+ [
+ {
+ "configMap":
+ {
+ "defaultMode":420,
+ "name":"kube-proxy"
+ },
+ "name":"kube-proxy"
+ },
+ {
+ "name":"kube-proxy-token-m9b6j",
+ "secret":
+ {
+ "defaultMode":420,
+ "secretName":"kube-proxy-token-m9b6j"
+ }
+ }
+ ]
+}
+```
+
+## Cool Links
+
+* [dominictarr/JSON.sh](https://github.com/dominictarr/JSON.sh) The original, the best, JSON.sh.
+
+## Performance
+
+* Performance is acceptable for small data sizes
+* Worse when using:
+ * large data files (hundreds of kilobytes).
+ * filter (script) expressions (An extra pass is required).
+ * Indexes greater than 9.
+ * Indexes with steps even with indexes less than 10.
+* Better with:
+ * Small data files (A few kilobytes).
+ * Indexes less than 10 (then matching is done by regex, unless a step is used).
+ * No filter (script) expressions (so no extra pass through the data).
+
+## Limitations (todo)
+
+* Only one filter expression, '?(@', per query.
+ Use re-injection, detailed above, to overcome this limitation.
+
+## License
+
+This software is available under the following licenses:
+
+ * MIT
+ * Apache 2
+
diff --git a/deps/jsonpath/_config.yml b/deps/jsonpath/_config.yml
new file mode 100644
index 0000000000..c741881743
--- /dev/null
+++ b/deps/jsonpath/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-slate \ No newline at end of file
diff --git a/deps/jsonpath/all-tests.sh b/deps/jsonpath/all-tests.sh
new file mode 100644
index 0000000000..84f826f75d
--- /dev/null
+++ b/deps/jsonpath/all-tests.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+cd ${0%/*}
+
+#set -e
+fail=0
+tests=0
+#all_tests=${__dirname:}
+#echo PLAN ${#all_tests}
+for test in test/*.sh ;
+do
+ tests=$((tests+1))
+ echo TEST: $test
+ ./$test
+ ret=$?
+ if [ $ret -eq 0 ] ; then
+ echo OK: ---- $test
+ passed=$((passed+1))
+ else
+ echo FAIL: $test $fail
+ fail=$((fail+ret))
+ fi
+done
+
+if [ $fail -eq 0 ]; then
+ echo -n 'SUCCESS '
+ exitcode=0
+else
+ echo -n 'FAILURE '
+ exitcode=1
+fi
+echo $passed / $tests
+exit $exitcode
diff --git a/deps/jsonpath/package.json b/deps/jsonpath/package.json
new file mode 100644
index 0000000000..458b822a53
--- /dev/null
+++ b/deps/jsonpath/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "jsonpath.sh",
+ "version": "0.0.14",
+ "description": "JSONPath implementation written in Bash",
+ "homepage": "http://github.com/mclarkson/JSONPath.sh",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/mclarkson/JSONPath.sh.git"
+ },
+ "bin": {
+ "JSONPath.sh": "./JSONPath.sh"
+ },
+ "dependencies": {},
+ "devDependencies": {},
+ "author": "Mark Clarkson <mark.clarkson@smorg.co.uk>",
+ "scripts": {
+ "test": "./all-tests.sh"
+ }
+}
diff --git a/deps/jsonpath/setup.py b/deps/jsonpath/setup.py
new file mode 100644
index 0000000000..df9863f921
--- /dev/null
+++ b/deps/jsonpath/setup.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from setuptools import setup
+import os
+
+# Allow setup.py to be run from any path
+os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
+
+setup(
+ name='JSONPath.sh',
+ scripts=[
+ 'JSONPath.sh',
+ ],
+ version='0.0.14',
+ description="JSONPath implementation written in Bash",
+ long_description="",
+ author='Mark Clarkson',
+ author_email='mark.clarkson@smorg.co.uk',
+ url='https://github.com/mclarkson/JSONPath.sh',
+ classifiers=[
+ "Programming Language :: Unix Shell",
+ "License :: OSI Approved :: MIT License",
+ "License :: OSI Approved :: Apache Software License",
+ "Intended Audience :: System Administrators",
+ "Intended Audience :: Developers",
+ "Operating System :: POSIX :: Linux",
+ "Topic :: Utilities",
+ "Topic :: Software Development :: Libraries",
+ ],
+)
diff --git a/deps/semver_bash/.gitignore b/deps/semver_bash/.gitignore
new file mode 100644
index 0000000000..5cb19d201a
--- /dev/null
+++ b/deps/semver_bash/.gitignore
@@ -0,0 +1,4 @@
+*~
+*tmp
+*swp
+
diff --git a/deps/semver_bash/LICENSE b/deps/semver_bash/LICENSE
new file mode 100644
index 0000000000..04ac66f8f6
--- /dev/null
+++ b/deps/semver_bash/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2013, Ray Bejjani
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those
+of the authors and should not be interpreted as representing official policies,
+either expressed or implied, of the FreeBSD Project.
diff --git a/deps/semver_bash/README.md b/deps/semver_bash/README.md
new file mode 100644
index 0000000000..180c368964
--- /dev/null
+++ b/deps/semver_bash/README.md
@@ -0,0 +1,31 @@
+semver_bash is a bash parser for semantic versioning
+====================================================
+
+[Semantic Versioning](http://semver.org/) is a set of guidelines that help keep
+version and version management sane. This is a bash based parser to help manage
+a project's versions. Use it from a Makefile or any scripts you use in your
+project.
+
+Usage
+-----
+semver_bash can be used from the command line as:
+
+ $ ./semver.sh "3.2.1" "3.2.1-alpha"
+ 3.2.1 -> M: 3 m:2 p:1 s:
+ 3.2.1-alpha -> M: 3 m:2 p:1 s:-alpha
+ 3.2.1 == 3.2.1-alpha -> 1.
+ 3.2.1 < 3.2.1-alpha -> 1.
+ 3.2.1 > 3.2.1-alpha -> 0.
+
+
+Alternatively, you can source it from within a script:
+
+ . ./semver.sh
+
+ local MAJOR=0
+ local MINOR=0
+ local PATCH=0
+ local SPECIAL=""
+
+ semverParseInto "1.2.3" MAJOR MINOR PATCH SPECIAL
+ semverParseInto "3.2.1" MAJOR MINOR PATCH SPECIAL
diff --git a/deps/semver_bash/semver.sh b/deps/semver_bash/semver.sh
new file mode 100644
index 0000000000..e5237a4e2e
--- /dev/null
+++ b/deps/semver_bash/semver.sh
@@ -0,0 +1,130 @@
+#!/usr/bin/env sh
+
+function semverParseInto() {
+ local RE='[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)'
+ #MAJOR
+ eval $2=`echo $1 | sed -e "s#$RE#\1#"`
+ #MINOR
+ eval $3=`echo $1 | sed -e "s#$RE#\2#"`
+ #MINOR
+ eval $4=`echo $1 | sed -e "s#$RE#\3#"`
+ #SPECIAL
+ eval $5=`echo $1 | sed -e "s#$RE#\4#"`
+}
+
+function semverEQ() {
+ local MAJOR_A=0
+ local MINOR_A=0
+ local PATCH_A=0
+ local SPECIAL_A=0
+
+ local MAJOR_B=0
+ local MINOR_B=0
+ local PATCH_B=0
+ local SPECIAL_B=0
+
+ semverParseInto $1 MAJOR_A MINOR_A PATCH_A SPECIAL_A
+ semverParseInto $2 MAJOR_B MINOR_B PATCH_B SPECIAL_B
+
+ if [ $MAJOR_A -ne $MAJOR_B ]; then
+ return 1
+ fi
+
+ if [ $MINOR_A -ne $MINOR_B ]; then
+ return 1
+ fi
+
+ if [ $PATCH_A -ne $PATCH_B ]; then
+ return 1
+ fi
+
+ if [[ "_$SPECIAL_A" != "_$SPECIAL_B" ]]; then
+ return 1
+ fi
+
+
+ return 0
+
+}
+
+function semverLT() {
+ local MAJOR_A=0
+ local MINOR_A=0
+ local PATCH_A=0
+ local SPECIAL_A=0
+
+ local MAJOR_B=0
+ local MINOR_B=0
+ local PATCH_B=0
+ local SPECIAL_B=0
+
+ semverParseInto $1 MAJOR_A MINOR_A PATCH_A SPECIAL_A
+ semverParseInto $2 MAJOR_B MINOR_B PATCH_B SPECIAL_B
+
+ if [ $MAJOR_A -lt $MAJOR_B ]; then
+ return 0
+ fi
+
+ if [[ $MAJOR_A -le $MAJOR_B && $MINOR_A -lt $MINOR_B ]]; then
+ return 0
+ fi
+
+ if [[ $MAJOR_A -le $MAJOR_B && $MINOR_A -le $MINOR_B && $PATCH_A -lt $PATCH_B ]]; then
+ return 0
+ fi
+
+ if [[ "_$SPECIAL_A" == "_" ]] && [[ "_$SPECIAL_B" == "_" ]] ; then
+ return 1
+ fi
+ if [[ "_$SPECIAL_A" == "_" ]] && [[ "_$SPECIAL_B" != "_" ]] ; then
+ return 1
+ fi
+ if [[ "_$SPECIAL_A" != "_" ]] && [[ "_$SPECIAL_B" == "_" ]] ; then
+ return 0
+ fi
+
+ if [[ "_$SPECIAL_A" < "_$SPECIAL_B" ]]; then
+ return 0
+ fi
+
+ return 1
+
+}
+
+function semverGT() {
+ semverEQ $1 $2
+ local EQ=$?
+
+ semverLT $1 $2
+ local LT=$?
+
+ if [ $EQ -ne 0 ] && [ $LT -ne 0 ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+if [ "___semver.sh" == "___`basename $0`" ]; then
+
+MAJOR=0
+MINOR=0
+PATCH=0
+SPECIAL=""
+
+semverParseInto $1 MAJOR MINOR PATCH SPECIAL
+echo "$1 -> M: $MAJOR m:$MINOR p:$PATCH s:$SPECIAL"
+
+semverParseInto $2 MAJOR MINOR PATCH SPECIAL
+echo "$2 -> M: $MAJOR m:$MINOR p:$PATCH s:$SPECIAL"
+
+semverEQ $1 $2
+echo "$1 == $2 -> $?."
+
+semverLT $1 $2
+echo "$1 < $2 -> $?."
+
+semverGT $1 $2
+echo "$1 > $2 -> $?."
+
+fi
diff --git a/deps/semver_bash/semver_test.sh b/deps/semver_bash/semver_test.sh
new file mode 100644
index 0000000000..a0ff99461e
--- /dev/null
+++ b/deps/semver_bash/semver_test.sh
@@ -0,0 +1,151 @@
+#!/usr/bin/env bash
+
+. ./semver.sh
+
+semverTest() {
+local A=R1.3.2
+local B=R2.3.2
+local C=R1.4.2
+local D=R1.3.3
+local E=R1.3.2a
+local F=R1.3.2b
+local G=R1.2.3
+
+local MAJOR=0
+local MINOR=0
+local PATCH=0
+local SPECIAL=""
+
+semverParseInto $A MAJOR MINOR PATCH SPECIAL
+echo "$A -> M:$MAJOR m:$MINOR p:$PATCH s:$SPECIAL. Expect M:1 m:3 p:2 s:"
+semverParseInto $E MAJOR MINOR PATCH SPECIAL
+echo "$E -> M:$MAJOR m:$MINOR p:$PATCH s:$SPECIAL. Expect M:1 m:3 p:2 s:a"
+
+echo "Equality comparisions"
+semverEQ $A $A
+echo "$A == $A -> $?. Expect 0."
+
+semverLT $A $A
+echo "$A < $A -> $?. Expect 1."
+
+semverGT $A $A
+echo "$A > $A -> $?. Expect 1."
+
+
+echo "Major number comparisions"
+semverEQ $A $B
+echo "$A == $B -> $?. Expect 1."
+
+semverLT $A $B
+echo "$A < $B -> $?. Expect 0."
+
+semverGT $A $B
+echo "$A > $B -> $?. Expect 1."
+
+semverEQ $B $A
+echo "$B == $A -> $?. Expect 1."
+
+semverLT $B $A
+echo "$B < $A -> $?. Expect 1."
+
+semverGT $B $A
+echo "$B > $A -> $?. Expect 0."
+
+
+echo "Minor number comparisions"
+semverEQ $A $C
+echo "$A == $C -> $?. Expect 1."
+
+semverLT $A $C
+echo "$A < $C -> $?. Expect 0."
+
+semverGT $A $C
+echo "$A > $C -> $?. Expect 1."
+
+semverEQ $C $A
+echo "$C == $A -> $?. Expect 1."
+
+semverLT $C $A
+echo "$C < $A -> $?. Expect 1."
+
+semverGT $C $A
+echo "$C > $A -> $?. Expect 0."
+
+echo "patch number comparisions"
+semverEQ $A $D
+echo "$A == $D -> $?. Expect 1."
+
+semverLT $A $D
+echo "$A < $D -> $?. Expect 0."
+
+semverGT $A $D
+echo "$A > $D -> $?. Expect 1."
+
+semverEQ $D $A
+echo "$D == $A -> $?. Expect 1."
+
+semverLT $D $A
+echo "$D < $A -> $?. Expect 1."
+
+semverGT $D $A
+echo "$D > $A -> $?. Expect 0."
+
+echo "special section vs no special comparisions"
+semverEQ $A $E
+echo "$A == $E -> $?. Expect 1."
+
+semverLT $A $E
+echo "$A < $E -> $?. Expect 1."
+
+semverGT $A $E
+echo "$A > $E -> $?. Expect 0."
+
+semverEQ $E $A
+echo "$E == $A -> $?. Expect 1."
+
+semverLT $E $A
+echo "$E < $A -> $?. Expect 0."
+
+semverGT $E $A
+echo "$E > $A -> $?. Expect 1."
+
+echo "special section vs special comparisions"
+semverEQ $E $F
+echo "$E == $F -> $?. Expect 1."
+
+semverLT $E $F
+echo "$E < $F -> $?. Expect 0."
+
+semverGT $E $F
+echo "$E > $F -> $?. Expect 1."
+
+semverEQ $F $E
+echo "$F == $E -> $?. Expect 1."
+
+semverLT $F $E
+echo "$F < $E -> $?. Expect 1."
+
+semverGT $F $E
+echo "$F > $E -> $?. Expect 0."
+
+echo "Minor and patch number comparisons"
+semverEQ $A $G
+echo "$A == $G -> $?. Expect 1."
+
+semverLT $A $G
+echo "$A < $G -> $?. Expect 1."
+
+semverGT $A $G
+echo "$A > $G -> $?. Expect 0."
+
+semverEQ $G $A
+echo "$G == $A -> $?. Expect 1."
+
+semverLT $G $A
+echo "$G < $A -> $?. Expect 0."
+
+semverGT $G $A
+echo "$G > $A -> $?. Expect 1."
+}
+
+semverTest
diff --git a/install.sh b/install.sh
index 24a8320b4a..8950dab666 100755
--- a/install.sh
+++ b/install.sh
@@ -3,16 +3,8 @@
set -e
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-PATH_APPS="$CUR_PATH/apps/"
-PATH_MODULES="$CUR_PATH/modules/"
-[ ! -d $PATH_APPS/drassil/joiner ] && git clone https://github.com/drassil/joiner $PATH_APPS/drassil/joiner -b master
-source "$PATH_APPS/drassil/joiner/joiner.sh"
+source "$CUR_PATH/apps/installer/includes/includes.sh"
-# installing repository dependencies
-if [[ $1 == "dev" ]]; then
- git submodule update --init "$CUR_PATH/data/doc"
-fi
-source "$CUR_PATH/apps/installer/main.sh"