Rewrite of bash system

+ Implemented new dashboard menu
+ some fixes for db_assembler
+ new module installation process with version check via json files
+ some fixes to modules installer
+ implemented simple crossplatform worldserver and authserver restarters
+ new compiler script
+ client data downloader (beta)
+ various other fixes
This commit is contained in:
Yehonal 2018-07-15 22:40:49 +02:00
parent 07a451e140
commit 85388901cf
38 changed files with 2179 additions and 163 deletions

5
acore.json Normal file
View File

@ -0,0 +1,5 @@
{
"name" : "azerothcore-wotlk",
"version" : "2.0.0-dev",
"license" : "AGPL3"
}

7
acore.sh Normal file
View File

@ -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"

View File

@ -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')

View File

@ -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

View File

@ -1,5 +0,0 @@
#!/usr/bin/env bash
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
bash "$CURRENT_PATH/compiler.sh" 1

View File

@ -1,5 +0,0 @@
#!/usr/bin/env bash
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
bash "$CURRENT_PATH/compiler.sh" 2

View File

@ -1,5 +0,0 @@
#!/usr/bin/env bash
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
bash "$CURRENT_PATH/compiler.sh" 3

View File

@ -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"
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
}
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")
PS3='[ Please enter your choice ]: '
runHooks "ON_AFTER_OPTIONS" #you can create your custom options
# push exit after custom options
comp_options+=('Exit')
comp_functions+=('exit 0')
function _switch() {
_reply="$1"
_opt="$2"
# run option directly if specified in argument
[ ! -z $1 ] && run_option $1 && exit 0
PS3='[ Please enter your choice ]: '
select opt in "${comp_options[@]}"
do
case $opt in
'Exit')
break
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

View File

@ -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
}

View File

@ -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
}
while true
do
# run option directly if specified in argument
[ ! -z $1 ] && _switch "${options[$cmdopt-1]}" && exit 0
[ ! -z $1 ] && _switch $@
[ ! -z $1 ] && exit 0
select opt in "${options[@]}"
do
_switch "$opt"
echo "===== DB ASSEMBLER MENU ====="
_switch $REPLY
break
done
done

View File

@ -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
}

View File

@ -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"

View File

@ -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
}
while true
do
# run option directly if specified in argument
[ ! -z $1 ] && _switch "${options[$cmdopt-1]}"
[ ! -z $1 ] && _switch $@ # old method: "${options[$cmdopt-1]}"
[ ! -z $1 ] && exit 0
select opt in "${options[@]}"
do
_switch "$opt"
echo "==== ACORE DASHBOARD ===="
_switch $REPLY
break
done
done

View File

@ -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

View File

@ -1,3 +1,5 @@
#!/usr/bin/env bash
source ./acore-installer
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CUR_PATH/acore-installer"

View File

@ -1,3 +1,5 @@
#!/usr/bin/env bash
bash ../apps/compiler/compiler.sh
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CUR_PATH/../apps/compiler/compiler.sh"

View File

@ -1,3 +1,5 @@
#!/usr/bin/env bash
bash ../apps/db_assembler/db_assembler.sh
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CUR_PATH/../apps/db_assembler/db_assembler.sh"

View File

@ -1,3 +1,5 @@
#!/usr/bin/env bash
bash ../apps/db_exporter/db_exporter.sh
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CUR_PATH/../apps/db_exporter/db_exporter.sh"

View File

@ -1,3 +1,5 @@
#!/usr/bin/env bash
bash ../apps/db_pendings/import.sh
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CUR_PATH/../apps/db_pendings/import.sh"

View File

@ -1,3 +1,5 @@
#!/usr/bin/env bash
bash ../apps/installer/main.sh
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$CUR_PATH/../apps/installer/main.sh"

5
deps/jsonpath/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
test/errlog
test/outlog
# vi .swp files
.*.swp

10
deps/jsonpath/.travis.yml vendored Normal file
View File

@ -0,0 +1,10 @@
language: python
addons:
apt:
packages:
- bash
# Whatever the current shebang, replace with hardcoded shell
script: >
./all-tests.sh

1
deps/jsonpath/CNAME vendored Normal file
View File

@ -0,0 +1 @@
jsonpath.obdi.io

857
deps/jsonpath/JSONPath.sh vendored Normal file
View File

@ -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

15
deps/jsonpath/LICENSE.APACHE2 vendored Normal file
View File

@ -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.

24
deps/jsonpath/LICENSE.MIT vendored Normal file
View File

@ -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.

3
deps/jsonpath/MANIFEST.in vendored Normal file
View File

@ -0,0 +1,3 @@
include README.md
include LICENSE.MIT
include LICENSE.APACHE2

491
deps/jsonpath/README.md vendored Normal file
View File

@ -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

1
deps/jsonpath/_config.yml vendored Normal file
View File

@ -0,0 +1 @@
theme: jekyll-theme-slate

33
deps/jsonpath/all-tests.sh vendored Normal file
View File

@ -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

19
deps/jsonpath/package.json vendored Normal file
View File

@ -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"
}
}

31
deps/jsonpath/setup.py vendored Normal file
View File

@ -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",
],
)

4
deps/semver_bash/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*~
*tmp
*swp

26
deps/semver_bash/LICENSE vendored Normal file
View File

@ -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.

31
deps/semver_bash/README.md vendored Normal file
View File

@ -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

130
deps/semver_bash/semver.sh vendored Normal file
View File

@ -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

151
deps/semver_bash/semver_test.sh vendored Normal file
View File

@ -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

View File

@ -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"