toys-core 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Daniel Azuma
4
+ #
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions are met:
9
+ #
10
+ # * Redistributions of source code must retain the above copyright notice,
11
+ # this list of conditions and the following disclaimer.
12
+ # * Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ # * Neither the name of the copyright holder, nor the names of any other
16
+ # contributors to this software, may be used to endorse or promote products
17
+ # derived from this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ ;
31
+
32
+ module Toys
33
+ ##
34
+ # Namespace for standard middleware classes.
35
+ #
36
+ module StandardMiddleware
37
+ ## @private
38
+ COMMON_FLAG_GROUP = :__common
39
+
40
+ ## @private
41
+ def self.append_common_flag_group(tool)
42
+ tool.add_flag_group(type: :optional, name: COMMON_FLAG_GROUP,
43
+ desc: "Common Flags", report_collisions: false)
44
+ COMMON_FLAG_GROUP
45
+ end
46
+ end
47
+ end
@@ -82,6 +82,7 @@ module Toys
82
82
  #
83
83
  def config(tool_definition, _loader)
84
84
  unless tool_definition.argument_parsing_disabled?
85
+ StandardMiddleware.append_common_flag_group(tool_definition)
85
86
  add_verbose_flags(tool_definition)
86
87
  add_quiet_flags(tool_definition)
87
88
  end
@@ -99,7 +100,8 @@ module Toys
99
100
  report_collisions: false,
100
101
  handler: ->(_val, cur) { cur + 1 },
101
102
  desc: "Increase verbosity",
102
- long_desc: "Increase verbosity, causing additional logging levels to display."
103
+ long_desc: "Increase verbosity, causing additional logging levels to display.",
104
+ group: StandardMiddleware::COMMON_FLAG_GROUP
103
105
  )
104
106
  end
105
107
  end
@@ -112,7 +114,8 @@ module Toys
112
114
  report_collisions: false,
113
115
  handler: ->(_val, cur) { cur - 1 },
114
116
  desc: "Decrease verbosity",
115
- long_desc: "Decrease verbosity, causing fewer logging levels to display."
117
+ long_desc: "Decrease verbosity, causing fewer logging levels to display.",
118
+ group: StandardMiddleware::COMMON_FLAG_GROUP
116
119
  )
117
120
  end
118
121
  end
@@ -232,6 +232,7 @@ module Toys
232
232
  #
233
233
  def config(tool_definition, loader)
234
234
  unless tool_definition.argument_parsing_disabled?
235
+ StandardMiddleware.append_common_flag_group(tool_definition)
235
236
  has_subtools = loader.has_subtools?(tool_definition.full_name)
236
237
  help_flags = add_help_flags(tool_definition)
237
238
  usage_flags = add_usage_flags(tool_definition)
@@ -323,7 +324,8 @@ module Toys
323
324
  tool_definition.add_flag(
324
325
  SHOW_HELP_KEY, flags,
325
326
  report_collisions: false,
326
- desc: "Display help for this tool"
327
+ desc: "Display help for this tool",
328
+ group: StandardMiddleware::COMMON_FLAG_GROUP
327
329
  )
328
330
  end
329
331
  flags
@@ -335,7 +337,8 @@ module Toys
335
337
  tool_definition.add_flag(
336
338
  SHOW_USAGE_KEY, flags,
337
339
  report_collisions: false,
338
- desc: "Display a brief usage string for this tool"
340
+ desc: "Display a brief usage string for this tool",
341
+ group: StandardMiddleware::COMMON_FLAG_GROUP
339
342
  )
340
343
  end
341
344
  flags
@@ -347,7 +350,8 @@ module Toys
347
350
  tool_definition.add_flag(
348
351
  SHOW_LIST_KEY, flags,
349
352
  report_collisions: false,
350
- desc: "List the subtools under this tool"
353
+ desc: "List the subtools under this tool",
354
+ group: StandardMiddleware::COMMON_FLAG_GROUP
351
355
  )
352
356
  end
353
357
  flags
