Skip to content

Commit

Permalink
Merge pull request #79 from shellspec/xtrace
Browse files Browse the repository at this point in the history
Implement xtrace feature
  • Loading branch information
ko1nksm committed Jun 18, 2020
2 parents 2e1e828 + de4d997 commit 7917eb2
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 27 deletions.
15 changes: 8 additions & 7 deletions lib/core/dsl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ shellspec_example() {
done
fi

# shellcheck disable=SC2034
SHELLSPEC_STDIN_FILE="$SHELLSPEC_STDIO_FILE_BASE.stdin"
SHELLSPEC_STDOUT_FILE="$SHELLSPEC_STDIO_FILE_BASE.stdout"
SHELLSPEC_STDERR_FILE="$SHELLSPEC_STDIO_FILE_BASE.stderr"
SHELLSPEC_XTRACE_FILE="$SHELLSPEC_STDIO_FILE_BASE.trace"

[ "$SHELLSPEC_ENABLED" ] || return 0
[ "$SHELLSPEC_FILTER" ] || return 0

Expand All @@ -150,13 +156,6 @@ shellspec_example() {
return 0
fi

# shellcheck disable=SC2034
{
SHELLSPEC_STDIN_FILE="$SHELLSPEC_STDIO_FILE_BASE.stdin"
SHELLSPEC_STDOUT_FILE="$SHELLSPEC_STDIO_FILE_BASE.stdout"
SHELLSPEC_STDERR_FILE="$SHELLSPEC_STDIO_FILE_BASE.stderr"
}

shellspec_profile_start
case $- in
*e*) eval "set -- -e ${1+\"\$@\"}" ;;
Expand Down Expand Up @@ -318,6 +317,7 @@ shellspec_the() {
eval shellspec_join SHELLSPEC_EXPECTATION '" "' The ${1+'"$@"'}
shellspec_off NOT_IMPLEMENTED
shellspec_on EXPECTATION
[ "$SHELLSPEC_XTRACE_ONLY" ] && return 0

if [ $# -eq 0 ]; then
shellspec_output SYNTAX_ERROR_EXPECTATION "Missing expectation"
Expand All @@ -332,6 +332,7 @@ shellspec_assert() {
eval shellspec_join SHELLSPEC_EXPECTATION '" "' Assert ${1+'"$@"'}
shellspec_off NOT_IMPLEMENTED
shellspec_on EXPECTATION
[ "$SHELLSPEC_XTRACE_ONLY" ] && return 0

if [ $# -eq 0 ]; then
shellspec_output SYNTAX_ERROR_EXPECTATION "Missing assertion"
Expand Down
80 changes: 68 additions & 12 deletions lib/core/evaluation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,40 @@ shellspec_syntax 'shellspec_evaluation_run'

shellspec_proxy 'shellspec_evaluation' 'shellspec_syntax_dispatch evaluation'

shellspec_evaluation_from_tty() { "$@" < "$SHELLSPEC_STDIN_DEV"; }
shellspec_evaluation_from_stdin() { "$@" < "$SHELLSPEC_STDIN_FILE"; }
shellspec_evaluation_to_stdout() { "$@" > "$SHELLSPEC_STDOUT_FILE"; }
shellspec_evaluation_to_stderr() { "$@" 2> "$SHELLSPEC_STDERR_FILE"; }
shellspec_evaluation_from_tty() {
"$@" < "$SHELLSPEC_STDIN_DEV"
}
shellspec_evaluation_from_stdin() {
"$@" < "$SHELLSPEC_STDIN_FILE"
}
shellspec_evaluation_to_null() {
"$@" > /dev/null
}
shellspec_evaluation_to_stdout() {
"$@" > "$SHELLSPEC_STDOUT_FILE"
}
shellspec_evaluation_to_stderr() {
"$@" 2> "$SHELLSPEC_STDERR_FILE"
}
shellspec_evaluation_to_xtrace() {
# shellcheck disable=SC2153
set -- "$SHELLSPEC_XTRACEFD" SHELLSPEC_XTRACE_FILE "$@"
eval "shellspec_evaluation_to_xtrace_() { \"\$@\" $1> \"\$$2\"; }"
shift 2
shellspec_evaluation_to_xtrace_ "$@"
}

shellspec_evaluation_execute() {
set -- shellspec_evaluation_to_stdout "$@"
set -- shellspec_evaluation_to_stderr "$@"
if [ "$SHELLSPEC_XTRACE" ]; then
set -- shellspec_evaluation_to_xtrace "$@"
if [ "$SHELLSPEC_XTRACE_ONLY" ]; then
set -- shellspec_evaluation_to_null "$@"
else
set -- shellspec_evaluation_to_stdout shellspec_evaluation_to_stderr "$@"
fi
else
set -- shellspec_evaluation_to_stdout shellspec_evaluation_to_stderr "$@"
fi
if [ "$SHELLSPEC_DATA" ]; then
set -- shellspec_evaluation_from_stdin "$@"
else
Expand Down Expand Up @@ -119,8 +145,16 @@ shellspec_shebang_arguments() {

shellspec_evaluation_call_function() {
shellspec_coverage_start
"$@"
set -- "$?"
if [ ! "$SHELLSPEC_XTRACE" ]; then
"$@"
set -- $?
else
SHELLSPEC_XTRACE=''
eval "$SHELLSPEC_XTRACE_ON"
"$@"
eval "$SHELLSPEC_XTRACE_OFF" -- $?
SHELLSPEC_XTRACE=1
fi
shellspec_coverage_stop
return "$1"
}
Expand All @@ -143,7 +177,22 @@ shellspec_evaluation_run_script() {
[ "$1" ] || shift
fi
( shellspec_coverage_env
eval "$SHELLSPEC_SHELL $SHELLSPEC_COVERAGE_SHELL_OPTIONS \"\$@\""
if [ "$SHELLSPEC_XTRACE" ]; then
# shellcheck disable=SC2030
SHELLSPEC_XTRACE=''
if [ "$SHELLSPEC_XTRACEFD_VAR" ]; then
export PS4
export SHELLSPEC_PS4="${PS4:-}"
export "$SHELLSPEC_XTRACEFD_VAR"="$SHELLSPEC_XTRACEFD"
fi
eval "$SHELLSPEC_SHELL $SHELLSPEC_COVERAGE_SHELL_OPTIONS -x \"\$@\""
set -- $?
SHELLSPEC_XTRACE=1
else
eval "$SHELLSPEC_SHELL $SHELLSPEC_COVERAGE_SHELL_OPTIONS \"\$@\""
set -- $?
fi
exit "$1"
)
fi
}
Expand All @@ -169,8 +218,14 @@ shellspec_evaluation_run_source() {
}
__() { shellspec_interceptor "$@"; }
shellspec_coverage_start
eval "shift; . \"$1\""
set -- "$?"
# shellcheck disable=SC2031
if [ "$SHELLSPEC_XTRACE" ]; then
SHELLSPEC_XTRACE=''
eval "shift; $SHELLSPEC_XTRACE_ON; . \"$1\"; $SHELLSPEC_XTRACE_OFF -- \$?"
SHELLSPEC_XTRACE=1
else
eval "shift; . \"$1\"; set -- \$?"
fi
shellspec_coverage_stop
return "$1"
}
Expand All @@ -191,7 +246,8 @@ shellspec_interceptor() {
}

shellspec_evaluation_cleanup() {
SHELLSPEC_STATUS=$1
SHELLSPEC_STATUS=$1 SHELLSPEC_STDOUT='' SHELLSPEC_STDERR=''
[ "$SHELLSPEC_XTRACE" ] && [ "$SHELLSPEC_XTRACEFD" -eq 2 ] && return 0
shellspec_readfile SHELLSPEC_STDOUT "$SHELLSPEC_STDOUT_FILE"
shellspec_readfile SHELLSPEC_STDERR "$SHELLSPEC_STDERR_FILE"
shellspec_toggle UNHANDLED_STATUS [ "$SHELLSPEC_STATUS" -ne 0 ]
Expand Down
3 changes: 2 additions & 1 deletion lib/core/output.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ shellspec_output_statement() {
}

shellspec_output_result() {
eval shellspec_output_raw type:result ${1:+'"$@"'}
[ "$SHELLSPEC_XTRACE" ] && set -- "$@" "trace:$SHELLSPEC_XTRACE_FILE"
shellspec_output_raw type:result "$@"
}

shellspec_output_if() {
Expand Down
3 changes: 2 additions & 1 deletion lib/general.sh
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,8 @@ shellspec_is_empty_directory() {
for found in * .*; do
case $found in (.|..) continue; esac
[ -e "$found" ] && return 1
done ||:
done &&:
return 0
)
}

Expand Down
9 changes: 9 additions & 0 deletions lib/libexec/reporter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,12 @@ filter_quick_file() {
done
putsn "$quick_data"
}

output_trace() {
# shellcheck disable=SC2154
putsn "${LF}[${field_specfile}:${field_lineno}] $field_evaluation"
while IFS= read -r output_trace; do
case $output_trace in (*@SHELLSPEC_XTRACE_OFF@*) break; esac
putsn "$output_trace"
done
}
13 changes: 10 additions & 3 deletions lib/libexec/reporter/summary_formatter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
create_buffers summary

summary_end() {
_summary='' _summary_error='' _color=''
_summary='' _summary_error='' _summary_warning='' _color=''

pluralize _summary "${example_count:-0} example"
pluralize _summary ", " "${failed_count:-0} failure"
Expand All @@ -31,9 +31,16 @@ summary_end() {
pluralize _summary_error ", " "$not_enough_examples example" \
" did not run (unexpected exit?)"

[ "$warned_count" ] && _color=$YELLOW || _color=$GREEN
if [ "$SHELLSPEC_DRYRUN" ]; then
_summary_warning="$_summary_warning [dry-run mode]"
elif [ "$SHELLSPEC_XTRACE_ONLY" ]; then
_summary_warning="$_summary_warning [trace-only mode]"
fi

[ "${warned_count}${_summary_warning}" ] && _color=$YELLOW || _color=$GREEN
[ "${failed_count}${fixed_count}${_summary_error}" ] && _color=$RED
summary '+=' "${_color}${_summary}${_summary_error}${RESET}${LF}${LF}"
_summary="${_summary}${_summary_error}${_summary_warning}"
summary '+=' "${_color}${_summary}${RESET}${LF}${LF}"
}

summary_output() {
Expand Down
9 changes: 8 additions & 1 deletion libexec/shellspec-inspection.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,14 @@ fi
elif [ "$({ ZSH_XTRACEFD=3; set -x; :; } 2>/dev/null 3>&1)" ]; then
echo "SHELLSPEC_XTRACEFD_VAR=ZSH_XTRACEFD"
fi
} 2>/dev/null

xtrace() { echo XTRACE > /dev/null; }
xtrace=$({ set -x; xtrace; } 2>&1)
case $xtrace in (*XTRACE*) ;; (*)
type typeset >/dev/null 2>&1 && xtrace=2 || xtrace=1
echo "SHELLSPEC_DEFECT_XTRACE=$xtrace"
esac
} 2>/dev/null &&:

# arithmetic expansion is also required
exit $((0))
5 changes: 4 additions & 1 deletion libexec/shellspec-reporter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ current_example_index=0 example_index=''
last_example_no='' last_skip_id='' not_enough_examples=''
field_id='' field_type='' field_tag='' field_example_no='' field_focused=''
field_temporary='' field_skipid='' field_pending='' field_message=''
field_quick=''
field_quick='' field_trace='' field_lineno='' field_specfile=''

# shellcheck disable=SC2034
specfile_count=0 expected_example_count=0 example_count=0 \
Expand Down Expand Up @@ -157,6 +157,9 @@ each_line() {

color_schema
output_formatters each "$@"
if [ "$field_type" = "result" ] && [ -e "$field_trace" ]; then
output_trace < "$field_trace" >> "$SHELLSPEC_LOGFILE"
fi
}
parse_lines

Expand Down
1 change: 1 addition & 0 deletions libexec/shellspec-runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ if [ "$SHELLSPEC_FAIL_FAST_COUNT" ]; then
fi
[ "$SHELLSPEC_WORKERS" -gt 0 ] && info="${info}--jobs $SHELLSPEC_WORKERS "
[ "$SHELLSPEC_DRYRUN" ] && info="${info}--dry-run "
[ "$SHELLSPEC_XTRACE" ] && info="${info}--trace${SHELLSPEC_XTRACE_ONLY:+-only} "
[ "$SHELLSPEC_RANDOM" ] && info="${info}--random $SHELLSPEC_RANDOM "
[ "$info" ] && info="{${info% }}"
SHELLSPEC_INFO="${quick_mode}${info}${info_extra:+ }${info_extra}"
Expand Down
37 changes: 36 additions & 1 deletion shellspec
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export SHELLSPEC_DEFECT_ERREXIT=''
export SHELLSPEC_DEFECT_ZSHEXIT=''
export SHELLSPEC_DEFECT_SUBSHELL=''
export SHELLSPEC_DEFECT_SETE=''
export SHELLSPEC_DEFECT_XTRACE=''
export SHELLSPEC_SHEBANG_MULTIARG=''
export SHELLSPEC_BUSYBOX_W32=''
export SHELLSPEC_SHOPT_AVAILABLE=''
Expand All @@ -102,7 +103,11 @@ export SHELLSPEC_REPAIR=''
export SHELLSPEC_INFO=''
export SHELLSPEC_TTY=''
export SHELLSPEC_DEV_TTY="/dev/null"
export SHELLSPEC_XTRACEFD=3
export SHELLSPEC_XTRACE=''
export SHELLSPEC_XTRACE_ONLY=''
export SHELLSPEC_XTRACE_ON=''
export SHELLSPEC_XTRACE_OFF=''
export SHELLSPEC_XTRACEFD=2
export SHELLSPEC_XTRACEFD_VAR=''

#shellcheck disable=SC2039
Expand Down Expand Up @@ -206,6 +211,9 @@ Usage: shellspec [options...] [files or directories...]
[none] run in the defined order [default]
[specfiles] randomize the order of specfiles
[examples] randomize the order of examples (slow)
-x, --xtrace Run examples with trace mode [default: disabled]
Fall back to trace-only mode if BASH_XTRACEFD is not supported.
-X, --xtrace-only Run examples with trace-only mode [default: disabled]
--dry-run Print the formatter output without running any examples [default: disabled]
**** Output ****
Expand Down Expand Up @@ -428,6 +436,8 @@ parse_options() {
esac
SHELLSPEC_MODE=list SHELLSPEC_LIST=$2
shift ;;
-x | --xtrace) SHELLSPEC_XTRACE=1 ;;
-X | --xtrace-only) SHELLSPEC_XTRACE=1 SHELLSPEC_XTRACE_ONLY=1 ;;
-h | --help) usage "$1" && exit 0;;
-v | --version) echo "$SHELLSPEC_VERSION" && exit 0 ;;
-*) invalid "Unknown option '$1'." ;;
Expand Down Expand Up @@ -504,6 +514,31 @@ fi
[ "$SHELLSPEC_TTY" ] && SHELLSPEC_DEV_TTY=/dev/tty
}

if [ "$SHELLSPEC_XTRACE" ]; then
if [ ! "$SHELLSPEC_XTRACE_ONLY" ]; then
[ "$SHELLSPEC_XTRACEFD_VAR" ] && SHELLSPEC_XTRACEFD=9
if [ "$SHELLSPEC_XTRACEFD" = "2" ] && SHELLSPEC_XTRACE_ONLY=1; then
warn "Fall back to trace-only mode. All expectations will be skipped."
fi
fi

if [ "$SHELLSPEC_DEFECT_XTRACE" ]; then
warn "If xtrace doesn't work, " \
'execute `set -x` manually inside the function.'
fi
fi

if [ "$SHELLSPEC_DEFECT_XTRACE" = "2" ]; then
SHELLSPEC_XTRACE_ON='typeset -ft $(typeset +f); '
SHELLSPEC_XTRACE_OFF='typeset +ft $(typeset +f); '
else
if [ "$SHELLSPEC_XTRACEFD_VAR" ]; then
SHELLSPEC_XTRACE_ON="$SHELLSPEC_XTRACEFD_VAR=\$SHELLSPEC_XTRACEFD; "
fi
fi
SHELLSPEC_XTRACE_ON="${SHELLSPEC_XTRACE_ON}set -x"
SHELLSPEC_XTRACE_OFF=": @SHELLSPEC_XTRACE_OFF@; ${SHELLSPEC_XTRACE_OFF}set +x"

if command_path "time" || [ "$SHELLSPEC_BUSYBOX_W32" ]; then
SHELLSPEC_TIME="time -p"
else
Expand Down

0 comments on commit 7917eb2

Please sign in to comment.