Hello community, here is the log from the commit of package duply for openSUSE:Factory checked in at 2019-10-21 12:30:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/duply (Old) and /work/SRC/openSUSE:Factory/.duply.new.2352 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "duply" Mon Oct 21 12:30:27 2019 rev:21 rq:741250 version:2.2 Changes: -------- --- /work/SRC/openSUSE:Factory/duply/duply.changes 2018-08-02 15:00:40.864534434 +0200 +++ /work/SRC/openSUSE:Factory/.duply.new.2352/duply.changes 2019-10-21 12:30:29.776103230 +0200 @@ -1,0 +2,25 @@ +Fri Oct 18 11:42:12 UTC 2019 - [email protected] + +- Fix source download URL. + +------------------------------------------------------------------- +Thu Oct 17 19:12:57 UTC 2019 - [email protected] + +- Updated to version 2.2: + + Implement grouping for batch commands new separators are [] + (square brackets) or groupIn/groupOut command 'backup' + translates now to [pre_bkp_post] to be skipped as one block in + case a condition was set in the batch instruction. +- Changes from version 2.1: + + Be more verbose when duplicity version detection fails. + + Using info shows python binary's path for easier + identification now. + + Reworked python interpreter handling, it's either configured + per PYTHON var unconfigured, parsed from duplicity shebang or + set to current duplicity default 'python2' (was 'python' until + now). + + Donot quotewrap strings because of slashes (eg. paths) anymore. + + Bugfix: improved in/exclude stripping from conf DUPL_PARAMS. +- Remove obsolete Groups tag (fate#326485). + +------------------------------------------------------------------- Old: ---- duply_2.0.4.tgz New: ---- duply_2.2.tgz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ duply.spec ++++++ --- /var/tmp/diff_new_pack.V9md9k/_old 2019-10-21 12:30:30.556104114 +0200 +++ /var/tmp/diff_new_pack.V9md9k/_new 2019-10-21 12:30:30.564104123 +0200 @@ -1,8 +1,8 @@ # # spec file for package duply # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. -# Copyright (c) 2011-2018 Malcolm J Lewis <[email protected]> +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2011-2019 Malcolm J Lewis <[email protected]> # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -13,18 +13,17 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: duply -Version: 2.0.4 +Version: 2.2 Release: 0 Summary: A frontend for the "duplicity" backup program License: GPL-2.0-only -Group: Productivity/Archiving/Compression Url: http://duply.net/ -Source0: https://svwh.dl.sourceforge.net/project/ftplicity/duply%20%28simple%20duplicity%29/2.0.x/%{name}_%{version}.tgz +Source0: https://sourceforge.net/projects/ftplicity/files/duply%20%28simple%20duplicity%29/2.2.x/%{name}_%{version}.tgz # MANUAL BEGIN Requires: duplicity # MANUAL END ++++++ duply_2.0.4.tgz -> duply_2.2.tgz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/duply_2.0.4/CHANGELOG.txt new/duply_2.2/CHANGELOG.txt --- old/duply_2.0.4/CHANGELOG.txt 2018-02-20 17:02:08.000000000 +0100 +++ new/duply_2.2/CHANGELOG.txt 2018-12-30 18:16:11.000000000 +0100 @@ -17,6 +17,22 @@ - import/export profile from/to .tgz function !!! CHANGELOG: +2.2 (30.12.2018) +- featreq 44: implement grouping for batch commands + new separators are [] (square brackets) or groupIn/groupOut + command 'backup' translates now to [pre_bkp_post] to be skipped as + one block in case a condition was set in the batch instruction + +2.1 (23.07.2018) +- be more verbose when duplicity version detection fails +- using info shows python binary's path for easier identification now +- reworked python interpreter handling, it's either + configured per PYTHON var + unconfigured, parsed from duplicity shebang + or set to current duplicity default 'python2' (was 'python' until now) +- do not quotewrap strings because of slashes (eg. paths) anymore +- bugfix: improved in/exclude stripping from conf DUPL_PARAMS + 2.0.4 (20.02.2018) - bugfix 114: "duply usage is not current" wrt. purgeFull/Incr - bugfix 115: typo in error message - "Not GPG_KEY entries" should be "No" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/duply_2.0.4/duply new/duply_2.2/duply --- old/duply_2.0.4/duply 2018-02-20 17:02:08.000000000 +0100 +++ new/duply_2.2/duply 2018-12-30 18:16:11.000000000 +0100 @@ -9,11 +9,11 @@ # changed from ftplicity to duply. # # See http://duply.net or http://ftplicity.sourceforge.net/ for more info. # # (c) 2006 Christiane Ruetten, Heise Zeitschriften Verlag, Germany # -# (c) 2008-2017 Edgar Soldin (changes since version 1.3) # +# (c) 2008-2019 Edgar Soldin (changes since version 1.3) # ################################################################################ # LICENSE: # # This program is licensed under GPLv2. # -# Please read the accompanying license information in gpl.txt. # +# Please read the accompanying license information in gpl-2.0.txt. # ################################################################################ # TODO/IDEAS/KNOWN PROBLEMS: # - possibility to restore time frames (incl. deleted files) @@ -33,6 +33,22 @@ # - import/export profile from/to .tgz function !!! # # CHANGELOG: +# 2.2 (30.12.2018) +# - featreq 44: implement grouping for batch commands +# new separators are [] (square brackets) or groupIn/groupOut +# command 'backup' translates now to [pre_bkp_post] to be skipped as +# one block in case a condition was set in the batch instruction +# +# 2.1 (23.07.2018) +# - be more verbose when duplicity version detection fails +# - using info shows python binary's path for easier identification now +# - reworked python interpreter handling, it's either +# configured per PYTHON var +# unconfigured, parsed from duplicity shebang +# or set to current duplicity default 'python2' (was 'python' until now) +# - do not quotewrap strings because of slashes (eg. paths) anymore +# - bugfix: improved in/exclude stripping from conf DUPL_PARAMS +# # 2.0.4 (20.02.2018) # - bugfix 114: "duply usage is not current" wrt. purgeFull/Incr # - bugfix 115: typo in error message - "Not GPG_KEY entries" should be "No" @@ -476,12 +492,26 @@ ( [ "${bin##*/}" == "$bin" ] && hash "$bin" 2>/dev/null ) || [ -x "$bin" ] } +# the python binary to use, exit code 0 when configured, else 1 +function python_binary { + # if unset, parse from duplicity shebang + if ! var_isset 'PYTHON'; then + duplicity_python_binary_parse; + echo $DUPL_PYTHON_BIN; + return 1; + else + # tell if PYTHON was configured manually + echo $PYTHON; + return 0 + fi +} + # important definitions ####################################################### ME_LONG="$0" ME="$(basename $0)" ME_NAME="${ME%%.*}" -ME_VERSION="2.0.4" +ME_VERSION="2.2" ME_WEBSITE="http://duply.net" # default config values @@ -492,7 +522,7 @@ DEFAULT_GPG='gpg' DEFAULT_GPG_KEY='_KEY_ID_' DEFAULT_GPG_PW='_GPG_PASSWORD_' -DEFAULT_PYTHON='python' +DEFAULT_PYTHON='python2' # function definitions ########################## @@ -552,22 +582,21 @@ END } -function python_binary { - echo "${PYTHON-$DEFAULT_PYTHON}" -} - function using_info { - lookup duplicity && duplicity_version_get - local NOTFOUND="MISSING" + # init needed vars into global name space + lookup duplicity && { duplicity_python_binary_parse; duplicity_version_get; } + local NOTFOUND="INVALID" + local AWK_VERSION GREP_VERSION PYTHON_RUNNER # freebsd awk (--version only), debian mawk (-W version only), deliver '' so awk does not wait for input - local AWK_VERSION=$( lookup awk && (awk --version 2>/dev/null || awk -W version 2>&1) | awk 'NR<=2&&tolower($0)~/(busybox|awk)/{success=1;print;exit} END{if(success<1) print "unknown"}' || echo "$NOTFOUND" ) - local GREP_VERSION=$( lookup grep && grep --version 2>&1 | awk 'NR<=2&&tolower($0)~/(busybox|grep.*[0-9]+\.[0-9]+)/{success=1;print;exit} END{if(success<1) print "unknown"}' || echo "$NOTFOUND" ) - local PYTHON_RUNNER=$(python_binary) + AWK_VERSION=$( lookup awk && (awk --version 2>/dev/null || awk -W version 2>&1) | awk 'NR<=2&&tolower($0)~/(busybox|awk)/{success=1;print;exit} END{if(success<1) print "unknown"}' || echo "$NOTFOUND" ) + GREP_VERSION=$( lookup grep && grep --version 2>&1 | awk 'NR<=2&&tolower($0)~/(busybox|grep.*[0-9]+\.[0-9]+)/{success=1;print;exit} END{if(success<1) print "unknown"}' || echo "$NOTFOUND" ) + PYTHON_RUNNER=$(python_binary) local PYTHON_VERSION=$(lookup "$PYTHON_RUNNER" && "$PYTHON_RUNNER" -V 2>&1| awk '{print tolower($0);exit}' || echo "'$PYTHON_RUNNER' $NOTFOUND" ) local GPG_INFO=$(gpg_avail && gpg --version 2>&1| awk '/^gpg.*[0-9\.]+$/&&length(v)<1{v=$1" "$3}/^Home:/{h=" ("$0")"}END{print v""h}' || echo "gpg $NOTFOUND") local BASH_VERSION=$(bash --version | awk 'NR==1{IGNORECASE=1;sub(/GNU bash, version[ ]+/,"",$0);print $0}') + # print out echo -e "Using installed duplicity version ${DUPL_VERSION:-$NOTFOUND}\ -${PYTHON_VERSION+, $PYTHON_VERSION${PYTHONPATH:+ 'PYTHONPATH=$PYTHONPATH'}}\ +${PYTHON_VERSION+, $PYTHON_VERSION ${PYTHON_RUNNER:+($(which "$PYTHON_RUNNER"))}${PYTHONPATH:+ 'PYTHONPATH=$PYTHONPATH'}}\ ${GPG_INFO:+, $GPG_INFO}${AWK_VERSION:+, awk '${AWK_VERSION}'}${GREP_VERSION:+, grep '${GREP_VERSION}'}\ ${BASH_VERSION:+, bash '${BASH_VERSION}'}." } @@ -637,16 +666,21 @@ - (minus sign), _or_ conditional OR the next command will only be executed if the previous failed + [] (square brackets), _groupIn_/_groupOut_ + enables grouping of commands example: - 'pre+bkp-verify_post' translates to 'pre_and_bkp_or_verify_post' + 'pre+[bkp-verify]_post' translates to + 'pre_and_groupIn_bkp_or_verify_groupOut_post' COMMANDS: usage get usage help text - and/or pseudo commands for better batch cmd readability (see SEPARATORS) + and/or/groupIn/groupOut + pseudo commands used in batches (see SEPARATORS above) + create creates a configuration profile - backup backup with pre/post script execution (batch: pre_bkp_post), + backup backup with pre/post script execution (batch: [pre_bkp_post]), full (if full_if_older matches or no earlier backup is found) incremental (in all other cases) pre/post execute '<profile>/$(basename "$PRE")', '<profile>/$(basename "$POST")' scripts @@ -707,8 +741,9 @@ Some useful internal duply variables are exported to the scripts. PROFILE, CONFDIR, SOURCE, TARGET_URL_<PROT|HOSTPATH|USER|PASS>, - GPG_<KEYS_ENC|KEY_SIGN|PW>, CMD_<PREV|NEXT>, CMD_ERR, RUN_START, - CND_<PREV|NEXT> (condition before/after next/prev command) + GPG_<KEYS_ENC|KEY_SIGN|PW>, CMD_ERR, RUN_START, + CMD_<PREV|NEXT> (previous/next command), + CND_<PREV|NEXT> (condition before/after) The CMD_* variables were introduced to allow different actions according to the command the scripts were attached to e.g. 'pre_bkp_post_pre_verify_post' @@ -861,7 +896,8 @@ # "trickle -s -u 640 -d 5120" # 5Mb up, 40Mb down" #DUPL_PRECMD="" -# override the used python interpreter, defaults to "python" +# override the used python interpreter, defaults to +# - parsed result of duplicity's shebang or 'python2' # e.g. "python2" or "/usr/bin/python2.7" #PYTHON="python" @@ -1069,32 +1105,45 @@ } function duplicity_version_get { - var_isset DUPL_VERSION && return - DUPL_VERSION=`duplicity --version 2>&1 | awk '/^duplicity /{print $2; exit;}'` - #DUPL_VERSION='0.7.03' #'0.6.08b' #,0.4.4.RC4,0.6.08b - DUPL_VERSION_VALUE=0 - DUPL_VERSION_AWK=$(awk -v v="$DUPL_VERSION" 'BEGIN{ - if (match(v,/[^\.0-9]+[0-9]*$/)){ - rest=substr(v,RSTART,RLENGTH);v=substr(v,0,RSTART-1);} - if (pos=match(rest,/RC([0-9]+)$/)) rc=substr(rest,pos+2) - split(v,f,"[. ]"); if(f[1]f[2]f[3]~/^[0-9]+$/) vvalue=f[1]*10000+f[2]*100+f[3]; else vvalue=0 - print "#"v"_"rest"("rc"):"f[1]"-"f[2]"-"f[3] - print "DUPL_VERSION_VALUE=\047"vvalue"\047" - print "DUPL_VERSION_RC=\047"rc"\047" - print "DUPL_VERSION_SUFFIX=\047"rest"\047" - }') - eval "$DUPL_VERSION_AWK" - #echo -e ",$DUPL_VERSION,$DUPL_VERSION_VALUE,$DUPL_VERSION_RC,$DUPL_VERSION_SUFFIX," -} - -function duplicity_version_check { - if [ $DUPL_VERSION_VALUE -eq 0 ]; then - inform "duplicity version check failed (please report, this is a bug)" - elif [ $DUPL_VERSION_VALUE -le 404 ] && [ ${DUPL_VERSION_RC:-4} -lt 4 ]; then - error "The installed version $DUPL_VERSION is incompatible with $ME_NAME v$ME_VERSION. + # nothing to do, just print + var_isset DUPL_VERSION && return + + local DUPL_VERSION_OUT DUPL_VERSION_AWK PYTHON_BIN CMD='duplicity' + # only run with a user specific python if configured (running by default + # breaks homebrew as they place a shell wrapper for duplicity in path) + PYTHON_BIN="$(python_binary)" &&\ + CMD="$(qw "$PYTHON_BIN") $(which $CMD)" + CMD="$CMD --version 2>&1" + DUPL_VERSION_OUT=$(eval "$CMD") + DUPL_VERSION=`echo $DUPL_VERSION_OUT | awk '/^duplicity /{print $2; exit;}'` + #DUPL_VERSION='0.7.03' #'0.6.08b' #,0.4.4.RC4,0.6.08b + DUPL_VERSION_VALUE=0 + DUPL_VERSION_AWK=$(awk -v v="$DUPL_VERSION" 'BEGIN{ + if (match(v,/[^\.0-9]+[0-9]*$/)){ + rest=substr(v,RSTART,RLENGTH);v=substr(v,0,RSTART-1);} + if (pos=match(rest,/RC([0-9]+)$/)) rc=substr(rest,pos+2) + split(v,f,"[. ]"); if(f[1]f[2]f[3]~/^[0-9]+$/) vvalue=f[1]*10000+f[2]*100+f[3]; else vvalue=0 + print "#"v"_"rest"("rc"):"f[1]"-"f[2]"-"f[3] + print "DUPL_VERSION_VALUE=\047"vvalue"\047" + print "DUPL_VERSION_RC=\047"rc"\047" + print "DUPL_VERSION_SUFFIX=\047"rest"\047" + }') + eval "$DUPL_VERSION_AWK" + #echo -e ",$DUPL_VERSION,$DUPL_VERSION_VALUE,$DUPL_VERSION_RC,$DUPL_VERSION_SUFFIX," + + # doublecheck findings and report error + if [ $DUPL_VERSION_VALUE -eq 0 ]; then + inform "duplicity version check failed (please report, this is a bug) +the command + $CMD +resulted in + $DUPL_VERSION_OUT +" + elif [ $DUPL_VERSION_VALUE -le 404 ] && [ ${DUPL_VERSION_RC:-4} -lt 4 ]; then + error "The installed version $DUPL_VERSION is incompatible with $ME_NAME v$ME_VERSION. You should upgrade your version of duplicity to at least v0.4.4RC4 or use the older ftplicity version 1.1.1 from $ME_WEBSITE." - fi + fi } function duplicity_version_ge { @@ -1105,6 +1154,21 @@ ! duplicity_version_ge "$1" } +# parse interpreter from duplicity shebang +function duplicity_python_binary_parse { + # cached result + ( var_isset 'PYTHON' || var_isset 'DUPL_PYTHON_BIN' ) && return + + # parse it or warn + local DUPL_BIN=$(which duplicity) + DUPL_PYTHON_BIN=$(awk 'NR==1&&/^#!/{sub(/^#!( *\/usr\/bin\/env *)?/,""); print}' < "$DUPL_BIN") + if ! echo "$DUPL_PYTHON_BIN" | grep -q -i 'python'; then + warning "Could not parse the python interpreter used from duplicity ($DUPL_BIN). Result was '$DUPL_PYTHON_BIN'. +Will assume it is '$DEFAULT_PYTHON'." + DUPL_PYTHON_BIN="$DEFAULT_PYTHON" + fi +} + function run_script { # run pre/post scripts local ERR=0 local SCRIPT="$1" @@ -1156,7 +1220,7 @@ function quotewrap { local param="$@" # quote strings having non word chars (e.g. spaces) - if echo "$param" | awk '/[^A-Za-z0-9_\.\-]/{exit 0}{exit 1}'; then + if echo "$param" | awk '/[^A-Za-z0-9_\.\-\/]/{exit 0}{exit 1}'; then echo "$param" | awk '{\ gsub(/[\047]/,"\047\\\047\047",$0);\ gsub(/[\042]/,"\047\\\042\047",$0);\ @@ -1208,20 +1272,42 @@ ${DUPL_ARG_ENC}" } - # function to filter the DUPL_PARAMS var from user conf function duplicity_params_conf { # reuse cmd var from main loop ## in/exclude parameters are currently not supported on restores if [ "$cmd" = "fetch" ] || [ "$cmd" = "restore" ] || [ "$cmd" = "status" ]; then - # filter exclude params from fetch/restore - echo "$DUPL_PARAMS" | awk '{gsub(/--(ex|in)clude[a-z-]*(([ \t]+|=)[^-][^ \t]+)?/,"");print}' + # filter exclude params from fetch/restore/status + eval "stripXcludes $DUPL_PARAMS" return fi - + + # nothing done, print unchanged echo "$DUPL_PARAMS" } +# strip in/exclude parameters from param string +function stripXcludes { + local STRIPNEXT OUT; + for p in "$@"; do + if [ -n "$STRIPNEXT" ]; then + unset STRIPNEXT + # strip the value of previous parameter + continue + elif echo "$p" | awk '/^\-\-(in|ex)clude(\-[a-zA-Z]+)?$/{exit 0;}{exit 1;}'; then + # strips eg. --include /foo/bar + STRIPNEXT="yes" + continue + elif echo "$p" | awk '/^\-\-(in|ex)clude(\-[a-zA-Z]+)?=/{exit 0;}{exit 1;}'; then + # strips eg. --include=/foo/bar + continue + fi + + OUT="$OUT $(qw "$p")" + done + echo "$OUT" +} + function duplify { # the actual wrapper function local PARAMSNOW DUPL_CMD DUPL_CMD_PARAMS @@ -1242,18 +1328,18 @@ # init global duplicity parameters same for all tasks duplicity_params_global - local RUN=eval BIN=duplicity DUPL_BIN + local RUN=eval BIN=duplicity DUPL_BIN PYTHON_BIN # run in cmd line preview mode if requested var_isset 'PREVIEW' && RUN=echo # try to resolve duplicity path for usage with python interpreter DUPL_BIN=$(which "$BIN") || DUPL_BIN="$BIN" # only run with a user specific python if configured (running by default # breaks homebrew as they place a shell wrapper for duplicity in path) - [ -n "$PYTHON" ] && [ "$PYTHON" != "$DEFAULT_PYTHON" ] &&\ - BIN="$(qw "$(python_binary)") $(qw "$DUPL_BIN")" + PYTHON_BIN="$(python_binary)" &&\ + BIN="$(qw "$PYTHON_BIN") $(qw "$DUPL_BIN")" -$RUN "${DUPL_VARS_GLOBAL} ${BACKEND_PARAMS} \ -${DUPL_PRECMD} $BIN $DUPL_CMD $DUPL_PARAMS_GLOBAL $(duplicity_params_conf)\ +$RUN "${DUPL_VARS_GLOBAL} ${BACKEND_PARAMS}\ + ${DUPL_PRECMD} $BIN $DUPL_CMD $DUPL_PARAMS_GLOBAL $(duplicity_params_conf)\ $GPG_USEAGENT $(gpg_custom_binary) $DUPL_CMD_PARAMS" local ERR=$? @@ -1342,10 +1428,20 @@ } function is_condition { - local CMD=$(tolower "$@") + local CMD=$(tolower "$1") [ "$CMD" == 'and' ] || [ "$CMD" == 'or' ] } +function is_groupMarker { + local CMD=$(tolower "$1") + [ "$CMD" == 'groupin' ] || [ "$CMD" == 'groupout' ] +} + +function is_command { + local CMD=$(tolower "$1") + ! is_condition "$CMD" && ! is_groupMarker "$CMD" +} + function url_encode { # utilize python, silently do nothing on error - because no python no duplicity OUT=$("$(python_binary)" -c " @@ -1653,7 +1749,7 @@ lookup "$(gpg_binary)" } -# enforce the use our selected gpg binary +# enforce the use of our selected gpg binary function gpg { command "$(gpg_binary)" "$@" } @@ -1710,7 +1806,7 @@ exit 0 ;; version|-version|--version|-v|-V) - # profile can override GPG, so import it if it was given + # profile can override GPG/PYTHON, so import it if it was given var_isset FTPLCFG && { set_config [ -r "$CONF" ] && . "$CONF" || warning "Cannot import config '$CONF'." @@ -1742,8 +1838,8 @@ # is duplicity avail lookup duplicity || error_path "duplicity missing. installed und available in path?" # init, exec duplicity version check info +duplicity_python_binary_parse duplicity_version_get -duplicity_version_check # check for certain important helper programs for f in awk grep "$(python_binary)"; do @@ -1820,9 +1916,6 @@ # Hint: cmds is also used to check if authentification info sufficient in the next step cmds="$2"; shift 2 -# translate backup to batch command -cmds=${cmds//backup/pre_bkp_post} - # complain if command(s) missing [ -z $cmds ] && error " No command given. @@ -2203,9 +2296,18 @@ # since 0.7.03 --exclude-globbing-filelist is deprecated EXCLUDE_PARAM="--exclude$(duplicity_version_lt 703 && echo -globbing)-filelist" -# replace magic separators to condition command equivalents (+=and,-=or) -cmds=$(awk -v cmds="$cmds" "BEGIN{ gsub(/\+/,\"_and_\",cmds); gsub(/\-/,\"_or_\",cmds); print cmds}") +# translate backup to batch command +cmds=${cmds//backup/groupIn_pre_bkp_post_groupOut} + +# replace magic separators to command equivalents (+=and,-=or,[=groupIn,]=groupOut) +cmds=$(awk -v cmds="$cmds" "BEGIN{ \ + gsub(/\+/,\"_and_\",cmds);\ + gsub(/\-/,\"_or_\",cmds);\ + gsub(/\[/,\"_groupIn_\",cmds);\ + gsub(/\]/,\"_groupOut_\",cmds);\ + print cmds}") # convert cmds to array, lowercase for safety +declare -a CMDS CMDS=( $(awk "BEGIN{ cmds=tolower(\"$cmds\"); gsub(/_/,\" \",cmds); print cmds }") ) unset FTPL_ERR @@ -2218,61 +2320,109 @@ # raise index in cmd array for pre/post param var_isset 'CMD_NO' && CMD_NO=$((++CMD_NO)) || CMD_NO=0 -# deal with condition "commands" -unset SKIP_NOW -if var_isset 'CMD_SKIP' && [ $CMD_SKIP -gt 0 ]; then - echo -e "\n--- Skipping command $(toupper $cmd) ! ---" - CMD_SKIP=$(($CMD_SKIP - 1)) - SKIP_NOW="yes" -elif [ "$cmd" == 'and' ] && [ "$CMD_ERR" -ne "0" ]; then - CMD_SKIP=1 - SKIP_NOW="yes" -elif [ "$cmd" == 'or' ] && [ "$CMD_ERR" -eq "0" ]; then - CMD_SKIP=1 - SKIP_NOW="yes" -elif [ "$cmd" == 'and' ] || [ "$cmd" == 'or' ]; then - unset 'CMD_SKIP'; - SKIP_NOW="yes" -fi - -# sum up how many commands we skip and actually skip -if [ -n "$SKIP_NOW" ]; then - CMD_SKIPPED=$((${CMD_SKIPPED-0} + 1)) - continue -fi - unset CMD_VALUE CMD_NEXT CMD_PREV CND_NEXT CND_PREV # get next cmd,cnd vars -nextno=$(( $CMD_NO + 1 )) +nextno=$(( $CMD_NO )) while ! var_isset 'CMD_NEXT' do + nextno=$(($nextno+1)) if [ "$nextno" -lt "${#CMDS[@]}" ]; then CMD_VALUE=${CMDS[$nextno]} - is_condition "$CMD_VALUE" && CND_NEXT="$CMD_VALUE" || CMD_NEXT="$CMD_VALUE" + is_condition "$CMD_VALUE" && CND_NEXT="$CMD_VALUE" && continue + is_groupMarker "$CMD_VALUE" && continue + CMD_NEXT="$CMD_VALUE" else CMD_NEXT='END' fi - nextno=$(($nextno+1)) done -# get prev cnd, cnd are skipped pseudocmds -prevno=$(( $CMD_NO - 1 )) -[ "$prevno" -ge 0 ] && is_condition "${CMDS[$prevno]}" && CND_PREV=${CMDS[$prevno]} +# get prev cnd, cnds are skipped pseudocmds +prevno=$(( $CMD_NO )); +while ! var_isset 'CND_PREV' +do + prevno=$(($prevno-1)) + if [ "$prevno" -ge 0 ]; then + CMD_VALUE=${CMDS[$prevno]} + is_condition "$CMD_VALUE" && CND_PREV="$CMD_VALUE" && break + is_command "$CMD_VALUE" && break + else + break + fi +done # get prev cmd command minus skipped commands, only executed -prevno=$(( $CMD_NO - ${CMD_SKIPPED-0} - 1 )); unset CMD_SKIPPED +prevno=$(( $CMD_NO - ${CMD_SKIPPED-0} )); while ! var_isset 'CMD_PREV' do + prevno=$(($prevno-1)) if [ "$prevno" -ge 0 ]; then CMD_VALUE=${CMDS[$prevno]} - is_condition "$CMD_VALUE" || CMD_PREV="$CMD_VALUE" + is_condition "$CMD_VALUE" && CND_PREV="$CMD_VALUE" && continue + is_groupMarker "$CMD_VALUE" && continue + CMD_PREV="$CMD_VALUE" else CMD_PREV='START' fi - prevno=$(($prevno-1)) done +function get_cmd_skip_count { + # find closing bracket, get group skip count + local nextno=$CMD_NO + local GRP_OPEN=0 + local GRP_SKIP=0 + local CMD_VALUE + while [ "$nextno" -lt "${#CMDS[@]}" ] + do + nextno=$(($nextno+1)) + CMD_VALUE=${CMDS[$nextno]} + GRP_SKIP=$(( ${GRP_SKIP} + 1 )); + if is_command "$CMD_VALUE" && [ "$GRP_OPEN" -lt 1 ]; then + break; + elif [ "$CMD_VALUE" == 'groupin' ]; then + GRP_OPEN=$(( ${GRP_OPEN} + 1 )) + elif [ "$CMD_VALUE" == 'groupout' ]; then + GRP_OPEN=$(( ${GRP_OPEN} - 1 )) + if [ "$GRP_OPEN" -lt 1 ]; then + break; + fi + fi + done + + echo $GRP_SKIP; +} + +# decision time: are we skipping already or dealing with condition "commands" or other non-cmds? +unset SKIP_NOW +if var_isset 'CMD_SKIP' && [ $CMD_SKIP -gt 0 ]; then + # skip cnd/grp cmds silently + is_command "$cmd" && echo -e "\n--- Skipping command $(toupper $cmd) ! ---" + CMD_SKIP=$(($CMD_SKIP - 1)) + SKIP_NOW="yes" +elif ! var_isset 'PREVIEW' && [ "$cmd" == 'and' ] && [ "$CMD_ERR" -ne "0" ]; then + CMD_SKIP=$(get_cmd_skip_count) + # incl. this "cmd" + CMD_SKIP=$(( $CMD_SKIP + 1 )) + unset CMD_SKIPPED + SKIP_NOW="yes" +elif ! var_isset 'PREVIEW' && [ "$cmd" == 'or' ] && [ "$CMD_ERR" -eq "0" ]; then + CMD_SKIP=$(get_cmd_skip_count) + # incl. this "cmd" + CMD_SKIP=$(( $CMD_SKIP + 1 )) + unset CMD_SKIPPED + SKIP_NOW="yes" +elif is_condition "$cmd" || is_groupMarker "$cmd"; then + unset 'CMD_SKIP'; + SKIP_NOW="yes" +fi + +# let's do the skip now +if [ -n "$SKIP_NOW" ]; then + # sum up how many commands we actually skipped for the prev var routines + CMD_SKIPPED=$((${CMD_SKIPPED-0} + 1)) + continue +fi + # save start time RUN_START=$(nsecs)
