toys-core 0.3.10 → 0.3.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bfede9155648ae5e0b3766dfad5b5165f80fa865eca0e91d390706616372c6e
4
- data.tar.gz: 78ba80645b891e5382049153d47168ef69f18e7e762efe553a0f77ad14aa178a
3
+ metadata.gz: 170a7493ef1b6d852d4a551b7e6f38d0cf861f6660c8b2b1d710c1eee7b5dd2b
4
+ data.tar.gz: eb2b614017aff294664306a4a2aa6ce96eda22bf37a375c9bb03641c39eb439d
5
5
  SHA512:
6
- metadata.gz: f0f9533b044b056ea6ea46d121a18fd0a9966b1aadacc845c36651c258bf7bdf8ba8851ccd0f00770a27da67697dcf1fe003804e94b720f87efab4a348cb9cab
7
- data.tar.gz: c010707f7452adf31bdbe1d4bd692f39a285091e899c46d6cd964c686ba1aa3df7e119df3888da0f2f660732409c96b1768604f0af48768efa90c188c8497d22
6
+ metadata.gz: 2e0dc6614370daa927916614b19631dd6b9541d3ed664593b4aeaa6cab2407cb8abf7284afbf13c100fc7b6a783ac261c10e280f7112e6f359bcce90125ab414
7
+ data.tar.gz: aa7dbaf6c473f233207886fb2b4ce11a7dd551f802dd4e16ad9e8647ee394c8c96f5b6f483e3a775aab08224d4213cce05cf78dbf5fb1000258c4630942e2dc9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Release History
2
2
 
3
+ ### 0.3.11 / 2018-07-02
4
+
5
+ * CHANGED: Require Ruby 2.3 or later
6
+ * CHANGED: Renamed "set" directive to "static" to reduce confusion with Tool#set.
7
+ * ADDED: Convenience methods for getting option values
8
+
3
9
  ### 0.3.10 / 2018-06-30
4
10
 
5
11
  * CHANGED: Dropped Tool#option. Use Tool#get instead.
data/README.md CHANGED
@@ -10,7 +10,7 @@ Toys-Core is the command line tool framework underlying Toys. It can be used
10
10
  to create command line binaries using the internal Toys APIs.
11
11
 
12
12
  To get started using toys-core for your own command line binary, see the
