gistfile1.txt
· 1.8 KiB · Text
原始檔案
#!/usr/bin/env bash
# ============================================
# Command Registry
# ============================================
declare -A _LOADED_COMMANDS=()
readonly _COMMAND_NAMESPACE="cmd"
readonly _COMMAND_AUTO_LOAD_HOOK="on_load"
# ============================================
# Helpers
# ============================================
function command::loaded() { [[ -n "${_LOADED_COMMANDS["$1"]:-}" ]]; }
# Convert path-style name to namespace
# e.g. service/wireguard -> service::wireguard
function command::to_namespace() { echo "${1//\//:}"; }
# Build fully qualified function name
# e.g. command::fn "add" "run" -> cmd::add::run
# e.g. command::fn "service/wg" "run" -> cmd::service::wg::run
function command::fn() {
local name namespace
namespace=$(command::to_namespace "$1")
echo "${_COMMAND_NAMESPACE}::${namespace}::${2}"
}
function command::has_function() { declare -F "$(command::fn "$1" "$2")" >/dev/null 2>&1; }
function command::is_auto_load() { declare -F "$(command::fn "$1" on_load)" >/dev/null 2>&1; }
function command::exists() { command::has_function "$1" run; }
# ============================================
# Runner
# ============================================
function command::run() {
local cmd="$1"
shift
local fn
fn=$(command::fn "$cmd" run)
core::call_function "$fn" "$@"
}
function core::call_function() {
local fn="$1"
shift
"$fn" "$@"
}
# ============================================
# Loader
# ============================================
function load_command() {
local name="$1"
command::loaded "$name" && return 0
local path
path="$(ctx::commands)/${name}.command.sh"
if [[ ! -f "$path" ]]; then
log::error "Command not found: ${name} (${path})"
return 1
fi
source "$path"
_LOADED_COMMANDS["$name"]=1
core::call_if_exists "$(command::fn "$name" on_load)"
return 0
}
| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | # ============================================ |
| 4 | # Command Registry |
| 5 | # ============================================ |
| 6 | |
| 7 | declare -A _LOADED_COMMANDS=() |
| 8 | |
| 9 | readonly _COMMAND_NAMESPACE="cmd" |
| 10 | readonly _COMMAND_AUTO_LOAD_HOOK="on_load" |
| 11 | |
| 12 | # ============================================ |
| 13 | # Helpers |
| 14 | # ============================================ |
| 15 | |
| 16 | function command::loaded() { [[ -n "${_LOADED_COMMANDS["$1"]:-}" ]]; } |
| 17 | |
| 18 | # Convert path-style name to namespace |
| 19 | # e.g. service/wireguard -> service::wireguard |
| 20 | function command::to_namespace() { echo "${1//\//:}"; } |
| 21 | |
| 22 | # Build fully qualified function name |
| 23 | # e.g. command::fn "add" "run" -> cmd::add::run |
| 24 | # e.g. command::fn "service/wg" "run" -> cmd::service::wg::run |
| 25 | function command::fn() { |
| 26 | local name namespace |
| 27 | namespace=$(command::to_namespace "$1") |
| 28 | echo "${_COMMAND_NAMESPACE}::${namespace}::${2}" |
| 29 | } |
| 30 | |
| 31 | function command::has_function() { declare -F "$(command::fn "$1" "$2")" >/dev/null 2>&1; } |
| 32 | function command::is_auto_load() { declare -F "$(command::fn "$1" on_load)" >/dev/null 2>&1; } |
| 33 | function command::exists() { command::has_function "$1" run; } |
| 34 | |
| 35 | # ============================================ |
| 36 | # Runner |
| 37 | # ============================================ |
| 38 | |
| 39 | function command::run() { |
| 40 | local cmd="$1" |
| 41 | shift |
| 42 | local fn |
| 43 | fn=$(command::fn "$cmd" run) |
| 44 | core::call_function "$fn" "$@" |
| 45 | } |
| 46 | |
| 47 | function core::call_function() { |
| 48 | local fn="$1" |
| 49 | shift |
| 50 | "$fn" "$@" |
| 51 | } |
| 52 | |
| 53 | # ============================================ |
| 54 | # Loader |
| 55 | # ============================================ |
| 56 | |
| 57 | function load_command() { |
| 58 | local name="$1" |
| 59 | |
| 60 | command::loaded "$name" && return 0 |
| 61 | |
| 62 | local path |
| 63 | path="$(ctx::commands)/${name}.command.sh" |
| 64 | |
| 65 | if [[ ! -f "$path" ]]; then |
| 66 | log::error "Command not found: ${name} (${path})" |
| 67 | return 1 |
| 68 | fi |
| 69 | |
| 70 | source "$path" |
| 71 | _LOADED_COMMANDS["$name"]=1 |
| 72 | |
| 73 | core::call_if_exists "$(command::fn "$name" on_load)" |
| 74 | |
| 75 | return 0 |
| 76 | } |
| 77 |