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