13
- {file:docs/getting-started.md Getting Started Guide}.
13
+ [Getting Started Guide](https://www.rubydoc.info/gems/toys-core/file/docs/getting-started.md)
14
14
 
15
15
  ## Contributing
16
16
 
data/lib/toys-core.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
data/lib/toys/cli.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -32,5 +34,5 @@ module Toys
32
34
  # Current version of Toys core
33
35
  # @return [String]
34
36
  #
35
- CORE_VERSION = "0.3.10".freeze
37
+ CORE_VERSION = "0.3.11"
36
38
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -465,8 +467,8 @@ module Toys
465
467
  # the script may use to obtain the flag value from the context.
466
468
  # You may then provide the flags themselves in `OptionParser` form.
467
469
  #
468
- # @param [Symbol] key The key to use to retrieve the value from the
469
- # execution context.
470
+ # @param [String,Symbol] key The key to use to retrieve the value from
471
+ # the execution context.
470
472
  # @param [Array<String>] flags The flags in OptionParser format.
471
473
  # @param [Object] accept An acceptor that validates and/or converts the
472
474
  # value. You may provide either the name of an acceptor you have
@@ -529,8 +531,8 @@ module Toys
529
531
  # a key which the script may use to obtain the argument value from the
530
532
  # context.
531
533
  #
532
- # @param [Symbol] key The key to use to retrieve the value from the
533
- # execution context.
534
+ # @param [String,Symbol] key The key to use to retrieve the value from
535
+ # the execution context.
534
536
  # @param [Object] accept An acceptor that validates and/or converts the
535
537
  # value. You may provide either the name of an acceptor you have
536
538
  # defined, or one of the default acceptors provided by OptionParser.
@@ -559,8 +561,8 @@ module Toys
559
561
  # context. If an optional argument is not given on the command line, the
560
562
  # value is set to the given default.
561
563
  #
562
- # @param [Symbol] key The key to use to retrieve the value from the
563
- # execution context.
564
+ # @param [String,Symbol] key The key to use to retrieve the value from
565
+ # the execution context.
564
566
  # @param [Object] default The default value. This is the value that will
565
567
  # be set in the context if this argument is not provided on the command
566
568
  # line. Defaults to `nil`.
@@ -594,8 +596,8 @@ module Toys
594
596
  # specify a key which the script may use to obtain the remaining args
595
597
  # from the context.
596
598
  #
597
- # @param [Symbol] key The key to use to retrieve the value from the
598
- # execution context.
599
+ # @param [String,Symbol] key The key to use to retrieve the value from
600
+ # the execution context.
599
601
  # @param [Object] default The default value. This is the value that will
600
602
  # be set in the context if no unmatched arguments are provided on the
601
603
  # command line. Defaults to the empty array `[]`.
data/lib/toys/dsl/arg.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
data/lib/toys/dsl/flag.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
data/lib/toys/dsl/tool.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -48,7 +50,7 @@ module Toys
48
50
  # optional_arg :recipient, default: "world"
49
51
  #
50
52
  # def run
51
- # puts "Hello, #{get(:recipient)}!"
53
+ # puts "Hello, #{recipient}!"
52
54
  # end
53
55
  # end
54
56
  #
@@ -294,8 +296,7 @@ module Toys
294
296
  # @param [Toys::Utils::WrappableString,String,Array<String>...] strs
295
297
  #
296
298
  def long_desc(*strs)
297
- cur_tool = DSL::Tool.current_tool(self, true)
298
- cur_tool.append_long_desc(strs) if cur_tool
299
+ DSL::Tool.current_tool(self, true)&.append_long_desc(strs)
299
300
  self
300
301
  end
301
302
 
@@ -304,11 +305,17 @@ module Toys
304
305
  # the script may use to obtain the flag value from the context.
305
306
  # You may then provide the flags themselves in OptionParser form.
306
307
  #
308
+ # If the given key is a symbol representing a valid method name, then a
309
+ # helper method is automatically added to retrieve the value. Otherwise,
310
+ # if the key is a string or does not represent a valid method name, the
311
+ # tool can retrieve the value by calling {Toys::Tool#get}.
312
+ #
307
313
  # Attributes of the flag may be passed in as arguments to this method, or
308
- # set in a block passed to this method.
314
+ # set in a block passed to this method. If you provide a block, you can
315
+ # use directives in {Toys::DSL::Flag} within the block.
309
316
  #
310
- # @param [Symbol] key The key to use to retrieve the value from the
311
- # execution context.
317
+ # @param [String,Symbol] key The key to use to retrieve the value from
318
+ # the execution context.
312
319
  # @param [String...] flags The flags in OptionParser format.
313
320
  # @param [Object] accept An acceptor that validates and/or converts the
314
321
  # value. You may provide either the name of an acceptor you have
@@ -343,10 +350,11 @@ module Toys
343
350
  &block)
344
351
  cur_tool = DSL::Tool.current_tool(self, true)
345
352
  return self if cur_tool.nil?
346
- flag_dsl = DSL::Flag.new(flags, accept, default, handler, report_collisions,
347
- desc, long_desc)
353
+ flag_dsl = DSL::Flag.new(flags, accept, default, handler,
354
+ report_collisions, desc, long_desc)
348
355
  flag_dsl.instance_exec(flag_dsl, &block) if block
349
356
  flag_dsl._add_to(cur_tool, key)
357
+ DSL::Tool.maybe_add_getter(self, key)
350
358
  self
351
359
  end
352
360
 
@@ -355,8 +363,17 @@ module Toys
355
363
  # a key which the script may use to obtain the argument value from the
356
364
  # context.
357
365
  #
358
- # @param [Symbol] key The key to use to retrieve the value from the
359
- # execution context.
366
+ # If the given key is a symbol representing a valid method name, then a
367
+ # helper method is automatically added to retrieve the value. Otherwise,
368
+ # if the key is a string or does not represent a valid method name, the
369
+ # tool can retrieve the value by calling {Toys::Tool#get}.
370
+ #
371
+ # Attributes of the arg may be passed in as arguments to this method, or
372
+ # set in a block passed to this method. If you provide a block, you can
373
+ # use directives in {Toys::DSL::Arg} within the block.
374
+ #
375
+ # @param [String,Symbol] key The key to use to retrieve the value from
376
+ # the execution context.
360
377
  # @param [Object] accept An acceptor that validates and/or converts the
361
378
  # value. You may provide either the name of an acceptor you have
362
379
  # defined, or one of the default acceptors provided by OptionParser.
@@ -375,13 +392,15 @@ module Toys
375
392
  # this argument in a block.
376
393
  #
377
394
  def required_arg(key,
378
- accept: nil, display_name: nil, desc: nil, long_desc: nil,
395
+ accept: nil, display_name: nil,
396
+ desc: nil, long_desc: nil,
379
397
  &block)
380
398
  cur_tool = DSL::Tool.current_tool(self, true)
381
399
  return self if cur_tool.nil?
382
400
  arg_dsl = DSL::Arg.new(accept, nil, display_name, desc, long_desc)
