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:
parent
07a451e140
commit
85388901cf
5
acore.json
Normal file
5
acore.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name" : "azerothcore-wotlk",
|
||||
"version" : "2.0.0-dev",
|
||||
"license" : "AGPL3"
|
||||
}
|
||||
7
acore.sh
Normal file
7
acore.sh
Normal 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"
|
||||
23
apps/bash_shared/common.sh
Normal file
23
apps/bash_shared/common.sh
Normal 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')
|
||||
@ -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
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
bash "$CURRENT_PATH/compiler.sh" 1
|
||||
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
bash "$CURRENT_PATH/compiler.sh" 2
|
||||
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURRENT_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
bash "$CURRENT_PATH/compiler.sh" 3
|
||||
@ -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
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
9
apps/startup-scripts/simple-restarter
Normal file
9
apps/startup-scripts/simple-restarter
Normal 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
|
||||
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./acore-installer
|
||||
CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
source "$CUR_PATH/acore-installer"
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
5
deps/jsonpath/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
test/errlog
|
||||
test/outlog
|
||||
|
||||
# vi .swp files
|
||||
.*.swp
|
||||
10
deps/jsonpath/.travis.yml
vendored
Normal file
10
deps/jsonpath/.travis.yml
vendored
Normal 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
1
deps/jsonpath/CNAME
vendored
Normal file
@ -0,0 +1 @@
|
||||
jsonpath.obdi.io
|
||||
857
deps/jsonpath/JSONPath.sh
vendored
Normal file
857
deps/jsonpath/JSONPath.sh
vendored
Normal 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
15
deps/jsonpath/LICENSE.APACHE2
vendored
Normal 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
24
deps/jsonpath/LICENSE.MIT
vendored
Normal 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
3
deps/jsonpath/MANIFEST.in
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
include README.md
|
||||
include LICENSE.MIT
|
||||
include LICENSE.APACHE2
|
||||
491
deps/jsonpath/README.md
vendored
Normal file
491
deps/jsonpath/README.md
vendored
Normal file
@ -0,0 +1,491 @@
|
||||
# JSONPath.sh
|
||||
|
||||
yo, so it's a JSONPath implementation written in Bash - and it probably only works in Bash.
|
||||
|
||||
[](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
1
deps/jsonpath/_config.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
theme: jekyll-theme-slate
|
||||
33
deps/jsonpath/all-tests.sh
vendored
Normal file
33
deps/jsonpath/all-tests.sh
vendored
Normal 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
19
deps/jsonpath/package.json
vendored
Normal 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
31
deps/jsonpath/setup.py
vendored
Normal 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
4
deps/semver_bash/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
*~
|
||||
*tmp
|
||||
*swp
|
||||
|
||||
26
deps/semver_bash/LICENSE
vendored
Normal file
26
deps/semver_bash/LICENSE
vendored
Normal 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
31
deps/semver_bash/README.md
vendored
Normal 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
130
deps/semver_bash/semver.sh
vendored
Normal 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
151
deps/semver_bash/semver_test.sh
vendored
Normal 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
|
||||
12
install.sh
12
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"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user