-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspinner.sh
More file actions
executable file
·87 lines (75 loc) · 2.3 KB
/
Copy pathspinner.sh
File metadata and controls
executable file
·87 lines (75 loc) · 2.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/env bash
#
# Spinner for shell scripts.
#
# <background job> &
# spinner $! "message"
#
# Returns the background job's exit code, so it can be tested by the caller.
#
# Environment:
# SPINNER_DELAY seconds between spinner frames (default 0.1)
spinner() {
local pid=$1 # PID of the background job
local message="$2" # message to display
local delay="${SPINNER_DELAY:-0.1}"
local spin='|/-\'
local i=0
local cr="" clear_eol=""
# Overwriting the line in place only works on a terminal. Piped to a file or
# a CI log, every frame would be appended instead, burying the real output in
# hundreds of spinner characters. There we stay quiet and just report the
# result, which also saves a `sleep` fork per frame.
if [ -t 1 ]; then
cr=$'\r'
clear_eol=$'\033[K'
while kill -0 "$pid" 2>/dev/null; do
# The offset must be wrapped in $(( )). Written bare as ${spin:i++%...},
# zsh reads the `:i` as a history modifier and dies with
# "unrecognized modifier `i'"; this form works in both shells.
printf "%s[%c] %s%s" \
"$cr" "${spin:$((i++ % ${#spin})):1}" "$message" "$clear_eol"
sleep "$delay"
done
fi
wait "$pid"
local exit_code=$?
if [ "$exit_code" -eq 0 ]; then
printf "%s[✔] %s%s\n" "$cr" "$message" "$clear_eol"
else
printf "%s[✖] %s (failed)%s\n" "$cr" "$message" "$clear_eol"
fi
return "$exit_code"
}
# Only run the demo when executed directly, so the file can be sourced for the
# `spinner` function alone. bash reports this through BASH_SOURCE; zsh has no
# such variable and would otherwise skip the demo silently, so it is detected
# via ZSH_EVAL_CONTEXT, which contains ":file" only when sourcing.
_spinner_is_main=0
if [ -n "${ZSH_VERSION:-}" ]; then
case "${ZSH_EVAL_CONTEXT:-}" in
*:file*) ;;
*) _spinner_is_main=1 ;;
esac
elif [ "${BASH_SOURCE[0]:-}" = "$0" ]; then
_spinner_is_main=1
fi
if [ "$_spinner_is_main" -eq 1 ]; then
unset _spinner_is_main
exit_ok() {
sleep 2
exit 0
}
exit_error() {
sleep 2
exit 1
}
exit_ok &
spinner "$!" "Calling function returning 0"
exit_error &
spinner "$!" "Calling function returning 1"
# The demo deliberately runs a job that fails, so a non-zero exit here would
# be misleading.
exit 0
fi
unset _spinner_is_main