function bar_main {
trace "$*"
set -euo pipefail
export LC_ALL=$(locale -a 2>/dev/null | grep -i 'C.utf.*8' || echo C)
export TMPDIR="${TMPDIR:-/tmp}"
declare -grx BAR_SELF="$(realpath "$BASH_ARGV0")" declare -grx BAR_CALLED_AS="${BASH_ARGV0##*/}" declare -gx BAR_DIR declare -g BAR_BARE declare -gx BARF_FILE declare -gxr BAR_PWD="$PWD" declare -gxi BAR_VERBOSITY_LEVEL="${BAR_VERBOSITY_LEVEL:-2}" declare -gA BAR_REQUIRE_LOADED
declare -gA TTYCTL TTYNIL
declare -gA TTYOUT TTYERR
find_toplevel
debug "using Bar directory: $BAR_DIR"
require std_lib rule_lib
require '*_rules'
local maybe_barf=
local initial_rule=
if [[ "$BAR_CALLED_AS" =~ \.?bar|please ]]; then
maybe_barf="${1:-}"
else
initial_rule="$BAR_CALLED_AS"
fi
local barfs=("$BAR_TOPLEVEL/Barf" "$BAR_TOPLEVEL/barf" "$BAR_TOPLEVEL/.Barf" "$BAR_TOPLEVEL/.barf")
if [[ "$BAR_CALLED_AS" = please ]]; then
barfs=("Pleasef" "pleasef" ".Pleasef" ".pleasef" "$HOME/.Pleasef")
fi
for BARF_FILE in "$maybe_barf" "${barfs[@]}"; do
if [[ -f "$BARF_FILE" ]]; then
debug "using: $BARF_FILE"
[[ "$BARF_FILE" = "$maybe_barf" ]] && shift
BARF_FILE="$(realpath "$BARF_FILE")"
require "$BARF_FILE"
break
fi
done
if [[ "${1:-}" = '--bare' ]]; then
shift
BAR_BARE=true
fi
local rc=0
[[ -z "$initial_rule" && -n "${1:-}" ]] && rule_autoload "$1"
declare -grix BAR_TIMESTAMP="$(bar_now)"
[[ -z "${initial_rule}" ]] && {
initial_rule="${1:-MAIN}"
shift || true
}
[[ "${BAR_RULE_FLAGS[$initial_rule]:-}" == *b* ]] && BAR_BARE=true
if rule_exists "$initial_rule"; then
[[ -z "${BAR_BARE:-}" ]] && {
trap 'rule_exists CLEANUP && { rule_eval CLEANUP || error "CLEANUP failed" ; }' EXIT
rule_exists SETUP && {
rule_eval SETUP || die "SETUP failed" ;
}
rule_exists PREPROCESS && {
rule_eval PREPROCESS || die "PREPROCESS failed" ;
}
}
rule_eval "$initial_rule" "$@" || rc=$?
if (( "$rc" == 0 )); then
success "$initial_rule" "$@"
[[ -z "${BAR_BARE:-}" ]] && rule_exists POSTPROCESS && { rule_eval POSTPROCESS || error "POSTPROCCESS failed" ; }
else
failure "$initial_rule" "$@"
fi
return $rc
else
die "No Barf/Pleasef file found in current directory and no rule defined.
USAGE
bar [Rulefile] [Rule [Arguments]]
please [Rulefile] [Rule [Arguments]]
or
bar help
please help
"
fi
}
function find_toplevel
{
local origin="$(command -v bar)"
declare -gxr BAR_PREFIX="${origin%/bin/*}"
declare -gx BAR_TOPLEVEL="$BAR_PWD"
local initial_fs_id="$(stat -f -c %i "$BAR_TOPLEVEL")"
local barfd=("$BAR_TOPLEVEL/Bar.d" "$BAR_TOPLEVEL/bar.d/" "$BAR_TOPLEVEL/.Bar.d/" "$BAR_TOPLEVEL/.bar.d/")
if [[ "$BAR_CALLED_AS" = please ]]; then
barfd=("$HOME/.config/please")
fi
for BAR_DIR in "${barfd[@]}"; do
if [[ -d "$BAR_DIR" ]]; then
readonly BAR_TOPLEVEL
return 0
fi
if [[ "$BAR_TOPLEVEL" = "/" ]]; then
break
fi
BAR_TOPLEVEL="$(readlink -f "$BAR_TOPLEVEL/..")"
if [[ ! -v BAR_CROSS_FS && "$(stat -f -c %i "$BAR_TOPLEVEL")" != "$initial_fs_id" ]]; then
break
fi
done
warn "No Bar.d directory found, trying original/installed"
if [[ ! -d "$BAR_DIR" ]]; then
BAR_DIR="$BAR_PREFIX/share/bar/Bar.d"
[[ -d "$BAR_DIR" ]] || die "Bar directory '$BAR_DIR' does not exist"
fi
}
function require {
trace "$*"
declare -i rc=0
local try_load=""
if [[ "$1" = "--opt" ]]; then
try_load=true
shift
fi
local mod
for mod in "$@"; do
local moddir="$BAR_DIR/"
[[ "$mod" = */* ]] && moddir=
for mod in "$moddir"$mod; do
local modname="${mod##*/}"
if [[ ! -v BAR_REQUIRE_LOADED["$modname"] ]]; then
if [[ -f "$mod" ]]; then
debug "loading: $mod"
BAR_REQUIRE_LOADED["$modname"]=pending
source "$mod" && BAR_REQUIRE_LOADED["$modname"]=true
else
if [[ -z "$try_load" ]]; then
warn "failed loading: $mod"
rc=1
else
trace "failed try loading: $mod"
fi
BAR_REQUIRE_LOADED["$modname"]=false
fi
fi
done
done
return $rc
}
function tty_newline { :; }
function source_info {
echo "${BASH_SOURCE[$((${1:-0}+1))]}:${BASH_LINENO[$((${1:-0}))]}:${FUNCNAME[$((${1:-0}+1))]:+${FUNCNAME[$((${1:-0}+1))]}:}"
}
function DBG {
{
tty_newline
echo "${TTYERR[r_R]:-}${TTYERR[__B]:-} DBG:${TTYERR[n]:-} $(source_info 1) $*"
} >&2
}
function die {
if (( BAR_VERBOSITY_LEVEL > 0 )); then
tty_newline
echo "${TTYERR[R_B]:-}PANIC:${TTYERR[n]:-} $(source_info 1) $*"
fi >&2
exit 1
}
function error {
if (( BAR_VERBOSITY_LEVEL > 0 )); then
tty_newline
echo "${TTYERR[r_B]:-}ERROR:${TTYERR[n]:-} $(source_info 1) $*"
fi >&2
}
function warn {
if (( BAR_VERBOSITY_LEVEL > 1 )); then
tty_newline
echo "${TTYERR[m_B]:-} WARN:${TTYERR[n]:-} $*" >&2
fi >&2
}
function note {
if (( BAR_VERBOSITY_LEVEL > 2 )); then
tty_newline
echo "${TTYERR[m_B]:-} NOTE:${TTYERR[n]:-} $*"
fi >&2
}
function info {
if (( BAR_VERBOSITY_LEVEL > 3 )); then
tty_newline
echo "${TTYERR[b_B]:-} INFO:${TTYERR[n]:-} $*"
fi >&2
}
function debug {
if (( BAR_VERBOSITY_LEVEL > 4 )); then
tty_newline
echo "${TTYERR[c_B]:-}DEBUG:${TTYERR[n]:-} $(source_info 1) $*"
fi >&2
}
function trace {
if (( BAR_VERBOSITY_LEVEL > 5 )); then
tty_newline
echo "${TTYERR[C_B]:-}TRACE:${TTYERR[n]:-} $(source_info 1) $*"
fi >&2
}
bar_main "$@"