almost done with command_not_found
This commit is contained in:
@@ -49,20 +49,23 @@ function is_true {
|
||||
# example: alias toto="bash -c \"[[ \\\$MIAOU_DEBUG == 'true' ]] && echo yes \\\$* || echo nope\""
|
||||
function miaou_debug {
|
||||
if is_true "${MIAOU_DEBUG}"; then
|
||||
local i message="$*" padding=''
|
||||
local compute_hierarchy=true
|
||||
[[ ! -v miaou_debug_hierarchy ]] && miaou_debug_hierarchy=0
|
||||
local i message="$*" padding=''
|
||||
|
||||
regex='^</' # starts with </
|
||||
[[ $miaou_debug_hierarchy -gt 0 ]] &&
|
||||
[[ "${message}" =~ $regex ]] &&
|
||||
((--miaou_debug_hierarchy)) &&
|
||||
miaou_debug_hierarchy=$((miaou_debug_hierarchy - 1)) &&
|
||||
compute_hierarchy=false
|
||||
|
||||
for ((i = 0; i < miaou_debug_hierarchy; i++)); do padding+=' '; done
|
||||
>&4 builtin echo -e "\e[90m <== DEBUG ==> ${padding}\e[33m${message}\e[0m"
|
||||
|
||||
regex='[^/]>$' # does NOT end with />
|
||||
is_true $compute_hierarchy &&
|
||||
[[ "${message}" =~ $regex ]] &&
|
||||
((++miaou_debug_hierarchy)) ||
|
||||
miaou_debug_hierarchy=$((miaou_debug_hierarchy + 1)) ||
|
||||
true
|
||||
fi
|
||||
}
|
||||
@@ -117,7 +120,15 @@ function print_miaou_error {
|
||||
local message
|
||||
message="${source}: line ${line}: miaou_error: ${type} ${code}"
|
||||
[[ -n "$payload" ]] && message+=" payload: ${payload}"
|
||||
[[ -v tmp_error ]] && miaou_debug "tmp_error=${#tmp_error[@]}" && tmp_error+=("$message") || >&2 echo "$message"
|
||||
>&2 echo "$message"
|
||||
}
|
||||
|
||||
function add_miaou_error {
|
||||
local source="$1" line="$2" code="$3" type="$4" payload="${5:-}"
|
||||
local message
|
||||
message="${source}: line ${line}: miaou_error: ${type} ${code}"
|
||||
[[ -n "$payload" ]] && message+=" payload: ${payload}"
|
||||
tmp_error+=("$message")
|
||||
}
|
||||
|
||||
function on_error {
|
||||
@@ -131,11 +142,28 @@ function on_error {
|
||||
if [[ ! -v failure_type ]]; then
|
||||
if [[ ${BASH_COMMAND} == 'false' ]]; then
|
||||
failure_type="FALSE"
|
||||
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}"
|
||||
else
|
||||
failure_type="COMMAND_ERROR"
|
||||
failure_payload="${BASH_COMMAND}"
|
||||
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
|
||||
|
||||
if [[ ${#tmp_error[@]} -gt 1 ]]; then
|
||||
local last_error regex
|
||||
last_error="${tmp_error[-2]}" # the second latest cause previous print_miaou_error above
|
||||
|
||||
regex='^(.*): line ([0-9]+): (.*): command not found$'
|
||||
if [[ $failure_code == 127 && "$last_error" =~ $regex ]]; then
|
||||
failure_type='COMMAND_NOT_FOUND'
|
||||
failure_payload="${BASH_REMATCH[3]}"
|
||||
miaou_debug "<command_not_found payload=${failure_payload}/>"
|
||||
fi
|
||||
fi
|
||||
miaou_debug '</investigate_tmp_error>'
|
||||
fi
|
||||
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}"
|
||||
fi
|
||||
|
||||
error_source=("${BASH_SOURCE[@]}")
|
||||
@@ -153,11 +181,10 @@ function on_error {
|
||||
else
|
||||
miaou_debug "</on_error exit=$failure_code type=${failure_type}>"
|
||||
fi
|
||||
|
||||
builtin exit "$failure_code"
|
||||
else
|
||||
miaou_debug "</on_error pipe=$failure_code sub_pid=$BASHPID pid=$$ command={${BASH_COMMAND}}>"
|
||||
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" 'SUBSHELL_ERROR' "${BASH_COMMAND}"
|
||||
miaou_debug "</on_error pipe=$failure_code sub_pid=$BASHPID pid=$$ command={${BASH_COMMAND}}>"
|
||||
kill -PIPE $$
|
||||
fi
|
||||
}
|
||||
@@ -174,7 +201,7 @@ function on_pipe {
|
||||
unset 'error_source[-1]' 'error_lineno[-1]' 'error_funcname[-1]'
|
||||
unset 'error_source[-1]' 'error_lineno[-1]' 'error_funcname[-1]'
|
||||
|
||||
miaou_debug '<load_tmp_error/>' && mapfile -t tmp_error <"$MIAOU_BASH_ERROR"
|
||||
load_tmp_error
|
||||
|
||||
last_error="${tmp_error[-1]}"
|
||||
regex='^(.*): line ([0-9]+): miaou_error: SUBSHELL_ERROR ([0-9]+) payload: (.*)$'
|
||||
@@ -247,15 +274,24 @@ function dump_stacktrace {
|
||||
miaou_debug '</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 "<tmp_error empty/>"
|
||||
else
|
||||
miaou_debug "<tmp_error count=${count}/>"
|
||||
fi
|
||||
}
|
||||
|
||||
function on_exit {
|
||||
trap - RETURN
|
||||
local code="${1:-0}" last_error regex
|
||||
|
||||
miaou_debug "<on_exit code=$code>"
|
||||
|
||||
[[ ! -v tmp_error ]] &&
|
||||
miaou_debug '<load_tmp_error/>' &&
|
||||
mapfile -t tmp_error <"$MIAOU_BASH_ERROR"
|
||||
load_tmp_error
|
||||
|
||||
if [[ -v failure_type && "$failure_type" == 'RETURN' ]]; then
|
||||
last_error="${tmp_error[-1]}"
|
||||
@@ -272,7 +308,7 @@ function on_exit {
|
||||
miaou_debug "<return type=unexpected/>"
|
||||
fi
|
||||
|
||||
else
|
||||
elif [[ ! -v failure_type ]]; then
|
||||
if [[ $code -gt 0 && ${#tmp_error[@]} -gt 0 ]]; then
|
||||
last_error="${tmp_error[-1]}"
|
||||
miaou_debug "<investigate_tmp_error last={$last_error}>"
|
||||
@@ -298,9 +334,10 @@ function on_exit {
|
||||
failure_type='UNBOUND_VARIABLE'
|
||||
failure_payload=$payload
|
||||
|
||||
print_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}"
|
||||
unset 'tmp_error[-2]' # replace previous last_error
|
||||
add_miaou_error "${BASH_SOURCE[1]}" "${BASH_LINENO[0]}" "${failure_code}" "${failure_type}" "${failure_payload}"
|
||||
miaou_debug "<unbound_variable source=${source} line=${line} payload={${failure_payload}}/>"
|
||||
else
|
||||
failure_type='UNKNOWN ERROR'
|
||||
fi
|
||||
miaou_debug "</investigate_tmp_error>"
|
||||
fi
|
||||
@@ -332,6 +369,8 @@ trap 'on_exit $?' EXIT
|
||||
trap 'on_pipe' PIPE
|
||||
trap 'on_return' RETURN
|
||||
|
||||
declare -a tmp_error # to prevent loading multiple times
|
||||
|
||||
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"
|
||||
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ function fail_type {
|
||||
mapfile -t stderr <<<"$(./poc ./test/stub/scenario.bash "$1" 2>&1 >/dev/null 3>/dev/null)"
|
||||
last_error="${stderr[-1]}"
|
||||
|
||||
regex="^(.*): line ([0-9]+): miaou_error: $2 ([0-9]+) payload: (.*)\$"
|
||||
regex="^(.*): line ([0-9]+): miaou_error: $2 ([0-9]+)"
|
||||
[[ "${last_error}" =~ $regex ]] && success=true
|
||||
|
||||
# if [[ $success == true && -n "${hint_message}" ]]; then
|
||||
@@ -60,13 +60,13 @@ fail_type command_not_found COMMAND_NOT_FOUND
|
||||
# fail_type subshell_error COMMAND_NOT_FOUND '(hint: prefer source than subshell)'
|
||||
# fail_type command_error COMMAND_ERROR
|
||||
|
||||
failed=$((test_count - ${#failures[@]}))
|
||||
failed=${#failures[@]}
|
||||
success=$((test_count - failed))
|
||||
|
||||
echo
|
||||
if [[ $failed -gt 0 ]]; then
|
||||
ratio=$((100 * success / test_count))
|
||||
echo "${ratio}% passed, $success succeeded, $failed failed!"
|
||||
echo "${ratio}% passed, ${test_count} tests, ${failed} failed!"
|
||||
echo failures:
|
||||
for failure in "${failures[@]}"; do
|
||||
echo -e "\t- $failure"
|
||||
|
||||
Reference in New Issue
Block a user