#!/bin/bash
# commands - heirarchical command support library
set -e
lib_load 'core/script'
######
# Library Configuration
core_commands_config_init() {
# $cmd_tempdir - Path to temporary directory for this command instance.
lib_setting_vars cmd_tempdir
cmd_tempdir="$user_tempdir/run/$script_name/$$"
run_mkdir "$cmd_tempdir"
cleanup_add cmd_cleanup_tempdir
}
# $error_usage_hook - Set to ``cmd_error_usage()`` to provide command usage.
error_usage_hook=cmd_error_usage
######
# Library Cleanup
# cmd_cleanup_tempdir() - Removes the command's temporary directory:
# ``$cmd_tempdir``.
cmd_cleanup_tempdir() { rm -rf "$cmd_tempdir"; }
######
# Commands Names
# cmd_tempfile() - Creates a temporary file in ``$cmd_tempdir``, printing
# its name to stdout. **All of these files will be deleted when the
# script terminates.** See ``cmd_cleanup_tempdir()`` for more information.
cmd_tempfile() { tempfile -d "$cmd_tempdir"; }
# cmd_name() - Prints a command name, given ``${script[@]}`` and ``$@``.
cmd_name() {
local -a a=( "${script[@]}" "$@" )
( export IFS='_'; echo "${a[*]}"; )
}
# cmd_exists() - Returns success if a named command function exists.
# $@ - Command names to pass to ``cmd_name()``.
cmd_exists() { is_function $(cmd_name "$@"); }
######
# Command Execution
# cmd_run() - Executes the current command with the given arguments ($@)
cmd_run() { $(cmd_name) "$@"; }
# cmd_dispatch_builtins() - Attempts to dispatch a built-in command ($1).
# Returns success if the given command was handled.
#
# **TODO**: Extend this mechanism to allow registering new commands
cmd_dispatch_builtins() {
local cmd=$1
local handled=true
case "$cmd" in
usage|--usage)
cmd_usage
;;
help|--help|-h|-?)
cmd_help
;;
*)
handled=false
;;
esac
$handled
}
# cmd_dispatch() - Dispatches a command ($1) and moves to that
# command's namespace. Where used, this function effectively creates
# the script's command language heirarchy. Recursive calls extend the
# ``${script[@]}`` array, so each successive call operates on a new
# nested namespace.
# $1 - Command name
# $@ - Command arguments
cmd_dispatch() {
min_args 1 "$@"
if cmd_dispatch_builtins "$@"; then
return
fi
local cmd=$1
if cmd_exists "$cmd"; then
local script=( "${script[@]}" "$cmd" )
shift
cmd_run "$@"
else
error_usage "'$cmd' is not a known command"
fi
}
# cmd_exec() - Executes a command ($1) in the current namespace.
# $1 - Command name
# $@ - Command arguments
cmd_exec() {
min_args 1 "$@"
local cmd=$1
shift
if cmd_exists "$cmd"; then
$(cmd_name $cmd) "$@"
fi
}
# cmd_exec_something() - Executes a command ($1) in the first ancenstor
# namespace that contains it. The search begins in current command namespace
# and ascends up to the script namespace. Once a command handler has been
# found, that function will be executed and control returned to the caller.
cmd_exec_something() {
local cmd=$1
local -a _script=( "${script[@]}" )
local -a script=( "${_script[@]}" )
while [ "${script[*]}" ]; do
if cmd_exists "$cmd"; then
cmd_exec "$cmd"
break
fi
list_pop script >/dev/null
done
}
######
# Command Usage and Help Support
# cmd_usage() - Prints usage information for the current command. To be
# user-friendly, searchs for usage in anscestor command namespaces.
# This allows commands to defer their usage information to their parent
# commands.
cmd_usage() {
local usage
usage=$(cmd_exec_something usage)
echo "usage: ${script[*]} $usage"
if [ "${#script[*]}" -eq 1 -a "$script_name" == "$script" ]; then
app_usage
fi
cat <<USAGE
General Commands:
usage|--usage Print basic command usage
help|--help|-h|-? Print full command help
USAGE
}
# cmd_help() - Prints help text for the current command. This function
# operates according to the same principles as ``cmd_usage()``.
cmd_help() {
cmd_usage
local body
body=$(cmd_exec_something help)
if [ "$body" ]; then
echo
echo "$body"
fi
#; if present, display support contact name/email
local support_name="${package_support_name:-contacting this address}"
if [ "$package_support_email" ]; then
cat <<EMAIL
Support for this package is provided by $support_name:
$package_support_email
EMAIL
elif [ "$package_support_name" ]; then
echo "Support for this package is provided by $support_name."
fi
#; if present, display package URL
if [ "$package_url" ]; then
cat <<URL
For more information, please visit the package webpage:
$package_url
URL
fi
}
# cmd_error_usage() - Overrides the stub from ``core/output`` library,
# allowing dynamic command usage lookup.
cmd_error_usage() {
! error "$1"
cmd_usage >&2
false
}
Generated on Thu May 4 18:59:16 PDT 2017 by mcsh i7 v0.19.0.