toys-core 0.6.1 → 0.7.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.
@@ -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