383
401
  arg_dsl.instance_exec(arg_dsl, &block) if block
384
402
  arg_dsl._add_required_to(cur_tool, key)
403
+ DSL::Tool.maybe_add_getter(self, key)
385
404
  self
386
405
  end
387
406
  alias required required_arg
@@ -392,8 +411,17 @@ module Toys
392
411
  # context. If an optional argument is not given on the command line, the
393
412
  # value is set to the given default.
394
413
  #
395
- # @param [Symbol] key The key to use to retrieve the value from the
396
- # execution context.
414
+ # If the given key is a symbol representing a valid method name, then a
415
+ # helper method is automatically added to retrieve the value. Otherwise,
416
+ # if the key is a string or does not represent a valid method name, the
417
+ # tool can retrieve the value by calling {Toys::Tool#get}.
418
+ #
419
+ # Attributes of the arg may be passed in as arguments to this method, or
420
+ # set in a block passed to this method. If you provide a block, you can
421
+ # use directives in {Toys::DSL::Arg} within the block.
422
+ #
423
+ # @param [String,Symbol] key The key to use to retrieve the value from
424
+ # the execution context.
397
425
  # @param [Object] default The default value. This is the value that will
398
426
  # be set in the context if this argument is not provided on the command
399
427
  # line. Defaults to `nil`.
@@ -423,6 +451,7 @@ module Toys
423
451
  arg_dsl = DSL::Arg.new(accept, default, display_name, desc, long_desc)
424
452
  arg_dsl.instance_exec(arg_dsl, &block) if block
425
453
  arg_dsl._add_optional_to(cur_tool, key)
454
+ DSL::Tool.maybe_add_getter(self, key)
426
455
  self
427
456
  end
428
457
  alias optional optional_arg
@@ -432,8 +461,17 @@ module Toys
432
461
  # specify a key which the script may use to obtain the remaining args from
433
462
  # the context.
434
463
  #
435
- # @param [Symbol] key The key to use to retrieve the value from the
436
- # execution context.
464
+ # If the given key is a symbol representing a valid method name, then a
465
+ # helper method is automatically added to retrieve the value. Otherwise,
466
+ # if the key is a string or does not represent a valid method name, the
467
+ # tool can retrieve the value by calling {Toys::Tool#get}.
468
+ #
469
+ # Attributes of the arg may be passed in as arguments to this method, or
470
+ # set in a block passed to this method. If you provide a block, you can
471
+ # use directives in {Toys::DSL::Arg} within the block.
472
+ #
473
+ # @param [String,Symbol] key The key to use to retrieve the value from
474
+ # the execution context.
437
475
  # @param [Object] default The default value. This is the value that will
438
476
  # be set in the context if no unmatched arguments are provided on the
439
477
  # command line. Defaults to the empty array `[]`.
@@ -463,6 +501,7 @@ module Toys
463
501
  arg_dsl = DSL::Arg.new(accept, default, display_name, desc, long_desc)
464
502
  arg_dsl.instance_exec(arg_dsl, &block) if block
465
503
  arg_dsl._set_remaining_on(cur_tool, key)
504
+ DSL::Tool.maybe_add_getter(self, key)
466
505
  self
467
506
  end
468
507
  alias remaining remaining_args
@@ -470,17 +509,26 @@ module Toys
470
509
  ##
471
510
  # Set an option value statically.
472
511
  #
473
- # @param [Symbol] key The key to use to retrieve the value from the
474
- # execution context.
512
+ # If the given key is a symbol representing a valid method name, then a
513
+ # helper method is automatically added to retrieve the value. Otherwise,
514
+ # if the key is a string or does not represent a valid method name, the
515
+ # tool can retrieve the value by calling {Toys::Tool#get}.
516
+ #
517
+ # @param [String,Symbol] key The key to use to retrieve the value from
518
+ # the execution context.
475
519
  # @param [Object] value The value to set.
476
520
  #
477
- def set(key, value = nil)
521
+ def static(key, value = nil)
478
522
  cur_tool = DSL::Tool.current_tool(self, true)
479
523
  return self if cur_tool.nil?
480
524
  if key.is_a?(::Hash)
481
525
  cur_tool.default_data.merge!(key)
526
+ key.each_key do |k|
527
+ DSL::Tool.maybe_add_getter(self, k)
528
+ end
482
529
  else
483
530
  cur_tool.default_data[key] = value
531
+ DSL::Tool.maybe_add_getter(self, key)
484
532
  end
485
533
  self
486
534
  end
@@ -494,8 +542,7 @@ module Toys
494
542
  # declare arguments or flags.
495
543
  #
496
544
  def disable_argument_parsing
