dx/dxkit/drivers/dispatcher.sh

98 lines
No EOL
2.7 KiB
Bash

#!/usr/bin/env bash
# ============================================
# Driver Dispatcher
# ============================================
#
# Resolves the active framework via app::framework()
# and loads the corresponding driver from dxkit/drivers/.
#
# Called in main() after load_module app, so app::framework()
# is guaranteed to be available.
#
# Each driver registers its commands into DRIVER_COMMANDS
# for dx::dispatch to pick up.
#
# Usage (in dx entrypoint, after load_module app):
# driver::load
declare -gA DRIVER_COMMANDS=()
# ============================================
# Resolution
# ============================================
# Maps APP_FRAMEWORK values to driver directory names.
# Multiple framework variants can share one driver (e.g. yii2-advanced
# and yii2-basic both use the yii2 driver).
# Unknown frameworks fall through as-is, so new drivers
# just need a matching directory — no changes here required.
function driver::resolve() {
local framework
framework="$(app::framework)"
case "$framework" in
yii2-advanced|yii2-basic) echo "yii2" ;;
laravel) echo "laravel" ;;
*) echo "$framework" ;;
esac
}
# ============================================
# Loader
# ============================================
function driver::load() {
local driver
driver="$(driver::resolve)"
local driver_file
driver_file="$(ctx::dxkit)/drivers/${driver}/driver.sh"
if [[ ! -f "$driver_file" ]]; then
log::warn "No driver found for framework '$(app::framework)' at ${driver_file}"
log::warn "Framework-specific commands (e.g. migrate-create) will not be available."
return 0
fi
# shellcheck source=/dev/null
source "$driver_file"
log::debug "Loaded driver: ${driver} (framework: $(app::framework))"
}
# ============================================
# Runtime Helpers
# ============================================
# Returns true if a command is registered by the active driver.
function driver::has_command() {
local cmd="$1"
[[ -n "${DRIVER_COMMANDS[$cmd]:-}" ]]
}
# Runs a driver command.
function driver::run() {
local cmd="$1"
shift
if ! driver::has_command "$cmd"; then
log::error "Driver command not found: '${cmd}'"
return 1
fi
"${DRIVER_COMMANDS[$cmd]}" "$@"
}
# Prints all registered driver commands (used by dx help and dx workspace).
function driver::list_commands() {
if [[ ${#DRIVER_COMMANDS[@]} -eq 0 ]]; then
return 0
fi
echo ""
echo " Framework commands ($(app::framework)):"
for cmd in $(echo "${!DRIVER_COMMANDS[@]}" | tr ' ' '\n' | sort); do
printf " %-28s\n" "$cmd"
done
}