diff --git a/bin/miaou-bash b/bin/miaou-bash index 02eb3a3..0412aaa 100755 --- a/bin/miaou-bash +++ b/bin/miaou-bash @@ -4,6 +4,7 @@ # constants MIAOU_DEBUG=${MIAOU_DEBUG:-false} +MIAOU_ERROR_REGEX='^(.*): line ([0-9]+): miaou_error:' declare -A ANSI ANSI[RESET]=0 @@ -36,7 +37,7 @@ ANSI[BG_WHITE]=47 ANSI[BG_GRAY]=90 ANSI[BG_MAGENTA]=95 -readonly MIAOU_DEBUG ANSI +readonly MIAOU_DEBUG MIAOU_ERROR_REGEX ANSI ## functions @@ -139,8 +140,6 @@ function on_error { trap - RETURN failure_code="${1:-200}" - # >&4 printf '\r' # TODO: force carriage return explicitly, is it really useful? - miaou_debug "" if [[ $$ == "$BASHPID" ]]; then @@ -310,7 +309,22 @@ function on_pipe { } function dump_stderr { - miaou_debug "" + local tmp_error_count=${#tmp_error[@]} + miaou_debug "" + if [[ -v MAIN_FD_MIAOU && $tmp_error_count -gt 0 && "$MAIN_FD_STDERR" == false ]]; then + miaou_debug "" + local last_error="${tmp_error[-1]}" + if [[ "$last_error" =~ $MIAOU_ERROR_REGEX ]]; then + tmp_error_count=$((tmp_error_count - 1)) + miaou_debug "" + unset 'tmp_error[-1]' + if [[ $tmp_error_count == 0 ]]; then + # TODO: grab last_stdout and test no carriage_return, cf: ../test/stub/tee_last_line.bash + miaou_debug "" + printf "\r" + fi + fi + fi tty_ansi FG_LIGHTBLUE for i in "${tmp_error[@]}"; do is_true "$CHILD_PROCESS" && miaou_debug "" @@ -431,13 +445,12 @@ function load_tmp_error { miaou_debug "" else miaou_debug "" - local i miaou_error_regex last_miaou_error_index=-1 content + local i last_miaou_error_index=-1 content local multiple_errors=() - miaou_error_regex='^(.*): line ([0-9]+): miaou_error:' for i in "${!tmp_error[@]}"; do content="${tmp_error[i]}" # miaou_debug "" - if [[ "$content" =~ $miaou_error_regex ]]; then + if [[ "$content" =~ $MIAOU_ERROR_REGEX ]]; then if [[ $last_miaou_error_index -ge 0 ]]; then multiple_errors+=("$last_miaou_error_index") fi @@ -623,7 +636,13 @@ if is_true "$CHILD_PROCESS"; then miaou_debug "" else # the MAIN Process - [[ -e /proc/$$/fd/3 ]] && exec 4>&3 3>&- || exec 4>/dev/tty # swap fd 3 4 when fd 3 sent off + if [[ -e /proc/$$/fd/3 ]]; then + exec 4>&3 3>&- # swap fd 3 4 when fd 3 sent off + else + MAIN_FD_MIAOU=true + [[ -t 2 ]] && MAIN_FD_STDERR=false || MAIN_FD_STDERR=true + exec 4>/dev/tty + fi exec 3>/dev/stderr 2>"$MIAOU_BASH_ERROR" miaou_debug "
" fi diff --git a/test/miaou-bash.test.bash b/test/miaou-bash.test.bash index 3425c53..0c62c54 100755 --- a/test/miaou-bash.test.bash +++ b/test/miaou-bash.test.bash @@ -41,6 +41,7 @@ function assert_grep { failures+=("$cmd $safe_args") return 1 } + function fail_type { ((test_count++)) local success regex hint_message @@ -68,7 +69,24 @@ function fail_type { failures+=("$cmd") return 1 } +function fail_stderr_count { + ((test_count++)) + local regex count="$2" + cmd="./test/stub/scenario.bash $1" + # mapfile -t stderr <<<"$(miaou-bash ./test/stub/scenario.bash "$1" 2>&1 >/dev/null 3>/dev/null)" + if ! $cmd >/dev/null 2>_stderr 3>/dev/null; then + mapfile -t stderr <_stderr + if [[ "${#stderr[@]}" == "$count" ]]; then + echo -n . + return + fi + fi + + echo -n F + failures+=("$cmd 2>_stderr") + return 1 +} # main set -uo pipefail @@ -95,6 +113,9 @@ time { fail_type source_not_found SOURCE_NOT_FOUND fail_type file_not_found FILE_NOT_FOUND fail_type child_error CHILD_ERROR 'prefer source than child process' + + fail_stderr_count unbound_variable 1 + fail_stderr_count child_error 4 } failed=${#failures[@]} success=$((test_count - failed)) diff --git a/test/stub/extra/onemore.bash b/test/stub/extra/onemore.bash index 4e3e042..5f6ee74 100755 --- a/test/stub/extra/onemore.bash +++ b/test/stub/extra/onemore.bash @@ -1,5 +1,4 @@ #!/usr/bin/env miaou-bash -#!/usr/bin/env bash function onemore { echo onemore loaded diff --git a/test/stub/scenario.bash b/test/stub/scenario.bash index ade21ee..e76ac3c 100755 --- a/test/stub/scenario.bash +++ b/test/stub/scenario.bash @@ -71,7 +71,7 @@ function do_false { function do_success { echo "count args: $#" - [[ true==true ]] && echo true + [[ true != 'false' ]] && echo true ! false && echo unfalse return } @@ -89,6 +89,8 @@ function do_success_with_args { function do_unbound_variable { a=5 echo -n "content: " + # >&2 echo err1 + # echo "content: " echo -n "a=${a} b=${b}" }