dx/dxkit/core/utils.sh

99 lines
2.5 KiB
Bash

#!/usr/bin/env bash
# ===========================================
# System
# ===========================================
function system::uuid() {
od -x /dev/urandom | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'
}
function system::hosts() {
cat "$(platform::hosts_file)"
}
function system::stderr() {
"$1" >&2
}
# ===========================================
# Path
# ===========================================
function path::relative_to_root() {
local abs="$1"
local root="$(ctx::root)"
# remove root prefix
echo "${abs#$root/}"
}
function path::from_root() {
local path="$1"
[[ "$path" == /* ]] && echo "$path" || echo "$(ctx::root)/${path}"
}
function path::relative_to() {
local from="$1"
local to="$2"
# ===========================================
# 1. GNU realpath (best case)
# ===========================================
if platform::has_gnu_realpath; then
realpath --relative-to="$from" "$to"
return 0
fi
# ===========================================
# 2. Homebrew GNU coreutils
# ===========================================
if platform::has_grealpath; then
grealpath --relative-to="$from" "$to"
return 0
fi
# ===========================================
# 3. Python fallback (POSIX-safe)
# ===========================================
if platform::has_python; then
python3 -c '
import os, sys
print(os.path.relpath(sys.argv[2], sys.argv[1]))
' "$from" "$to"
return 0
fi
# ===========================================
# 4. Hard failure
# ===========================================
echo "path::relative_to: no suitable backend found" >&2
return 1
}
# ===========================================
# Core
# ===========================================
# Returns true if stdout is connected to a real TTY.
# Used to decide whether winpty or interactive flags are needed.
# False inside $(), pipes, or non-interactive subshells.
function core::has_tty() { [[ -t 1 ]]; } # stdout is a TTY
function core::is_interactive() { [[ $- == *i* ]]; } # shell is interactive mode
function core::function_exists() { declare -F "$1" >/dev/null 2>&1; }
function core::variable_exists() { declare -p "$1" &>/dev/null; }
function core::array_exists() { [[ "$(declare -p "$1" 2>/dev/null)" == "declare -a"* ]]; }
function core::call_function() {
local fn="$1"
shift
"$fn" "$@";
}
function core::call_if_exists() {
local fn="$1"
shift
if declare -F "$fn" >/dev/null 2>&1; then
"$fn" "$@"
fi
return 0
}