78 lines
No EOL
1.9 KiB
Bash
78 lines
No EOL
1.9 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# ============================================
|
|
# Module Registry
|
|
# ============================================
|
|
|
|
declare -A _LOADED_MODULES=()
|
|
|
|
readonly _MODULE_AUTO_LOAD_HOOK="on_load"
|
|
|
|
# ============================================
|
|
# Helpers
|
|
# ============================================
|
|
|
|
function module::loaded() { [[ -n "${_LOADED_MODULES["$1"]:-}" ]]; }
|
|
|
|
# Convert path-style name to namespace
|
|
# e.g. firewall/iptables -> fw::iptables
|
|
function module::to_namespace() { echo "${1//\//:}"; }
|
|
|
|
# Build fully qualified function name
|
|
# e.g. module::fn "firewall/iptables" "on_load" -> fw::iptables::on_load
|
|
function module::fn() {
|
|
local namespace
|
|
namespace=$(module::to_namespace "$1")
|
|
echo "${namespace}::${2}"
|
|
}
|
|
|
|
function module::has_function() { declare -F "$(module::fn "$1" "$2")" >/dev/null 2>&1; }
|
|
function module::is_auto_load() { declare -F "$(module::fn "$1" on_load)" >/dev/null 2>&1; }
|
|
|
|
# ============================================
|
|
# Loader
|
|
# ============================================
|
|
|
|
function load_module() {
|
|
local name="$1"
|
|
|
|
# Wildcard: load all submodules in a directory
|
|
if [[ "$name" == *"/*" ]]; then
|
|
_load_module_dir "${name%/*}"
|
|
return $?
|
|
fi
|
|
|
|
module::loaded "$name" && return 0
|
|
|
|
local path
|
|
path="$(ctx::modules)/${name}.module.sh"
|
|
|
|
if [[ ! -f "$path" ]]; then
|
|
log::error "Module not found: ${name} (${path})"
|
|
return 1
|
|
fi
|
|
|
|
source "$path"
|
|
_LOADED_MODULES["$name"]=1
|
|
|
|
core::call_if_exists "$(module::fn "$name" on_load)"
|
|
|
|
return 0
|
|
}
|
|
|
|
function _load_module_dir() {
|
|
local dir="${1:-}"
|
|
local module_dir
|
|
module_dir="$(ctx::modules)/${dir}"
|
|
|
|
if [[ ! -d "$module_dir" ]]; then
|
|
log::error "Module directory not found: ${dir} (${module_dir})"
|
|
return 1
|
|
fi
|
|
|
|
for file in "${module_dir}"/*.module.sh; do
|
|
[[ -f "$file" ]] || continue
|
|
local subname="${dir}/$(basename "${file%.module.sh}")"
|
|
load_module "$subname"
|
|
done
|
|
} |