@@ -362,7 +366,8 @@ module Toys
362
366
  RECURSIVE_SUBTOOLS_KEY, flags,
363
367
  report_collisions: false, default: @default_recursive,
364
368
  desc: "List all subtools recursively when displaying help" \
365
- " (default is #{@default_recursive})"
369
+ " (default is #{@default_recursive})",
370
+ group: StandardMiddleware::COMMON_FLAG_GROUP
366
371
  )
367
372
  end
368
373
  flags
@@ -374,7 +379,8 @@ module Toys
374
379
  tool_definition.add_flag(
375
380
  SEARCH_STRING_KEY, flags,
376
381
  report_collisions: false,
377
- desc: "Search subtools for the given regular expression when displaying help"
382
+ desc: "Search subtools for the given regular expression when displaying help",
383
+ group: StandardMiddleware::COMMON_FLAG_GROUP
378
384
  )
379
385
  end
380
386
  flags
@@ -390,7 +396,8 @@ module Toys
390
396
  SHOW_ALL_SUBTOOLS_KEY, flags,
391
397
  report_collisions: false, default: @default_show_all_subtools,
392
398
  desc: "List all subtools including hidden subtools and namespaces" \
393
- " (default is #{@default_show_all_subtools})"
399
+ " (default is #{@default_show_all_subtools})",
400
+ group: StandardMiddleware::COMMON_FLAG_GROUP
394
401
  )
395
402
  end
396
403
  flags
@@ -48,8 +48,11 @@ module Toys
48
48
  # * **:env** (Hash) Environment variables to pass to the subprocess
49
49
  # * **:logger** (Logger) Logger to use for logging the actual command.
50
50
  # If not present, the command is not logged.
51
- # * **:log_level** (Integer) Log level for logging the actual command.
52
- # Defaults to Logger::INFO if not present.
51
+ # * **:log_level** (Integer,false) Level for logging the actual command.
52
+ # Defaults to Logger::INFO if not present. You may also pass `false` to
53
+ # disable logging of the command.
54
+ # * **:log_cmd** (String) The string logged for the actual command.
55
+ # Defaults to the `inspect` representation of the command.
53
56
  # * **:background** (Boolean) Runs the process in the background,
54
57
  # returning a controller object instead of a result object.
55
58
  # * **:in** Connects the input stream of the subprocess. See the section
@@ -456,7 +459,7 @@ module Toys
456
459
  end
457
460
 
458
461
  ##
459
- # Captures the remaining data in the stdandard output stream.
462
+ # Captures the remaining data in the standard output stream.
460
463
  # After calling this, do not read directly from the stream.
461
464
  #
462
465
  def capture_out
@@ -464,7 +467,7 @@ module Toys
464
467
  end
465
468
 
466
469
  ##
467
- # Captures the remaining data in the stdandard error stream.
470
+ # Captures the remaining data in the standard error stream.
468
471
  # After calling this, do not read directly from the stream.
469
472
  #
470
473
  def capture_err
@@ -129,7 +129,7 @@ module Toys
129
129
  if @suppress_confirm
130
130
  @default_confirm
131
131
  else
