refactor: core directory restructure

- core/framework/: flag.sh, hook.sh, help.sh, command.sh, mixin.sh
- core/app/: wgctl-specific context.sh, json.sh
- core/framework/mixins/: json_output, no_color mixins
- core/core.sh: sources framework/core.sh + app/core.sh
- PYTHONPATH exported in app/core.sh for lib/ module resolution
- command::_load_mixins: uses _FRAMEWORK_DIR for mixin path
This commit is contained in:
Nuno Duque Nunes 2026-05-30 02:50:43 +00:00
parent e4545a400b
commit 290ac24d88
26 changed files with 105 additions and 42 deletions

22
core.sh
View file

@ -1,22 +0,0 @@
#!/usr/bin/env bash
# ============================================
# Core Bootstrap
# ============================================
WGCTL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${WGCTL_DIR}/core/log.sh"
source "${WGCTL_DIR}/core/context.sh"
source "${WGCTL_DIR}/core/utils.sh"
source "${WGCTL_DIR}/core/module.sh"
source "${WGCTL_DIR}/core/command.sh"
source "${WGCTL_DIR}/core/command_mixins.sh"
source "${WGCTL_DIR}/core/flag.sh"
source "${WGCTL_DIR}/core/json.sh"
source "${WGCTL_DIR}/core/ui.sh"
source "${WGCTL_DIR}/core/color.sh"
source "${WGCTL_DIR}/core/fmt.sh"
source "${WGCTL_DIR}/core/test/test.sh"
command::_load_mixins

View file

