consoler 1.0.3 → 1.3.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.
- checksums.yaml +5 -5
- data/.github/workflows/tests.yml +34 -0
- data/.rubocop.yml +45 -0
- data/README.md +50 -37
- data/consoler.gemspec +4 -3
- data/lib/consoler/application.rb +73 -29
- data/lib/consoler/arguments.rb +0 -1
- data/lib/consoler/command.rb +0 -1
- data/lib/consoler/matcher.rb +73 -49
- data/lib/consoler/option.rb +75 -27
- data/lib/consoler/options.rb +34 -17
- data/lib/consoler/version.rb +1 -2
- metadata +23 -23
- data/.travis.yml +0 -11
data/lib/consoler/matcher.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Consoler
|
4
|
-
|
5
4
|
# Argument/Options matcher
|
6
5
|
#
|
7
6
|
# Given a list of arguments and a list option try to match them
|
8
7
|
class Matcher
|
9
|
-
|
10
8
|
# Create a matcher
|
11
9
|
#
|
12
10
|
# @param [Consoler::Arguments] arguments List of arguments
|
@@ -27,14 +25,14 @@ module Consoler
|
|
27
25
|
parse_options = true
|
28
26
|
|
29
27
|
_loop_args do |arg|
|
30
|
-
unless parse_options
|
28
|
+
unless parse_options
|
31
29
|
@argument_values.push arg
|
32
30
|
next
|
33
31
|
end
|
34
32
|
|
35
33
|
# when "argument" is --, then stop parsing the rest of the arguments
|
36
34
|
# and treat the rest as regular arguments
|
37
|
-
if arg == '--'
|
35
|
+
if arg == '--'
|
38
36
|
parse_options = false
|
39
37
|
next
|
40
38
|
end
|
@@ -49,12 +47,20 @@ module Consoler
|
|
49
47
|
remaining = _match_arguments
|
50
48
|
_fill_defaults
|
51
49
|
|
52
|
-
if @matched_options.size == @options.size
|
50
|
+
if @matched_options.size == @options.size
|
53
51
|
@matched_options['remaining'] = remaining
|
52
|
+
|
53
|
+
# make sure all aliases are also filled
|
54
|
+
@options.each do |option|
|
55
|
+
option.aliases.each do |alias_|
|
56
|
+
@matched_options[alias_.name] = @matched_options[option.name]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
54
60
|
return @matched_options
|
55
61
|
end
|
56
62
|
|
57
|
-
|
63
|
+
nil
|
58
64
|
end
|
59
65
|
|
60
66
|
private
|
@@ -68,59 +74,58 @@ module Consoler
|
|
68
74
|
is_short = false
|
69
75
|
name = nil
|
70
76
|
|
71
|
-
if arg[0..1] == '--'
|
77
|
+
if arg[0..1] == '--'
|
72
78
|
is_long = true
|
73
79
|
name = arg[2..-1]
|
74
|
-
elsif arg[0] == '-'
|
80
|
+
elsif arg[0] == '-'
|
75
81
|
is_short = true
|
76
82
|
name = arg[1..-1]
|
77
83
|
end
|
78
84
|
|
79
85
|
# arg is not a long/short option, add to arguments values
|
80
|
-
unless is_long
|
86
|
+
unless is_long || is_short
|
81
87
|
@argument_values.push arg
|
82
88
|
return true
|
83
89
|
end
|
84
90
|
|
85
|
-
unless name.nil?
|
91
|
+
unless name.nil?
|
86
92
|
# get the name of the option, short options use the first character
|
87
|
-
option_name = if is_short
|
93
|
+
option_name = if is_short
|
88
94
|
name[0]
|
89
95
|
else
|
90
96
|
name
|
91
97
|
end
|
92
98
|
|
93
|
-
option = @options.
|
99
|
+
option, matched = @options.get_with_alias option_name
|
94
100
|
|
95
101
|
# no option by this name in options
|
96
102
|
return nil if option.nil?
|
97
103
|
|
98
|
-
needs_short = option.is_short
|
99
|
-
needs_long = option.is_long
|
100
|
-
|
101
104
|
# see if the type if right, short or long
|
102
|
-
if
|
105
|
+
if matched.is_long && !is_long
|
103
106
|
return nil
|
104
|
-
elsif
|
107
|
+
elsif matched.is_short && !is_short
|
105
108
|
return nil
|
106
109
|
end
|
107
110
|
|
108
|
-
if is_long
|
109
|
-
if option.is_value
|
111
|
+
if is_long
|
112
|
+
if option.is_value
|
110
113
|
# is_value needs a next argument for its value
|
111
114
|
return nil if _peek_next.nil?
|
112
|
-
|
115
|
+
|
116
|
+
@matched_options[option.name] = _peek_next
|
113
117
|
_skip_next
|
114
118
|
else
|
115
|
-
|
119
|
+
option_value! option
|
116
120
|
end
|
117
121
|
end
|
118
122
|
|
119
|
-
if is_short
|
120
|
-
if name.size == 1
|
123
|
+
if is_short
|
124
|
+
if name.size == 1 && option.is_value
|
121
125
|
# is_value needs a next argument for its value
|
122
126
|
return nil if _peek_next.nil?
|
123
|
-
|
127
|
+
|
128
|
+
@matched_options[option.name] = _peek_next
|
124
129
|
_skip_next
|
125
130
|
else
|
126
131
|
# for every character (short option) increment the option value
|
@@ -128,17 +133,30 @@ module Consoler
|
|
128
133
|
short_option = @options.get n
|
129
134
|
return nil if short_option.nil?
|
130
135
|
|
131
|
-
|
132
|
-
@matched_options[n] = 0
|
133
|
-
end
|
134
|
-
|
135
|
-
@matched_options[n] += 1
|
136
|
+
option_value! short_option
|
136
137
|
end
|
137
138
|
end
|
138
139
|
end
|
139
140
|
end
|
140
141
|
|
141
|
-
|
142
|
+
true
|
143
|
+
end
|
144
|
+
|
145
|
+
# Set the value of an option
|
146
|
+
#
|
147
|
+
# Long or short option needed
|
148
|
+
#
|
149
|
+
# @param [Consoler::Option]
|
150
|
+
def option_value!(option)
|
151
|
+
if option.is_short
|
152
|
+
if @matched_options[option.name].nil?
|
153
|
+
@matched_options[option.name] = 0
|
154
|
+
end
|
155
|
+
|
156
|
+
@matched_options[option.name] += 1
|
157
|
+
else
|
158
|
+
@matched_options[option.name] = true
|
159
|
+
end
|
142
160
|
end
|
143
161
|
|
144
162
|
# Loop through the arguments
|
@@ -151,7 +169,7 @@ module Consoler
|
|
151
169
|
|
152
170
|
# use an incrementing index, to be able to peek to the next in the list
|
153
171
|
# and to skip an item
|
154
|
-
while @index < size
|
172
|
+
while @index < size
|
155
173
|
yield @arguments.args[@index]
|
156
174
|
|
157
175
|
_skip_next
|
@@ -183,11 +201,13 @@ module Consoler
|
|
183
201
|
|
184
202
|
# Match arguments to defined option arguments
|
185
203
|
#
|
186
|
-
# @return [Array<String
|
204
|
+
# @return [Array<String>, nil] The remaining args,
|
205
|
+
# or <tt>nil</tt> if there are not enough arguments
|
187
206
|
def _match_arguments
|
188
207
|
@optionals_before = {}
|
189
208
|
@optionals_before_has_remaining = false
|
190
209
|
|
210
|
+
total_argument_values = @argument_values.size
|
191
211
|
argument_values_index = 0
|
192
212
|
|
193
213
|
_match_arguments_optionals_before
|
@@ -197,7 +217,9 @@ module Consoler
|
|
197
217
|
# arguments supplied (info available from optionals map)
|
198
218
|
optionals.each do |_, optional|
|
199
219
|
optional.each do |before|
|
200
|
-
if before[:included]
|
220
|
+
if before[:included]
|
221
|
+
return nil if argument_values_index >= total_argument_values
|
222
|
+
|
201
223
|
@matched_options[before[:name]] = @argument_values[argument_values_index]
|
202
224
|
argument_values_index += 1
|
203
225
|
end
|
@@ -205,7 +227,9 @@ module Consoler
|
|
205
227
|
end
|
206
228
|
|
207
229
|
# only fill mandatory argument if its not the :REMAINING key
|
208
|
-
if mandatory_arg_name != :REMAINING
|
230
|
+
if mandatory_arg_name != :REMAINING
|
231
|
+
return nil if argument_values_index >= total_argument_values
|
232
|
+
|
209
233
|
@matched_options[mandatory_arg_name] = @argument_values[argument_values_index]
|
210
234
|
argument_values_index += 1
|
211
235
|
end
|
@@ -214,7 +238,7 @@ module Consoler
|
|
214
238
|
remaining = []
|
215
239
|
|
216
240
|
# left over arguments
|
217
|
-
while argument_values_index < @argument_values.size
|
241
|
+
while argument_values_index < @argument_values.size
|
218
242
|
remaining.push @argument_values[argument_values_index]
|
219
243
|
argument_values_index += 1
|
220
244
|
end
|
@@ -229,18 +253,18 @@ module Consoler
|
|
229
253
|
@optionals_before = {}
|
230
254
|
tracker = {}
|
231
255
|
|
232
|
-
@options.each do |option,
|
256
|
+
@options.each do |option, _key|
|
233
257
|
next unless option.is_argument
|
234
258
|
|
235
|
-
if option.is_optional
|
259
|
+
if option.is_optional
|
236
260
|
# setup tracker for optional group
|
237
261
|
tracker[option.is_optional] = [] if tracker[option.is_optional].nil?
|
238
262
|
|
239
263
|
# mark all optionals as not-included
|
240
|
-
tracker[option.is_optional].push(
|
264
|
+
tracker[option.is_optional].push(
|
241
265
|
included: false,
|
242
266
|
name: option.name,
|
243
|
-
|
267
|
+
)
|
244
268
|
else
|
245
269
|
@optionals_before[option.name] = tracker
|
246
270
|
tracker = {}
|
@@ -248,7 +272,7 @@ module Consoler
|
|
248
272
|
end
|
249
273
|
|
250
274
|
# make sure all optionals are accounted for in the map
|
251
|
-
if tracker != {}
|
275
|
+
if tracker != {}
|
252
276
|
# use a special key so we can handle it differently in the filling process
|
253
277
|
@optionals_before[:REMAINING] = tracker
|
254
278
|
@optionals_before_has_remaining = true
|
@@ -267,7 +291,7 @@ module Consoler
|
|
267
291
|
mandatories_matched = @optionals_before.size
|
268
292
|
|
269
293
|
# there are optionals at the end of the options, don't match the void
|
270
|
-
if @optionals_before_has_remaining
|
294
|
+
if @optionals_before_has_remaining
|
271
295
|
mandatories_matched -= 1
|
272
296
|
end
|
273
297
|
|
@@ -276,11 +300,11 @@ module Consoler
|
|
276
300
|
# loop through optional map
|
277
301
|
_each_optional_before_sorted do |before|
|
278
302
|
# are there enough arguments left to fill this optional group
|
279
|
-
if (total + before.size + mandatories_matched) <= @argument_values.size
|
303
|
+
if (total + before.size + mandatories_matched) <= @argument_values.size
|
280
304
|
total += before.size
|
281
305
|
|
282
306
|
before.each do |val|
|
283
|
-
val[:included] = true
|
307
|
+
val[:included] = true
|
284
308
|
end
|
285
309
|
end
|
286
310
|
end
|
@@ -293,10 +317,10 @@ module Consoler
|
|
293
317
|
# @return [Consoler::Matcher]
|
294
318
|
def _fill_defaults
|
295
319
|
@options.each do |option|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
320
|
+
next unless option.is_optional
|
321
|
+
|
322
|
+
unless @matched_options.key? option.name
|
323
|
+
@matched_options[option.name] = option.default_value
|
300
324
|
end
|
301
325
|
end
|
302
326
|
|
@@ -312,10 +336,10 @@ module Consoler
|
|
312
336
|
@optionals_before.each do |_, optionals|
|
313
337
|
tmp = []
|
314
338
|
optionals.each do |optional_index, before|
|
315
|
-
tmp.push(
|
339
|
+
tmp.push(
|
316
340
|
count: before.size,
|
317
341
|
index: optional_index,
|
318
|
-
|
342
|
+
)
|
319
343
|
end
|
320
344
|
|
321
345
|
tmp.sort! { |a, b| b[:count] - a[:count] }.each do |item|
|
data/lib/consoler/option.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Consoler
|
4
|
-
|
5
4
|
# Represents an option
|
6
5
|
#
|
7
6
|
# @attr_reader [String] name Name of the options
|
@@ -10,6 +9,7 @@ module Consoler
|
|
10
9
|
# @attr_reader [Boolean] is_argument Is the option an argument
|
11
10
|
# @attr_reader [Boolean] is_value Does the option need a value (<tt>--option=</tt>)
|
12
11
|
# @attr_reader [Integer] is_optional Is the option optional (> 0) (<tt>[option]</tt>)
|
12
|
+
# @attr_reader [Array] aliases List of aliases of option (<tt>-v|--verbose</tt>)
|
13
13
|
class Option
|
14
14
|
attr_reader :name
|
15
15
|
attr_reader :is_long
|
@@ -17,6 +17,7 @@ module Consoler
|
|
17
17
|
attr_reader :is_argument
|
18
18
|
attr_reader :is_value
|
19
19
|
attr_reader :is_optional
|
20
|
+
attr_reader :aliases
|
20
21
|
|
21
22
|
# Create a option
|
22
23
|
#
|
@@ -28,13 +29,13 @@ module Consoler
|
|
28
29
|
option = Option.new option_def, tracker
|
29
30
|
|
30
31
|
# split short options with more than 1 char in multiple options
|
31
|
-
if option.is_short
|
32
|
+
if option.is_short && option.name.size > 1
|
32
33
|
# remember state
|
33
34
|
old_tracking = tracker.is_tracking
|
34
35
|
old_is_value = option.is_value
|
35
36
|
|
36
37
|
# if the complete option is optional, fake the tracker
|
37
|
-
if option.is_optional
|
38
|
+
if option.is_optional
|
38
39
|
tracker.is_tracking = true
|
39
40
|
end
|
40
41
|
|
@@ -44,7 +45,7 @@ module Consoler
|
|
44
45
|
new_name = "-#{name}"
|
45
46
|
|
46
47
|
# if the short option should have a value, this only counts for the last option
|
47
|
-
if old_is_value
|
48
|
+
if old_is_value && i == names.count - 1
|
48
49
|
new_name = "#{new_name}="
|
49
50
|
end
|
50
51
|
|
@@ -67,14 +68,20 @@ module Consoler
|
|
67
68
|
def to_definition
|
68
69
|
definition = name
|
69
70
|
|
70
|
-
if is_long
|
71
|
+
if is_long
|
71
72
|
definition = "--#{definition}"
|
72
|
-
elsif is_short
|
73
|
+
elsif is_short
|
73
74
|
definition = "-#{definition}"
|
74
75
|
end
|
75
76
|
|
76
|
-
if is_value
|
77
|
+
if is_value
|
77
78
|
definition = "#{definition}="
|
79
|
+
elsif is_argument
|
80
|
+
definition = "<#{definition}>"
|
81
|
+
end
|
82
|
+
|
83
|
+
aliases.each do |alias_|
|
84
|
+
definition = "#{definition}|#{alias_.to_definition}"
|
78
85
|
end
|
79
86
|
|
80
87
|
definition
|
@@ -88,7 +95,7 @@ module Consoler
|
|
88
95
|
return 0 if is_short
|
89
96
|
return false if is_long
|
90
97
|
|
91
|
-
|
98
|
+
nil
|
92
99
|
end
|
93
100
|
|
94
101
|
protected
|
@@ -103,19 +110,33 @@ module Consoler
|
|
103
110
|
# Check for multiple attributes in the option definition till we got the
|
104
111
|
# final name and all of its attributes
|
105
112
|
|
106
|
-
|
113
|
+
# make sure we don't wrongly process any alias
|
114
|
+
alias_defs = option_def.split '|'
|
115
|
+
option = alias_defs.shift || ''
|
116
|
+
|
117
|
+
option, @is_optional = _is_optional option, tracker
|
107
118
|
option, @is_long = _is_long option
|
108
119
|
option, @is_short = _is_short option
|
109
|
-
@is_argument = (
|
120
|
+
@is_argument = (!@is_long && !@is_short)
|
110
121
|
option, @is_value = _value option, @is_argument
|
122
|
+
option, @aliases = _aliases option, alias_defs, tracker
|
123
|
+
|
124
|
+
if option[0] == '<'
|
125
|
+
raise 'Invalid <, missing >' if option[-1] != '>'
|
126
|
+
raise 'Only arguments support <, > around name' unless @is_argument
|
127
|
+
|
128
|
+
option = option[1..-2]
|
129
|
+
end
|
130
|
+
|
131
|
+
raise 'Missing starting <' if option[-1] == '>'
|
111
132
|
|
112
133
|
@name = option
|
113
134
|
|
114
|
-
if @name.empty?
|
135
|
+
if @name.empty?
|
115
136
|
raise 'Option must have a name'
|
116
137
|
end
|
117
138
|
|
118
|
-
if @is_long
|
139
|
+
if @is_long && @is_short
|
119
140
|
raise 'Option can not be a long and a short option'
|
120
141
|
end
|
121
142
|
end
|
@@ -135,8 +156,8 @@ module Consoler
|
|
135
156
|
# @raise [RuntimeError] if you try to close an unopened optional
|
136
157
|
# @return [(String, Integer|nil)] Remaining option definition, and, optional group if available
|
137
158
|
def _is_optional(option, tracker)
|
138
|
-
if option[0] == '['
|
139
|
-
if !tracker.is_tracking
|
159
|
+
if option[0] == '['
|
160
|
+
if !tracker.is_tracking
|
140
161
|
# mark tracker as tracking
|
141
162
|
tracker.is_tracking = true
|
142
163
|
tracker.index += 1
|
@@ -147,14 +168,12 @@ module Consoler
|
|
147
168
|
end
|
148
169
|
|
149
170
|
# get optional group index from tracking, if tracking
|
150
|
-
optional = if tracker.is_tracking
|
171
|
+
optional = if tracker.is_tracking
|
151
172
|
tracker.index
|
152
|
-
else
|
153
|
-
nil
|
154
173
|
end
|
155
174
|
|
156
|
-
if option[-1] == ']'
|
157
|
-
if tracker.is_tracking
|
175
|
+
if option[-1] == ']'
|
176
|
+
if tracker.is_tracking
|
158
177
|
# mark tracker as non-tracking
|
159
178
|
tracker.is_tracking = false
|
160
179
|
option = option[0..-2]
|
@@ -163,7 +182,7 @@ module Consoler
|
|
163
182
|
end
|
164
183
|
end
|
165
184
|
|
166
|
-
|
185
|
+
[option, optional]
|
167
186
|
end
|
168
187
|
|
169
188
|
# Check long definition
|
@@ -171,14 +190,14 @@ module Consoler
|
|
171
190
|
# @param [String] option Option definition
|
172
191
|
# @return [(String, Boolean)]
|
173
192
|
def _is_long(option)
|
174
|
-
if option[0..1] == '--'
|
193
|
+
if option[0..1] == '--'
|
175
194
|
long = true
|
176
195
|
option = option[2..-1]
|
177
196
|
else
|
178
197
|
long = false
|
179
198
|
end
|
180
199
|
|
181
|
-
|
200
|
+
[option, long]
|
182
201
|
end
|
183
202
|
|
184
203
|
# Check short definition
|
@@ -186,14 +205,14 @@ module Consoler
|
|
186
205
|
# @param [String] option Option definition
|
187
206
|
# @return [(String, Boolean)]
|
188
207
|
def _is_short(option)
|
189
|
-
if option[0] == '-'
|
208
|
+
if option[0] == '-'
|
190
209
|
short = true
|
191
210
|
option = option[1..-1]
|
192
211
|
else
|
193
212
|
short = false
|
194
213
|
end
|
195
214
|
|
196
|
-
|
215
|
+
[option, short]
|
197
216
|
end
|
198
217
|
|
199
218
|
# Check value definition
|
@@ -202,8 +221,8 @@ module Consoler
|
|
202
221
|
# @raise [RuntimeError] if you try to assign a value to an argument
|
203
222
|
# @return [(String, Boolean)]
|
204
223
|
def _value(option, argument)
|
205
|
-
if option[-1] == '='
|
206
|
-
if argument
|
224
|
+
if option[-1] == '='
|
225
|
+
if argument
|
207
226
|
raise 'Arguments can\'t have a value'
|
208
227
|
end
|
209
228
|
|
@@ -213,7 +232,36 @@ module Consoler
|
|
213
232
|
value = false
|
214
233
|
end
|
215
234
|
|
216
|
-
|
235
|
+
[option, value]
|
236
|
+
end
|
237
|
+
|
238
|
+
# Parse all possible aliases
|
239
|
+
#
|
240
|
+
# @param [String] option Option definition
|
241
|
+
# @param [Consoler::Tracker] tracker Optional tracker
|
242
|
+
# @raise [RuntimeError] On all kinds of occasions
|
243
|
+
# @return [(String, Array)] Remaining option definition, and, aliases if available
|
244
|
+
def _aliases(option, alias_defs, tracker)
|
245
|
+
return option, [] if alias_defs.empty?
|
246
|
+
|
247
|
+
raise 'Argument can\'t have aliases' if is_argument
|
248
|
+
raise 'Aliases are not allowed for multiple short options' if is_short && option.size > 1
|
249
|
+
|
250
|
+
aliases_ = []
|
251
|
+
alias_names = []
|
252
|
+
|
253
|
+
while (alias_def = alias_defs.shift)
|
254
|
+
Consoler::Option.create alias_def, tracker do |alias_|
|
255
|
+
raise "Duplicate alias name: #{alias_.name}" if alias_names.include? alias_.name
|
256
|
+
raise "Alias must have a value: #{alias_.name}" if is_value && !alias_.is_value
|
257
|
+
raise "Alias can't have a value: #{alias_.name}" if !is_value && alias_.is_value
|
258
|
+
|
259
|
+
aliases_.push alias_
|
260
|
+
alias_names.push alias_.name
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
[option, aliases_]
|
217
265
|
end
|
218
266
|
end
|
219
267
|
end
|
data/lib/consoler/options.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require_relative 'option'
|
4
4
|
|
5
5
|
module Consoler
|
6
|
-
|
7
6
|
# List of options
|
8
7
|
#
|
9
8
|
# @attr_reader [String] description Description of the options
|
@@ -21,7 +20,7 @@ module Consoler
|
|
21
20
|
return if options_def.nil?
|
22
21
|
|
23
22
|
# strip the description
|
24
|
-
if match = /(^|\s+)-- (?<description>.*)$/.match(options_def)
|
23
|
+
if (match = /(^|\s+)-- (?<description>.*)$/.match(options_def))
|
25
24
|
@description = match[:description]
|
26
25
|
options_def = options_def[0...-match[0].size]
|
27
26
|
end
|
@@ -31,28 +30,50 @@ module Consoler
|
|
31
30
|
|
32
31
|
option_names = []
|
33
32
|
|
34
|
-
while option_def = options.shift
|
33
|
+
while (option_def = options.shift)
|
35
34
|
Consoler::Option.create option_def, tracker do |option|
|
36
35
|
raise "Duplicate option name: #{option.name}" if option_names.include? option.name
|
37
36
|
|
38
|
-
@options.push option
|
39
37
|
option_names.push option.name
|
38
|
+
|
39
|
+
option.aliases.each do |alias_|
|
40
|
+
raise "Duplicate alias name: #{alias_.name}" if option_names.include? alias_.name
|
41
|
+
|
42
|
+
option_names.push alias_.name
|
43
|
+
end
|
44
|
+
|
45
|
+
@options.push option
|
40
46
|
end
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
44
|
-
# Get a
|
50
|
+
# Get a option by its name
|
51
|
+
#
|
52
|
+
# May be matched by one of its aliases
|
45
53
|
#
|
46
54
|
# @param name [String] Name of the option
|
47
55
|
# @return [Consoler::Option, nil]
|
48
56
|
def get(name)
|
57
|
+
option, = get_with_alias name
|
58
|
+
option
|
59
|
+
end
|
60
|
+
|
61
|
+
# Get a option by its name, with matched alias
|
62
|
+
#
|
63
|
+
# @param name [String] Name of the option
|
64
|
+
# @return [[(Consoler::Option, nil), (Consoler::Option, nil)]]
|
65
|
+
def get_with_alias(name)
|
49
66
|
each do |option, _|
|
50
|
-
if option.name == name
|
51
|
-
return option
|
67
|
+
if option.name == name
|
68
|
+
return option, option
|
69
|
+
end
|
70
|
+
|
71
|
+
option.aliases.each do |alias_|
|
72
|
+
return option, alias_ if alias_.name == name
|
52
73
|
end
|
53
74
|
end
|
54
75
|
|
55
|
-
|
76
|
+
[nil, nil]
|
56
77
|
end
|
57
78
|
|
58
79
|
# Loop through all options
|
@@ -84,19 +105,17 @@ module Consoler
|
|
84
105
|
each do |option, i|
|
85
106
|
definition += ' '
|
86
107
|
|
87
|
-
if optional.nil?
|
108
|
+
if optional.nil? && option.is_optional
|
88
109
|
definition += '['
|
89
110
|
optional = option.is_optional
|
90
111
|
end
|
91
112
|
|
92
113
|
definition += option.to_definition
|
93
114
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
optional = nil
|
99
|
-
end
|
115
|
+
# only close when the next option is not optional, or another optional group
|
116
|
+
if option.is_optional && (@options[i + 1].nil? || optional != @options[i + 1].is_optional)
|
117
|
+
definition += ']'
|
118
|
+
optional = nil
|
100
119
|
end
|
101
120
|
end
|
102
121
|
|
@@ -104,8 +123,6 @@ module Consoler
|
|
104
123
|
end
|
105
124
|
end
|
106
125
|
|
107
|
-
private
|
108
|
-
|
109
126
|
# Optionals tracker
|
110
127
|
#
|
111
128
|
# @attr [Boolean] is_tracking Is inside optional options
|