497
- cur_tool = DSL::Tool.current_tool(self, true)
498
- cur_tool.disable_argument_parsing unless cur_tool.nil?
545
+ DSL::Tool.current_tool(self, true)&.disable_argument_parsing
499
546
  self
500
547
  end
501
548
 
@@ -507,8 +554,7 @@ module Toys
507
554
  # @param [String...] flags The flags to disable
508
555
  #
509
556
  def disable_flag(*flags)
510
- cur_tool = DSL::Tool.current_tool(self, true)
511
- cur_tool.disable_flag(*flags) unless cur_tool.nil?
557
+ DSL::Tool.current_tool(self, true)&.disable_flag(*flags)
512
558
  self
513
559
  end
514
560
 
@@ -608,6 +654,17 @@ module Toys
608
654
  tool_class.instance_variable_set(:@__remaining_words, nil)
609
655
  tool_class.instance_variable_set(:@__path, nil)
610
656
  end
657
+
658
+ ## @private
659
+ def self.maybe_add_getter(tool_class, key)
660
+ if key.is_a?(::Symbol) && key.to_s =~ /^[_a-zA-Z]\w*[!\?]?$/
661
+ tool_class.class_eval do
662
+ define_method(key) do
663
+ self[key]
664
+ end
665
+ end
666
+ end
667
+ end
611
668
  end
612
669
  end
613
670
  end
data/lib/toys/errors.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
data/lib/toys/loader.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -44,9 +46,6 @@ module Toys
44
46
  end
45
47
  end
46
48
 
47
- ## @private
48
- LOW_PRIORITY = -999_999
49
-
50
49
  ##
51
50
  # Create a Loader
52
51
  #
@@ -86,6 +85,7 @@ module Toys
86
85
  @worklist = []
87
86
  @tool_data = {}
88
87
  @max_priority = @min_priority = 0
88
+ get_tool_definition([], -999_999)
89
89
  end
90
90
 
91
91
  ##
@@ -151,7 +151,7 @@ module Toys
151
151
  break if p.empty? || p.length <= cur_prefix.length
152
152
  p = p.slice(0..-2)
153
153
  end
154
- return get_tool_definition([], LOW_PRIORITY) if cur_prefix.empty?
154
+ raise "Unexpected error" if cur_prefix.empty?
155
155
  cur_prefix = cur_prefix.slice(0..-2)
156
156
  end
157
157
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
data/lib/toys/mixin.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -66,8 +68,12 @@ module Toys
66
68
  #
67
69
  # # Mixin methods are called with self set to the tool and can affect
68
70
  # # the tool state.
71
+ # def counter_value
72
+ # get(:counter_value)
73
+ # end
74
+ #
69
75
  # def increment
70
- # self[:counter_value] += 1
76
+ # set(:counter_value, counter_value + 1)
71
77
  # logger.info("Incremented counter")
72
78
  # end
73
79
  # end
@@ -79,8 +85,9 @@ module Toys
79
85
  # include MyCounterMixin, 1
80
86
  #
81
87
  # def run
88
+ # # Mixin methods can be called.
82
89
  # 5.times { increment }
83
- # puts "Final value is #{get(:counter_value)}"
90
+ # puts "Final value is #{counter_value}"
84
91
  # end
85
92
  # end
86
93
  #
data/lib/toys/runner.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -62,7 +64,7 @@ module Toys
62
64
  @terminal.puts(tool[Tool::Keys::USAGE_ERROR], :bright_red, :bold)
63
65
  @terminal.puts("")
64
66
  @terminal.puts(help_text.usage_string(wrap_width: @terminal.width))
65
- tool.exit(@exit_code)
67
+ Tool.exit(@exit_code)
66
68
  else
67
69
  yield
68
70
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -44,19 +46,19 @@ module Toys
44
46
  # The default description for tools.
45
47
  # @return [String]
46
48
  #
47
- DEFAULT_TOOL_DESC = "(No tool description available)".freeze
49
+ DEFAULT_TOOL_DESC = "(No tool description available)"
48
50
 
49
51
  ##
50
52
  # The default description for namespaces.
51
53
  # @return [String]
52
54
  #
53
- DEFAULT_NAMESPACE_DESC = "(A namespace of tools)".freeze
55
+ DEFAULT_NAMESPACE_DESC = "(A namespace of tools)"
54
56
 
55
57
  ##
56
58
  # The default description for the root tool.
57
59
  # @return [String]
58
60
  #
59
- DEFAULT_ROOT_DESC = "Command line tool built using the toys-core gem.".freeze
61
+ DEFAULT_ROOT_DESC = "Command line tool built using the toys-core gem."
60
62
 
61
63
  ##
62
64
  # The default long description for the root tool.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -251,15 +253,15 @@ module Toys
