4 Commits

Author SHA1 Message Date
fcd2b454de Test breaking a test
Some checks failed
CI with JUnit Report / build-and-test (push) Has been cancelled
2026-01-18 12:07:37 -05:00
0f8aaef08b Fix dependency installation for github CI (again) 2026-01-18 12:07:31 -05:00
b69e961687 Fix dependency installation for github CI (again) 2026-01-18 12:04:40 -05:00
0faa8b6eb3 Fix dependency installation for github CI 2026-01-18 12:02:05 -05:00
4 changed files with 199 additions and 215 deletions

View File

@@ -23,11 +23,6 @@ jobs:
cd ../../ cd ../../
PREFIX="$PREFIX" make test-ci PREFIX="$PREFIX" make test-ci
cat junit.xml cat junit.xml
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@master
with:
ignore_paths: deps tests installed
scandir: .
- name: Publish Test Report - name: Publish Test Report
uses: mikepenz/action-junit-report@v5 uses: mikepenz/action-junit-report@v5
if: success() || failure() # always run even if the previous step fails if: success() || failure() # always run even if the previous step fails

View File

@@ -1,8 +0,0 @@
# Many array expressions are constructed and eval-ed
disable=SC2016
# False positive on "CMDARG_ERROR_BEHAVIOR=return"
disable=SC2209
# Checking exit code with $? is more of a preference when the script doesn't try to support the errexit shell option
disable=SC2181
# Masking exit codes isn't much of a problem in this script
disable=SC2155

View File

