-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy patharguments.sh
241 lines (222 loc) · 7.15 KB
/
arguments.sh
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/usr/bin/env bash
# shellcheck source=./core.sh
source $(dirname ${BASH_SOURCE[0]})/core.sh
core.import array
# shellcheck disable=SC2034,SC2016
arguments__doc__='
The arguments module provides an argument parser that can be used in
functions and scripts.
Different functions are provided in order to parse an arguments array.
#### Example
>>> _() {
>>> local value
>>> arguments.set "$@"
>>> arguments.get_parameter param1 value
>>> echo "param1: $value"
>>> arguments.get_keyword keyword2 value
>>> echo "keyword2: $value"
>>> arguments.get_flag --flag4 value
>>> echo "--flag4: $value"
>>> # NOTE: Get the positionals last
>>> arguments.get_positional 1 value
>>> echo 1: "$value"
>>> # Alternative way to get positionals: Set the arguments array to
>>> # to all unparsed arguments.
>>> arguments.apply_new_arguments
>>> echo 1: "$1"
>>> }
>>> _ param1 value1 keyword2=value2 positional3 --flag4
param1: value1
keyword2: value2
--flag4: true
1: positional3
1: positional3
'
arguments_new_arguments=()
arguments_set() {
# shellcheck disable=SC2034,SC2016
local __doc__='
```
arguments.set argument1 argument2 ...
```
Set the array the arguments-module is working on. After getting the desired
arguments, the new argument array can be accessed via
`arguments_new_arguments`. This new array contains all remaining arguments.
'
arguments_new_arguments=("$@")
}
arguments_get_flag() {
# shellcheck disable=SC2034,SC2016
local __doc__='
```
arguments.get_flag flag [flag_aliases...] variable_name
```
Sets `variable_name` to true if flag (or on of its aliases) is contained in
the argument array (see `arguments.set`)
#### Example
```
arguments.get_flag verbose --verbose -v verbose_is_set
```
#### Tests
>>> arguments.set other_param1 --foo other_param2
>>> local foo bar
>>> arguments.get_flag --foo -f foo
>>> echo $foo
>>> arguments.get_flag --bar bar
>>> echo $bar
>>> echo "${arguments_new_arguments[@]}"
true
false
other_param1 other_param2
>>> arguments.set -f
>>> local foo
>>> arguments.get_flag --foo -f foo
>>> echo $foo
true
'
local variable match argument flag
local flag_aliases=($(array.slice :-1 "$@"))
variable="$(array.slice -1 "$@")"
local new_arguments=()
eval "${variable}=false"
for argument in "${arguments_new_arguments[@]:-}"; do
match=false
for flag in "${flag_aliases[@]}"; do
if [[ "$argument" == "$flag" ]]; then
match=true
eval "${variable}=true"
fi
done
$match || new_arguments+=( "$argument" )
done
arguments_new_arguments=( "${new_arguments[@]:+${new_arguments[@]}}" )
}
arguments_get_keyword() {
# shellcheck disable=SC2034,SC2016
local __doc__='
```
arguments.get_keyword keyword variable_name
```
Sets `variable_name` to the "value" of `keyword` the argument array (see
`arguments.set`) contains "keyword=value".
#### Example
```
arguments.get_keyword log loglevel
```
#### Tests
>>> local foo
>>> arguments.set other_param1 foo=bar baz=baz other_param2
>>> arguments.get_keyword foo foo
>>> echo $foo
>>> echo "${arguments_new_arguments[@]}"
bar
other_param1 baz=baz other_param2
>>> local foo
>>> arguments.set other_param1 foo=bar baz=baz other_param2
>>> arguments.get_keyword foo
>>> echo $foo
>>> arguments.get_keyword baz foo
>>> echo $foo
bar
baz
'
local keyword="$1"
local variable="$1"
[[ "${2:-}" != "" ]] && variable="$2"
# NOTE: use unique variable name "value_csh94wwn25" here as this prevents
# evaling something like "value=$value"
local argument key value_csh94wwn25
local new_arguments=()
for argument in "${arguments_new_arguments[@]:-}"; do
if [[ "$argument" == *=* ]]; then
IFS="=" read -r key value_csh94wwn25 <<<"$argument"
if [[ "$key" == "$keyword" ]]; then
eval "${variable}=$value_csh94wwn25"
else
new_arguments+=( "$argument" )
fi
else
new_arguments+=( "$argument" )
fi
done
arguments_new_arguments=( "${new_arguments[@]:+${new_arguments[@]}}" )
}
arguments_get_parameter() {
# shellcheck disable=SC2034,SC2016
local __doc__='
```
arguments.get_parameter parameter [parameter_aliases...] variable_name
```
Sets `variable_name` to the field following `parameter` (or one of the
`parameter_aliases`) from the argument array (see `arguments.set`).
#### Example
```
arguments.get_parameter --log-level -l loglevel
```
#### Tests
>>> local foo
>>> arguments.set other_param1 --foo bar other_param2
>>> arguments.get_parameter --foo -f foo
>>> echo $foo
>>> echo "${arguments_new_arguments[@]}"
bar
other_param1 other_param2
'
local parameter_aliases parameter variable argument index match
parameter_aliases=($(array.slice :-1 "$@"))
variable="$(array.slice -1 "$@")"
match=false
local new_arguments=()
for index in "${!arguments_new_arguments[@]}"; do
argument="${arguments_new_arguments[$index]}"
$match && match=false && continue
match=false
for parameter in "${parameter_aliases[@]}"; do
if [[ "$argument" == "$parameter" ]]; then
eval "${variable}=${arguments_new_arguments[((index+1))]}"
match=true
break
fi
done
$match || new_arguments+=( "$argument" )
done
arguments_new_arguments=( "${new_arguments[@]:+${new_arguments[@]}}" )
}
arguments_get_positional() {
# shellcheck disable=SC2034,SC2016
local __doc__='
```
arguments.get_positional index variable_name
```
Get the positional parameter at `index`. Use after extracting parameters,
keywords and flags.
>>> arguments.set parameter foo --flag pos1 pos2 --keyword=foo
>>> arguments.get_flag --flag _
>>> arguments.get_parameter parameter _
>>> arguments.get_keyword --keyword _
>>> local positional1 positional2
>>> arguments.get_positional 1 positional1
>>> arguments.get_positional 2 positional2
>>> echo "$positional1 $positional2"
pos1 pos2
'
local index="$1"
(( index-- )) # $0 is not available here
local variable="$2"
eval "${variable}=${arguments_new_arguments[index]}"
}
arguments_apply_new_arguments() {
local __doc__='
Call this function after you are finished with argument parsing. The
arguments array ($@) will then contain all unparsed arguments that are
left.
'
# implemented as alias
true
}
alias arguments.apply_new_arguments='set -- "${arguments_new_arguments[@]}"'
alias arguments.set="arguments_set"
alias arguments.get_flag="arguments_get_flag"
alias arguments.get_keyword="arguments_get_keyword"
alias arguments.get_parameter="arguments_get_parameter"
alias arguments.get_positional="arguments_get_positional"