251
253
  loader = tool[Tool::Keys::LOADER]
252
254
  tool_definition, rest = loader.lookup(tool_name)
253
255
  help_text = Utils::HelpText.new(tool_definition, loader, tool[Tool::Keys::BINARY_NAME])
254
- report_usage_error(tool, tool_name, help_text) unless rest.empty?
256
+ report_usage_error(tool_name, help_text) unless rest.empty?
255
257
  help_text
256
258
  end
257
259
 
258
- def report_usage_error(tool, tool_name, help_text)
260
+ def report_usage_error(tool_name, help_text)
259
261
  terminal.puts("Tool not found: #{tool_name.join(' ')}", :bright_red, :bold)
260
262
  terminal.puts
261
263
  terminal.puts help_text.usage_string(wrap_width: terminal.width)
262
- tool.exit(1)
264
+ Tool.exit(1)
263
265
  end
264
266
 
265
267
  def add_help_flags(tool_definition)
@@ -289,13 +291,16 @@ module Toys
289
291
  def add_recursive_flags(tool_definition)
290
292
  recursive_flags = resolve_flags_spec(@recursive_flags, tool_definition,
291
293
  DEFAULT_RECURSIVE_FLAGS)
292
- unless recursive_flags.empty?
294
+ if recursive_flags.empty?
295
+ tool_definition.default_data[RECURSIVE_SUBTOOLS_KEY] = @default_recursive
296
+ else
293
297
  tool_definition.add_flag(
294
298
  RECURSIVE_SUBTOOLS_KEY, recursive_flags,
295
299
  report_collisions: false, default: @default_recursive,
296
300
  desc: "Show all subtools recursively (default is #{@default_recursive})"
297
301
  )
298
302
  end
303
+ recursive_flags
299
304
  end
300
305
 
301
306
  def add_search_flags(tool_definition)
@@ -307,10 +312,11 @@ module Toys
307
312
  desc: "Search subtools for the given regular expression"
308
313
  )
309
314
  end
315
+ search_flags
310
316
  end
311
317
 
312
- def resolve_flags_spec(flags, tool, defaults)
313
- flags = flags.call(tool) if flags.respond_to?(:call)
318
+ def resolve_flags_spec(flags, tool_definition, defaults)
319
+ flags = flags.call(tool_definition) if flags.respond_to?(:call)
314
320
  case flags
315
321
  when true, :default
316
322
  Array(defaults)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -46,7 +48,7 @@ module Toys
46
48
  # Default description for the version flags
47
49
  # @return [String]
48
50
  #
49
- DEFAULT_VERSION_FLAG_DESC = "Display the version".freeze
51
+ DEFAULT_VERSION_FLAG_DESC = "Display the version"
50
52
 
51
53
  ##
52
54
  # Key set when the version flag is present
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -43,6 +45,23 @@ module Toys
43
45
  # This is a frontend for {Toys::Utils::Exec}. More information is
44
46
  # available in that class's documentation.
45
47
  #
48
+ # ## Configuration Options
49
+ #
50
+ # Subprocesses may be configured using the options in the
51
+ # {Toys::Utils::Exec} class. These include a variety of options supported
52
+ # by `Process#spawn`, and some options supported by {Toys::Utils::Exec}
53
+ # itself.
54
+ #
55
+ # In addition, this mixin supports one more option,
56
+ # `exit_on_nonzero_status`. When set to true, if any subprocess returns a
57
+ # nonzero result code, the tool will immediately exit with that same code,
58
+ # similar to `set -e` in a bash script.
59
+ #
60
+ # You can set initial configuration by passing options to the `include`
61
+ # directive. For example:
62
+ #
63
+ # include :exec, exit_on_nonzero_status: true
64
+ #
46
65
  module Exec
47
66
  include Mixin
48
67
 
@@ -54,6 +73,7 @@ module Toys
54
73
 
55
74
  to_initialize do |opts = {}|
56
75
  tool = self
76
+ opts = Exec._setup_exec_opts(opts, tool)
57
77
  tool[KEY] = Utils::Exec.new(opts) do |k|
58
78
  case k
59
79
  when :logger
@@ -67,8 +87,10 @@ module Toys
67
87
  ##
68
88
  # Set default configuration keys.
69
89
  #
70
- # @param [Hash] opts The default options. See the section on
71
- # configuration options in the {Toys::Utils::Exec} docs.
90
+ # All options listed in the {Toys::Utils::Exec} documentation are
91
+ # supported, plus the `exit_on_nonzero_status` option.
92
+ #
93
+ # @param [Hash] opts The default options.
72
94
  #
73
95
  def configure_exec(opts = {})
74
96
  self[KEY].configure_defaults(Exec._setup_exec_opts(opts, self))
