rwx/sh/main.sh
2025-07-04 03:52:38 +02:00

213 lines
4.6 KiB
Bash
Executable file

#! /usr/bin/env sh
# main module
# ╭──────╮
# │ main │
# ╰──────╯
# ╭──────┬───────────╮
# │ main │ constants │
# ╰──────┴───────────╯
# name of the entrypoint file
RWX_MAIN_NAME="main.sh"
RWX_SELF_NAME="rwx"
RWX_SELF_COMMAND="_${RWX_SELF_NAME}_cmd_"
# ╭──────┬───────────╮
# │ main │ variables │
# ╰──────┴───────────╯
RWX_COMMAND_ARGUMENT="${0}"
RWX_SHELL="$(cat "/proc/${$}/comm")"
RWX_COMMAND_NAME="$(basename "${RWX_COMMAND_ARGUMENT}" |
sed "s|^-||")"
case "${RWX_COMMAND_NAME}" in
"bash" | "dash" | "sh") unset RWX_COMMAND_NAME ;;
*) ;;
esac
RWX_ROOT_SYSTEM="/usr/local/lib/${RWX_SELF_NAME}"
RWX_SELF_USER="${HOME}/${RWX_SELF_NAME}"
RWX_MAIN_PATH="${RWX_ROOT_SYSTEM}/${RWX_MAIN_NAME}"
# ╭──────┬──────╮
# │ main │ main │
# ╰──────┴──────╯
# run initial steps
rwx_main() {
# cache main
rwx_cache "${RWX_ROOT_SYSTEM}" "${RWX_MAIN_NAME}"
# source system root
if ! rwx_source "${RWX_ROOT_SYSTEM}" "${RWX_MAIN_NAME}"; then
__rwx_log "Not a directory: ${RWX_ROOT_SYSTEM}"
return 1
fi
# source user root
rwx_source "${RWX_SELF_USER}"
# parse code cache
rwx_parse
# context / command
if [ -n "${RWX_COMMAND_NAME}" ]; then
"${RWX_SELF_COMMAND}${RWX_COMMAND_NAME}" "${@}"
# context / shell
else
rwx_self_init
fi
}
# ╭──────┬───────╮
# │ main │ cache │
# ╰──────┴───────╯
RWX_CODE=""
# cache source code of a module
rwx_cache() {
local root="${1}"
local module="${2}"
local name="${module%.sh}"
local path="${root}/${module}"
local text
text="$(cat "${path}")"
RWX_CODE="${RWX_CODE}\
#↓ ${name}
${text}
"
}
# ╭──────┬────────╮
# │ main │ source │
# ╰──────┴────────╯
# source code from file path
rwx_source() {
local root="${1}"
[ -d "${root}" ] ||
return 1
local file="${2}"
local count module
count=0
__rwx_log "" \
". ${root}"
rwx_ifs_set
for module in $(rwx_find_shell "${root}" "${file}"); do
count=$((count + 1))
__rwx_log "$(printf "%02d" "${count}") ${module%.sh}"
# shellcheck disable=SC1090
. "${root}/${module}"
# cache code
rwx_cache "${root}" "${module}"
done
rwx_ifs_unset
}
# ╭──────┬─────╮
# │ main │ log │
# ╰──────┴─────╯
__rwx_log() {
if rwx_shell_interactive; then
[ ${#} -gt 0 ] || set -- ""
local line
for line in "${@}"; do
echo "${line}"
done
fi
}
# ╭──────┬───────╮
# │ main │ shell │
# ╰──────┴───────╯
# test if active shell is in interactive mode
rwx_shell_interactive() {
case "${-}" in
*i*) ;;
*) return 1 ;;
esac
}
# ╭──────┬─────╮
# │ main │ ifs │
# ╰──────┴─────╯
# set internal field separator to line feed
rwx_ifs_set() {
_RWX_IFS="${IFS}"
IFS="
"
}
# unset internal field separator
rwx_ifs_unset() {
IFS="${_RWX_IFS}"
unset RWX_IFS
}
# ╭──────┬──────╮
# │ main │ find │
# ╰──────┴──────╯
# find directory’s files by extension
rwx_find_extension() {
local extension="${1}"
local root="${2}"
local file="${3}"
set -- \
"${root}" \
-name "*.${extension}" \
-type "f"
[ -n "${file}" ] &&
set -- "${@}" \
-not \
-name "${file}"
find "${@}" \
-printf "%P\n" |
sort
}
# find directory’s sh files
rwx_find_shell() {
rwx_find_extension "sh" "${@}"
}
# ╭──────┬───────╮
# │ main │ parse │
# ╰──────┴───────╯
rwx_parse() {
local ws="[[:space:]]*"
local start="^${ws}"
local constant="[_A-Z][_0-9A-Z]*"
local setting="=.*"
local func="${ws}(${ws})${ws}{.*"
local id="[_a-zA-Z][_a-z0-9A-Z]*"
local line
RWX_CONSTANTS=""
printf "%s\n" "${RWX_CODE}" |
grep "${start}${constant}${setting}" |
sed "s|${start}\\(${constant}\\)${setting}|\\1|" |
while IFS= read -r line; do
RWX_CONSTANTS="${RWX_CONSTANTS}${line}
"
done
RWX_FUNCTIONS=""
printf "%s\n" "${RWX_CODE}" |
grep "${start}${id}${func}" |
sed "s|${start}\\(${id}\\)${func}|\\1|" |
while IFS= read -r line; do
RWX_FUNCTIONS="${RWX_FUNCTIONS}${line}
"
done
}
# ╭──────┬─────╮
# │ main │ run │
# ╰──────┴─────╯
# run main function
rwx_main "${@}"