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
7 changed files with 265 additions and 222 deletions

View File

@@ -23,11 +23,6 @@ jobs:
cd ../../
PREFIX="$PREFIX" make test-ci
cat junit.xml
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@master
with:
ignore_paths: deps tests installed
scandir: .
- name: Publish Test Report
uses: mikepenz/action-junit-report@v5
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

@@ -5,6 +5,18 @@ endif
VERSION:=$(shell if [ -d .git ]; then bash -c '$(PREFIX)/bin/gitversion.sh | grep "^MAJOR=" | cut -d = -f 2'; else source version.sh && echo $$MAJOR ; fi)
RELEASE:=$(shell if [ -d .git ]; then bash -c '$(PREFIX)/bin/gitversion.sh | grep "^BUILD=" | cut -d = -f 2'; else source version.sh && echo $$BUILD ; fi)
DISTFILE=./dist/cmdarg-$(VERSION)-$(RELEASE).tar.gz
SPECFILE=cmdarg.spec
ifndef RHEL_VERSION
RHEL_VERSION=5
endif
ifeq ($(RHEL_VERSION),5)
MOCKFLAGS=--define "_source_filedigest_algorithm md5" --define "_binary_filedigest_algorithm md5"
endif
RHEL_RELEASE:=$(RELEASE).el$(RHEL_VERSION)
SRPM=cmdarg-$(VERSION)-$(RHEL_RELEASE).src.rpm
RPM=cmdarg-$(VERSION)-$(RHEL_RELEASE).noarch.rpm
RHEL_DISTFILE=./dist/cmdarg-$(VERSION)-$(RHEL_RELEASE).tar.gz
ifndef PREFIX
PREFIX=''
@@ -13,7 +25,7 @@ endif
DISTFILE_DEPS=$(shell find . -type f | grep -Ev '\.git|\./dist/|$(DISTFILE)')
JUNIT_DEPS=$(wildcard *.sh) $(wildcard tests/*.sh)
all: $(DISTFILE)
all: ./dist/$(RPM)
# --- PHONY targets
@@ -24,6 +36,10 @@ clean:
dist: $(DISTFILE)
srpm: ./dist/$(SRPM)
rpm: ./dist/$(RPM) ./dist/$(SRPM)
gitclean:
git clean -df
@@ -48,6 +64,19 @@ $(DISTFILE): version.sh
rsync -aWH . --exclude=.git --exclude=dist ./dist/cmdarg-$(VERSION)-$(RELEASE)/
cd dist && tar -czvf ../$@ cmdarg-$(VERSION)-$(RELEASE)
$(RHEL_DISTFILE): $(DISTFILE)
cd dist && \
cp -R cmdarg-$(VERSION)-$(RELEASE) cmdarg-$(VERSION)-$(RHEL_RELEASE) && \
tar -czvf ../$@ cmdarg-$(VERSION)-$(RHEL_RELEASE)
./dist/$(SRPM): $(RHEL_DISTFILE)
rm -fr ./dist/$(SRPM)
mock -r epel-$(RHEL_VERSION)-noarch --buildsrpm --verbose --spec $(SPECFILE) $(MOCKFLAGS) --sources ./dist/ --resultdir ./dist/ --define "version $(VERSION)" --define "release $(RHEL_RELEASE)"
./dist/$(RPM): ./dist/$(SRPM)
rm -fr ./dist/$(RPM)
mock --verbose -r epel-$(RHEL_VERSION)-noarch ./dist/$(SRPM) --resultdir ./dist/ --define "version $(VERSION)" --define "release $(RHEL_RELEASE)"
uninstall:
rm -f $(PREFIX)/usr/lib/cmdarg.sh

View File

@@ -1,6 +1,8 @@
cmdarg
======
[![Build Status](http://jenkins.aklabs.net/buildStatus/icon?job=cmdarg-test)](http://jenkins.aklabs.net/job/cmdarg-test/)
Requires bash >= 4.
source cmdarg.sh
@@ -12,7 +14,13 @@ Installation
From source
cp cmdarg.sh PATH_WHERE_YOU_WANT_IT
cd cmdarg
make install
From RPM
# add http://yum.aklabs.net/el/[5|6]/noarch as a yum repo for your system
yum install cmdarg
Usage
=====

404
cmdarg.sh
View File

@@ -33,14 +33,14 @@ function cmdarg
local shortopt=${1:0:1}
local key="$2"
if [[ "$shortopt" == "h" ]]; then
echo "-h is reserved for cmdarg usage" >&2
${CMDARG_ERROR_BEHAVIOR} 1
echo "-h is reserved for cmdarg usage" >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
if [[ "$(type -t cmdarg_"$key")" != "" ]] || \
[[ "${CMDARG_FLAGS[$shortopt]}" != "" ]] || \
[[ "${CMDARG_TYPES[$key]}" != "" ]]; then
echo "command line key '$shortopt ($key)' is reserved by cmdarg or defined twice" >&2
${CMDARG_ERROR_BEHAVIOR} 1
if [[ "$(type -t cmdarg_$key)" != "" ]] || \
[[ "${CMDARG_FLAGS[$shortopt]}" != "" ]] || \
[[ "${CMDARG_TYPES[$key]}" != "" ]]; then
echo "command line key '$shortopt ($key)' is reserved by cmdarg or defined twice" >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
declare -A argtypemap
@@ -48,31 +48,31 @@ function cmdarg
argtypemap['?']=$CMDARG_FLAG_OPTARG
local argtype=${1:1:1}
if [[ "$argtype" =~ ^[\[{]$ ]]; then
echo "Flags required [:?] when specifying Hash or Array arguments (${argtype})" >&2
${CMDARG_ERROR_BEHAVIOR} 1
echo "Flags required [:?] when specifying Hash or Array arguments (${argtype})" >&2
${CMDARG_ERROR_BEHAVIOR} 1
elif [[ "$argtype" != "" ]]; then
CMDARG_FLAGS[$shortopt]=${argtypemap["$argtype"]}
if [[ "${1:2:4}" == "[]" ]]; then
declare -p "${key}" >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo 'Array variable '"${key}"' does not exist. Array variables MUST be declared by the user!' >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
CMDARG_TYPES[$key]=$CMDARG_TYPE_ARRAY
elif [[ "${1:2:4}" == "{}" ]]; then
declare -p "${key}" >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo 'Hash variable '"${key}"' does not exist. Hash variables MUST be declared by the user!' >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
CMDARG_TYPES[$key]=$CMDARG_TYPE_HASH
else
CMDARG_TYPES[$key]=$CMDARG_TYPE_STRING
fi
CMDARG_FLAGS[$shortopt]=${argtypemap["$argtype"]}
if [[ "${1:2:4}" == "[]" ]]; then
declare -p ${key} >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo 'Array variable '"${key}"' does not exist. Array variables MUST be declared by the user!' >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
CMDARG_TYPES[$key]=$CMDARG_TYPE_ARRAY
elif [[ "${1:2:4}" == "{}" ]]; then
declare -p ${key} >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo 'Hash variable '"${key}"' does not exist. Hash variables MUST be declared by the user!' >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
CMDARG_TYPES[$key]=$CMDARG_TYPE_HASH
else
CMDARG_TYPES[$key]=$CMDARG_TYPE_STRING
fi
else
CMDARG_FLAGS[$shortopt]=$CMDARG_FLAG_NOARG
CMDARG_TYPES[$key]=$CMDARG_TYPE_BOOLEAN
cmdarg_cfg[$key]=false
CMDARG_FLAGS[$shortopt]=$CMDARG_FLAG_NOARG
CMDARG_TYPES[$key]=$CMDARG_TYPE_BOOLEAN
cmdarg_cfg[$key]=false
fi
CMDARG["$shortopt"]=$2
@@ -80,16 +80,16 @@ function cmdarg
CMDARG_DESC["$shortopt"]=$3
CMDARG_DEFAULT["$shortopt"]=${4:-}
if [[ ${CMDARG_FLAGS[$shortopt]} -eq $CMDARG_FLAG_REQARG ]] && [[ "${4:-}" == "" ]]; then
CMDARG_REQUIRED+=("$shortopt")
CMDARG_REQUIRED+=($shortopt)
else
CMDARG_OPTIONAL+=("$shortopt")
CMDARG_OPTIONAL+=($shortopt)
fi
cmdarg_cfg["$2"]="${4:-}"
local validatorfunc
validatorfunc=${5:-}
if [[ "$validatorfunc" != "" ]] && [[ "$(declare -F "$validatorfunc")" == "" ]]; then
echo "Validators must be bash functions accepting 1 argument (not '$validatorfunc')" >&2
${CMDARG_ERROR_BEHAVIOR} 1
if [[ "$validatorfunc" != "" ]] && [[ "$(declare -F $validatorfunc)" == "" ]]; then
echo "Validators must be bash functions accepting 1 argument (not '$validatorfunc')" >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
CMDARG_VALIDATORS["$shortopt"]="$validatorfunc"
CMDARG_GETOPTLIST="${CMDARG_GETOPTLIST}$1"
@@ -103,9 +103,9 @@ function cmdarg_info
#
local flags="header|copyright|footer|author"
if [[ ! "$1" =~ $flags ]]; then
echo "cmdarg_info <flag> <value>" >&2
echo "Where <flag> is one of $flags" >&2
${CMDARG_ERROR_BEHAVIOR} 1
echo "cmdarg_info <flag> <value>" >&2
echo "Where <flag> is one of $flags" >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
CMDARG_INFO["$1"]=$2
}
@@ -120,7 +120,7 @@ function cmdarg_describe
local flags="${CMDARG_FLAGS[$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
@@ -136,25 +136,25 @@ function cmdarg_describe_default
set +u
if [ "${default}" != "" ]; then
default="(Default \"${default}\")"
default="(Default \"${default}\")"
fi
case ${argtype} in
"$CMDARG_TYPE_STRING")
echo "-${opt},--${longopt} v : String. ${description} ${default}"
;;
"$CMDARG_TYPE_BOOLEAN")
echo "-${opt},--${longopt} : Boolean. ${description} ${default}"
;;
"$CMDARG_TYPE_ARRAY")
echo "-${opt},--${longopt} v[, ...] : Array. ${description}. Pass this argument multiple times for multiple values. ${default}"
;;
"$CMDARG_TYPE_HASH")
echo "-${opt},--${longopt} k=v{, ..} : Hash. ${description}. Pass this argument multiple times for multiple key/value pairs. ${default}"
;;
*)
echo "Unable to return string description for ${opt}; unknown type ${argtype}" >&2
${CMDARG_ERROR_BEHAVIOR} 1
;;
$CMDARG_TYPE_STRING)
echo "-${opt},--${longopt} v : String. ${description} ${default}"
;;
$CMDARG_TYPE_BOOLEAN)
echo "-${opt},--${longopt} : Boolean. ${description} ${default}"
;;
$CMDARG_TYPE_ARRAY)
echo "-${opt},--${longopt} v[, ...] : Array. ${description}. Pass this argument multiple times for multiple values. ${default}"
;;
$CMDARG_TYPE_HASH)
echo "-${opt},--${longopt} k=v{, ..} : Hash. ${description}. Pass this argument multiple times for multiple key/value pairs. ${default}"
;;
*)
echo "Unable to return string description for ${opt}; unknown type ${argtype}" >&2
${CMDARG_ERROR_BEHAVIOR} 1
;;
esac
}
@@ -164,28 +164,25 @@ function cmdarg_usage
# cmdarg_usage
#
# Prints a very helpful usage message about the current program.
local copyright=${CMDARG_INFO['copyright']:+ ${CMDARG_INFO['copyright']}}
local author=${CMDARG_INFO['author']:+ : ${CMDARG_INFO['author']}}
echo "$(basename "$0")$copyright$author"
echo "$(basename $0) ${CMDARG_INFO['copyright']} : ${CMDARG_INFO['author']}"
echo
echo "${CMDARG_INFO['header']}"
echo
local key
if [[ "${#CMDARG_REQUIRED[@]}" -ne 0 ]]; then
echo "Required Arguments:"
for key in "${CMDARG_REQUIRED[@]}"
do
echo " $(cmdarg_describe "$key")"
done
echo
echo "Required Arguments:"
for key in "${CMDARG_REQUIRED[@]}"
do
echo " $(cmdarg_describe $key)"
done
echo
fi
if [[ "${#CMDARG_OPTIONAL[@]}" -ne 0 ]]; then
echo "Optional Arguments":
for key in "${CMDARG_OPTIONAL[@]}"
do
echo " $(cmdarg_describe "$key")"
done
echo "Optional Arguments":
for key in "${CMDARG_OPTIONAL[@]}"
do
echo " $(cmdarg_describe $key)"
done
fi
echo
echo "${CMDARG_INFO['footer']}"
@@ -202,10 +199,10 @@ function cmdarg_validate
local shortopt=${CMDARG_REV[$longopt]}
if [ "${CMDARG_VALIDATORS[$shortopt]}" != "" ]; then
( ${CMDARG_VALIDATORS[${shortopt}]} "$value" "$hashkey")
if [ $? -ne 0 ]; then
echo "Invalid value for -$shortopt : ${value}" >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
if [ $? -ne 0 ]; then
echo "Invalid value for -$shortopt : ${value}" >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
fi
return 0
}
@@ -218,35 +215,35 @@ function cmdarg_set_opt
set +u
case ${CMDARG_TYPES[$key]} in
"$CMDARG_TYPE_STRING")
cmdarg_cfg[$key]=$arg
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;;
"$CMDARG_TYPE_BOOLEAN")
cmdarg_cfg[$key]=true
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;;
"$CMDARG_TYPE_ARRAY")
local arrname="${key}"
local str='${#'"$arrname"'[@]}'
local prevlen=$(eval "echo $str")
eval "${arrname}[$((prevlen + 1))]=\"$arg\""
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;;
"$CMDARG_TYPE_HASH")
local k=${arg%%=*}
local v=${arg#*=}
if [[ "$k" == "$arg" ]] && [[ "$v" == "$arg" ]] && [[ "$k" == "$v" ]]; then
echo "Malformed hash argument: $arg" >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
eval "${key}[\$k]=\$v"
cmdarg_validate "$key" "$v" "$k" || ${CMDARG_ERROR_BEHAVIOR} 1
;;
*)
echo "Unable to return string description for ${key}; unknown type ${CMDARG_TYPES[$key]}" >&2
${CMDARG_ERROR_BEHAVIOR} 1
;;
$CMDARG_TYPE_STRING)
cmdarg_cfg[$key]=$arg
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;;
$CMDARG_TYPE_BOOLEAN)
cmdarg_cfg[$key]=true
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;;
$CMDARG_TYPE_ARRAY)
local arrname="${key}"
local str='${#'"$arrname"'[@]}'
local prevlen=$(eval "echo $str")
eval "${arrname}[$((prevlen + 1))]=\"$arg\""
cmdarg_validate "$key" "$arg" || ${CMDARG_ERROR_BEHAVIOR} 1
;;
$CMDARG_TYPE_HASH)
local k=${arg%%=*}
local v=${arg#*=}
if [[ "$k" == "$arg" ]] && [[ "$v" == "$arg" ]] && [[ "$k" == "$v" ]]; then
echo "Malformed hash argument: $arg" >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
eval "$key[\$k]=\$v"
cmdarg_validate "$key" "$v" "$k" || ${CMDARG_ERROR_BEHAVIOR} 1
;;
*)
echo "Unable to return string description for ${key}; unknown type ${CMDARG_TYPES[$key]}" >&2
${CMDARG_ERROR_BEHAVIOR} 1
;;
esac
return 0
}
@@ -258,25 +255,25 @@ function cmdarg_check_empty
local type=${CMDARG_TYPES[$longopt]}
case $type in
"$CMDARG_TYPE_STRING")
echo "${cmdarg_cfg[$longopt]}"
;;
"$CMDARG_TYPE_BOOLEAN")
echo "${cmdarg_cfg[$longopt]}"
;;
"$CMDARG_TYPE_ARRAY")
local arrname="${longopt}"
local lval='${!'"${arrname}"'[@]}'
eval "echo $lval"
;;
"$CMDARG_TYPE_HASH")
local arrname="${longopt}"
local lval='${!'"${arrname}"'[@]}'
eval "echo $lval"
;;
*)
echo "${cmdarg_cfg[$longopt]}"
$CMDARG_TYPE_STRING)
echo ${cmdarg_cfg[$longopt]}
;;
$CMDARG_TYPE_BOOLEAN)
echo ${cmdarg_cfg[$longopt]}
;;
$CMDARG_TYPE_ARRAY)
local arrname="${longopt}"
local lval='${!'"${arrname}"'[@]}'
eval "echo $lval"
;;
$CMDARG_TYPE_HASH)
local arrname="${longopt}"
local lval='${!'"${arrname}"'[@]}'
eval "echo $lval"
;;
*)
echo "${cmdarg_cfg[$longopt]}"
;;
esac
}
@@ -291,61 +288,61 @@ function cmdarg_parse
local parsing=0
while [[ $# -ne 0 ]]; do
local optarg=""
local opt=""
local longopt=""
local fullopt=$1
local is_equals_arg=1
local optarg=""
local opt=""
local longopt=""
local fullopt=$1
local is_equals_arg=1
shift
if [[ "${fullopt}" =~ ^(--[a-zA-Z0-9_\-]+|^-[a-zA-Z0-9])= ]]; then
local tmpopt=$fullopt
fullopt=${tmpopt%%=*}
optarg=${tmpopt##*=}
is_equals_arg=0
fi
shift
if [[ "${fullopt}" =~ ^(--[a-zA-Z0-9_\-]+|^-[a-zA-Z0-9])= ]]; then
local tmpopt=$fullopt
fullopt=${tmpopt%%=*}
optarg=${tmpopt##*=}
is_equals_arg=0
fi
if [[ "$fullopt" == "--" ]] && [[ $parsing -eq 0 ]]; then
cmdarg_argv+=("$@")
break
elif [[ "${fullopt:0:2}" == "--" ]]; then
longopt=${fullopt:2}
opt=${CMDARG_REV[$longopt]}
elif [[ "${fullopt:0:1}" == "-" ]] && [[ ${#fullopt} -eq 2 ]]; then
opt=${fullopt:1}
longopt=${CMDARG[$opt]}
elif [[ "${fullopt:0:1}" != "-" ]]; then
cmdarg_argv+=("$fullopt")
continue
else
echo "Malformed argument: ${fullopt}" >&2
echo "While parsing: $*" >&2
${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
if [[ "$fullopt" == "--" ]] && [[ $parsing -eq 0 ]]; then
cmdarg_argv+=($@)
break
elif [[ "${fullopt:0:2}" == "--" ]]; then
longopt=${fullopt:2}
opt=${CMDARG_REV[$longopt]}
elif [[ "${fullopt:0:1}" == "-" ]] && [[ ${#fullopt} -eq 2 ]]; then
opt=${fullopt:1}
longopt=${CMDARG[$opt]}
elif [[ "${fullopt:0:1}" != "-" ]]; then
cmdarg_argv+=("$fullopt")
continue
else
echo "Malformed argument: ${fullopt}" >&2
echo "While parsing: $@" >&2
${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
if [[ "$opt" == "h" ]] || [[ "$longopt" == "help" ]]; then
${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
if [[ "$opt" == "h" ]] || [[ "$longopt" == "help" ]]; then
${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
if [[ $is_equals_arg -eq 1 && -n "$opt" ]]; then
if [[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_REQARG} ]] || \
[[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_OPTARG} ]]; then
optarg=$1
shift
fi
fi
if [[ $is_equals_arg -eq 1 ]]; then
if [[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_REQARG} ]] || \
[[ ${CMDARG_FLAGS[$opt]} -eq ${CMDARG_FLAG_OPTARG} ]]; then
optarg=$1
shift
fi
fi
if [ -n "$opt" ] && [ ${CMDARG["${opt}"]+abc} ]; then
cmdarg_set_opt "${CMDARG[$opt]}" "$optarg"
local rc=$?
failed=$((failed + rc))
else
echo "Unknown argument or invalid value : -${opt} | --${longopt}" >&2
${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
if [ ${CMDARG["${opt}"]+abc} ]; then
cmdarg_set_opt "${CMDARG[$opt]}" "$optarg"
local rc=$?
failed=$((failed + $rc))
else
echo "Unknown argument or invalid value : -${opt} | --${longopt}" >&2
${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
done
# --- Don't ${CMDARG_ERROR_BEHAVIOR} early during validation, tell the user
@@ -354,19 +351,19 @@ function cmdarg_parse
local key
for key in "${CMDARG_REQUIRED[@]}"
do
if [[ "$(cmdarg_check_empty "$key")" == "" ]]; then
missing="${missing} -${key}"
failed=$((failed + 1))
fi
if [[ "$(cmdarg_check_empty $key)" == "" ]]; then
missing="${missing} -${key}"
failed=$((failed + 1))
fi
done
if [ $failed -gt 0 ]; then
if [[ "$missing" != "" ]]; then
echo "Missing arguments : ${missing}" >&2
fi
echo >&2
${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1
if [[ "$missing" != "" ]]; then
echo "Missing arguments : ${missing}" >&2
fi
echo >&2
${cmdarg_helpers['usage']} >&2
${CMDARG_ERROR_BEHAVIOR} 1
fi
}
@@ -377,9 +374,9 @@ function cmdarg_traceback
local FRAMES=${#BASH_LINENO[@]}
# FRAMES-2 skips main, the last one in arrays
for ((i=FRAMES-2; i>=1; i--)); do
echo " File \"${BASH_SOURCE[i+1]}\", line ${BASH_LINENO[i]}, probably in ${FUNCNAME[i+1]}" >&2
# Grab the source code of the line
sed -n "${BASH_LINENO[i]}{s/^/ /;p}" "${BASH_SOURCE[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
sed -n "${BASH_LINENO[i]}{s/^/ /;p}" "${BASH_SOURCE[i+1]}" >&2
done
echo " Error: $LASTERR"
unset FRAMES
@@ -395,27 +392,22 @@ function cmdarg_dump
local ref
local value
for key in "${!cmdarg_cfg[@]}"
for key in ${!cmdarg_cfg[@]}
do
repr="${key}:${CMDARG_TYPES[$key]}"
if [[ ${CMDARG_TYPES[$key]} == "$CMDARG_TYPE_ARRAY" ]] || [[ ${CMDARG_TYPES[$key]} == "$CMDARG_TYPE_HASH" ]] ; then
arrname="${key}"
echo "${repr} => "
keys='${!'"$arrname"'[@]}'
for idx in $(eval "echo $keys")
do
ref='${'"$arrname"'[$idx]}'
value=$(eval "echo $ref")
echo " ${idx} => $value"
done
else
echo "${repr} => ${cmdarg_cfg[$key]}"
fi
done
echo "argv =>"
for idx in "${!cmdarg_argv[@]}"
do
echo " ${idx} => ${cmdarg_argv[$idx]}"
repr="${key}:${CMDARG_TYPES[$key]}"
if [[ ${CMDARG_TYPES[$key]} == $CMDARG_TYPE_ARRAY ]] || [[ ${CMDARG_TYPES[$key]} == $CMDARG_TYPE_HASH ]] ; then
arrname="${key}"
echo "${repr} => "
keys='${!'"$arrname"'[@]}'
for idx in $(eval "echo $keys")
do
ref='${'"$arrname"'[$idx]}'
value=$(eval "echo $ref")
echo " ${idx} => $value"
done
else
echo "${repr} => ${cmdarg_cfg[$key]}"
fi
done
}
@@ -428,7 +420,7 @@ function cmdarg_purge
arrays="$arrays CMDARG_FLAGS CMDARG_TYPES cmdarg_argv cmdarg_helpers"
for arr in $arrays
do
eval "$arr=()"
eval "$arr=()"
done
cmdarg_helpers['describe']=cmdarg_describe_default
cmdarg_helpers['usage']=cmdarg_usage

27
cmdarg.spec Normal file
View File

@@ -0,0 +1,27 @@
%define __os_install_post %{nil}
Summary: Bash Command Line Argument Parsing Library
Name: cmdarg
Version: %{version}
Release: %{release}
License: MIT
Vendor: Andrew Kesterson
Packager: Andrew Kesterson <andrew@aklabs.net>
Group: Development Tools
Provides: %{name}
BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}
Source: %{name}-%{version}-%{release}.tar.gz
Requires: bash
%description
%install
mkdir -p %{buildroot}/usr/src
tar -zxvf %{_sourcedir}/%{name}-%{version}-%{release}.tar.gz
cd %{name}-%{version}-%{release}
PREFIX=%{buildroot} make install
PREFIX=%{buildroot} make MANIFEST
cp MANIFEST /tmp/
%files -f /tmp/MANIFEST

View File

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