@@ -82,8 +104,9 @@ module Toys
82
104
  # yielded to it, allowing you to interact with the subprocess streams.
83
105
  #
84
106
  # @param [String,Array<String>] cmd The command to execute.
85
- # @param [Hash] opts The command options. See the section on
86
- # configuration options in the {Toys::Utils::Exec} module docs.
107
+ # @param [Hash] opts The command options. All options listed in the
108
+ # {Toys::Utils::Exec} documentation are supported, plus the
109
+ # `exit_on_nonzero_status` option.
87
110
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
88
111
  # the subprocess streams.
89
112
  #
@@ -101,8 +124,9 @@ module Toys
101
124
  # yielded to it, allowing you to interact with the subprocess streams.
102
125
  #
103
126
  # @param [String,Array<String>] args The arguments to ruby.
104
- # @param [Hash] opts The command options. See the section on
105
- # configuration options in the {Toys::Utils::Exec} module docs.
127
+ # @param [Hash] opts The command options. All options listed in the
128
+ # {Toys::Utils::Exec} documentation are supported, plus the
129
+ # `exit_on_nonzero_status` option.
106
130
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller for
107
131
  # for the subprocess streams.
108
132
  #
@@ -121,8 +145,9 @@ module Toys
121
145
  # yielded to it, allowing you to interact with the subprocess streams.
122
146
  #
123
147
  # @param [Proc] func The proc to call.
124
- # @param [Hash] opts The command options. See the section on
125
- # configuration options in the {Toys::Utils::Exec} module docs.
148
+ # @param [Hash] opts The command options. Most options listed in the
149
+ # {Toys::Utils::Exec} documentation are supported, plus the
150
+ # `exit_on_nonzero_status` option.
126
151
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
127
152
  # for the subprocess streams.
128
153
  #
@@ -141,8 +166,9 @@ module Toys
141
166
  # yielded to it, allowing you to interact with the subprocess streams.
142
167
  #
143
168
  # @param [String,Array<String>] cmd The tool to execute.
144
- # @param [Hash] opts The command options. See the section on
145
- # configuration options in the {Toys::Utils::Exec} module docs.
169
+ # @param [Hash] opts The command options. Most options listed in the
170
+ # {Toys::Utils::Exec} documentation are supported, plus the
171
+ # `exit_on_nonzero_status` option.
146
172
  # @yieldparam controller [Toys::Utils::Exec::Controller] A controller
147
173
  # for the subprocess streams.
148
174
  #
@@ -161,8 +187,9 @@ module Toys
161
187
  # Captures standard out and returns it as a string.
162
188
  #
163
189
  # @param [String,Array<String>] cmd The command to execute.
164
- # @param [Hash] opts The command options. See the section on
165
- # configuration options in the {Toys::Utils::Exec} module docs.
190
+ # @param [Hash] opts The command options. All options listed in the
191
+ # {Toys::Utils::Exec} documentation are supported, plus the
192
+ # `exit_on_nonzero_status` option.
166
193
  #
167
194
  # @return [String] What was written to standard out.
168
195
  #
@@ -176,8 +203,9 @@ module Toys
176
203
  # Captures standard out and returns it as a string.
177
204
  #
178
205
  # @param [String,Array<String>] args The arguments to ruby.
179
- # @param [Hash] opts The command options. See the section on
180
- # configuration options in the {Toys::Utils::Exec} module docs.
206
+ # @param [Hash] opts The command options. All options listed in the
207
+ # {Toys::Utils::Exec} documentation are supported, plus the
208
+ # `exit_on_nonzero_status` option.
181
209
  #
182
210
  # @return [String] What was written to standard out.
183
211
  #
@@ -191,8 +219,9 @@ module Toys
191
219
  # Captures standard out and returns it as a string.
192
220
  #
193
221
  # @param [Proc] func The proc to call.
194
- # @param [Hash] opts The command options. See the section on
195
- # configuration options in the {Toys::Utils::Exec} module docs.
222
+ # @param [Hash] opts The command options. Most options listed in the
223
+ # {Toys::Utils::Exec} documentation are supported, plus the
224
+ # `exit_on_nonzero_status` option.
196
225
  #
197
226
  # @return [String] What was written to standard out.
198
227
  #
@@ -207,8 +236,9 @@ module Toys
207
236
  # Captures standard out and returns it as a string.
208
237
  #
209
238
  # @param [String,Array<String>] cmd The tool to execute.
210
- # @param [Hash] opts The command options. See the section on
211
- # configuration options in the {Toys::Utils::Exec} module docs.
239
+ # @param [Hash] opts The command options. Most options listed in the
240
+ # {Toys::Utils::Exec} documentation are supported, plus the
241
+ # `exit_on_nonzero_status` option.
212
242
  #