@ -4,11 +4,8 @@
# Static Context — resolved once at source time
# ============================================
_CTX_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
_CTX_WG="/etc/wireguard"
_CTX_CORE="${_CTX_ROOT}/core"
_CTX_MODULES="${_CTX_ROOT}/modules"
_CTX_COMMANDS="${_CTX_ROOT}/commands"
_CTX_WGCTL="/etc/wireguard/wgctl"
_CTX_CLIENTS="${_CTX_WG}/clients"
# ── Directory layout ──────────────────────────────────
@ -17,10 +14,10 @@ _CTX_CLIENTS="${_CTX_WG}/clients"
# data/ ← all persistent data (rules, identities, etc.)
# daemon/ ← runtime files (logs, caches)
_CTX_WGCTL="${_CTX_WG}/.wgctl"
_CTX_CONFIG="${_CTX_WGCTL}/config"
_CTX_DATA="${_CTX_WGCTL}/data"
_CTX_DAEMON="${_CTX_WGCTL}/daemon"
_CTX_WGCTL_ARTIFACT="${_CTX_WG}/.wgctl"
_CTX_CONFIG="${_CTX_WGCTL_ARTIFACT}/config"
_CTX_DATA="${_CTX_WGCTL_ARTIFACT}/data"
_CTX_DAEMON="${_CTX_WGCTL_ARTIFACT}/daemon"
# ── Data subdirs ──────────────────────────────────────
_CTX_RULES="${_CTX_DATA}/rules"
@ -44,15 +41,11 @@ _CTX_CONFIG_FILE="${_CTX_CONFIG}/wgctl.json"
# Accessors
# ============================================
function ctx::root() { echo "$_CTX_ROOT"; }
function ctx::core() { echo "$_CTX_CORE"; }
function ctx::modules() { echo "$_CTX_MODULES"; }
function ctx::commands() { echo "$_CTX_COMMANDS"; }
function ctx::wg() { echo "$_CTX_WG"; }
function ctx::clients() { echo "$_CTX_CLIENTS"; }
# Top-level dirs
function ctx::wgctl() { echo "$_CTX_WGCTL"; }
function ctx::wgctl() { echo "$_CTX_WGCTL_ARTIFACT"; } # needs to change to ctx::wgctl_artifact or ctx::artifact
function ctx::config() { echo "$_CTX_CONFIG"; }
function ctx::data() { echo "$_CTX_DATA"; }
function ctx::daemon() { echo "$_CTX_DAEMON"; }
@ -83,9 +76,9 @@ function ctx::endpoint_cache() { echo "${_CTX_DAEMON}/endpoint_cache.json";
function ctx::accept_events_log() { echo "${_CTX_DAEMON}/accept_events.log"; }
# Tool paths
function ctx::json_helper() { echo "${_CTX_CORE}/json_helper.py"; }
function ctx::monitor_script() { echo "${_CTX_ROOT}/daemon/wgctl-monitor.py"; }
function ctx::lib() { echo "${_CTX_CORE}/lib"; }
function ctx::json_helper() { echo "${_CTX_WGCTL}/core/json_helper.py"; }
function ctx::monitor_script() { echo "${_CTX_WGCTL}/daemon/wgctl-monitor.py"; }
function ctx::lib() { echo "${_CTX_WGCTL}/core/lib"; }
function ctx::block_history() { echo "${_CTX_DATA}/block-history"; }

20
core/app/core.sh Normal file
View file

@ -0,0 +1,20 @@
#!/usr/bin/env bash
_APP_CORE_DIR="$(dirname "${BASH_SOURCE[0]}")"
# ============================================
# Core Bootstrap
# ============================================
source "${_APP_CORE_DIR}/context.sh"
source "${_APP_CORE_DIR}/json.sh"
export PYTHONPATH="$(ctx::core):${PYTHONPATH:-}"
function app::_load_mixins() {
local mixin_file
for mixin_file in "${WGCTL_DIR}/commands/mixins/"*.mixin.sh; do
[[ -f "$mixin_file" ]] && source "$mixin_file"
done
}
app::_load_mixins

View file

@ -1,6 +1,7 @@
#!/usr/bin/env bash
JSON_HELPER="${_CTX_ROOT}/core/json_helper.py"
JSON_HELPER="$(ctx::app)/json_helper.py"
# echo "JSON_HELPER: $JSON_HELPER"
function json::get() { python3 "$JSON_HELPER" get "$@" </dev/null; }
function json::set() { python3 "$JSON_HELPER" set "$@" </dev/null; }

12
core/core.sh Normal file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
# ============================================
# Core Bootstrap
# ============================================
WGCTL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
FRAMEWORK_DIR="$WGCTL_DIR/core/framework"
APP_CORE_DIR="$WGCTL_DIR/core/app"
source "${FRAMEWORK_DIR}/core.sh"
source "${APP_CORE_DIR}/core.sh"

View file

@ -15,8 +15,7 @@ declare -a _ACTIVE_MIXINS=()
function command::_load_mixins() {
local mixin_file
local -a mixin_paths=(
"${WGCTL_DIR}/core/mixins/"*.mixin.sh
"${WGCTL_DIR}/commands/mixins/"*.mixin.sh
"${_FRAMEWORK_DIR}/mixins/"*.mixin.sh
)
for mixin_file in "${mixin_paths[@]:-}"; do
[[ -f "$mixin_file" ]] && source "$mixin_file"

35
core/framework/context.sh Normal file
View file

@ -0,0 +1,35 @@
#!/usr/bin/env bash
# ============================================
# Static Context — resolved once at source time
# ============================================
_CTX_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
_CTX_CORE="${_CTX_ROOT}/core"
_CTX_FRAMEWORK_CORE="${_CTX_ROOT}/core/framework"
_CTX_APP_CORE="${_CTX_ROOT}/core/app"
_CTX_MODULES="${_CTX_ROOT}/modules"
_CTX_COMMANDS="${_CTX_ROOT}/commands"
# echo "ctx::root: $_CTX_ROOT"
# echo "ctx::modules: $_CTX_MODULES"
# ============================================
# Accessors
# ============================================
function ctx::root() { echo "$_CTX_ROOT"; }
function ctx::core() { echo "$_CTX_CORE"; }
function ctx::framework() { echo "$_CTX_FRAMEWORK_CORE"; }
function ctx::app() { echo "$_CTX_APP_CORE"; }
function ctx::modules() { echo "$_CTX_MODULES"; }
function ctx::commands() { echo "$_CTX_COMMANDS"; }
# ============================================
# Path Helpers
# ============================================
function ctx::core::path() { local IFS="/"; echo "$_CTX_CORE/$*"; }
function ctx::framework::path() { local IFS="/"; echo "$_CTX_FRAMEWORK_CORE/$*"; }
function ctx::module::path() { local IFS="/"; echo "$_CTX_MODULES/$*"; }
function ctx::command::path() { local IFS="/"; echo "$_CTX_COMMANDS/$*"; }

22
core/framework/core.sh Normal file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
# core/framework/core.sh
_FRAMEWORK_DIR="$(dirname "${BASH_SOURCE[0]}")"
source "${_FRAMEWORK_DIR}/context.sh"
source "${_FRAMEWORK_DIR}/module.sh"
source "${_FRAMEWORK_DIR}/command.sh"
source "${_FRAMEWORK_DIR}/command_mixins.sh"
source "${_FRAMEWORK_DIR}/flag.sh"
source "${_FRAMEWORK_DIR}/hook.sh"
source "${_FRAMEWORK_DIR}/help.sh"
source "${_FRAMEWORK_DIR}/mixin.sh"
source "${_FRAMEWORK_DIR}/ui.sh"
source "${_FRAMEWORK_DIR}/color.sh"
source "${_FRAMEWORK_DIR}/fmt.sh"
source "${_FRAMEWORK_DIR}/log.sh"
source "${_FRAMEWORK_DIR}/utils.sh"
source "${_FRAMEWORK_DIR}/test/test.sh"
command::_load_mixins

1
core/framework/help.sh Normal file
View file

@ -0,0 +1 @@
#!/usr/bin/env bash

1
core/framework/hook.sh Normal file
View file

@ -0,0 +1 @@
#!/usr/bin/env bash

1
core/framework/mixin.sh Normal file
View file

@ -0,0 +1 @@
#!/usr/bin/env bash

2
wgctl
View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -uo pipefail
source "$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)/core.sh"
source "$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)/core/core.sh"
LOG_LEVEL=DEBUG