1
#!/bin/sh
2
#shellcheck disable=SC2004
3

4 0
set -eu
5

6
# shellcheck source=lib/libexec/runner.sh
7 0
. "${SHELLSPEC_LIB:-./lib}/libexec/runner.sh"
8

9
start_profiler() {
10 0
  [ "$SHELLSPEC_PROFILER" ] || return 0
11 0
  $SHELLSPEC_SHELL "$SHELLSPEC_LIBEXEC/shellspec-profiler.sh" &
12 0
} 2>/dev/null
13

14
stop_profiler() {
15 0
  [ "$SHELLSPEC_PROFILER" ] || return 0
16 0
  if [ -e "$SHELLSPEC_PROFILER_SIGNAL" ]; then
17 0
    rm "$SHELLSPEC_PROFILER_SIGNAL"
18
  fi
19
}
20

21
cleanup() {
22 0
  "$SHELLSPEC_TRAP" '' INT
23 0
  set -- "$SHELLSPEC_TMPBASE" && SHELLSPEC_TMPBASE=''
24 0
  [ "$SHELLSPEC_KEEP_TMPDIR" ] && return 0
25 0
  [ "$1" ] || return 0
26 0
  { rmtempdir "$1" & } 2>/dev/null
27
}
28

29
interrupt() {
30 0
  "$SHELLSPEC_TRAP" '' TERM # Workaround for posh: Prevent display 'Terminated'.
31 0
  stop_profiler
32 0
  reporter_pid=''
33 0
  read_pid_file reporter_pid "$SHELLSPEC_REPORTER_PID" 0
34 0
  [ "$reporter_pid" ] && sleep_wait signal 0 "$reporter_pid" 2>/dev/null
35 0
  signal TERM 0 2>/dev/null &&:
36 0
  cleanup
37 0
  exit 130
38
}
39

40
executor() {
41 0
  start_profiler
42 0
  executor="$SHELLSPEC_LIBEXEC/shellspec-executor.sh"
43
  # shellcheck disable=SC2086
44 0
  $SHELLSPEC_TIME $SHELLSPEC_SHELL "$executor" "$@" 3>&2 2>"$SHELLSPEC_TIME_LOG"
45 0
  eval "stop_profiler; return $?"
46
}
47

48
reporter() {
49 0
  $SHELLSPEC_SHELL "$SHELLSPEC_LIBEXEC/shellspec-reporter.sh" "$@"
50
}
51

52
error_handler() {
53 0
  error_count=0
54

55 0
  while IFS= read -r line; do
56 0
    error_count=$(($error_count + 1))
57 0
    error "$line"
58
  done
59

60 0
  [ "$error_count" -eq 0 ] || exit "$SHELLSPEC_ERROR_EXIT_CODE"
61
}
62

63 0
"$SHELLSPEC_TRAP" 'interrupt' INT
64 0
"$SHELLSPEC_TRAP" ':' TERM
65 0
trap 'cleanup' EXIT
66

67 0
if [ "$SHELLSPEC_REPAIR" ]; then
68 0
  if [ -e "$SHELLSPEC_QUICK_FILE" ]; then
69 0
    SHELLSPEC_QUICK=1
70
  else
71 0
    warn "Quick Mode is disabled. Run with --quick option first."
72 0
    exit
73
  fi
74
fi
75

76 0
if [ "$SHELLSPEC_QUICK" ]; then
77 0
  if ! [ -e "$SHELLSPEC_QUICK_FILE" ]; then
78 0
    if ( : > "$SHELLSPEC_QUICK_FILE" ) 2>/dev/null; then
79 0
      warn "Quick Mode is automatically enabled." \
80
        "If you want disable it, delete '$SHELLSPEC_QUICK_FILE'."
81
    else
82 0
      warn "Failed to enable Quick Mode " \
83
        "due to failed to create '$SHELLSPEC_QUICK_FILE'."
84
    fi
85
  fi
86

87 0
  if [ -e "$SHELLSPEC_QUICK_FILE" ]; then
88 0
    count=$# line='' last_line=''
89 0
    while read_quickfile line state "$SHELLSPEC_REPAIR"; do
90 0
      [ "$last_line" = "$line" ] && continue || last_line=$line
91 0
      match_quick_data "$line" "$@" && set -- "$@" "$line"
92 0
    done < "$SHELLSPEC_QUICK_FILE"
93 0
    if [ "$#" -gt "$count" ] && shift "$count"; then
94 0
      warn "Run only not-passed examples the last time they ran."
