tty-option 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +1200 -488
- data/lib/tty/option/conversions.rb +27 -17
- data/lib/tty/option/deep_dup.rb +43 -19
- data/lib/tty/option/errors.rb +33 -3
- data/lib/tty/option/formatter.rb +364 -69
- data/lib/tty/option/param_permitted.rb +7 -3
- data/lib/tty/option/param_validation.rb +124 -20
- data/lib/tty/option/parameter.rb +2 -1
- data/lib/tty/option/parser/options.rb +6 -1
- data/lib/tty/option/version.rb +1 -1
- metadata +3 -2
data/lib/tty/option/formatter.rb
CHANGED
@@ -5,30 +5,55 @@ require_relative "usage_wrapper"
|
|
5
5
|
|
6
6
|
module TTY
|
7
7
|
module Option
|
8
|
+
# Responsible for formatting help display
|
9
|
+
#
|
10
|
+
# @api private
|
8
11
|
class Formatter
|
9
12
|
include UsageWrapper
|
10
13
|
|
11
|
-
|
14
|
+
BOOLEANS = [true, false].freeze
|
12
15
|
DEFAULT_WIDTH = 80
|
13
|
-
|
16
|
+
DOUBLE_SPACE = " "
|
14
17
|
ELLIPSIS = "..."
|
18
|
+
EMPTY = ""
|
19
|
+
LIST_SEPARATOR = ", "
|
20
|
+
MAP_SEPARATOR = ":"
|
21
|
+
NEWLINE = "\n"
|
15
22
|
SPACE = " "
|
16
23
|
|
17
|
-
|
24
|
+
DEFAULT_NAME_SELECTOR = ->(param) { param.name }
|
18
25
|
DEFAULT_ORDER = ->(params) { params.sort }
|
26
|
+
DEFAULT_PARAM_DISPLAY = ->(str) { str.to_s.upcase }
|
19
27
|
NOOP_PROC = ->(param) { param }
|
20
|
-
DEFAULT_NAME_SELECTOR = ->(param) { param.name }
|
21
28
|
|
29
|
+
# Generate help for parameters and usage
|
30
|
+
#
|
31
|
+
# @param [TTY::Option::Parameters] parameters
|
32
|
+
# the parameters to format
|
33
|
+
# @param [TTY::Option::Usage] usage
|
34
|
+
# the usage to format
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
#
|
22
38
|
# @api public
|
23
39
|
def self.help(parameters, usage, **config, &block)
|
24
40
|
new(parameters, usage, **config).help(&block)
|
25
41
|
end
|
26
42
|
|
27
|
-
|
28
|
-
|
29
|
-
# Create a help formatter
|
43
|
+
# Create a Formatter instance
|
30
44
|
#
|
31
|
-
# @param [Parameters]
|
45
|
+
# @param [TTY::Option::Parameters] parameters
|
46
|
+
# the parameters to format
|
47
|
+
# @param [TTY::Option::Usage] usage
|
48
|
+
# the usage to format
|
49
|
+
# @param [Proc] param_display
|
50
|
+
# the parameter display formatter, by default, uppercases all chars
|
51
|
+
# @param [Integer] width
|
52
|
+
# the width at which to wrap the help display, by default 80 columns
|
53
|
+
# @param [Proc] order
|
54
|
+
# the order for displaying parameters, by default alphabetical
|
55
|
+
# @param [Integer] indent
|
56
|
+
# the indent for help display
|
32
57
|
#
|
33
58
|
# @api public
|
34
59
|
def initialize(parameters, usage, param_display: DEFAULT_PARAM_DISPLAY,
|
@@ -51,7 +76,10 @@ module TTY
|
|
51
76
|
}
|
52
77
|
end
|
53
78
|
|
54
|
-
#
|
79
|
+
# Generate help display
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
# formatter.help
|
55
83
|
#
|
56
84
|
# @yieldparam [TTY::Option::Sections] sections
|
57
85
|
#
|
@@ -90,18 +118,50 @@ module TTY
|
|
90
118
|
formatted.end_with?(NEWLINE) ? formatted : formatted + NEWLINE
|
91
119
|
end
|
92
120
|
|
121
|
+
# Generate help header
|
122
|
+
#
|
123
|
+
# @example
|
124
|
+
# formatter.help_header
|
125
|
+
#
|
126
|
+
# @return [String]
|
127
|
+
#
|
128
|
+
# @api public
|
93
129
|
def help_header
|
94
130
|
"#{format_multiline(@usage.header, @indent)}#{NEWLINE}"
|
95
131
|
end
|
96
132
|
|
133
|
+
# Generate help banner
|
134
|
+
#
|
135
|
+
# @example
|
136
|
+
# formatter.help_banner
|
137
|
+
#
|
138
|
+
# @return [String]
|
139
|
+
#
|
140
|
+
# @api public
|
97
141
|
def help_banner
|
98
142
|
(@usage.banner? ? @usage.banner : format_usage)
|
99
143
|
end
|
100
144
|
|
145
|
+
# Generate help description
|
146
|
+
#
|
147
|
+
# @example
|
148
|
+
# formatter.help_description
|
149
|
+
#
|
150
|
+
# @return [String]
|
151
|
+
#
|
152
|
+
# @api public
|
101
153
|
def help_description
|
102
154
|
"#{NEWLINE}#{format_description}"
|
103
155
|
end
|
104
156
|
|
157
|
+
# Generate help arguments
|
158
|
+
#
|
159
|
+
# @example
|
160
|
+
# formatter.help_arguments
|
161
|
+
#
|
162
|
+
# @return [String]
|
163
|
+
#
|
164
|
+
# @api public
|
105
165
|
def help_arguments
|
106
166
|
"#{NEWLINE}#{@space_indent}#{@section_names[:arguments]}#{NEWLINE}" +
|
107
167
|
format_section(@parameters.arguments, ->(param) do
|
@@ -109,6 +169,14 @@ module TTY
|
|
109
169
|
end)
|
110
170
|
end
|
111
171
|
|
172
|
+
# Generate help keywords
|
173
|
+
#
|
174
|
+
# @example
|
175
|
+
# formatter.help_keywords
|
176
|
+
#
|
177
|
+
# @return [String]
|
178
|
+
#
|
179
|
+
# @api public
|
112
180
|
def help_keywords
|
113
181
|
"#{NEWLINE}#{@space_indent}#{@section_names[:keywords]}#{NEWLINE}" +
|
114
182
|
format_section(@parameters.keywords, ->(param) do
|
@@ -116,28 +184,62 @@ module TTY
|
|
116
184
|
end)
|
117
185
|
end
|
118
186
|
|
187
|
+
# Generate help options
|
188
|
+
#
|
189
|
+
# @example
|
190
|
+
# formatter.help_options
|
191
|
+
#
|
192
|
+
# @return [String]
|
193
|
+
#
|
194
|
+
# @api public
|
119
195
|
def help_options
|
120
196
|
"#{NEWLINE}#{@space_indent}#{@section_names[:options]}#{NEWLINE}" +
|
121
197
|
format_options
|
122
198
|
end
|
123
199
|
|
200
|
+
# Generate help environment variables
|
201
|
+
#
|
202
|
+
# @example
|
203
|
+
# formatter.help_environments
|
204
|
+
#
|
205
|
+
# @return [String]
|
206
|
+
#
|
207
|
+
# @api public
|
124
208
|
def help_environments
|
125
209
|
"#{NEWLINE}#{@space_indent}#{@section_names[:env]}#{NEWLINE}" +
|
126
210
|
format_section(@order.(@parameters.environments))
|
127
211
|
end
|
128
212
|
|
213
|
+
# Generate help examples
|
214
|
+
#
|
215
|
+
# @example
|
216
|
+
# formatter.help_examples
|
217
|
+
#
|
218
|
+
# @return [String]
|
219
|
+
#
|
220
|
+
# @api public
|
129
221
|
def help_examples
|
130
222
|
"#{NEWLINE}#{@space_indent}#{@section_names[:examples]}#{NEWLINE}" +
|
131
223
|
format_examples
|
132
224
|
end
|
133
225
|
|
226
|
+
# Generate help footer
|
227
|
+
#
|
228
|
+
# @example
|
229
|
+
# formatter.help_footer
|
230
|
+
#
|
231
|
+
# @return [String]
|
232
|
+
#
|
233
|
+
# @api public
|
134
234
|
def help_footer
|
135
235
|
"#{NEWLINE}#{format_multiline(@usage.footer, @indent)}"
|
136
236
|
end
|
137
237
|
|
138
238
|
private
|
139
239
|
|
140
|
-
#
|
240
|
+
# Format default usage banner
|
241
|
+
#
|
242
|
+
# @return [String]
|
141
243
|
#
|
142
244
|
# @api private
|
143
245
|
def format_usage
|
@@ -149,10 +251,12 @@ module TTY
|
|
149
251
|
output << " [#{@param_display.("environment")}]" if @parameters.environments?
|
150
252
|
output << " #{format_arguments_usage}" if @parameters.arguments?
|
151
253
|
output << " #{format_keywords_usage}" if @parameters.keywords?
|
152
|
-
usage + wrap(output.join, indent: usage.length, width: width)
|
254
|
+
usage + wrap(output.join, indent: usage.length, width: @width)
|
153
255
|
end
|
154
256
|
|
155
|
-
# Format arguments
|
257
|
+
# Format arguments usage
|
258
|
+
#
|
259
|
+
# @return [String]
|
156
260
|
#
|
157
261
|
# @api private
|
158
262
|
def format_arguments_usage
|
@@ -165,7 +269,12 @@ module TTY
|
|
165
269
|
end.join(SPACE)
|
166
270
|
end
|
167
271
|
|
168
|
-
#
|
272
|
+
# Format argument usage
|
273
|
+
#
|
274
|
+
# @param [TTY::Option::Parameter::Argument] arg
|
275
|
+
# the argument to format
|
276
|
+
#
|
277
|
+
# @return [String]
|
169
278
|
#
|
170
279
|
# @api private
|
171
280
|
def format_argument_usage(arg)
|
@@ -175,6 +284,13 @@ module TTY
|
|
175
284
|
|
176
285
|
# Format parameter usage
|
177
286
|
#
|
287
|
+
# @param [TTY::Option::Parameter] param
|
288
|
+
# the parameter to format
|
289
|
+
# @param [String] param_name
|
290
|
+
# the parameter name
|
291
|
+
#
|
292
|
+
# @return [String]
|
293
|
+
#
|
178
294
|
# @api private
|
179
295
|
def format_parameter_usage(param, param_name)
|
180
296
|
args = []
|
@@ -193,6 +309,8 @@ module TTY
|
|
193
309
|
|
194
310
|
# Format keywords usage
|
195
311
|
#
|
312
|
+
# @return [String]
|
313
|
+
#
|
196
314
|
# @api private
|
197
315
|
def format_keywords_usage
|
198
316
|
return "" unless @parameters.keywords?
|
@@ -204,7 +322,12 @@ module TTY
|
|
204
322
|
end.join(SPACE)
|
205
323
|
end
|
206
324
|
|
207
|
-
#
|
325
|
+
# Format keyword usage
|
326
|
+
#
|
327
|
+
# @param [TTY::Option::Parameter::Keyword] kwarg
|
328
|
+
# the keyword to format
|
329
|
+
#
|
330
|
+
# @return [String]
|
208
331
|
#
|
209
332
|
# @api private
|
210
333
|
def format_keyword_usage(kwarg)
|
@@ -212,7 +335,14 @@ module TTY
|
|
212
335
|
format_parameter_usage(kwarg, param_name)
|
213
336
|
end
|
214
337
|
|
215
|
-
#
|
338
|
+
# Format keyword name
|
339
|
+
#
|
340
|
+
# @param [TTY::Option::Parameter::Keyword] kwarg
|
341
|
+
# the keyword to format
|
342
|
+
# @param [Proc] param_display
|
343
|
+
# the parameter display formatter, by default, uppercases all chars
|
344
|
+
#
|
345
|
+
# @return [String]
|
216
346
|
#
|
217
347
|
# @api private
|
218
348
|
def kwarg_param_display(kwarg, param_display = NOOP_PROC)
|
@@ -227,19 +357,18 @@ module TTY
|
|
227
357
|
"#{kwarg_name}=#{conv_name}"
|
228
358
|
end
|
229
359
|
|
230
|
-
# Format
|
231
|
-
#
|
232
|
-
# @param [String] parameters_name
|
233
|
-
# the name of parameter type
|
360
|
+
# Format section parameters
|
234
361
|
#
|
362
|
+
# @param [Array<TTY::Option::Parameter>] params
|
363
|
+
# the parameters to format
|
235
364
|
# @param [Proc] name_selector
|
236
|
-
#
|
365
|
+
# the parameter name selector, by default, calls the name
|
237
366
|
#
|
238
367
|
# @return [String]
|
239
368
|
#
|
240
369
|
# @api private
|
241
370
|
def format_section(params, name_selector = DEFAULT_NAME_SELECTOR)
|
242
|
-
longest_param = params
|
371
|
+
longest_param = find_longest_parameter(params, &name_selector)
|
243
372
|
|
244
373
|
params.reduce([]) do |acc, param|
|
245
374
|
next acc if param.hidden?
|
@@ -248,44 +377,45 @@ module TTY
|
|
248
377
|
end.join(NEWLINE)
|
249
378
|
end
|
250
379
|
|
251
|
-
# Format
|
380
|
+
# Format section parameter
|
381
|
+
#
|
382
|
+
# @param [TTY::Option::Parameter] param
|
383
|
+
# the parameter to format
|
384
|
+
# @param [Integer] longest_param
|
385
|
+
# the longest parameter length
|
386
|
+
# @param [Proc] name_selector
|
387
|
+
# the parameter name selector, by default, calls the name
|
252
388
|
#
|
253
389
|
# @return [String]
|
254
390
|
#
|
255
391
|
# @api private
|
256
392
|
def format_section_parameter(param, longest_param, name_selector)
|
257
393
|
line = []
|
258
|
-
desc = []
|
259
|
-
indent = @param_indent + longest_param + 2
|
260
394
|
param_name = name_selector.(param)
|
395
|
+
description = parameter_description?(param)
|
396
|
+
template = description ? "%s%-#{longest_param}s" : "%s%s"
|
261
397
|
|
262
|
-
|
263
|
-
line << format("%s%-#{longest_param}s", SPACE * @param_indent, param_name)
|
264
|
-
desc << " #{param.desc}"
|
265
|
-
else
|
266
|
-
line << format("%s%s", SPACE * @param_indent, param_name)
|
267
|
-
end
|
398
|
+
line << format(template, SPACE * @param_indent, param_name)
|
268
399
|
|
269
|
-
if
|
270
|
-
desc
|
400
|
+
if description
|
401
|
+
desc = format_parameter_description(param)
|
402
|
+
indent = @param_indent + longest_param + 2
|
403
|
+
line << wrap(desc, indent: indent, width: @width)
|
271
404
|
end
|
272
405
|
|
273
|
-
if (default = format_default(param))
|
274
|
-
desc << default
|
275
|
-
end
|
276
|
-
|
277
|
-
line << wrap(desc.join, indent: indent, width: width)
|
278
406
|
line.join
|
279
407
|
end
|
280
408
|
|
281
409
|
# Format multiline description
|
282
410
|
#
|
411
|
+
# @return [String]
|
412
|
+
#
|
283
413
|
# @api private
|
284
414
|
def format_description
|
285
415
|
format_multiline(@usage.desc, @indent)
|
286
416
|
end
|
287
417
|
|
288
|
-
#
|
418
|
+
# Format options
|
289
419
|
#
|
290
420
|
# @return [String]
|
291
421
|
#
|
@@ -293,69 +423,225 @@ module TTY
|
|
293
423
|
def format_options
|
294
424
|
return "" if @parameters.options.empty?
|
295
425
|
|
296
|
-
longest_option = @parameters.options.map(&:long)
|
297
|
-
.compact.max_by(&:length).length
|
298
|
-
any_short = @parameters.options.map(&:short).compact.any?
|
299
426
|
ordered_options = @order.(@parameters.options)
|
427
|
+
longest_short = find_longest_short_option
|
428
|
+
longest_long = find_longest_long_option
|
300
429
|
|
301
430
|
ordered_options.reduce([]) do |acc, option|
|
302
431
|
next acc if option.hidden?
|
303
|
-
|
432
|
+
|
433
|
+
acc << format_option(option, longest_short, longest_long)
|
304
434
|
end.join(NEWLINE)
|
305
435
|
end
|
306
436
|
|
437
|
+
# Find the longest short option
|
438
|
+
#
|
439
|
+
# @return [Integer, nil]
|
440
|
+
#
|
441
|
+
# @api private
|
442
|
+
def find_longest_short_option
|
443
|
+
short_options = @parameters.options.select(&:short?)
|
444
|
+
find_longest_parameter(short_options) do |option|
|
445
|
+
option.long? ? option.short_name : option.short
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
# Find the longest long option
|
450
|
+
#
|
451
|
+
# @return [Integer, nil]
|
452
|
+
#
|
453
|
+
# @api private
|
454
|
+
def find_longest_long_option
|
455
|
+
long_options = @parameters.options.select(&:long?)
|
456
|
+
find_longest_parameter(long_options, &:long)
|
457
|
+
end
|
458
|
+
|
459
|
+
# Find the longest parameter
|
460
|
+
#
|
461
|
+
# @param [Array<TTY::Option::Parameter>] params
|
462
|
+
# the parameters to search
|
463
|
+
#
|
464
|
+
# @yield [TTY::Option::Parameter]
|
465
|
+
#
|
466
|
+
# @return [Integer, nil]
|
467
|
+
#
|
468
|
+
# @api private
|
469
|
+
def find_longest_parameter(params, &name_selector)
|
470
|
+
params = params.reject(&:hidden?).map(&name_selector)
|
471
|
+
|
472
|
+
params.max_by(&:length).length if params.any?
|
473
|
+
end
|
474
|
+
|
307
475
|
# Format an option
|
308
476
|
#
|
477
|
+
# @param [TTY::Option::Parameter::Option] option
|
478
|
+
# the option to format
|
479
|
+
# @param [Integer, nil] longest_short
|
480
|
+
# the longest short option length or nil
|
481
|
+
# @param [Integer, nil] longest_long
|
482
|
+
# the longest long option length or nil
|
483
|
+
#
|
484
|
+
# @return [String]
|
485
|
+
#
|
309
486
|
# @api private
|
310
|
-
def format_option(option,
|
487
|
+
def format_option(option, longest_short, longest_long)
|
311
488
|
line = [@space_indent]
|
312
|
-
desc = []
|
313
489
|
indent = @indent
|
314
490
|
|
315
|
-
if
|
316
|
-
|
317
|
-
|
318
|
-
indent += SHORT_OPT_LENGTH
|
491
|
+
if longest_short
|
492
|
+
line << " #{format_short_option(option, longest_short)}"
|
493
|
+
indent += line.last.length
|
319
494
|
end
|
320
495
|
|
321
|
-
|
322
|
-
|
323
|
-
|
496
|
+
if longest_long
|
497
|
+
separator = short_and_long_option_separator(option)
|
498
|
+
line << "#{separator}#{format_long_option(option, longest_long)}"
|
499
|
+
indent += line.last.length
|
500
|
+
end
|
324
501
|
|
502
|
+
if parameter_description?(option)
|
503
|
+
indent += 2
|
504
|
+
desc = format_parameter_description(option)
|
505
|
+
line << wrap(desc, indent: indent, width: @width)
|
506
|
+
end
|
507
|
+
|
508
|
+
line.join
|
509
|
+
end
|
510
|
+
|
511
|
+
# Format a short option
|
512
|
+
#
|
513
|
+
# @param [TTY::Option::Parameter::Option] option
|
514
|
+
# the option to format
|
515
|
+
# @param [Integer] longest
|
516
|
+
# the longest short option length
|
517
|
+
#
|
518
|
+
# @return [String]
|
519
|
+
#
|
520
|
+
# @api private
|
521
|
+
def format_short_option(option, longest)
|
522
|
+
if option.long?
|
523
|
+
format("%-#{longest}s", option.short_name)
|
524
|
+
elsif parameter_description?(option)
|
525
|
+
format("%-#{longest}s", option.short)
|
526
|
+
else
|
527
|
+
option.short
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
# Format a long option
|
532
|
+
#
|
533
|
+
# @param [TTY::Option::Parameter::Option] option
|
534
|
+
# the option to format
|
535
|
+
# @param [Integer] longest
|
536
|
+
# the longest long option length
|
537
|
+
#
|
538
|
+
# @return [String]
|
539
|
+
#
|
540
|
+
# @api private
|
541
|
+
def format_long_option(option, longest)
|
325
542
|
if option.long?
|
326
|
-
if option
|
327
|
-
|
543
|
+
if parameter_description?(option)
|
544
|
+
format("%-#{longest}s", option.long)
|
328
545
|
else
|
329
|
-
|
546
|
+
option.long
|
330
547
|
end
|
331
|
-
|
332
|
-
|
548
|
+
elsif parameter_description?(option)
|
549
|
+
format("%-#{longest}s", SPACE)
|
333
550
|
end
|
334
|
-
|
551
|
+
end
|
335
552
|
|
336
|
-
|
337
|
-
|
553
|
+
# Short and long option separator
|
554
|
+
#
|
555
|
+
# @param [TTY::Option::Parameter::Option] option
|
556
|
+
# the option to separate short and long names
|
557
|
+
#
|
558
|
+
# @return [String]
|
559
|
+
#
|
560
|
+
# @api private
|
561
|
+
def short_and_long_option_separator(option)
|
562
|
+
if option.short? && option.long?
|
563
|
+
LIST_SEPARATOR
|
564
|
+
elsif option.long? || parameter_description?(option)
|
565
|
+
DOUBLE_SPACE
|
566
|
+
else
|
567
|
+
EMPTY
|
338
568
|
end
|
339
|
-
|
569
|
+
end
|
570
|
+
|
571
|
+
# Format a parameter description
|
572
|
+
#
|
573
|
+
# @param [TTY::Option::Parameter] param
|
574
|
+
# the parameter to format
|
575
|
+
#
|
576
|
+
# @return [String]
|
577
|
+
#
|
578
|
+
# @api private
|
579
|
+
def format_parameter_description(param)
|
580
|
+
desc = []
|
340
581
|
|
341
|
-
if
|
342
|
-
|
582
|
+
desc << " #{param.desc}" if param.desc?
|
583
|
+
|
584
|
+
if param.permit?
|
585
|
+
desc << SPACE unless param.desc?
|
586
|
+
desc << format_permitted(param.permit)
|
343
587
|
end
|
344
588
|
|
345
|
-
if (default = format_default(
|
589
|
+
if (default = format_default(param))
|
590
|
+
desc << SPACE unless param.desc?
|
346
591
|
desc << default
|
347
592
|
end
|
348
593
|
|
349
|
-
|
594
|
+
desc.join
|
595
|
+
end
|
350
596
|
|
351
|
-
|
597
|
+
# Check whether or not parameter has description
|
598
|
+
#
|
599
|
+
# @param [TTY::Option::Parameter] param
|
600
|
+
# the parameter to check for description
|
601
|
+
#
|
602
|
+
# @return [Boolean]
|
603
|
+
#
|
604
|
+
# @api private
|
605
|
+
def parameter_description?(param)
|
606
|
+
param.desc? || param.permit? || parameter_default?(param)
|
607
|
+
end
|
608
|
+
|
609
|
+
# Check whether or not parameter has default
|
610
|
+
#
|
611
|
+
# @param [TTY::Option::Parameter] param
|
612
|
+
# the parameter to check for default
|
613
|
+
#
|
614
|
+
# @return [Boolean]
|
615
|
+
#
|
616
|
+
# @api private
|
617
|
+
def parameter_default?(param)
|
618
|
+
param.default? && !BOOLEANS.include?(param.default)
|
619
|
+
end
|
620
|
+
|
621
|
+
# Format permitted values
|
622
|
+
#
|
623
|
+
# @param [Parameter] values
|
624
|
+
# the permitted values to format
|
625
|
+
#
|
626
|
+
# @return [String]
|
627
|
+
#
|
628
|
+
# @api private
|
629
|
+
def format_permitted(values)
|
630
|
+
format(" (permitted: %s)", values.map do |val|
|
631
|
+
val.respond_to?(:to_ary) ? val.join(MAP_SEPARATOR) : val
|
632
|
+
end.join(LIST_SEPARATOR))
|
352
633
|
end
|
353
634
|
|
354
|
-
# Format default value
|
635
|
+
# Format a default value
|
636
|
+
#
|
637
|
+
# @param [TTY::Option::Parameter] param
|
638
|
+
# the parameter to format
|
639
|
+
#
|
640
|
+
# @return [String]
|
355
641
|
#
|
356
642
|
# @api private
|
357
643
|
def format_default(param)
|
358
|
-
return
|
644
|
+
return unless parameter_default?(param)
|
359
645
|
|
360
646
|
if param.default.is_a?(String)
|
361
647
|
format(" (default %p)", param.default)
|
@@ -366,6 +652,8 @@ module TTY
|
|
366
652
|
|
367
653
|
# Format examples section
|
368
654
|
#
|
655
|
+
# @return [String]
|
656
|
+
#
|
369
657
|
# @api private
|
370
658
|
def format_examples
|
371
659
|
format_multiline(@usage.example, @param_indent)
|
@@ -373,15 +661,22 @@ module TTY
|
|
373
661
|
|
374
662
|
# Format multiline content
|
375
663
|
#
|
664
|
+
# @param [Array<Array<String>>] lines
|
665
|
+
# the lines to format
|
666
|
+
# @param [Integer] indent
|
667
|
+
# the indent for the lines
|
668
|
+
#
|
669
|
+
# @return [String]
|
670
|
+
#
|
376
671
|
# @api private
|
377
672
|
def format_multiline(lines, indent)
|
378
673
|
last_index = lines.size - 1
|
379
674
|
lines.map.with_index do |line, i|
|
380
675
|
line.map do |part|
|
381
676
|
part.split(NEWLINE).map do |p|
|
382
|
-
wrap(p, indent: indent, width: width, indent_first: true)
|
677
|
+
wrap(p, indent: indent, width: @width, indent_first: true)
|
383
678
|
end.join(NEWLINE)
|
384
|
-
end.join(NEWLINE) + (last_index
|
679
|
+
end.join(NEWLINE) + (last_index == i ? EMPTY : NEWLINE)
|
385
680
|
end.join(NEWLINE)
|
386
681
|
end
|
387
682
|
end # Formatter
|
@@ -13,12 +13,16 @@ module TTY
|
|
13
13
|
#
|
14
14
|
# @api public
|
15
15
|
def call(param, value)
|
16
|
-
return Result.success(value)
|
16
|
+
return Result.success(value) if !param.permit? || value.nil?
|
17
17
|
|
18
|
-
|
18
|
+
unpermitted = Array(value) - Array(param.permit)
|
19
|
+
|
20
|
+
if unpermitted.empty?
|
19
21
|
Result.success(value)
|
20
22
|
else
|
21
|
-
Result.failure(
|
23
|
+
Result.failure(unpermitted.map do |val|
|
24
|
+
UnpermittedArgument.new(param, val)
|
25
|
+
end)
|
22
26
|
end
|
23
27
|
end
|
24
28
|
module_function :call
|