include/cmd.bash (73 lines of code) (raw):
declare -A CMDS
cmd-list() {
declare desc="Lists available commands"
declare ns="$1"
cmd-list-keys "$ns" | sed "s/$ns://"
}
cmd-list-keys() {
declare ns="$1"
for k in "${!CMDS[@]}"; do
echo "$k"
done | grep "^$ns:" | sort
}
cmd-list-ns() {
for k in "${!CMDS[@]}"; do
echo "$k"
done | grep -v : | sort
}
cmd-export() {
declare desc="Exports a function as a command"
declare fn="$1" as="${2:-$1}"
local ns=""
for n in $(cmd-list-ns); do
echo "$fn" | grep "^$n-" &> /dev/null && ns="$n"
done
CMDS["$ns:${as/#$ns-/}"]="$fn"
}
cmd-export-ns() {
declare ns="$1" desc="$2"
eval "$1() {
declare desc=\"$desc\"
cmd-ns $1 \"\$@\";
}"
cmd-export "$1"
CMDS["$1"]="$1"
}
cmd-ns() {
local ns="$1"; shift
local cmd="$1"; shift || true
local status=0
if cmd-list "$ns" | grep ^"$cmd"\$ &> /dev/null; then
${CMDS["$ns:$cmd"]} "$@"
else
if [[ "$cmd" ]]; then
echo "No such command: $cmd"
status=2
elif [[ "$ns" ]]; then
fn-desc "$ns"
fi
echo
echo "Available commands:"
for cmd in $(cmd-list "$ns"); do
printf " %-24s %s\n" "$cmd" "$(fn-desc "${CMDS["$ns:$cmd"]}")"
for subcmd in $(cmd-list "$cmd"); do
printf " %-24s %s\n" "$subcmd" "$(fn-desc "${CMDS["$cmd:$subcmd"]}")"
done
done
echo
exit $status
fi
}
cmd-help() {
declare desc="Shows help information for a command"
declare args="$*"
if [[ "$args" ]]; then
for cmd; do true; done # last arg
local ns="${args/%$cmd/}"; ns="${ns/% /}"; ns="${ns/ /-}"
local fn="${CMDS["$ns:$cmd"]}"
fn-info "$fn" 1
else
cmd-ns ""
fi
}
cmd-export cmd-help help