132
- @terminal.confirm("Gem needed: #{requirements_text}. Install?",
132
+ @terminal.confirm("Gem needed: #{requirements_text}. Install? ",
133
133
  default: @default_confirm)
134
134
  end
135
135
  unless response
@@ -193,7 +193,7 @@ module Toys
193
193
 
194
194
  def assemble
195
195
  add_synopsis_section
196
- add_flags_section
196
+ add_flag_group_sections
197
197
  add_positional_arguments_section if @tool.runnable?
198
198
  add_subtool_list_section
199
199
  @result = @lines.join("\n") + "\n"
@@ -224,12 +224,14 @@ module Toys
224
224
  ([@binary_name] + @tool.full_name + ["TOOL", "[ARGUMENTS...]"]).join(" ")
225
225
  end
226
226
 
227
- def add_flags_section
228
- return if @tool.flag_definitions.empty?
229
- @lines << ""
230
- @lines << "Flags:"
231
- @tool.flag_definitions.each do |flag|
232
- add_flag(flag)
227
+ def add_flag_group_sections
228
+ @tool.flag_groups.each do |group|
229
+ next if group.empty?
230
+ @lines << ""
231
+ @lines << group.desc.to_s + ":"
232
+ group.flag_definitions.each do |flag|
233
+ add_flag(flag)
234
+ end
233
235
  end
234
236
  end
235
237
 
@@ -328,7 +330,7 @@ module Toys
328
330
  add_name_section
329
331
  add_synopsis_section
330
332
  add_description_section
331
- add_flags_section
333
+ add_flag_group_sections
332
334
  add_positional_arguments_section
333
335
  add_subtool_list_section
334
336
  add_source_section
@@ -358,13 +360,9 @@ module Toys
358
360
  def add_synopsis_section
359
361
  @lines << ""
360
362
  @lines << bold("SYNOPSIS")
361
- if !@subtools.empty? && !@tool.runnable?
362
- add_synopsis_clause(namespace_synopsis)
363
- end
363
+ add_synopsis_clause(namespace_synopsis) if !@subtools.empty? && !@tool.runnable?
364
364
  add_synopsis_clause(tool_synopsis)
365
- if !@subtools.empty? && @tool.runnable?
366
- add_synopsis_clause(namespace_synopsis)
367
- end
365
+ add_synopsis_clause(namespace_synopsis) if !@subtools.empty? && @tool.runnable?
368
366
  end
369
367
 
370
368
  def add_synopsis_clause(synopsis)
@@ -377,8 +375,19 @@ module Toys
377
375
 
378
376
  def tool_synopsis
379
377
  synopsis = [full_binary_name]
380
- @tool.flag_definitions.each do |flag_def|
381
- synopsis << "[#{flag_spec_string(flag_def)}]"
378
+ @tool.flag_groups.each do |flag_group|
379
+ case flag_group
380
+ when Definition::FlagGroup::Required
381
+ add_required_group_to_synopsis(flag_group, synopsis)
382
+ when Definition::FlagGroup::ExactlyOne
383
+ add_exactly_one_group_to_synopsis(flag_group, synopsis)
384
+ when Definition::FlagGroup::AtMostOne
385
+ add_at_most_one_group_to_synopsis(flag_group, synopsis)
386
+ when Definition::FlagGroup::AtLeastOne
387
+ add_at_least_one_group_to_synopsis(flag_group, synopsis)
388
+ else
389
+ add_ordinary_group_to_synopsis(flag_group, synopsis)
390
+ end
382
391
  end
383
392
  @tool.arg_definitions.each do |arg_info|
384
393
  synopsis << arg_name(arg_info)
@@ -386,6 +395,57 @@ module Toys
386
395
  wrap_indent_indent2(Utils::WrappableString.new(synopsis))
387
396
  end
388
397
 
398
+ def add_ordinary_group_to_synopsis(flag_group, synopsis)
399
+ flag_group.flag_definitions.each do |flag_def|
400
+ synopsis << "[#{flag_spec_string(flag_def, true)}]"
401
+ end
402
+ end
403
+
404
+ def add_required_group_to_synopsis(flag_group, synopsis)
405
+ flag_group.flag_definitions.each do |flag_def|
406
+ synopsis << "(#{flag_spec_string(flag_def, true)})"
407
+ end
408
+ end
409
+
410
+ def add_exactly_one_group_to_synopsis(flag_group, synopsis)
411
+ return if flag_group.empty?
412
+ synopsis << "("
413
+ first = true
414
+ flag_group.flag_definitions.each do |flag_def|
415
+ if first
416
+ first = false
417
+ else
418
+ synopsis << "|"
419
+ end
420
+ synopsis << flag_spec_string(flag_def, true)
421
+ end
422
+ synopsis << ")"
423
+ end
424
+
425
+ def add_at_most_one_group_to_synopsis(flag_group, synopsis)
426
+ return if flag_group.empty?
427
+ synopsis << "["
428
+ first = true
429
+ flag_group.flag_definitions.each do |flag_def|
430
+ if first
431
+ first = false
432
+ else
433
+ synopsis << "|"
434
+ end
435
+ synopsis << flag_spec_string(flag_def, true)
436
+ end
437
+ synopsis << "]"
438
+ end
439
+
440
+ def add_at_least_one_group_to_synopsis(flag_group, synopsis)
441
+ return if flag_group.empty?
442
+ synopsis << "("
443
+ flag_group.flag_definitions.each do |flag_def|
444
+ synopsis << "[#{flag_spec_string(flag_def, true)}]"
445
+ end
446
+ synopsis << ")"
447
+ end
448
+
389
449
  def namespace_synopsis
390
450
  synopsis = [full_binary_name, underline("TOOL"), "[#{underline('ARGUMENTS')}...]"]
391
451
  wrap_indent_indent2(Utils::WrappableString.new(synopsis))
@@ -412,18 +472,26 @@ module Toys
412
472
  end
413
473
  end
414
474
 
415
- def add_flags_section
416
- return if @tool.flag_definitions.empty?
417
- @lines << ""
418
- @lines << bold("FLAGS")
419
- precede_with_blank = false
420
- @tool.flag_definitions.each do |flag|
421
- add_indented_section(flag_spec_string(flag), flag, precede_with_blank)
422
- precede_with_blank = true
475
+ def add_flag_group_sections
476
+ @tool.flag_groups.each do |group|
477
+ next if group.empty?
478
+ @lines << ""
479
+ @lines << bold(group.desc.to_s.upcase)
480
+ precede_with_blank = false
481
+ unless group.long_desc.empty?
482
+ wrap_indent(group.long_desc).each do |line|
483
+ @lines << indent_str(line)
484
+ end
485
+ precede_with_blank = true
486
+ end
487
+ group.flag_definitions.each do |flag|
488
+ add_indented_section(flag_spec_string(flag), flag, precede_with_blank)
489
+ precede_with_blank = true
490
+ end
423
491
  end
424
492
  end
425
493
 
426
- def flag_spec_string(flag)
494
+ def flag_spec_string(flag, in_synopsis = false)
427
495
  flag.flag_syntax.map do |fs|
428
496
  str = bold(fs.str_without_value)
429
497
  if fs.flag_type != :value
@@ -433,7 +501,7 @@ module Toys
433
501
  else
434
502
  "#{str}#{fs.value_delim}#{underline(fs.value_label)}"
435
503
  end
436
- end.join(", ")
504
+ end.join(in_synopsis ? " | " : ", ")
437
505
  end
438
506
 
439
507
  def add_positional_arguments_section
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toys-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-08 00:00:00.000000000 Z
11
+ date: 2019-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -128,10 +128,12 @@ files:
128
128
  - lib/toys/definition/alias.rb
129
129
  - lib/toys/definition/arg.rb
130
130
  - lib/toys/definition/flag.rb
131
+ - lib/toys/definition/flag_group.rb
131
132
  - lib/toys/definition/source_info.rb
132
133
  - lib/toys/definition/tool.rb
133
134
  - lib/toys/dsl/arg.rb
134
135
  - lib/toys/dsl/flag.rb
136
+ - lib/toys/dsl/flag_group.rb
135
137
  - lib/toys/dsl/tool.rb
136
138
  - lib/toys/errors.rb
137
139
  - lib/toys/input_file.rb
@@ -139,6 +141,7 @@ files:
139
141
  - lib/toys/middleware.rb
140
142
  - lib/toys/mixin.rb
141
143
  - lib/toys/runner.rb
144
+ - lib/toys/standard_middleware.rb
142
145
  - lib/toys/standard_middleware/add_verbosity_flags.rb
143
146
  - lib/toys/standard_middleware/handle_usage_errors.rb
144
147
  - lib/toys/standard_middleware/set_default_descriptions.rb