|
|
@ -1,9 +1,8 @@ |
|
|
#!/usr/bin/env -S -- bash |
|
|
|
|
|
|
|
|
#!/usr/bin/env bash |
|
|
#!/usr/bin/env -S -- bash -x |
|
|
#!/usr/bin/env -S -- bash -x |
|
|
|
|
|
|
|
|
# constants |
|
|
# constants |
|
|
|
|
|
|
|
|
MIAOU_BASH_ERROR=$(mktemp -t "$(basename "$0").XXXXXXXX" --tmpdir="/run/user/$UID") |
|
|
|
|
|
MIAOU_DEBUG=${MIAOU_DEBUG:-false} |
|
|
MIAOU_DEBUG=${MIAOU_DEBUG:-false} |
|
|
|
|
|
|
|
|
declare -A ANSI |
|
|
declare -A ANSI |
|
|
@ -37,7 +36,7 @@ ANSI[BG_WHITE]=47 |
|
|
ANSI[BG_GRAY]=90 |
|
|
ANSI[BG_GRAY]=90 |
|
|
ANSI[BG_MAGENTA]=95 |
|
|
ANSI[BG_MAGENTA]=95 |
|
|
|
|
|
|
|
|
readonly MIAOU_BASH_ERROR MIAOU_DEBUG ANSI |
|
|
|
|
|
|
|
|
readonly MIAOU_DEBUG ANSI |
|
|
|
|
|
|
|
|
## functions |
|
|
## functions |
|
|
|
|
|
|
|
|
@ -148,8 +147,8 @@ function on_error { |
|
|
failure_payload="${BASH_COMMAND}" |
|
|
failure_payload="${BASH_COMMAND}" |
|
|
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}" |
|
|
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}" |
|
|
|
|
|
|
|
|
miaou_debug "<investigate_tmp_error pid=${BASHPID}>" |
|
|
|
|
|
load_tmp_error # cannot print_miaou_error after investigation |
|
|
load_tmp_error # cannot print_miaou_error after investigation |
|
|
|
|
|
miaou_debug "<investigate_tmp_error pid=${BASHPID}>" |
|
|
|
|
|
|
|
|
if [[ ${#tmp_error[@]} -gt 1 ]]; then |
|
|
if [[ ${#tmp_error[@]} -gt 1 ]]; then |
|
|
local last_error regex |
|
|
local last_error regex |
|
|
@ -244,7 +243,12 @@ function on_pipe { |
|
|
function dump_stderr { |
|
|
function dump_stderr { |
|
|
miaou_debug "<stderr count=${#tmp_error[@]}>" |
|
|
miaou_debug "<stderr count=${#tmp_error[@]}>" |
|
|
tty_ansi FG_LIGHTBLUE |
|
|
tty_ansi FG_LIGHTBLUE |
|
|
for i in "${tmp_error[@]}"; do echo "$i"; done |
|
|
|
|
|
|
|
|
for i in "${tmp_error[@]}"; do |
|
|
|
|
|
is_true "$CHILD_PROCESS" && |
|
|
|
|
|
miaou_debug "<childerr content={$i}/>" || |
|
|
|
|
|
miaou_debug "<mainerr content={$i}/>" |
|
|
|
|
|
echo "$i" |
|
|
|
|
|
done |
|
|
tty_ansi RESET |
|
|
tty_ansi RESET |
|
|
miaou_debug '</stderr>' |
|
|
miaou_debug '</stderr>' |
|
|
} |
|
|
} |
|
|
@ -303,15 +307,25 @@ function dump_stacktrace { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function load_tmp_error { |
|
|
function load_tmp_error { |
|
|
[[ -v tmp_error ]] && return 0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
miaou_debug "<load_tmp_error from=$MIAOU_BASH_ERROR>" |
|
|
|
|
|
if [[ ! -v tmp_error ]]; then |
|
|
mapfile -t tmp_error <"$MIAOU_BASH_ERROR" |
|
|
mapfile -t tmp_error <"$MIAOU_BASH_ERROR" |
|
|
local count=${#tmp_error[@]} |
|
|
local count=${#tmp_error[@]} |
|
|
if [[ $count == 0 ]]; then |
|
|
if [[ $count == 0 ]]; then |
|
|
miaou_debug "<tmp_error empty/>" |
|
|
miaou_debug "<tmp_error empty/>" |
|
|
else |
|
|
else |
|
|
miaou_debug "<tmp_error count=${count}/>" |
|
|
|
|
|
|
|
|
miaou_debug "<tmp_error count=${count}>" |
|
|
|
|
|
local i |
|
|
|
|
|
for i in "${tmp_error[@]}"; do |
|
|
|
|
|
miaou_debug "<tmperr content={$i}/>" |
|
|
|
|
|
done |
|
|
|
|
|
miaou_debug "</tmp_error>" |
|
|
|
|
|
fi |
|
|
|
|
|
else |
|
|
|
|
|
local count=${#tmp_error[@]} |
|
|
|
|
|
miaou_debug "<already_loaded count=$count/>" |
|
|
fi |
|
|
fi |
|
|
|
|
|
miaou_debug '</load_tmp_error>' |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function on_exit { |
|
|
function on_exit { |
|
|
@ -339,12 +353,12 @@ function on_exit { |
|
|
|
|
|
|
|
|
elif [[ -v failure_type && "$failure_type" == 'COMMAND_NOT_FOUND' ]]; then |
|
|
elif [[ -v failure_type && "$failure_type" == 'COMMAND_NOT_FOUND' ]]; then |
|
|
unset 'tmp_error[-1]' 'tmp_error[-1]' |
|
|
unset 'tmp_error[-1]' 'tmp_error[-1]' |
|
|
add_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}" |
|
|
|
|
|
|
|
|
add_miaou_error "${BASH_SOURCE[2]}" "${BASH_LINENO[1]}" "${failure_code}" "${failure_type}" "${failure_payload}" |
|
|
miaou_debug '<command_not_found change_stderr />' |
|
|
miaou_debug '<command_not_found change_stderr />' |
|
|
|
|
|
|
|
|
elif [[ -v failure_type && "$failure_type" == 'FILE_NOT_FOUND' ]]; then |
|
|
elif [[ -v failure_type && "$failure_type" == 'FILE_NOT_FOUND' ]]; then |
|
|
unset 'tmp_error[-1]' 'tmp_error[-1]' |
|
|
unset 'tmp_error[-1]' 'tmp_error[-1]' |
|
|
add_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}" |
|
|
|
|
|
|
|
|
add_miaou_error "${BASH_SOURCE[2]}" "${BASH_LINENO[1]}" "${failure_code}" "${failure_type}" "${failure_payload}" |
|
|
miaou_debug '<file_not_found change_stderr />' |
|
|
miaou_debug '<file_not_found change_stderr />' |
|
|
|
|
|
|
|
|
elif [[ ! -v failure_type ]]; then |
|
|
elif [[ ! -v failure_type ]]; then |
|
|
@ -404,17 +418,42 @@ function on_exit { |
|
|
else |
|
|
else |
|
|
miaou_debug "</on_exit success>" |
|
|
miaou_debug "</on_exit success>" |
|
|
fi |
|
|
fi |
|
|
|
|
|
cleanup |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function build_miaou_bash_error { |
|
|
|
|
|
local directory |
|
|
|
|
|
directory="/run/user/$UID/$(basename "$0")" |
|
|
|
|
|
|
|
|
|
|
|
CHILD_PROCESS=false |
|
|
|
|
|
[[ -f "${directory}/${PPID}.tmp" ]] && CHILD_PROCESS=true |
|
|
|
|
|
|
|
|
|
|
|
mkdir -p "$directory" |
|
|
|
|
|
if is_true $CHILD_PROCESS; then |
|
|
|
|
|
MIAOU_BASH_ERROR="${directory}/${PPID}.$$.tmp" |
|
|
|
|
|
else |
|
|
|
|
|
MIAOU_BASH_ERROR="${directory}/$$.tmp" |
|
|
|
|
|
fi |
|
|
|
|
|
rm -f "$MIAOU_BASH_ERROR" |
|
|
|
|
|
|
|
|
|
|
|
readonly MIAOU_BASH_ERROR CHILD_PROCESS |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function cleanup { |
|
|
|
|
|
miaou_debug '<cleanup/>' |
|
|
|
|
|
# trap - ERR EXIT PIPE RETURN |
|
|
|
|
|
# rm "$MIAOU_BASH_ERROR" |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
## main |
|
|
## main |
|
|
|
|
|
|
|
|
|
|
|
[[ $# -lt 1 ]] && >&2 echo 'ERROR: script expected!' && builtin exit 1 |
|
|
|
|
|
|
|
|
set -euo pipefail |
|
|
set -euo pipefail |
|
|
set -E # HALT on subshell error |
|
|
set -E # HALT on subshell error |
|
|
set -T # DEBUG RETURN |
|
|
set -T # DEBUG RETURN |
|
|
|
|
|
|
|
|
[[ $# -lt 1 ]] && >&2 echo 'ERROR: script expected!' && builtin exit 1 |
|
|
|
|
|
|
|
|
build_miaou_bash_error |
|
|
BASH_ARGV0="$1" && shift # to pretend script runs by itself |
|
|
BASH_ARGV0="$1" && shift # to pretend script runs by itself |
|
|
|
|
|
|
|
|
trap 'on_error $?' ERR |
|
|
trap 'on_error $?' ERR |
|
|
trap 'on_exit $?' EXIT |
|
|
trap 'on_exit $?' EXIT |
|
|
trap 'on_pipe' PIPE |
|
|
trap 'on_pipe' PIPE |
|
|
@ -423,6 +462,10 @@ trap 'on_return' RETURN |
|
|
if [[ -e /proc/$$/fd/3 ]]; then exec 4>&3 3>&-; else exec 4>/dev/tty; fi # swap fd 3 4 when fd 3 sent off |
|
|
if [[ -e /proc/$$/fd/3 ]]; then exec 4>&3 3>&-; else exec 4>/dev/tty; fi # swap fd 3 4 when fd 3 sent off |
|
|
exec 3>/dev/stderr 2>"$MIAOU_BASH_ERROR" |
|
|
exec 3>/dev/stderr 2>"$MIAOU_BASH_ERROR" |
|
|
|
|
|
|
|
|
miaou_debug "<source file=$BASH_ARGV0 pid=${BASHPID}/>" |
|
|
|
|
|
|
|
|
if is_true "$CHILD_PROCESS"; then |
|
|
|
|
|
miaou_debug "<child file=$BASH_ARGV0 pid=${BASHPID} parent=${PPID}>" |
|
|
|
|
|
else |
|
|
|
|
|
miaou_debug "<main file=$BASH_ARGV0 pid=${BASHPID}/>" |
|
|
|
|
|
fi |
|
|
# shellcheck source=/dev/null |
|
|
# shellcheck source=/dev/null |
|
|
source "$BASH_ARGV0" |
|
|
source "$BASH_ARGV0" |