95 0
      export SHELLSPEC_PATTERN="*"
96 0
    elif [ "$SHELLSPEC_REPAIR" ]; then
97 0
      warn "No failed examples were found."
98 0
      exit
99
    fi
100
  fi
101
fi
102

103 0
quick_mode='' info='' info_extra=$SHELLSPEC_INFO
104 0
[ -e "$SHELLSPEC_QUICK_FILE" ] && quick_mode="<quick mode> "
105 0
[ "$SHELLSPEC_QUICK" ] && info="${info}--quick "
106 0
[ "$SHELLSPEC_REPAIR" ] && info="${info}--repair "
107 0
if [ "$SHELLSPEC_FAIL_FAST_COUNT" ]; then
108 0
  info="${info}--fail-fast $SHELLSPEC_FAIL_FAST_COUNT " && info="${info% 1 } "
109
fi
110 0
[ "$SHELLSPEC_WORKERS" -gt 0 ] && info="${info}--jobs $SHELLSPEC_WORKERS "
111 0
[ "$SHELLSPEC_DRYRUN" ] && info="${info}--dry-run "
112 0
[ "$SHELLSPEC_XTRACE" ] && info="${info}--trace${SHELLSPEC_XTRACE_ONLY:+-only} "
113 0
[ "$SHELLSPEC_RANDOM" ] && info="${info}--random $SHELLSPEC_RANDOM "
114 0
[ "$info" ] && info="{${info% }}"
115 0
SHELLSPEC_INFO="${quick_mode}${info}${info_extra:+ }${info_extra}"
116

117 0
mktempdir "$SHELLSPEC_TMPBASE"
118

119 0
if [ "$SHELLSPEC_KEEP_TMPDIR" ]; then
120 0
  warn "Keeping temporary directory. "
121 0
  warn "Manually delete: rm -rf \"$SHELLSPEC_TMPBASE\""
122
fi
123

124 0
if [ "$SHELLSPEC_BANNER" ] && [ -s "$SHELLSPEC_BANNER_FILE" ]; then
125 0
  cat "$SHELLSPEC_BANNER_FILE"
126
fi
127

128 0
if [ "${SHELLSPEC_RANDOM:-}" ]; then
129 0
  export SHELLSPEC_LIST=$SHELLSPEC_RANDOM
130 0
  exec="$SHELLSPEC_LIBEXEC/shellspec-list.sh"
131 0
  eval "$SHELLSPEC_SHELL" "\"$exec\"" ${1+'"$@"'} >"$SHELLSPEC_INFILE"
132 0
  set -- -
133
fi
134

135
# I want to process with non-blocking output
136
# and the stdout of runner streams to the reporter
137
# and capture stderr both of the runner and the reporter
138
# and the stderr streams to error hander
139
# and also handle both exit status. As a result of
140 0
( ( ( ( set -e; { executor "$@"; } 9>&1 >&8; echo $? >&5 ) \
141
  | reporter "$@" >&3; echo $? >&5 ) 2>&1 \
142
  | error_handler >&4; echo $? >&5 ) 5>&1 \
143
  | (
144 0
      read -r xs1; read -r xs2; read -r xs3
145 0
      xs='' error='' msg="Aborted with status code"
146 0
      for i in "$xs1" "$xs2" "$xs3"; do
147 0
        case $i in
148 0
          0) continue ;;
149 0
          "$SHELLSPEC_FAILURE_EXIT_CODE") [ "$xs" ] || xs=$i ;;
150 0
          "$SHELLSPEC_ERROR_EXIT_CODE") xs=$i error=1 && break ;;
151 0
          *) [ "${xs#$SHELLSPEC_FAILURE_EXIT_CODE}" ] || xs=$i; error=1
152
        esac
153
      done
154 0
      if [ "$error" ]; then
155 0
        error "$msg [executor: $xs1] [reporter: $xs2] [error handler: $xs3]"
156
      fi
157 0
      set_exit_status "${xs:-0}"
158
    )
159 0
) 3>&1 4>&2 8>&1 &&:
160 0
exit_status=$?
161

162 0
case $exit_status in
163 0
  0) ;; # Running specs exit with successfully.
164 0
  "$SHELLSPEC_FAILURE_EXIT_CODE") ;; # Running specs exit with failure.
165 0
  *) error "Fatal error occurred, terminated with exit status $exit_status."
166
esac
167

168 0
exit "$exit_status"

Read our documentation on viewing source code .

Loading