@renault-digital/bash-base 2.4.1 → 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 +596 -312
- 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 +122 -68
- package/man/bash-base.1 +71 -4
- package/package.json +4 -3
- 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 +109 -15
- 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 +28 -12
package/src/argument.sh
CHANGED
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
source src/constant.sh
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
if [[ -n "${ZSH_VERSION:-}" ]]; then
|
|
6
|
+
# zsh may temporarily replace $0 with the sourced filename when
|
|
7
|
+
# FUNCTION_ARGZERO is enabled. ZSH_ARGZERO always keeps the invocation name.
|
|
8
|
+
_bash_base_argzero="${ZSH_ARGZERO:-$0}"
|
|
9
|
+
else
|
|
10
|
+
_bash_base_argzero="$0"
|
|
11
|
+
fi
|
|
12
|
+
THIS_SCRIPT_PATH="$_bash_base_argzero" # script source path for args_valid_* lookup
|
|
13
|
+
THIS_SCRIPT_NAME="$(basename "$_bash_base_argzero")" # the main script name
|
|
14
|
+
unset _bash_base_argzero
|
|
6
15
|
|
|
7
16
|
SHORT_DESC="${THIS_SCRIPT_NAME%%.*}"
|
|
8
17
|
SHORT_DESC="${SHORT_DESC/[\-_]/ }" # redefine it to show your script short description in the 'NAME' field of generated -h response
|
|
@@ -17,9 +26,14 @@ USAGE='' # redefine it in your script only if the gene
|
|
|
17
26
|
# @EXAMPLES
|
|
18
27
|
# args_parse $# "$@" newVar1 newVar2 newVar3
|
|
19
28
|
# @SEE_ALSO
|
|
20
|
-
|
|
21
|
-
local nbArgValues nbPositionalVarNames option
|
|
22
|
-
local
|
|
29
|
+
args_parse() {
|
|
30
|
+
local nbArgValues nbPositionalVarNames option OPTARG OPTIND nbPositionalArgValues
|
|
31
|
+
local showUsage=false
|
|
32
|
+
local element validCommand description defaultUsage
|
|
33
|
+
local strPositionalVarNames="" strPositionalValuesExamples=""
|
|
34
|
+
local -a positionalArgValues positionalVarNames
|
|
35
|
+
# Bash legacy contract: prompt, possibleValues, i, descriptions and
|
|
36
|
+
# onlyPositionalVarNames were caller-visible, not function-local.
|
|
23
37
|
|
|
24
38
|
nbArgValues=$1
|
|
25
39
|
shift 1
|
|
@@ -42,79 +56,103 @@ function args_parse() {
|
|
|
42
56
|
shift $((OPTIND - 1))
|
|
43
57
|
|
|
44
58
|
nbPositionalArgValues=$((nbArgValues - OPTIND + 1))
|
|
45
|
-
positionalArgValues=(
|
|
46
|
-
|
|
59
|
+
positionalArgValues=()
|
|
60
|
+
# Split positional values from destination names without a new local
|
|
61
|
+
# counter; the historical Bash `i` global is handled below.
|
|
62
|
+
while (($# > nbPositionalVarNames)); do
|
|
63
|
+
positionalArgValues+=("$1")
|
|
64
|
+
shift
|
|
65
|
+
done
|
|
66
|
+
positionalVarNames=("$@")
|
|
47
67
|
|
|
48
68
|
onlyPositionalVarNames=()
|
|
49
69
|
descriptions=''
|
|
50
|
-
if ((nbPositionalVarNames > 0)); then
|
|
51
|
-
for i in $(seq 0 $((nbPositionalVarNames - 1))); do
|
|
52
|
-
element=${positionalVarNames[i]}
|
|
53
70
|
|
|
71
|
+
# Pair values with variable names without relying on Bash's 0-based array
|
|
72
|
+
# indexes (zsh uses a different default array index base).
|
|
73
|
+
set -- "${positionalArgValues[@]}"
|
|
74
|
+
for element in "${positionalVarNames[@]}"; do
|
|
75
|
+
# Do not introduce a local value variable: callers may legally name
|
|
76
|
+
# their destination positionalValue (or prompt). Save it only in $1.
|
|
77
|
+
|
|
78
|
+
# zsh FUNCTION_ARGZERO may change $0 to the current function name.
|
|
79
|
+
# Only scan a caller script when there is an actual script file.
|
|
80
|
+
validCommand=''
|
|
81
|
+
if [[ -f "${THIS_SCRIPT_PATH:-}" ]]; then
|
|
54
82
|
validCommand="$(
|
|
55
|
-
grep -E "
|
|
83
|
+
grep -E "^[[:space:]]*args_valid.*[[:space:]]+${element}[[:space:]]+" "$THIS_SCRIPT_PATH" | head -1 |
|
|
56
84
|
awk -F "'" -v OFS="'" '{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
85
|
+
for (i=2; i<=NF; i+=2) {
|
|
86
|
+
gsub(/ /, "_SPACE_", $i);
|
|
87
|
+
gsub(/\$/, "_DOLLAR_", $i);
|
|
88
|
+
gsub(/\(/, "_PARENTHESES_LEFT_", $i);
|
|
89
|
+
gsub(/\)/, "_PARENTHESES_RIGHT_", $i);
|
|
90
|
+
}
|
|
91
|
+
print
|
|
92
|
+
}' |
|
|
65
93
|
sed -e "s/\'//g"
|
|
66
94
|
)"
|
|
95
|
+
fi
|
|
67
96
|
|
|
68
|
-
|
|
69
|
-
|
|
97
|
+
if [[ -z $validCommand ]]; then
|
|
98
|
+
eval "${element}=\"\${1-}\""
|
|
99
|
+
onlyPositionalVarNames+=("${element}")
|
|
100
|
+
description="a valid value for ${element}"
|
|
101
|
+
else
|
|
102
|
+
if [[ "$validCommand" == *args_valid_or_select_pipe* ]]; then
|
|
103
|
+
eval "${element}=\"\${1-}\""
|
|
104
|
+
onlyPositionalVarNames+=("${element}")
|
|
105
|
+
prompt="$(reflect_nth_arg 4 "$validCommand")"
|
|
106
|
+
possibleValues=", possible values: $(reflect_nth_arg 3 "$validCommand")"
|
|
107
|
+
elif [[ "$validCommand" == *args_valid_or_select_args* ]]; then
|
|
108
|
+
eval "${element}=\"\${1-}\""
|
|
109
|
+
onlyPositionalVarNames+=("${element}")
|
|
110
|
+
prompt="$(reflect_nth_arg 3 "$validCommand")"
|
|
111
|
+
possibleValues=", you can select one using wizard if you do not know which value is valid"
|
|
112
|
+
elif [[ "$validCommand" == *args_valid_or_select* ]]; then
|
|
113
|
+
eval "${element}=\"\${1-}\""
|
|
70
114
|
onlyPositionalVarNames+=("${element}")
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
prompt="$
|
|
87
|
-
possibleValues=", you can select one using wizard if you do not know which value is valid"
|
|
88
|
-
elif [[ "${validCommand}" =~ args_valid_or_read ]]; then
|
|
89
|
-
eval "${positionalVarNames[i]}='${positionalArgValues[i]}'"
|
|
90
|
-
onlyPositionalVarNames+=("${element}")
|
|
91
|
-
prompt="$(reflect_nth_arg 4 "${validCommand}")"
|
|
92
|
-
if [[ -n $(reflect_nth_arg 5 "${validCommand}") ]]; then
|
|
93
|
-
prompt="${prompt}, proposed value: $(reflect_nth_arg 5 "${validCommand}")"
|
|
94
|
-
fi
|
|
95
|
-
possibleValues=""
|
|
96
|
-
elif [[ "${validCommand}" =~ args_valid_or_default ]]; then
|
|
97
|
-
prompt="optional, $(reflect_nth_arg 4 "${validCommand}"). should be set like '${element}=value' before ${THIS_SCRIPT_NAME} or export to OS environment"
|
|
98
|
-
if [[ -n $(reflect_nth_arg 5 "${validCommand}") ]]; then
|
|
99
|
-
prompt="${prompt}. if absent, fallback to: $(reflect_nth_arg 5 "${validCommand}")"
|
|
100
|
-
else
|
|
101
|
-
prompt="${prompt}, empty if absent"
|
|
102
|
-
fi
|
|
103
|
-
possibleValues=""
|
|
115
|
+
prompt="$(reflect_nth_arg 4 "$validCommand")"
|
|
116
|
+
possibleValues=", you can select one using wizard if you do not know which value is valid"
|
|
117
|
+
elif [[ "$validCommand" == *args_valid_or_read* ]]; then
|
|
118
|
+
eval "${element}=\"\${1-}\""
|
|
119
|
+
onlyPositionalVarNames+=("${element}")
|
|
120
|
+
prompt="$(reflect_nth_arg 4 "$validCommand")"
|
|
121
|
+
if [[ -n $(reflect_nth_arg 5 "$validCommand") ]]; then
|
|
122
|
+
prompt="${prompt}, proposed value: $(reflect_nth_arg 5 "$validCommand")"
|
|
123
|
+
fi
|
|
124
|
+
possibleValues=""
|
|
125
|
+
elif [[ "$validCommand" == *args_valid_or_default* ]]; then
|
|
126
|
+
prompt="optional, $(reflect_nth_arg 4 "$validCommand"). should be set like ${element}=value before ${THIS_SCRIPT_NAME} or export to OS environment"
|
|
127
|
+
if [[ -n $(reflect_nth_arg 5 "$validCommand") ]]; then
|
|
128
|
+
prompt="${prompt}. if absent, fallback to: $(reflect_nth_arg 5 "$validCommand")"
|
|
129
|
+
else
|
|
130
|
+
prompt="${prompt}, empty if absent"
|
|
104
131
|
fi
|
|
132
|
+
possibleValues=""
|
|
133
|
+
fi
|
|
105
134
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
135
|
+
prompt="$(
|
|
136
|
+
printf '%s\n' "${prompt}" |
|
|
137
|
+
string_replace "_SPACE_" " " |
|
|
138
|
+
string_replace "_DOLLAR_" "$" |
|
|
139
|
+
string_replace "_PARENTHESES_LEFT_" "(" |
|
|
140
|
+
string_replace "_PARENTHESES_RIGHT_" ")"
|
|
141
|
+
)"
|
|
113
142
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
143
|
+
description="${prompt}${possibleValues}"
|
|
144
|
+
fi
|
|
145
|
+
descriptions+="$(printf "\n %-20s%s" "${element} " "${description}")"
|
|
146
|
+
if (($# > 0)); then
|
|
147
|
+
shift
|
|
148
|
+
fi
|
|
149
|
+
done
|
|
150
|
+
if [[ -n "${BASH_VERSION:-}" && $nbPositionalVarNames -gt 0 ]]; then
|
|
151
|
+
# The original Bash implementation used a caller-visible `i` as
|
|
152
|
+
# a loop counter over output names. Respect a destination named i.
|
|
153
|
+
if ! array_in i "${positionalVarNames[@]}"; then
|
|
154
|
+
i=$((nbPositionalVarNames - 1))
|
|
155
|
+
fi
|
|
118
156
|
fi
|
|
119
157
|
|
|
120
158
|
if [ ${#onlyPositionalVarNames[@]} -gt 0 ]; then
|
|
@@ -122,36 +160,36 @@ function args_parse() {
|
|
|
122
160
|
strPositionalValuesExamples=" \"$(array_join 'Value" "' onlyPositionalVarNames)Value\""
|
|
123
161
|
fi
|
|
124
162
|
|
|
125
|
-
declare_heredoc defaultUsage
|
|
126
|
-
|
|
127
|
-
|
|
163
|
+
declare_heredoc defaultUsage <<EOF
|
|
164
|
+
${COLOR_BOLD_YELLOW}NAME${COLOR_END}
|
|
165
|
+
${THIS_SCRIPT_NAME} -- ${SHORT_DESC}
|
|
128
166
|
|
|
129
|
-
|
|
130
|
-
|
|
167
|
+
${COLOR_BOLD_YELLOW}SYNOPSIS${COLOR_END}
|
|
168
|
+
[optionalVariable=value ...] ./${THIS_SCRIPT_NAME} [-qh]${strPositionalVarNames}
|
|
131
169
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
170
|
+
${COLOR_BOLD_YELLOW}DESCRIPTION${COLOR_END}
|
|
171
|
+
[-h] help, print the usage
|
|
172
|
+
[-q] optional, Run quietly, no confirmation
|
|
173
|
+
${descriptions}
|
|
136
174
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
175
|
+
${COLOR_BOLD_YELLOW}EXAMPLES${COLOR_END}
|
|
176
|
+
help, print the usage:
|
|
177
|
+
./${THIS_SCRIPT_NAME} -h
|
|
140
178
|
|
|
141
|
-
|
|
142
|
-
|
|
179
|
+
run with all params, if run in quiet mode with -q, be sure all the params are valid:
|
|
180
|
+
./${THIS_SCRIPT_NAME} [-q]${strPositionalValuesExamples}
|
|
143
181
|
|
|
144
|
-
|
|
145
|
-
|
|
182
|
+
run using wizard, input value for params step by step:
|
|
183
|
+
./${THIS_SCRIPT_NAME}
|
|
146
184
|
|
|
147
|
-
|
|
148
|
-
|
|
185
|
+
run with optional variables, example:
|
|
186
|
+
myOpt1=myValue1 myOpt2=myValue2 ./${THIS_SCRIPT_NAME}
|
|
149
187
|
|
|
150
|
-
|
|
151
|
-
|
|
188
|
+
or you can run with some params, and input value for other params using wizard.
|
|
189
|
+
EOF
|
|
152
190
|
|
|
153
|
-
if [ "$showUsage" == true ]; then
|
|
154
|
-
|
|
191
|
+
if [[ "$showUsage" == true ]]; then
|
|
192
|
+
printf '%b\n' "${USAGE:-$defaultUsage}"
|
|
155
193
|
exit 0
|
|
156
194
|
fi
|
|
157
195
|
}
|
|
@@ -172,26 +210,38 @@ function args_parse() {
|
|
|
172
210
|
# args_valid_or_select varEmpty arr "Which app"
|
|
173
211
|
# @SEE_ALSO
|
|
174
212
|
# args_valid_or_select_pipe, args_valid_or_read, args_valid_or_default
|
|
175
|
-
|
|
176
|
-
local valueVarName validValuesVarName prompt value
|
|
213
|
+
args_valid_or_select() {
|
|
214
|
+
local valueVarName validValuesVarName prompt value PS3
|
|
215
|
+
local -a validValues
|
|
216
|
+
|
|
177
217
|
valueVarName="${1}"
|
|
178
|
-
validValuesVarName
|
|
179
|
-
validValues="$2[@]"
|
|
218
|
+
validValuesVarName="$2"
|
|
180
219
|
prompt="${3}"
|
|
181
|
-
|
|
182
|
-
|
|
220
|
+
eval 'value="${'"$valueVarName"'-}"'
|
|
221
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
222
|
+
# Preserve Bash's historical echo/word-splitting normalization, without
|
|
223
|
+
# reparsing the value with eval (which would execute input as code).
|
|
224
|
+
# shellcheck disable=SC2086,SC2116
|
|
225
|
+
value="$(echo $value)"
|
|
226
|
+
fi
|
|
227
|
+
eval "validValues=( \"\${${validValuesVarName}[@]}\" )"
|
|
183
228
|
|
|
184
229
|
while ! array_contains "${validValuesVarName}" "${value}"; do
|
|
185
|
-
|
|
230
|
+
printf '\n%s ?\n' "$prompt"
|
|
186
231
|
[[ -n "${value}" ]] && print_error "the input '${value}' is not valid."
|
|
187
232
|
|
|
188
233
|
PS3="choose one by ${COLOR_BOLD_YELLOW}number${COLOR_END} [1|2|...] ? "
|
|
189
|
-
select value in "${
|
|
234
|
+
select value in "${validValues[@]}"; do
|
|
190
235
|
break
|
|
191
236
|
done
|
|
192
237
|
done
|
|
193
|
-
|
|
194
|
-
|
|
238
|
+
|
|
239
|
+
eval "${valueVarName}=\"\$value\""
|
|
240
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
241
|
+
# shellcheck disable=SC2086,SC2116
|
|
242
|
+
value="$(echo $value)"
|
|
243
|
+
fi
|
|
244
|
+
printf "Selected value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$value"
|
|
195
245
|
}
|
|
196
246
|
|
|
197
247
|
# @NAME
|
|
@@ -207,8 +257,9 @@ function args_valid_or_select() {
|
|
|
207
257
|
# args_valid_or_select_pipe sel "a|ab|d" "which value"
|
|
208
258
|
# @SEE_ALSO
|
|
209
259
|
# args_valid_or_select, args_valid_or_select_args, args_valid_or_read, args_valid_or_default
|
|
210
|
-
|
|
211
|
-
local valueVarName validValues prompt
|
|
260
|
+
args_valid_or_select_pipe() {
|
|
261
|
+
local valueVarName validValues prompt
|
|
262
|
+
local -a newArray
|
|
212
263
|
valueVarName="${1}"
|
|
213
264
|
validValues="${2}"
|
|
214
265
|
prompt="${3}"
|
|
@@ -230,15 +281,21 @@ function args_valid_or_select_pipe() {
|
|
|
230
281
|
# args_valid_or_select_args sel "which value" "a" "ab" "d"
|
|
231
282
|
# @SEE_ALSO
|
|
232
283
|
# args_valid_or_select, args_valid_or_select_pipe, args_valid_or_read, args_valid_or_default
|
|
233
|
-
|
|
284
|
+
args_valid_or_select_args() {
|
|
234
285
|
local valueVarName value prompt PS3
|
|
235
286
|
valueVarName="${1}"
|
|
236
|
-
|
|
287
|
+
eval 'value="${'"$valueVarName"'-}"'
|
|
288
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
289
|
+
# Preserve Bash's historical echo/word-splitting normalization, without
|
|
290
|
+
# reparsing the value with eval (which would execute input as code).
|
|
291
|
+
# shellcheck disable=SC2086,SC2116
|
|
292
|
+
value="$(echo $value)"
|
|
293
|
+
fi
|
|
237
294
|
prompt="${2}"
|
|
238
295
|
shift 2
|
|
239
296
|
|
|
240
297
|
while ! array_in "${value}" "$@"; do
|
|
241
|
-
|
|
298
|
+
printf '\n%s ?\n' "$prompt"
|
|
242
299
|
[[ -n "${value}" ]] && print_error "the input '${value}' is not valid."
|
|
243
300
|
|
|
244
301
|
PS3="choose one by ${COLOR_BOLD_YELLOW}number${COLOR_END} [1|2|...] ? "
|
|
@@ -246,8 +303,13 @@ function args_valid_or_select_args() {
|
|
|
246
303
|
break
|
|
247
304
|
done
|
|
248
305
|
done
|
|
249
|
-
|
|
250
|
-
|
|
306
|
+
|
|
307
|
+
eval "${valueVarName}=\"\$value\""
|
|
308
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
309
|
+
# shellcheck disable=SC2086,SC2116
|
|
310
|
+
value="$(echo $value)"
|
|
311
|
+
fi
|
|
312
|
+
printf "Selected value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$value"
|
|
251
313
|
}
|
|
252
314
|
|
|
253
315
|
# @NAME
|
|
@@ -265,28 +327,48 @@ function args_valid_or_select_args() {
|
|
|
265
327
|
# args_valid_or_read destRootPackage '^.+$' "Destination root package" "${defaultDestRootPackage}"
|
|
266
328
|
# @SEE_ALSO
|
|
267
329
|
# args_valid_or_select, args_valid_or_select_args, args_valid_or_select_pipe, args_valid_or_default
|
|
268
|
-
|
|
269
|
-
local
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
330
|
+
args_valid_or_read() {
|
|
331
|
+
local valueVarName="$1"
|
|
332
|
+
local regExp="${2}"
|
|
333
|
+
local prompt="${3}"
|
|
334
|
+
local proposedValue="${4-}"
|
|
335
|
+
local value
|
|
336
|
+
|
|
337
|
+
eval 'value="${'"$valueVarName"'-}"'
|
|
338
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
339
|
+
# Preserve Bash's historical echo/word-splitting normalization, without
|
|
340
|
+
# reparsing the value with eval (which would execute input as code).
|
|
341
|
+
# shellcheck disable=SC2086,SC2116
|
|
342
|
+
value="$(echo $value)"
|
|
343
|
+
fi
|
|
274
344
|
|
|
275
345
|
if [[ -n "${proposedValue}" ]]; then
|
|
276
346
|
prompt="${prompt} [${proposedValue}]"
|
|
277
|
-
if [[ -z "${value}" && "${modeQuiet}" == true ]]; then
|
|
347
|
+
if [[ -z "${value}" && "${modeQuiet:-false}" == true ]]; then
|
|
278
348
|
value="${proposedValue}"
|
|
279
349
|
fi
|
|
280
350
|
fi
|
|
281
|
-
|
|
351
|
+
|
|
352
|
+
while ! [[ $value =~ $regExp ]]; do
|
|
282
353
|
[[ -n "${value}" ]] && print_error "the input '${value}' is not valid, please input again."
|
|
283
|
-
|
|
354
|
+
if [[ -t 0 ]]; then
|
|
355
|
+
printf '%s: ' "$prompt" >&2
|
|
356
|
+
fi
|
|
357
|
+
read -r value || value=""
|
|
284
358
|
if [[ -z "${value}" ]]; then
|
|
285
359
|
value="${proposedValue}"
|
|
286
360
|
fi
|
|
287
361
|
done
|
|
288
|
-
|
|
289
|
-
|
|
362
|
+
|
|
363
|
+
eval "${valueVarName}=\"\$value\""
|
|
364
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
365
|
+
# Legacy Bash printed via `eval echo $name`: collapse display-only
|
|
366
|
+
# whitespace, but leave the actual assigned value unchanged.
|
|
367
|
+
# shellcheck disable=SC2086,SC2116
|
|
368
|
+
printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$(echo $value)"
|
|
369
|
+
else
|
|
370
|
+
printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$value"
|
|
371
|
+
fi
|
|
290
372
|
}
|
|
291
373
|
|
|
292
374
|
# @NAME
|
|
@@ -307,20 +389,36 @@ function args_valid_or_read() {
|
|
|
307
389
|
# args_valid_or_default destRootPackage '^.+$' "Destination root package" "${defaultDestRootPackage}"
|
|
308
390
|
# @SEE_ALSO
|
|
309
391
|
# args_valid_or_select, args_valid_or_select_args, args_valid_or_select_pipe, args_valid_or_read
|
|
310
|
-
|
|
311
|
-
local
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
392
|
+
args_valid_or_default() {
|
|
393
|
+
local valueVarName="$1"
|
|
394
|
+
local regExp="${2}"
|
|
395
|
+
local prompt="${3}"
|
|
396
|
+
local defaultValue="${4-}"
|
|
397
|
+
local value
|
|
398
|
+
|
|
399
|
+
eval 'value="${'"$valueVarName"'-}"'
|
|
400
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
401
|
+
# Preserve Bash's historical echo/word-splitting normalization, without
|
|
402
|
+
# reparsing the value with eval (which would execute input as code).
|
|
403
|
+
# shellcheck disable=SC2086,SC2116
|
|
404
|
+
value="$(echo $value)"
|
|
405
|
+
fi
|
|
316
406
|
|
|
317
|
-
if [[ -z "${value}" || ! $
|
|
318
|
-
prompt="for param ${
|
|
407
|
+
if [[ -z "${value}" || ! $value =~ $regExp ]]; then
|
|
408
|
+
prompt="for param ${valueVarName}:"
|
|
319
409
|
[[ -n "${value}" ]] && prompt+=" the input '${value}' is not valid" || prompt+=" no input"
|
|
320
410
|
[[ -n "${defaultValue}" ]] && prompt+=", fallback to default value '${defaultValue}'" || prompt+=", fallback to empty"
|
|
321
411
|
print_warn "${prompt}"
|
|
322
412
|
value="${defaultValue}"
|
|
323
413
|
fi
|
|
324
|
-
|
|
325
|
-
|
|
414
|
+
|
|
415
|
+
eval "${valueVarName}=\"\$value\""
|
|
416
|
+
if [[ -n "${BASH_VERSION:-}" ]]; then
|
|
417
|
+
# Legacy Bash printed via `eval echo $name`: collapse display-only
|
|
418
|
+
# whitespace, but leave the actual assigned value unchanged.
|
|
419
|
+
# shellcheck disable=SC2086,SC2116
|
|
420
|
+
printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$(echo $value)"
|
|
421
|
+
else
|
|
422
|
+
printf "Inputted value: ${COLOR_BLUE}'%s'${COLOR_END}\n" "$value"
|
|
423
|
+
fi
|
|
326
424
|
}
|