99 lines
2.5 KiB
Bash
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
|
|
}
|