213
243
  # @return [String] What was written to standard out.
214
244
  #
@@ -221,8 +251,9 @@ module Toys
221
251
  # Execute the given string in a shell. Returns the exit code.
222
252
  #
223
253
  # @param [String] cmd The shell command to execute.
224
- # @param [Hash] opts The command options. See the section on
225
- # configuration options in the {Toys::Utils::Exec} module docs.
254
+ # @param [Hash] opts The command options. All options listed in the
255
+ # {Toys::Utils::Exec} documentation are supported, plus the
256
+ # `exit_on_nonzero_status` option.
226
257
  #
227
258
  # @return [Integer] The exit code
228
259
  #
@@ -238,7 +269,7 @@ module Toys
238
269
  def exit_on_nonzero_status(status)
239
270
  status = status.exit_code if status.respond_to?(:exit_code)
240
271
  status = status.exitstatus if status.respond_to?(:exitstatus)
241
- exit(status) unless status.zero?
272
+ Tool.exit(status) unless status.zero?
242
273
  0
243
274
  end
244
275
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -35,16 +37,33 @@ module Toys
35
37
  ##
36
38
  # A mixin that provides access to the capabilities of the highline gem.
37
39
  #
40
+ # This mixin requires the highline gem, version 2.0 or later. It will
41
+ # attempt to install the gem if it is not available.
42
+ #
38
43
  # You may make these methods available to your tool by including the
39
44
  # following directive in your tool configuration:
40
45
  #
41
46
  # include :highline
42
47
  #
48
+ # A HighLine object will then be available by calling the {#highline}
49
+ # method. For information on using this object, see the
50
+ # [Highline documentation](https://www.rubydoc.info/gems/highline). Some of
51
+ # the most common HighLine methods, such as `say`, are also mixed into the
52
+ # tool and can be called directly.
53
+ #
54
+ # You can configure the HighLine object by passing options to the `include`
55
+ # directive. For example:
56
+ #
57
+ # include :highline, my_stdin, my_stdout
58
+ #
59
+ # The arguments will be passed on to the
60
+ # [HighLine constructor](https://www.rubydoc.info/gems/highline/HighLine:initialize).
61
+ #
43
62
  module Highline
44
63
  include Mixin
45
64
 
46
65
  ##
47
- # Context key for the executor object.
66
+ # Context key for the highline object.
48
67
  # @return [Object]
49
68
  #
50
69
  KEY = ::Object.new.freeze
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -41,6 +43,18 @@ module Toys
41
43
  #
42
44
  # include :terminal
43
45
  #
46
+ # A Terminal object will then be available by calling the {#terminal}
47
+ # method. For information on using this object, see the documentation for
48
+ # {Toys::Utils::Terminal}. Some of the most useful methods are also mixed
49
+ # into the tool and can be called directly.
50
+ #
51
+ # You can configure the Terminal object by passing options to the `include`
52
+ # directive. For example:
53
+ #
54
+ # include :terminal, styled: true
55
+ #
56
+ # The arguments will be passed on to {Toys::Utils::Terminal#initialize}.
57
+ #
44
58
  module Terminal
45
59
  include Mixin
46
60
 
@@ -79,8 +93,8 @@ module Toys
79
93
  ##
80
94
  # @see Toys::Utils::Terminal#confirm
81
95
  #
82
- def confirm(prompt = "Proceed?")
83
- terminal.confirm(prompt)
96
+ def confirm(prompt = "Proceed?", default: false)
97
+ terminal.confirm(prompt, default: default)
84
98
  end
85
99
 
86
100
  ##
data/lib/toys/template.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
data/lib/toys/tool.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -272,9 +274,19 @@ module Toys
272
274
  # Exit immediately with the given status code
273
275
  #
274
276
  # @param [Integer] code The status code, which should be 0 for no error,
275
- # or nonzero for an error condition.
277
+ # or nonzero for an error condition. Default is 0.
278
+ #
279
+ def exit(code = 0)
280
+ throw :result, code
281
+ end
282
+
283
+ ##
284
+ # Exit immediately with the given status code
285
+ #
286
+ # @param [Integer] code The status code, which should be 0 for no error,
287
+ # or nonzero for an error condition. Default is 0.
276
288
  #
277
- def exit(code)
289
+ def self.exit(code = 0)
278
290
  throw :result, code
279
291
  end
280
292
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -60,16 +62,17 @@ module Toys
60
62
  #
61
63
  # @param [String] name Name of the gem
62
64
  # @param [String...] requirements Version requirements
65
+ # @param [Boolean] default_confirm Default response for the confirmation prompt
63
66
  #
