@renault-digital/bash-base 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +78 -10
- package/README.md +79 -6
- package/bin/bash-base +597 -313
- package/docs/bash-zsh-compatibility.md +202 -0
- package/docs/coverage.md +289 -0
- package/docs/design-principles.md +174 -0
- package/docs/references.md +123 -69
- package/man/bash-base.1 +72 -5
- package/package.json +5 -6
- package/scripts/test-shell-compat.sh +391 -0
- package/scripts/test.sh +82 -14
- package/spec/array.spec.sh +8 -2
- package/spec/coverage_edges.spec.sh +88 -0
- package/spec/coverage_zsh_array_map.spec.sh +24 -0
- package/spec/process.spec.sh +113 -16
- package/spec/reflection.spec.sh +1 -1
- package/spec/spec_helper.sh +17 -0
- package/spec/string.spec.sh +14 -17
- package/src/alias.sh +35 -4
- package/src/argument.sh +222 -124
- package/src/array.sh +96 -98
- package/src/constant.sh +1 -1
- package/src/document.sh +17 -11
- package/src/out.sh +26 -15
- package/src/process.sh +4 -4
- package/src/reflection.sh +76 -17
- package/src/string.sh +92 -27
- package/src/tool.sh +29 -13
package/src/reflection.sh
CHANGED
|
@@ -13,15 +13,50 @@
|
|
|
13
13
|
# string="args_valid_or_read myVar '^[0-9a-z]{3,3}$' \"SIA\""
|
|
14
14
|
# reflect_nth_arg 4 $string ==> "SIA"
|
|
15
15
|
# @SEE_ALSO
|
|
16
|
-
|
|
17
|
-
local index string
|
|
16
|
+
reflect_nth_arg() {
|
|
17
|
+
local index string word position
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
if [[ -n "${ZSH_VERSION:-}" ]]; then
|
|
20
|
+
# zsh's lexer splits shell-quoted words without executing their contents.
|
|
21
|
+
# Keep this expansion in eval so Bash can still parse the source file.
|
|
22
|
+
string="$*"
|
|
23
|
+
local -a __bash_base_reflect_words
|
|
24
|
+
eval '__bash_base_reflect_words=( "${(@Q)${(z)string}}" )' || return 1
|
|
25
|
+
set -- "${__bash_base_reflect_words[@]}"
|
|
26
|
+
else
|
|
27
|
+
string="$(printf '%s\n' "$*" | string_replace_regex '(\\|\||\{|>|<|&)' '\\\1')"
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
# Parse the same shell-like argument string as the historical implementation,
|
|
30
|
+
# but use positional parameters instead of an indexed array so Bash/zsh array
|
|
31
|
+
# index bases cannot change the result.
|
|
32
|
+
eval "set -- ${string}"
|
|
33
|
+
fi
|
|
34
|
+
index="${1-}"
|
|
35
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
36
|
+
# Bash legacy indexing addressed the entire parsed list, including
|
|
37
|
+
# the index argument at [0]; missing indexes printed a blank line.
|
|
38
|
+
# Keep that behavior, including Bash's native negative indexes.
|
|
39
|
+
local -a __bash_base_legacy_reflect_words
|
|
40
|
+
__bash_base_legacy_reflect_words=("$@")
|
|
41
|
+
echo "${__bash_base_legacy_reflect_words[$index]}"
|
|
42
|
+
return 0
|
|
43
|
+
fi
|
|
44
|
+
shift || true
|
|
45
|
+
|
|
46
|
+
if ! [[ "$index" =~ ^[0-9]+$ ]] || ((index < 1)); then
|
|
47
|
+
return 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
position=1
|
|
51
|
+
for word in "$@"; do
|
|
52
|
+
if ((position == index)); then
|
|
53
|
+
printf '%s\n' "$word"
|
|
54
|
+
return 0
|
|
55
|
+
fi
|
|
56
|
+
position=$((position + 1))
|
|
57
|
+
done
|
|
58
|
+
|
|
59
|
+
return 1
|
|
25
60
|
}
|
|
26
61
|
|
|
27
62
|
# @NAME
|
|
@@ -34,9 +69,9 @@ function reflect_nth_arg() {
|
|
|
34
69
|
# reflect_get_function_definition confirm_to_continue
|
|
35
70
|
# @SEE_ALSO
|
|
36
71
|
# reflect_function_names_of_file
|
|
37
|
-
|
|
72
|
+
reflect_get_function_definition() {
|
|
38
73
|
local functionName="$1"
|
|
39
|
-
|
|
74
|
+
typeset -f "$functionName"
|
|
40
75
|
}
|
|
41
76
|
|
|
42
77
|
# @NAME
|
|
@@ -50,9 +85,14 @@ function reflect_get_function_definition() {
|
|
|
50
85
|
# reflect_function_names_of_file scripts/my_script.sh
|
|
51
86
|
# @SEE_ALSO
|
|
52
87
|
# reflect_get_function_definition
|
|
53
|
-
|
|
88
|
+
reflect_function_names_of_file() {
|
|
54
89
|
local shellScriptFile="$1"
|
|
55
|
-
|
|
90
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
91
|
+
# Existing Bash callers may rely on the original output spelling.
|
|
92
|
+
grep -E '^[[:space:]]*(function)?[[:space:]]*[0-9A-Za-z_\-]+[[:space:]]*\(\)[[:space:]]*\{?' "$shellScriptFile" | cut -d'(' -f1 | sed -e 's/function//'
|
|
93
|
+
return
|
|
94
|
+
fi
|
|
95
|
+
grep -E '^[[:space:]]*(function[[:space:]]+)?[0-9A-Za-z_-]+[[:space:]]*\(\)[[:space:]]*\{?' "$shellScriptFile" | sed -E -e 's/^[[:space:]]*function[[:space:]]+//' -e 's/[[:space:]]*\(\).*//' -e 's/[[:space:]]+$//'
|
|
56
96
|
}
|
|
57
97
|
|
|
58
98
|
# @NAME
|
|
@@ -66,9 +106,13 @@ function reflect_function_names_of_file() {
|
|
|
66
106
|
# reflect_function_definitions_of_file scripts/my_script.sh
|
|
67
107
|
# @SEE_ALSO
|
|
68
108
|
# reflect_get_function_definition
|
|
69
|
-
|
|
109
|
+
reflect_function_definitions_of_file() {
|
|
70
110
|
local shellScriptFile="$1"
|
|
71
|
-
|
|
111
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
112
|
+
sed -E -n '/^[[:space:]]*(function)?[[:space:]]*[0-9A-Za-z_\-]+[[:space:]]*\(\)[[:space:]]*\{?/,/^[[:space:]]*}/p' "$shellScriptFile"
|
|
113
|
+
return
|
|
114
|
+
fi
|
|
115
|
+
sed -E -n '/^[[:space:]]*(function[[:space:]]+)?[0-9A-Za-z_-]+[[:space:]]*\(\)[[:space:]]*\{?/,/^[[:space:]]*}/p' "$shellScriptFile"
|
|
72
116
|
}
|
|
73
117
|
|
|
74
118
|
# @NAME
|
|
@@ -82,9 +126,17 @@ function reflect_function_definitions_of_file() {
|
|
|
82
126
|
# reflect_search_function '^args_.*'
|
|
83
127
|
# @SEE_ALSO
|
|
84
128
|
# reflect_search_variable
|
|
85
|
-
|
|
129
|
+
reflect_search_function() {
|
|
86
130
|
local functionNamePattern="$1"
|
|
87
|
-
|
|
131
|
+
|
|
132
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
133
|
+
# Exact Bash legacy extraction/output (no new sorting or dedupe).
|
|
134
|
+
typeset -f | grep -E '\s+\(\)\s+' | sed -E 's/[(){ ]//g' | grep -Ei "$functionNamePattern"
|
|
135
|
+
elif [[ -n "${ZSH_VERSION:-}" ]]; then
|
|
136
|
+
# Hide zsh-only parameter-expansion flags inside eval so the file still
|
|
137
|
+
# parses in Bash.
|
|
138
|
+
eval 'printf "%s\\n" "${(k)functions[@]}"' | LC_ALL=C sort -u | grep -Ei "$functionNamePattern"
|
|
139
|
+
fi
|
|
88
140
|
}
|
|
89
141
|
|
|
90
142
|
# @NAME
|
|
@@ -98,7 +150,14 @@ function reflect_search_function() {
|
|
|
98
150
|
# reflect_search_variable '^COLOR'
|
|
99
151
|
# @SEE_ALSO
|
|
100
152
|
# reflect_search_function
|
|
101
|
-
|
|
153
|
+
reflect_search_variable() {
|
|
102
154
|
local variableNamePattern="$1"
|
|
103
|
-
|
|
155
|
+
|
|
156
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
157
|
+
# Enumerate Bash variables directly. Parsing typeset -p using \s/\w
|
|
158
|
+
# depends on grep extensions unavailable on some macOS versions.
|
|
159
|
+
compgen -A variable | grep -Ei "$variableNamePattern"
|
|
160
|
+
elif [[ -n "${ZSH_VERSION:-}" ]]; then
|
|
161
|
+
eval 'printf "%s\\n" "${(k)parameters[@]}"' | LC_ALL=C sort -u | grep -Ei "$variableNamePattern"
|
|
162
|
+
fi
|
|
104
163
|
}
|
package/src/string.sh
CHANGED
|
@@ -13,7 +13,7 @@ source src/tool.sh
|
|
|
13
13
|
# string_trim < logfile
|
|
14
14
|
# echo " add " | string_trim
|
|
15
15
|
# @SEE_ALSO
|
|
16
|
-
|
|
16
|
+
string_trim() {
|
|
17
17
|
local string="${1-$(cat)}"
|
|
18
18
|
echo "${string}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' #trim ' '
|
|
19
19
|
}
|
|
@@ -29,7 +29,7 @@ function string_trim() {
|
|
|
29
29
|
# string_repeat 'abc' 5
|
|
30
30
|
# echo 5 | string_repeat 'abc'
|
|
31
31
|
# @SEE_ALSO
|
|
32
|
-
|
|
32
|
+
string_repeat() {
|
|
33
33
|
local string="$1"
|
|
34
34
|
local nbTimes=${2-$(cat)}
|
|
35
35
|
printf "${string}%.0s" $(seq 1 "$nbTimes")
|
|
@@ -46,7 +46,7 @@ function string_repeat() {
|
|
|
46
46
|
# string_length < logfile
|
|
47
47
|
# echo " add " | string_length
|
|
48
48
|
# @SEE_ALSO
|
|
49
|
-
|
|
49
|
+
string_length() {
|
|
50
50
|
local string index
|
|
51
51
|
string="${1-$(cat)}"
|
|
52
52
|
|
|
@@ -66,7 +66,7 @@ function string_length() {
|
|
|
66
66
|
# echo " add " | string_is_empty
|
|
67
67
|
# @SEE_ALSO
|
|
68
68
|
# string_length
|
|
69
|
-
|
|
69
|
+
string_is_empty() {
|
|
70
70
|
local string="${1-$(cat)}"
|
|
71
71
|
|
|
72
72
|
[[ $(string_length "$string") -eq 0 ]]
|
|
@@ -82,7 +82,7 @@ function string_is_empty() {
|
|
|
82
82
|
# string_revert 'aBc'
|
|
83
83
|
# echo 'aBc' | string_revert
|
|
84
84
|
# @SEE_ALSO
|
|
85
|
-
|
|
85
|
+
string_revert() {
|
|
86
86
|
local string="${1-$(cat)}"
|
|
87
87
|
echo "${string}" | rev
|
|
88
88
|
}
|
|
@@ -98,9 +98,16 @@ function string_revert() {
|
|
|
98
98
|
# echo 'abc' | string_upper
|
|
99
99
|
# @SEE_ALSO
|
|
100
100
|
# string_upper_first, string_lower
|
|
101
|
-
|
|
101
|
+
string_upper() {
|
|
102
102
|
local string=${1-$(cat)}
|
|
103
|
-
|
|
103
|
+
if [[ -n "${BASH_VERSION:-}" ]] && ((BASH_VERSINFO[0] >= 4)); then
|
|
104
|
+
# Bash's case expansion is locale-aware (unlike many tr versions).
|
|
105
|
+
# Keep the Bash 4+/5+ echo behavior verbatim. Construct the expression
|
|
106
|
+
# at runtime so Bash 3.2 can source this file without evaluating it.
|
|
107
|
+
eval 'echo "${string'"^^"'}"'
|
|
108
|
+
return
|
|
109
|
+
fi
|
|
110
|
+
printf '%s\n' "$string" | tr '[:lower:]' '[:upper:]'
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
# @NAME
|
|
@@ -114,9 +121,13 @@ function string_upper() {
|
|
|
114
121
|
# echo 'aBc' | string_lower
|
|
115
122
|
# @SEE_ALSO
|
|
116
123
|
# string_upper, string_upper_first
|
|
117
|
-
|
|
124
|
+
string_lower() {
|
|
118
125
|
local string=${1-$(cat)}
|
|
119
|
-
|
|
126
|
+
if [[ -n "${BASH_VERSION:-}" ]] && ((BASH_VERSINFO[0] >= 4)); then
|
|
127
|
+
eval 'echo "${string'",,"'}"'
|
|
128
|
+
return
|
|
129
|
+
fi
|
|
130
|
+
printf '%s\n' "$string" | tr '[:upper:]' '[:lower:]'
|
|
120
131
|
}
|
|
121
132
|
|
|
122
133
|
# @NAME
|
|
@@ -130,10 +141,29 @@ function string_lower() {
|
|
|
130
141
|
# echo 'aBc' | string_upper_first
|
|
131
142
|
# @SEE_ALSO
|
|
132
143
|
# string_lower, string_upper
|
|
133
|
-
|
|
144
|
+
string_upper_first() {
|
|
134
145
|
local string=${1-$(cat)}
|
|
135
|
-
local lower
|
|
136
|
-
|
|
146
|
+
local lower first rest
|
|
147
|
+
|
|
148
|
+
if [[ -n "${BASH_VERSION:-}" ]] && ((BASH_VERSINFO[0] >= 4)); then
|
|
149
|
+
# Do not round-trip through command substitution: it strips the
|
|
150
|
+
# trailing newlines that the old Bash parameter expansion preserved.
|
|
151
|
+
eval 'lower="${string'",,"'}"'
|
|
152
|
+
eval 'echo "${lower'"^"'}"'
|
|
153
|
+
return
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
lower="$(string_lower "$string")"
|
|
157
|
+
[[ -n "$lower" ]] || {
|
|
158
|
+
printf '\n'
|
|
159
|
+
return 0
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
# `${var^^}` / `${var,,}` / `${var^}` are Bash-specific. Parameter
|
|
163
|
+
# prefix/suffix removal is shared by Bash and zsh.
|
|
164
|
+
rest="${lower#?}"
|
|
165
|
+
first="${lower%"$rest"}"
|
|
166
|
+
printf '%s%s\n' "$(string_upper "$first")" "$rest"
|
|
137
167
|
}
|
|
138
168
|
|
|
139
169
|
# @NAME
|
|
@@ -149,11 +179,37 @@ function string_upper_first() {
|
|
|
149
179
|
# string_sub 3 5 < temp_file.txt
|
|
150
180
|
# echo ' as fd ' | string_sub 2 4
|
|
151
181
|
# @SEE_ALSO
|
|
152
|
-
|
|
182
|
+
string_sub() {
|
|
153
183
|
local startIndex=$1
|
|
154
184
|
local subStringLength=$2
|
|
155
185
|
local string="${3-$(cat)}"
|
|
156
|
-
|
|
186
|
+
if [[ -n "${BASH_VERSION:-}" ]] && ((BASH_VERSINFO[0] >= 4)); then
|
|
187
|
+
# Keep Bash 4+/5+ substring and error behavior exactly as before.
|
|
188
|
+
# Bash 3.2 continues to use the portable negative-length fallback.
|
|
189
|
+
echo "${string:$startIndex:$subStringLength}"
|
|
190
|
+
return
|
|
191
|
+
fi
|
|
192
|
+
local totalLength=${#string}
|
|
193
|
+
local actualStart=$startIndex
|
|
194
|
+
local actualLength=$subStringLength
|
|
195
|
+
|
|
196
|
+
# Bash 3.2 cannot use a negative substring length. Convert the
|
|
197
|
+
# documented negative start/end offsets to nonnegative bounds first.
|
|
198
|
+
if ((actualStart < 0)); then
|
|
199
|
+
actualStart=$((totalLength + actualStart))
|
|
200
|
+
fi
|
|
201
|
+
if ((actualLength < 0)); then
|
|
202
|
+
actualLength=$((totalLength + actualLength - actualStart))
|
|
203
|
+
fi
|
|
204
|
+
# Out-of-range starts produce an empty result (as in modern Bash).
|
|
205
|
+
if ((actualStart < 0 || actualStart > totalLength)); then
|
|
206
|
+
printf '\n'
|
|
207
|
+
return 0
|
|
208
|
+
fi
|
|
209
|
+
if ((actualLength < 0)); then
|
|
210
|
+
return 1
|
|
211
|
+
fi
|
|
212
|
+
printf '%s\n' "${string:$actualStart:$actualLength}"
|
|
157
213
|
}
|
|
158
214
|
|
|
159
215
|
# @NAME
|
|
@@ -167,7 +223,7 @@ function string_sub() {
|
|
|
167
223
|
# string_match 'name;+' "name;name;"
|
|
168
224
|
# @SEE_ALSO
|
|
169
225
|
# string_index_first
|
|
170
|
-
|
|
226
|
+
string_match() {
|
|
171
227
|
local value regExp
|
|
172
228
|
regExp=${1}
|
|
173
229
|
string="${2-$(cat)}"
|
|
@@ -185,10 +241,14 @@ function string_match() {
|
|
|
185
241
|
# escape_sed 'a$'
|
|
186
242
|
# @SEE_ALSO
|
|
187
243
|
# string_replace
|
|
188
|
-
|
|
189
|
-
|
|
244
|
+
escape_sed() {
|
|
245
|
+
if [[ -n "${ZSH_VERSION:-}" ]]; then
|
|
246
|
+
printf '%s\n' "$1"
|
|
247
|
+
else
|
|
248
|
+
# Preserve historical Bash echo semantics.
|
|
249
|
+
echo "$1"
|
|
250
|
+
fi | sed -e 's/\//\\\//g' -e 's/\&/\\\&/g' -e 's/\./\\\./g' -e 's/\^/\\\^/g' -e 's/\[/\\\[/g' -e 's/\$/\\\$/g'
|
|
190
251
|
}
|
|
191
|
-
export -f escape_sed >/dev/null
|
|
192
252
|
|
|
193
253
|
# @NAME
|
|
194
254
|
# string_replace -- replace literally the token string to new string, not support regular expression
|
|
@@ -204,11 +264,16 @@ export -f escape_sed >/dev/null
|
|
|
204
264
|
# string_replace '\*' 'b' 'a*a' ==> 'aba'
|
|
205
265
|
# @SEE_ALSO
|
|
206
266
|
# escape_sed, string_replace_regex
|
|
207
|
-
|
|
267
|
+
string_replace() {
|
|
208
268
|
local tokenString newString
|
|
209
269
|
tokenString=$(escape_sed "${1}")
|
|
210
270
|
newString=$(escape_sed "${2}")
|
|
211
|
-
|
|
271
|
+
if [[ -n "${ZSH_VERSION:-}" ]]; then
|
|
272
|
+
printf '%s\n' "${3-$(cat)}" | sed -e "s/${tokenString}/${newString}/g"
|
|
273
|
+
else
|
|
274
|
+
# Preserve historical Bash echo semantics.
|
|
275
|
+
echo "${3-$(cat)}" | sed -e "s/${tokenString}/${newString}/g"
|
|
276
|
+
fi
|
|
212
277
|
}
|
|
213
278
|
|
|
214
279
|
# @NAME
|
|
@@ -225,7 +290,7 @@ function string_replace() {
|
|
|
225
290
|
# string_replace_regex '*' 'b' 'a*a' ==> 'aba'
|
|
226
291
|
# @SEE_ALSO
|
|
227
292
|
# string_replace
|
|
228
|
-
|
|
293
|
+
string_replace_regex() {
|
|
229
294
|
echo "${3-$(cat)}" | sed -E -e "s/$1/$2/g"
|
|
230
295
|
}
|
|
231
296
|
|
|
@@ -242,11 +307,11 @@ function string_replace_regex() {
|
|
|
242
307
|
# echo " add " | string_index_first "token"
|
|
243
308
|
# @SEE_ALSO
|
|
244
309
|
# string_before_first, string_after_first
|
|
245
|
-
|
|
310
|
+
string_index_first() {
|
|
246
311
|
local tokenString=$1
|
|
247
312
|
local string="${2-$(cat)}"
|
|
248
313
|
local prefix="${string%%${tokenString}*}"
|
|
249
|
-
[ "${string}" == "${prefix}" ] &&
|
|
314
|
+
[[ "${string}" == "${prefix}" ]] && printf '%s\n' -1 || printf '%s\n' "${#prefix}"
|
|
250
315
|
}
|
|
251
316
|
|
|
252
317
|
# @NAME
|
|
@@ -262,7 +327,7 @@ function string_index_first() {
|
|
|
262
327
|
# echo " add " | string_before_first "dd"
|
|
263
328
|
# @SEE_ALSO
|
|
264
329
|
# string_index_first, string_after_first
|
|
265
|
-
|
|
330
|
+
string_before_first() {
|
|
266
331
|
local tokenString=$1
|
|
267
332
|
local string="${2-$(cat)}"
|
|
268
333
|
echo "${string%%${tokenString}*}" # Remove the first - and everything following it
|
|
@@ -281,7 +346,7 @@ function string_before_first() {
|
|
|
281
346
|
# echo " add " | string_after_first "dd"
|
|
282
347
|
# @SEE_ALSO
|
|
283
348
|
# string_index_first, string_before_first
|
|
284
|
-
|
|
349
|
+
string_after_first() {
|
|
285
350
|
local tokenString=$1
|
|
286
351
|
local string="${2-$(cat)}"
|
|
287
352
|
echo "${string#*${tokenString}}" # Remove everything up to and including first -
|
|
@@ -303,7 +368,7 @@ function string_after_first() {
|
|
|
303
368
|
# string_split_to_array $'\n' branchesToSelectArray "${branchesToSelectString}"
|
|
304
369
|
# @SEE_ALSO
|
|
305
370
|
# array_join, array_describe, array_from_describe, string_pick_to_array
|
|
306
|
-
|
|
371
|
+
string_split_to_array() {
|
|
307
372
|
local tokenString="$1"
|
|
308
373
|
local newArrayVarName="$2"
|
|
309
374
|
local string="${3-$(cat)}"
|
|
@@ -341,7 +406,7 @@ function string_split_to_array() {
|
|
|
341
406
|
# string_pick_to_array '{age:' '}' newArray "$str"
|
|
342
407
|
# @SEE_ALSO
|
|
343
408
|
# array_join, array_describe, array_from_describe, string_split_to_array
|
|
344
|
-
|
|
409
|
+
string_pick_to_array() {
|
|
345
410
|
local startTokenString="$1"
|
|
346
411
|
local endTokenString="$2"
|
|
347
412
|
local newArrayVarName="$3"
|
package/src/tool.sh
CHANGED
|
@@ -15,7 +15,7 @@ source src/out.sh
|
|
|
15
15
|
# stop_if_failed "ERROR: can't delete the directory '${destProjectPath}' !"
|
|
16
16
|
# @SEE_ALSO
|
|
17
17
|
# confirm_to_continue
|
|
18
|
-
|
|
18
|
+
stop_if_failed() {
|
|
19
19
|
if [[ $? -ne 0 ]]; then
|
|
20
20
|
print_error "$*"
|
|
21
21
|
exit 1
|
|
@@ -34,19 +34,25 @@ function stop_if_failed() {
|
|
|
34
34
|
# confirm_to_continue a b
|
|
35
35
|
# @SEE_ALSO
|
|
36
36
|
# print_args, stop_if_failed
|
|
37
|
-
|
|
37
|
+
confirm_to_continue() {
|
|
38
38
|
local response
|
|
39
39
|
print_args "$@"
|
|
40
|
-
if ! [ "${modeQuiet}" == true ]; then
|
|
41
|
-
read -r -p "Continue ? [y/N] " response
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
if [[ "${modeQuiet:-false}" != true ]]; then
|
|
42
|
+
# Bash `read -p` and zsh `read "name?prompt"` are shell-specific.
|
|
43
|
+
# Match Bash read -p behavior by showing the prompt only for a TTY.
|
|
44
|
+
if [[ -t 0 ]]; then
|
|
45
|
+
printf '%s' 'Continue ? [y/N] ' >&2
|
|
46
|
+
fi
|
|
47
|
+
read -r response || response=""
|
|
48
|
+
|
|
49
|
+
case "$response" in
|
|
50
|
+
[yY] | [yY][eE][sS])
|
|
51
|
+
printf '%s\n' 'Continue...'
|
|
52
|
+
sleep 1
|
|
47
53
|
;;
|
|
48
54
|
*)
|
|
49
|
-
|
|
55
|
+
printf '%s\n' 'Exiting...'
|
|
50
56
|
exit 1
|
|
51
57
|
;;
|
|
52
58
|
esac
|
|
@@ -64,8 +70,8 @@ function confirm_to_continue() {
|
|
|
64
70
|
# @EXAMPLES
|
|
65
71
|
# wait_for 'test -f /tmp/output.txt' 'file existed' 3
|
|
66
72
|
# @SEE_ALSO
|
|
67
|
-
# confirm_to_continue, stop_if_failed
|
|
68
|
-
|
|
73
|
+
# confirm_to_continue, stop_if_failed
|
|
74
|
+
wait_for() {
|
|
69
75
|
local predicate="${1}"
|
|
70
76
|
local subject="${2-${predicate}}"
|
|
71
77
|
local interval=${3-3}
|
|
@@ -91,6 +97,16 @@ function wait_for() {
|
|
|
91
97
|
# record2
|
|
92
98
|
# EOF
|
|
93
99
|
# @SEE_ALSO
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
declare_heredoc() {
|
|
101
|
+
local _bash_base_heredoc_target="${1-}"
|
|
102
|
+
local _bash_base_heredoc_content
|
|
103
|
+
|
|
104
|
+
# Only identifier names may appear as the left-hand side of an eval.
|
|
105
|
+
case "$_bash_base_heredoc_target" in
|
|
106
|
+
'' | [!a-zA-Z_]* | *[!a-zA-Z0-9_]*) return 2 ;;
|
|
107
|
+
esac
|
|
108
|
+
|
|
109
|
+
_bash_base_heredoc_content="$(cat)"
|
|
110
|
+
# Expand the content as a variable value, never parse it as shell code.
|
|
111
|
+
eval "${_bash_base_heredoc_target}=\"\$_bash_base_heredoc_content\""
|
|
96
112
|
}
|