diff --git a/bin/miaou-bash b/bin/miaou-bash index 677a1c4..45dd88b 100755 --- a/bin/miaou-bash +++ b/bin/miaou-bash @@ -1,9 +1,8 @@ -#!/usr/bin/env -S -- bash +#!/usr/bin/env bash #!/usr/bin/env -S -- bash -x # constants -MIAOU_BASH_ERROR=$(mktemp -t "$(basename "$0").XXXXXXXX" --tmpdir="/run/user/$UID") MIAOU_DEBUG=${MIAOU_DEBUG:-false} declare -A ANSI @@ -37,7 +36,7 @@ ANSI[BG_WHITE]=47 ANSI[BG_GRAY]=90 ANSI[BG_MAGENTA]=95 -readonly MIAOU_BASH_ERROR MIAOU_DEBUG ANSI +readonly MIAOU_DEBUG ANSI ## functions @@ -148,8 +147,8 @@ function on_error { failure_payload="${BASH_COMMAND}" print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}" - miaou_debug "" load_tmp_error # cannot print_miaou_error after investigation + miaou_debug "" if [[ ${#tmp_error[@]} -gt 1 ]]; then local last_error regex @@ -244,7 +243,12 @@ function on_pipe { function dump_stderr { miaou_debug "" 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 "" || + miaou_debug "" + echo "$i" + done tty_ansi RESET miaou_debug '' } @@ -303,15 +307,25 @@ function dump_stacktrace { } function load_tmp_error { - [[ -v tmp_error ]] && return 0 - - mapfile -t tmp_error <"$MIAOU_BASH_ERROR" - local count=${#tmp_error[@]} - if [[ $count == 0 ]]; then - miaou_debug "" + miaou_debug "" + if [[ ! -v tmp_error ]]; then + mapfile -t tmp_error <"$MIAOU_BASH_ERROR" + local count=${#tmp_error[@]} + if [[ $count == 0 ]]; then + miaou_debug "" + else + miaou_debug "" + local i + for i in "${tmp_error[@]}"; do + miaou_debug "" + done + miaou_debug "" + fi else - miaou_debug "" + local count=${#tmp_error[@]} + miaou_debug "" fi + miaou_debug '' } function on_exit { @@ -339,12 +353,12 @@ function on_exit { elif [[ -v failure_type && "$failure_type" == 'COMMAND_NOT_FOUND' ]]; then 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 '' elif [[ -v failure_type && "$failure_type" == 'FILE_NOT_FOUND' ]]; then 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 '' elif [[ ! -v failure_type ]]; then @@ -404,17 +418,42 @@ function on_exit { else miaou_debug "" 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 '' + # trap - ERR EXIT PIPE RETURN + # rm "$MIAOU_BASH_ERROR" } ## main +[[ $# -lt 1 ]] && >&2 echo 'ERROR: script expected!' && builtin exit 1 + set -euo pipefail set -E # HALT on subshell error 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 - trap 'on_error $?' ERR trap 'on_exit $?' EXIT 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 exec 3>/dev/stderr 2>"$MIAOU_BASH_ERROR" -miaou_debug "" +if is_true "$CHILD_PROCESS"; then + miaou_debug "" +else + miaou_debug "
" +fi # shellcheck source=/dev/null source "$BASH_ARGV0" diff --git a/test/miaou-bash.test.bash b/test/miaou-bash.test.bash index db510af..2d052af 100755 --- a/test/miaou-bash.test.bash +++ b/test/miaou-bash.test.bash @@ -59,7 +59,7 @@ fail_type exit EXIT fail_type command_not_found COMMAND_NOT_FOUND fail_type source_not_found SOURCE_NOT_FOUND fail_type file_not_found FILE_NOT_FOUND -fail_type subshell_error COMMAND_NOT_FOUND '(hint: prefer source than subshell)' +fail_type child_error CHILD_ERROR '(hint: prefer source than subshell)' failed=${#failures[@]} success=$((test_count - failed)) diff --git a/test/stub/scenario.bash b/test/stub/scenario.bash index 6c42ccf..73953f6 100755 --- a/test/stub/scenario.bash +++ b/test/stub/scenario.bash @@ -90,11 +90,10 @@ function do_file_not_found { ./lib/fake/nope.bash } -function do_subshell_error { - output=$(miaou_debug "---subshell1--$$ $BASHPID $PPID--") - output=$(miaou_debug "---subshell2--$$ $BASHPID $PPID--") - : "$output" +function do_child_error { "$BASEDIR/extra/library.bash" + echo SHOULD NOT APPEAR + . "$BASEDIR/extra/library.bash" } function do_command_error {