64
- def self.activate(name, *requirements)
65
- new.activate(name, *requirements)
67
+ def self.activate(name, *requirements, default_confirm: false)
68
+ new.activate(name, *requirements, default_confirm: default_confirm)
66
69
  end
67
70
 
68
71
  ##
69
72
  # Create a new gem activator.
70
73
  #
71
- def initialize
72
- @terminal = Terminal.new(output: $stderr)
74
+ def initialize(input: $stdin, output: $stderr)
75
+ @terminal = Terminal.new(input: input, output: output)
73
76
  @exec = Exec.new
74
77
  end
75
78
 
@@ -79,11 +82,12 @@ module Toys
79
82
  #
80
83
  # @param [String] name Name of the gem
81
84
  # @param [String...] requirements Version requirements
85
+ # @param [Boolean] default_confirm Default response for the confirmation prompt
82
86
  #
83
- def activate(name, *requirements)
87
+ def activate(name, *requirements, default_confirm: false)
84
88
  gem(name, *requirements)
85
89
  rescue ::Gem::MissingSpecError
86
- install_gem(name, requirements)
90
+ install_gem(name, requirements, default_confirm: default_confirm)
87
91
  rescue ::Gem::LoadError => e
88
92
  if ::ENV["BUNDLE_GEMFILE"]
89
93
  raise GemfileUpdateNeededError.new(gem_requirements_text(name, requirements),
@@ -98,9 +102,10 @@ module Toys
98
102
  "#{name.inspect}, #{requirements.map(&:inspect).join(', ')}"
99
103
  end
100
104
 
101
- def install_gem(name, requirements)
105
+ def install_gem(name, requirements, default_confirm: false)
102
106
  requirements_text = gem_requirements_text(name, requirements)
103
- response = @terminal.confirm("Gem needed: #{requirements_text}. Install?")
107
+ response = @terminal.confirm("Gem needed: #{requirements_text}. Install?",
108
+ default: default_confirm)
104
109
  unless response
105
110
  raise InstallFailedError, "Canceled installation of needed gem: #{requirements_text}"
106
111
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -54,7 +56,7 @@ module Toys
54
56
  #
55
57
  class Terminal
56
58
  ## ANSI style code to clear styles
57
- CLEAR_CODE = "\e[0m".freeze
59
+ CLEAR_CODE = "\e[0m"
58
60
 
59
61
  ## Standard ANSI style codes
60
62
  BUILTIN_STYLE_NAMES = {
@@ -205,15 +207,21 @@ module Toys
205
207
  # Confirm with the user.
206
208
  #
207
209
  # @param [String] prompt Prompt string. Defaults to `"Proceed?"`.
210
+ # @param [Boolean] default Default value (defaults to false).
208
211
  # @return [Boolean]
209
212
  #
210
- def confirm(prompt = "Proceed?")
211
- write("#{prompt} (y/n) ")
212
- resp = input.gets
213
- if resp =~ /^y/i
213
+ def confirm(prompt = "Proceed?", default: false)
214
+ y = default ? "Y" : "y"
215
+ n = default ? "n" : "N"
216
+ write("#{prompt} (#{y}/#{n}) ")
217
+ resp = input.gets.to_s.strip
218
+ case resp
219
+ when /^y/i
214
220
  true
215
- elsif resp =~ /^n/i
221
+ when /^n/i
216
222
  false
223
+ when ""
224
+ default
217
225
  else
218
226
  confirm("Please answer \"y\" or \"n\"")
219
227
  end
@@ -386,7 +394,7 @@ module Toys
386
394
  @stopping = true
387
395
  @cond.broadcast
388
396
  end
389
- @thread.join if @thread
397
+ @thread&.join
390
398
  self
391
399
  end
392
400
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2018 Daniel Azuma
2
4
  #
3
5
  # All rights reserved.
@@ -113,7 +115,7 @@ module Toys
113
115
  line = "#{line} #{frag}"
114
116
  end
115
117
  end
116
- lines << line if line_len > 0
118
+ lines << line if line_len.positive?
117
119
  lines
118
120
  end
119
121
 
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.3.10
4
+ version: 0.3.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-30 00:00:00.000000000 Z
11
+ date: 2018-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: highline
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
83
97
  description: Toys-Core is the command line tool framework underlying Toys. It can
84
98
  be used to create command line binaries using the internal Toys APIs.
85
99
  email:
@@ -139,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
139
153
  requirements:
140
154
  - - ">="
141
155
  - !ruby/object:Gem::Version
142
- version: 2.2.0
156
+ version: 2.3.0
143
157
  required_rubygems_version: !ruby/object:Gem::Requirement
144
158
  requirements:
145
159
  - - ">="