@@ -36,7 +36,7 @@ function cmdarg
echo "-h is reserved for cmdarg usage" >&2 echo "-h is reserved for cmdarg usage" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
if [[ "$(type -t cmdarg_"$key")" != "" ]] || \ if [[ "$(type -t cmdarg_$key)" != "" ]] || \
[[ "${CMDARG_FLAGS[$shortopt]}" != "" ]] || \ [[ "${CMDARG_FLAGS[$shortopt]}" != "" ]] || \
[[ "${CMDARG_TYPES[$key]}" != "" ]]; then [[ "${CMDARG_TYPES[$key]}" != "" ]]; then
echo "command line key '$shortopt ($key)' is reserved by cmdarg or defined twice" >&2 echo "command line key '$shortopt ($key)' is reserved by cmdarg or defined twice" >&2
@@ -53,14 +53,14 @@ function cmdarg
elif [[ "$argtype" != "" ]]; then elif [[ "$argtype" != "" ]]; then
CMDARG_FLAGS[$shortopt]=${argtypemap["$argtype"]} CMDARG_FLAGS[$shortopt]=${argtypemap["$argtype"]}
if [[ "${1:2:4}" == "[]" ]]; then if [[ "${1:2:4}" == "[]" ]]; then
declare -p "${key}" >/dev/null 2>&1 declare -p ${key} >/dev/null 2>&1
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo 'Array variable '"${key}"' does not exist. Array variables MUST be declared by the user!' >&2 echo 'Array variable '"${key}"' does not exist. Array variables MUST be declared by the user!' >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
CMDARG_TYPES[$key]=$CMDARG_TYPE_ARRAY CMDARG_TYPES[$key]=$CMDARG_TYPE_ARRAY
elif [[ "${1:2:4}" == "{}" ]]; then elif [[ "${1:2:4}" == "{}" ]]; then
declare -p "${key}" >/dev/null 2>&1 declare -p ${key} >/dev/null 2>&1
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo 'Hash variable '"${key}"' does not exist. Hash variables MUST be declared by the user!' >&2 echo 'Hash variable '"${key}"' does not exist. Hash variables MUST be declared by the user!' >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
@@ -80,14 +80,14 @@ function cmdarg
CMDARG_DESC["$shortopt"]=$3 CMDARG_DESC["$shortopt"]=$3
CMDARG_DEFAULT["$shortopt"]=${4:-} CMDARG_DEFAULT["$shortopt"]=${4:-}
if [[ ${CMDARG_FLAGS[$shortopt]} -eq $CMDARG_FLAG_REQARG ]] && [[ "${4:-}" == "" ]]; then if [[ ${CMDARG_FLAGS[$shortopt]} -eq $CMDARG_FLAG_REQARG ]] && [[ "${4:-}" == "" ]]; then
CMDARG_REQUIRED+=("$shortopt") CMDARG_REQUIRED+=($shortopt)
else else
CMDARG_OPTIONAL+=("$shortopt") CMDARG_OPTIONAL+=($shortopt)
fi fi
cmdarg_cfg["$2"]="${4:-}" cmdarg_cfg["$2"]="${4:-}"
local validatorfunc local validatorfunc
validatorfunc=${5:-} validatorfunc=${5:-}
if [[ "$validatorfunc" != "" ]] && [[ "$(declare -F "$validatorfunc")" == "" ]]; then if [[ "$validatorfunc" != "" ]] && [[ "$(declare -F $validatorfunc)" == "" ]]; then
echo "Validators must be bash functions accepting 1 argument (not '$validatorfunc')" >&2 echo "Validators must be bash functions accepting 1 argument (not '$validatorfunc')" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
@@ -120,7 +120,7 @@ function cmdarg_describe
local flags="${CMDARG_FLAGS[$opt]}" local flags="${CMDARG_FLAGS[$opt]}"
local validator="${CMDARG_VALIDATORS[$opt]}" local validator="${CMDARG_VALIDATORS[$opt]}"
${cmdarg_helpers['describe']} "$longopt" "$opt" "$argtype" "${default}" "${description}" "${flags}" "${validator}" ${cmdarg_helpers['describe']} $longopt $opt $argtype "${default}" "${description}" "${flags}" "${validator}"
} }
function cmdarg_describe_default function cmdarg_describe_default
@@ -139,16 +139,16 @@ function cmdarg_describe_default
default="(Default \"${default}\")" default="(Default \"${default}\")"
fi fi
case ${argtype} in case ${argtype} in
"$CMDARG_TYPE_STRING") $CMDARG_TYPE_STRING)
echo "-${opt},--${longopt} v : String. ${description} ${default}" echo "-${opt},--${longopt} v : String. ${description} ${default}"
;; ;;
"$CMDARG_TYPE_BOOLEAN") $CMDARG_TYPE_BOOLEAN)
echo "-${opt},--${longopt} : Boolean. ${description} ${default}" echo "-${opt},--${longopt} : Boolean. ${description} ${default}"
;; ;;
"$CMDARG_TYPE_ARRAY") $CMDARG_TYPE_ARRAY)
echo "-${opt},--${longopt} v[, ...] : Array. ${description}. Pass this argument multiple times for multiple values. ${default}" echo "-${opt},--${longopt} v[, ...] : Array. ${description}. Pass this argument multiple times for multiple values. ${default}"
;; ;;
"$CMDARG_TYPE_HASH") $CMDARG_TYPE_HASH)
echo "-${opt},--${longopt} k=v{, ..} : Hash. ${description}. Pass this argument multiple times for multiple key/value pairs. ${default}" echo "-${opt},--${longopt} k=v{, ..} : Hash. ${description}. Pass this argument multiple times for multiple key/value pairs. ${default}"
;; ;;
*) *)
@@ -164,10 +164,7 @@ function cmdarg_usage
# cmdarg_usage # cmdarg_usage
# #
# Prints a very helpful usage message about the current program. # Prints a very helpful usage message about the current program.
local copyright=${CMDARG_INFO['copyright']:+ ${CMDARG_INFO['copyright']}} echo "$(basename $0) ${CMDARG_INFO['copyright']} : ${CMDARG_INFO['author']}"
local author=${CMDARG_INFO['author']:+ : ${CMDARG_INFO['author']}}
echo "$(basename "$0")$copyright$author"
echo echo
echo "${CMDARG_INFO['header']}" echo "${CMDARG_INFO['header']}"
echo echo
@@ -176,7 +173,7 @@ function cmdarg_usage
echo "Required Arguments:" echo "Required Arguments:"
for key in "${CMDARG_REQUIRED[@]}" for key in "${CMDARG_REQUIRED[@]}"
do do
echo " $(cmdarg_describe "$key")" echo " $(cmdarg_describe $key)"
done done
echo echo
fi fi
@@ -184,7 +181,7 @@ function cmdarg_usage
echo "Optional Arguments": echo "Optional Arguments":
for key in "${CMDARG_OPTIONAL[@]}" for key in "${CMDARG_OPTIONAL[@]}"
do do
echo " $(cmdarg_describe "$key")" echo " $(cmdarg_describe $key)"
done done
fi fi
echo echo
@@ -218,29 +215,29 @@ function cmdarg_set_opt
set +u set +u
case ${CMDARG_TYPES[$key]} in case ${CMDARG_TYPES[$key]} in
"$CMDARG_TYPE_STRING") $CMDARG_TYPE_STRING)
cmdarg_cfg[$key]=$arg cmdarg_cfg[$key]=$arg
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1 cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
"$CMDARG_TYPE_BOOLEAN") $CMDARG_TYPE_BOOLEAN)
cmdarg_cfg[$key]=true cmdarg_cfg[$key]=true
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1 cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
"$CMDARG_TYPE_ARRAY") $CMDARG_TYPE_ARRAY)
local arrname="${key}" local arrname="${key}"
local str='${#'"$arrname"'[@]}' local str='${#'"$arrname"'[@]}'
local prevlen=$(eval "echo $str") local prevlen=$(eval "echo $str")
eval "${arrname}[$((prevlen + 1))]=\"$arg\"" eval "${arrname}[$((prevlen + 1))]=\"$arg\""
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1 cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
"$CMDARG_TYPE_HASH") $CMDARG_TYPE_HASH)
local k=${arg%%=*} local k=${arg%%=*}
local v=${arg#*=} local v=${arg#*=}
if [[ "$k" == "$arg" ]] && [[ "$v" == "$arg" ]] && [[ "$k" == "$v" ]]; then if [[ "$k" == "$arg" ]] && [[ "$v" == "$arg" ]] && [[ "$k" == "$v" ]]; then
echo "Malformed hash argument: $arg" >&2 echo "Malformed hash argument: $arg" >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
eval "${key}[\$k]=\$v" eval "$key[\$k]=\$v"
cmdarg_validate "$key" "$v" "$k" || ${CMDARG_ERROR_BEHAVIOR} 1 cmdarg_validate "$key" "$v" "$k" || ${CMDARG_ERROR_BEHAVIOR} 1
;; ;;
*) *)
@@ -258,18 +255,18 @@ function cmdarg_check_empty
local type=${CMDARG_TYPES[$longopt]} local type=${CMDARG_TYPES[$longopt]}
case $type in case $type in
"$CMDARG_TYPE_STRING") $CMDARG_TYPE_STRING)
echo "${cmdarg_cfg[$longopt]}" echo ${cmdarg_cfg[$longopt]}
;; ;;
"$CMDARG_TYPE_BOOLEAN") $CMDARG_TYPE_BOOLEAN)
echo "${cmdarg_cfg[$longopt]}" echo ${cmdarg_cfg[$longopt]}
;; ;;
"$CMDARG_TYPE_ARRAY") $CMDARG_TYPE_ARRAY)
local arrname="${longopt}" local arrname="${longopt}"
local lval='${!'"${arrname}"'[@]}' local lval='${!'"${arrname}"'[@]}'
eval "echo $lval" eval "echo $lval"
;; ;;
"$CMDARG_TYPE_HASH") $CMDARG_TYPE_HASH)
local arrname="${longopt}" local arrname="${longopt}"
local lval='${!'"${arrname}"'[@]}' local lval='${!'"${arrname}"'[@]}'
eval "echo $lval" eval "echo $lval"
@@ -306,7 +303,7 @@ function cmdarg_parse
fi fi
if [[ "$fullopt" == "--" ]] && [[ $parsing -eq 0 ]]; then if [[ "$fullopt" == "--" ]] && [[ $parsing -eq 0 ]]; then
cmdarg_argv+=("$@") cmdarg_argv+=($@)
break break
elif [[ "${fullopt:0:2}" == "--" ]]; then elif [[ "${fullopt:0:2}" == "--" ]]; then
longopt=${fullopt:2} longopt=${fullopt:2}
@@ -319,7 +316,7 @@ function cmdarg_parse
continue continue
else else
echo "Malformed argument: ${fullopt}" >&2 echo "Malformed argument: ${fullopt}" >&2
echo "While parsing: $*" >&2 echo "While parsing: $@" >&2
${cmdarg_helpers['usage']} >&2 ${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
@@ -329,7 +326,7 @@ function cmdarg_parse
${CMDARG_ERROR_BEHAVIOR} 1 ${CMDARG_ERROR_BEHAVIOR} 1
fi fi
if [[ $is_equals_arg -eq 1 && -n "$opt" ]]; then if [[ $is_equals_arg -eq 1 ]]; then
if [[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_REQARG} ]] || \ if [[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_REQARG} ]] || \
[[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_OPTARG} ]]; then [[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_OPTARG} ]]; then
optarg=$1 optarg=$1
@@ -337,10 +334,10 @@ function cmdarg_parse
fi fi
fi fi
if [ -n "$opt" ] && [ ${CMDARG["${opt}"]+abc} ]; then if [ ${CMDARG["${opt}"]+abc} ]; then
cmdarg_set_opt "${CMDARG[$opt]}" "$optarg" cmdarg_set_opt "${CMDARG[$opt]}" "$optarg"
local rc=$? local rc=$?
failed=$((failed + rc)) failed=$((failed + $rc))
else else
echo "Unknown argument or invalid value : -${opt} | --${longopt}" >&2 echo "Unknown argument or invalid value : -${opt} | --${longopt}" >&2
${cmdarg_helpers['usage']} >&2 ${cmdarg_helpers['usage']} >&2
@@ -354,7 +351,7 @@ function cmdarg_parse
local key local key
for key in "${CMDARG_REQUIRED[@]}" for key in "${CMDARG_REQUIRED[@]}"
do do
if [[ "$(cmdarg_check_empty "$key")" == "" ]]; then if [[ "$(cmdarg_check_empty $key)" == "" ]]; then
missing="${missing} -${key}" missing="${missing} -${key}"
failed=$((failed + 1)) failed=$((failed + 1))
fi fi
@@ -377,7 +374,7 @@ function cmdarg_traceback
local FRAMES=${#BASH_LINENO[@]} local FRAMES=${#BASH_LINENO[@]}
# FRAMES-2 skips main, the last one in arrays # FRAMES-2 skips main, the last one in arrays
for ((i=FRAMES-2; i>=1; i--)); do for ((i=FRAMES-2; i>=1; i--)); do
echo " File \"${BASH_SOURCE[i+1]}\", line ${BASH_LINENO[i]}, probably in ${FUNCNAME[i+1]}" >&2 echo ' File' \"${BASH_SOURCE[i+1]}\", line ${BASH_LINENO[i]}, probably in ${FUNCNAME[i+1]} >&2
# Grab the source code of the line # Grab the source code of the line
sed -n "${BASH_LINENO[i]}{s/^/ /;p}" "${BASH_SOURCE[i+1]}" >&2 sed -n "${BASH_LINENO[i]}{s/^/ /;p}" "${BASH_SOURCE[i+1]}" >&2
done done
@@ -395,10 +392,10 @@ function cmdarg_dump
local ref local ref
local value local value
for key in "${!cmdarg_cfg[@]}" for key in ${!cmdarg_cfg[@]}
do do
repr="${key}:${CMDARG_TYPES[$key]}" repr="${key}:${CMDARG_TYPES[$key]}"
if [[ ${CMDARG_TYPES[$key]} == "$CMDARG_TYPE_ARRAY" ]] || [[ ${CMDARG_TYPES[$key]} == "$CMDARG_TYPE_HASH" ]] ; then if [[ ${CMDARG_TYPES[$key]} == $CMDARG_TYPE_ARRAY ]] || [[ ${CMDARG_TYPES[$key]} == $CMDARG_TYPE_HASH ]] ; then
arrname="${key}" arrname="${key}"
echo "${repr} => " echo "${repr} => "
keys='${!'"$arrname"'[@]}' keys='${!'"$arrname"'[@]}'

View File

@@ -86,7 +86,7 @@ function shunittest_hash_values
cmp="$cmp ${k}=${hash[$k]}" cmp="$cmp ${k}=${hash[$k]}"
done done
cmp=$(echo "$cmp" | sed s/'^ *'//) cmp=$(echo "$cmp" | sed s/'^ *'//)
if [[ "$cmp" != "$base" ]]; then if [[ "$cmp" == "$base" ]]; then
echo "Hash does not contain expected arguments ($cmp vs $base)" echo "Hash does not contain expected arguments ($cmp vs $base)"
cmdarg_dump >&2 cmdarg_dump >&2
return 1 return 1