toys-core 0.3.9.1 → 0.3.10
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/toys/cli.rb +14 -0
- data/lib/toys/core_version.rb +1 -1
- data/lib/toys/definition/arg.rb +2 -2
- data/lib/toys/definition/flag.rb +3 -0
- data/lib/toys/definition/tool.rb +39 -1
- data/lib/toys/dsl/arg.rb +2 -2
- data/lib/toys/dsl/flag.rb +1 -1
- data/lib/toys/dsl/tool.rb +59 -39
- data/lib/toys/loader.rb +58 -15
- data/lib/toys/mixin.rb +112 -0
- data/lib/toys/runner.rb +1 -0
- data/lib/toys/standard_middleware/show_help.rb +40 -10
- data/lib/toys/standard_middleware/show_root_version.rb +8 -2
- data/lib/toys/standard_mixins/exec.rb +30 -22
- data/lib/toys/standard_mixins/fileutils.rb +2 -0
- data/lib/toys/standard_mixins/highline.rb +44 -20
- data/lib/toys/standard_mixins/terminal.rb +16 -2
- data/lib/toys/template.rb +2 -2
- data/lib/toys/tool.rb +0 -12
- data/lib/toys-core.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7bfede9155648ae5e0b3766dfad5b5165f80fa865eca0e91d390706616372c6e
|
4
|
+
data.tar.gz: 78ba80645b891e5382049153d47168ef69f18e7e762efe553a0f77ad14aa178a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0f9533b044b056ea6ea46d121a18fd0a9966b1aadacc845c36651c258bf7bdf8ba8851ccd0f00770a27da67697dcf1fe003804e94b720f87efab4a348cb9cab
|
7
|
+
data.tar.gz: c010707f7452adf31bdbe1d4bd692f39a285091e899c46d6cd964c686ba1aa3df7e119df3888da0f2f660732409c96b1768604f0af48768efa90c188c8497d22
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 0.3.10 / 2018-06-30
|
4
|
+
|
5
|
+
* CHANGED: Dropped Tool#option. Use Tool#get instead.
|
6
|
+
* CHANGED: "run" directive renamed to "to_run"
|
7
|
+
* CHANGED: Highline mixin now uses Highline 2.0
|
8
|
+
* CHANGED: Middleware-added keys no longer show up in the options hash
|
9
|
+
* ADDED: Mixins can provide initializers
|
10
|
+
* ADDED: Loader can load an inline block
|
11
|
+
|
3
12
|
### 0.3.9.1 / 2018-06-24
|
4
13
|
|
5
14
|
* FIXED: Built-in flags were interfering with disable_argument_parsing
|
data/lib/toys/cli.rb
CHANGED
@@ -151,6 +151,20 @@ module Toys
|
|
151
151
|
self
|
152
152
|
end
|
153
153
|
|
154
|
+
##
|
155
|
+
# Add a configuration block to the loader.
|
156
|
+
#
|
157
|
+
# @param [Boolean] high_priority Add the config at the head of the priority
|
158
|
+
# list rather than the tail.
|
159
|
+
# @param [String] path The "path" that will be shown in documentation for
|
160
|
+
# tools defined in this block. If omitted, a default unique string will
|
161
|
+
# be generated.
|
162
|
+
#
|
163
|
+
def add_config_block(high_priority: false, path: nil, &block)
|
164
|
+
@loader.add_block(high_priority: high_priority, path: path, &block)
|
165
|
+
self
|
166
|
+
end
|
167
|
+
|
154
168
|
##
|
155
169
|
# Searches the given directory for a well-known config directory and/or
|
156
170
|
# config file. If found, these are added to the loader.
|
data/lib/toys/core_version.rb
CHANGED
data/lib/toys/definition/arg.rb
CHANGED
@@ -39,7 +39,7 @@ module Toys
|
|
39
39
|
# Create an Arg definition
|
40
40
|
# @private
|
41
41
|
#
|
42
|
-
def initialize(key, type, accept, default, desc, long_desc, display_name)
|
42
|
+
def initialize(key, type, accept, default, desc, long_desc, display_name = nil)
|
43
43
|
@key = key
|
44
44
|
@type = type
|
45
45
|
@accept = accept
|
@@ -103,7 +103,7 @@ module Toys
|
|
103
103
|
result = input
|
104
104
|
optparse = ::OptionParser.new
|
105
105
|
optparse.accept(accept) if accept.is_a?(Acceptor)
|
106
|
-
optparse.on("--abc
|
106
|
+
optparse.on("--abc VALUE", accept) { |v| result = v }
|
107
107
|
optparse.parse(["--abc", input])
|
108
108
|
result
|
109
109
|
end
|
data/lib/toys/definition/flag.rb
CHANGED
@@ -43,6 +43,8 @@ module Toys
|
|
43
43
|
setup(str, [$1], $1, "-", nil, nil, nil, nil)
|
44
44
|
when /^(-[\?\w])( ?)\[(\w+)\]$/
|
45
45
|
setup(str, [$1], $1, "-", :value, :optional, $2, $3)
|
46
|
+
when /^(-[\?\w])\[( )(\w+)\]$/
|
47
|
+
setup(str, [$1], $1, "-", :value, :optional, $2, $3)
|
46
48
|
when /^(-[\?\w])( ?)(\w+)$/
|
47
49
|
setup(str, [$1], $1, "-", :value, :required, $2, $3)
|
48
50
|
when /^--\[no-\](\w[\?\w-]*)$/
|
@@ -305,6 +307,7 @@ module Toys
|
|
305
307
|
analyze_flag_syntax(flag)
|
306
308
|
end
|
307
309
|
@flag_type ||= :boolean
|
310
|
+
@value_type ||= :required if @flag_type == :value
|
308
311
|
flag_syntax.each do |flag|
|
309
312
|
flag.configure_canonical(@flag_type, @value_type, @value_label, @value_delim)
|
310
313
|
end
|
data/lib/toys/definition/tool.rb
CHANGED
@@ -82,6 +82,7 @@ module Toys
|
|
82
82
|
|
83
83
|
@default_data = {}
|
84
84
|
@used_flags = []
|
85
|
+
@initializers = []
|
85
86
|
|
86
87
|
@acceptors = {}
|
87
88
|
@mixins = {}
|
@@ -381,6 +382,20 @@ module Toys
|
|
381
382
|
@long_desc = Utils::WrappableString.make_array(long_desc)
|
382
383
|
end
|
383
384
|
|
385
|
+
##
|
386
|
+
# Append long description strings.
|
387
|
+
#
|
388
|
+
# Each string may be provided as a {Toys::Utils::WrappableString}, a single
|
389
|
+
# string (which will be wrapped), or an array of strings, which will be
|
390
|
+
# interpreted as string fragments that will be concatenated and wrapped.
|
391
|
+
#
|
392
|
+
# @param [Array<Toys::Utils::WrappableString,String,Array<String>>] long_desc
|
393
|
+
#
|
394
|
+
def append_long_desc(long_desc)
|
395
|
+
check_definition_state
|
396
|
+
@long_desc += Utils::WrappableString.make_array(long_desc)
|
397
|
+
end
|
398
|
+
|
384
399
|
##
|
385
400
|
# Add an acceptor to the tool. This acceptor may be refereneced by name
|
386
401
|
# when adding a flag or an arg.
|
@@ -615,7 +630,19 @@ module Toys
|
|
615
630
|
# @param [Proc] proc The runnable block
|
616
631
|
#
|
617
632
|
def runnable=(proc)
|
618
|
-
@tool_class.
|
633
|
+
@tool_class.to_run(&proc)
|
634
|
+
end
|
635
|
+
|
636
|
+
##
|
637
|
+
# Add an initializer.
|
638
|
+
#
|
639
|
+
# @param [Proc] proc The initializer block
|
640
|
+
# @param [Object...] args Arguments to pass to the initializer
|
641
|
+
#
|
642
|
+
def add_initializer(proc, *args)
|
643
|
+
check_definition_state
|
644
|
+
@initializers << [proc, args]
|
645
|
+
self
|
619
646
|
end
|
620
647
|
|
621
648
|
##
|
@@ -647,6 +674,17 @@ module Toys
|
|
647
674
|
self
|
648
675
|
end
|
649
676
|
|
677
|
+
##
|
678
|
+
# Run all initializers against a tool. Should be called from the Runner
|
679
|
+
# only.
|
680
|
+
# @private
|
681
|
+
#
|
682
|
+
def run_initializers(tool)
|
683
|
+
@initializers.each do |func, args|
|
684
|
+
tool.instance_exec(*args, &func)
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
650
688
|
private
|
651
689
|
|
652
690
|
def make_config_proc(middleware, loader, next_config)
|
data/lib/toys/dsl/arg.rb
CHANGED
@@ -44,7 +44,7 @@ module Toys
|
|
44
44
|
@default = default
|
45
45
|
@display_name = display_name
|
46
46
|
@desc = desc
|
47
|
-
@long_desc = long_desc
|
47
|
+
@long_desc = long_desc || []
|
48
48
|
end
|
49
49
|
|
50
50
|
##
|
@@ -70,7 +70,7 @@ module Toys
|
|
70
70
|
# @param [String] display_name
|
71
71
|
#
|
72
72
|
def display_name(display_name)
|
73
|
-
@
|
73
|
+
@display_name = display_name
|
74
74
|
self
|
75
75
|
end
|
76
76
|
|
data/lib/toys/dsl/flag.rb
CHANGED
data/lib/toys/dsl/tool.rb
CHANGED
@@ -48,7 +48,7 @@ module Toys
|
|
48
48
|
# optional_arg :recipient, default: "world"
|
49
49
|
#
|
50
50
|
# def run
|
51
|
-
# puts "Hello, #{
|
51
|
+
# puts "Hello, #{get(:recipient)}!"
|
52
52
|
# end
|
53
53
|
# end
|
54
54
|
#
|
@@ -63,7 +63,7 @@ module Toys
|
|
63
63
|
module Tool
|
64
64
|
## @private
|
65
65
|
def method_added(meth)
|
66
|
-
cur_tool = DSL::Tool.
|
66
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
67
67
|
cur_tool.mark_runnable if cur_tool && meth == :run
|
68
68
|
end
|
69
69
|
|
@@ -108,7 +108,7 @@ module Toys
|
|
108
108
|
# @param [Proc,nil] converter The validator.
|
109
109
|
#
|
110
110
|
def acceptor(name, validator = nil, converter = nil, &block)
|
111
|
-
cur_tool = DSL::Tool.
|
111
|
+
cur_tool = DSL::Tool.current_tool(self, false)
|
112
112
|
return self if cur_tool.nil?
|
113
113
|
accept =
|
114
114
|
case validator
|
@@ -134,8 +134,14 @@ module Toys
|
|
134
134
|
# @param [String] name Name of the mixin
|
135
135
|
#
|
136
136
|
def mixin(name, &block)
|
137
|
-
cur_tool = DSL::Tool.
|
138
|
-
|
137
|
+
cur_tool = DSL::Tool.current_tool(self, false)
|
138
|
+
if cur_tool
|
139
|
+
mixin_mod = ::Module.new do
|
140
|
+
include ::Toys::Mixin
|
141
|
+
end
|
142
|
+
mixin_mod.module_eval(&block)
|
143
|
+
cur_tool.add_mixin(name, mixin_mod)
|
144
|
+
end
|
139
145
|
self
|
140
146
|
end
|
141
147
|
|
@@ -152,7 +158,7 @@ module Toys
|
|
152
158
|
# @param [String] name Name of the template
|
153
159
|
#
|
154
160
|
def template(name, &block)
|
155
|
-
cur_tool = DSL::Tool.
|
161
|
+
cur_tool = DSL::Tool.current_tool(self, false)
|
156
162
|
if cur_tool
|
157
163
|
template_class = ::Class.new do
|
158
164
|
include ::Toys::Template
|
@@ -200,7 +206,7 @@ module Toys
|
|
200
206
|
# @param [String] path The file or directory to include.
|
201
207
|
#
|
202
208
|
def load(path)
|
203
|
-
@__loader.
|
209
|
+
@__loader.load_path(path, @__words, @__remaining_words, @__priority)
|
204
210
|
self
|
205
211
|
end
|
206
212
|
|
@@ -215,6 +221,8 @@ module Toys
|
|
215
221
|
# @param [Object...] args Template arguments
|
216
222
|
#
|
217
223
|
def expand(template_class, *args)
|
224
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
225
|
+
return self if cur_tool.nil?
|
218
226
|
name = template_class.to_s
|
219
227
|
if template_class.is_a?(::String)
|
220
228
|
template_class = cur_tool.resolve_template(template_class)
|
@@ -260,7 +268,7 @@ module Toys
|
|
260
268
|
# @param [Toys::Utils::WrappableString,String,Array<String>] str
|
261
269
|
#
|
262
270
|
def desc(str)
|
263
|
-
cur_tool = DSL::Tool.
|
271
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
264
272
|
cur_tool.desc = str if cur_tool
|
265
273
|
self
|
266
274
|
end
|
@@ -286,8 +294,8 @@ module Toys
|
|
286
294
|
# @param [Toys::Utils::WrappableString,String,Array<String>...] strs
|
287
295
|
#
|
288
296
|
def long_desc(*strs)
|
289
|
-
cur_tool = DSL::Tool.
|
290
|
-
cur_tool.
|
297
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
298
|
+
cur_tool.append_long_desc(strs) if cur_tool
|
291
299
|
self
|
292
300
|
end
|
293
301
|
|
@@ -333,7 +341,7 @@ module Toys
|
|
333
341
|
report_collisions: true,
|
334
342
|
desc: nil, long_desc: nil,
|
335
343
|
&block)
|
336
|
-
cur_tool = DSL::Tool.
|
344
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
337
345
|
return self if cur_tool.nil?
|
338
346
|
flag_dsl = DSL::Flag.new(flags, accept, default, handler, report_collisions,
|
339
347
|
desc, long_desc)
|
@@ -369,7 +377,7 @@ module Toys
|
|
369
377
|
def required_arg(key,
|
370
378
|
accept: nil, display_name: nil, desc: nil, long_desc: nil,
|
371
379
|
&block)
|
372
|
-
cur_tool = DSL::Tool.
|
380
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
373
381
|
return self if cur_tool.nil?
|
374
382
|
arg_dsl = DSL::Arg.new(accept, nil, display_name, desc, long_desc)
|
375
383
|
arg_dsl.instance_exec(arg_dsl, &block) if block
|
@@ -410,7 +418,7 @@ module Toys
|
|
410
418
|
default: nil, accept: nil, display_name: nil,
|
411
419
|
desc: nil, long_desc: nil,
|
412
420
|
&block)
|
413
|
-
cur_tool = DSL::Tool.
|
421
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
414
422
|
return self if cur_tool.nil?
|
415
423
|
arg_dsl = DSL::Arg.new(accept, default, display_name, desc, long_desc)
|
416
424
|
arg_dsl.instance_exec(arg_dsl, &block) if block
|
@@ -450,7 +458,7 @@ module Toys
|
|
450
458
|
default: [], accept: nil, display_name: nil,
|
451
459
|
desc: nil, long_desc: nil,
|
452
460
|
&block)
|
453
|
-
cur_tool = DSL::Tool.
|
461
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
454
462
|
return self if cur_tool.nil?
|
455
463
|
arg_dsl = DSL::Arg.new(accept, default, display_name, desc, long_desc)
|
456
464
|
arg_dsl.instance_exec(arg_dsl, &block) if block
|
@@ -466,10 +474,14 @@ module Toys
|
|
466
474
|
# execution context.
|
467
475
|
# @param [Object] value The value to set.
|
468
476
|
#
|
469
|
-
def set(key, value)
|
470
|
-
cur_tool = DSL::Tool.
|
477
|
+
def set(key, value = nil)
|
478
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
471
479
|
return self if cur_tool.nil?
|
472
|
-
|
480
|
+
if key.is_a?(::Hash)
|
481
|
+
cur_tool.default_data.merge!(key)
|
482
|
+
else
|
483
|
+
cur_tool.default_data[key] = value
|
484
|
+
end
|
473
485
|
self
|
474
486
|
end
|
475
487
|
|
@@ -482,29 +494,29 @@ module Toys
|
|
482
494
|
# declare arguments or flags.
|
483
495
|
#
|
484
496
|
def disable_argument_parsing
|
485
|
-
cur_tool = DSL::Tool.
|
497
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
486
498
|
cur_tool.disable_argument_parsing unless cur_tool.nil?
|
487
499
|
self
|
488
500
|
end
|
489
501
|
|
490
502
|
##
|
491
503
|
# Mark one or more flags as disabled, preventing their use by any
|
492
|
-
# subsequent flag definition. This
|
504
|
+
# subsequent flag definition. This can be used to prevent middleware from
|
493
505
|
# defining a particular flag.
|
494
506
|
#
|
495
507
|
# @param [String...] flags The flags to disable
|
496
508
|
#
|
497
509
|
def disable_flag(*flags)
|
498
|
-
cur_tool = DSL::Tool.
|
510
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
499
511
|
cur_tool.disable_flag(*flags) unless cur_tool.nil?
|
500
512
|
self
|
501
513
|
end
|
502
514
|
|
503
515
|
##
|
504
|
-
# Specify how to run this tool. You
|
516
|
+
# Specify how to run this tool. You can do this by providing a block to
|
505
517
|
# this directive, or by defining the `run` method in the tool.
|
506
518
|
#
|
507
|
-
def
|
519
|
+
def to_run(&block)
|
508
520
|
define_method(:run, &block)
|
509
521
|
self
|
510
522
|
end
|
@@ -518,9 +530,10 @@ module Toys
|
|
518
530
|
# of a well-known mixin.
|
519
531
|
#
|
520
532
|
# @param [Module,Symbol,String] mod Module or module name.
|
533
|
+
# @param [Object...] args Arguments to pass to the initializer
|
521
534
|
#
|
522
|
-
def include(mod)
|
523
|
-
cur_tool = DSL::Tool.
|
535
|
+
def include(mod, *args)
|
536
|
+
cur_tool = DSL::Tool.current_tool(self, true)
|
524
537
|
return if cur_tool.nil?
|
525
538
|
name = mod.to_s
|
526
539
|
if mod.is_a?(::String)
|
@@ -531,6 +544,9 @@ module Toys
|
|
531
544
|
if mod.nil?
|
532
545
|
raise ToolDefinitionError, "Module not found: #{name.inspect}"
|
533
546
|
end
|
547
|
+
if mod.respond_to?(:initializer)
|
548
|
+
cur_tool.add_initializer(mod.initializer, *args) if mod.initializer
|
549
|
+
end
|
534
550
|
super(mod)
|
535
551
|
end
|
536
552
|
|
@@ -558,24 +574,28 @@ module Toys
|
|
558
574
|
end
|
559
575
|
|
560
576
|
## @private
|
561
|
-
def self.
|
577
|
+
def self.current_tool(tool_class, activate)
|
578
|
+
memoize_var = activate ? :@__active_tool : :@__cur_tool
|
562
579
|
path = tool_class.instance_variable_get(:@__path)
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
580
|
+
if tool_class.instance_variable_defined?(memoize_var)
|
581
|
+
cur_tool = tool_class.instance_variable_get(memoize_var)
|
582
|
+
else
|
583
|
+
loader = tool_class.instance_variable_get(:@__loader)
|
584
|
+
words = tool_class.instance_variable_get(:@__words)
|
585
|
+
priority = tool_class.instance_variable_get(:@__priority)
|
586
|
+
cur_tool =
|
587
|
+
if activate
|
588
|
+
loader.activate_tool_definition(words, priority)
|
589
|
+
else
|
590
|
+
loader.get_tool_definition(words, priority)
|
574
591
|
end
|
575
|
-
|
576
|
-
|
592
|
+
if cur_tool.is_a?(Definition::Alias)
|
593
|
+
raise ToolDefinitionError,
|
594
|
+
"Cannot configure #{words.join(' ').inspect} because it is an alias"
|
577
595
|
end
|
578
|
-
|
596
|
+
tool_class.instance_variable_set(memoize_var, cur_tool)
|
597
|
+
end
|
598
|
+
cur_tool.lock_source_path(path) if cur_tool && activate
|
579
599
|
cur_tool
|
580
600
|
end
|
581
601
|
|
data/lib/toys/loader.rb
CHANGED
@@ -44,6 +44,9 @@ module Toys
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
## @private
|
48
|
+
LOW_PRIORITY = -999_999
|
49
|
+
|
47
50
|
##
|
48
51
|
# Create a Loader
|
49
52
|
#
|
@@ -80,7 +83,7 @@ module Toys
|
|
80
83
|
@index_file_name = index_file_name
|
81
84
|
@preload_file_name = preload_file_name
|
82
85
|
@middleware_stack = middleware_stack
|
83
|
-
@
|
86
|
+
@worklist = []
|
84
87
|
@tool_data = {}
|
85
88
|
@max_priority = @min_priority = 0
|
86
89
|
end
|
@@ -97,11 +100,28 @@ module Toys
|
|
97
100
|
paths = Array(path)
|
98
101
|
priority = high_priority ? (@max_priority += 1) : (@min_priority -= 1)
|
99
102
|
paths.each do |p|
|
100
|
-
@
|
103
|
+
@worklist << [:file, check_path(p), [], priority]
|
101
104
|
end
|
102
105
|
self
|
103
106
|
end
|
104
107
|
|
108
|
+
##
|
109
|
+
# Add a configuration block to the loader.
|
110
|
+
#
|
111
|
+
# @param [Boolean] high_priority If true, add this block at the top of the
|
112
|
+
# priority list. Defaults to false, indicating the block should be at
|
113
|
+
# the bottom of the priority list.
|
114
|
+
# @param [String] path The "path" that will be shown in documentation for
|
115
|
+
# tools defined in this block. If omitted, a default unique string will
|
116
|
+
# be generated.
|
117
|
+
#
|
118
|
+
def add_block(high_priority: false, path: nil, &block)
|
119
|
+
path ||= "(Block #{block.object_id})"
|
120
|
+
priority = high_priority ? (@max_priority += 1) : (@min_priority -= 1)
|
121
|
+
@worklist << [block, path, [], priority]
|
122
|
+
self
|
123
|
+
end
|
124
|
+
|
105
125
|
##
|
106
126
|
# Given a list of command line arguments, find the appropriate tool to
|
107
127
|
# handle the command, loading it from the configuration if necessary, and
|
@@ -131,7 +151,7 @@ module Toys
|
|
131
151
|
break if p.empty? || p.length <= cur_prefix.length
|
132
152
|
p = p.slice(0..-2)
|
133
153
|
end
|
134
|
-
return
|
154
|
+
return get_tool_definition([], LOW_PRIORITY) if cur_prefix.empty?
|
135
155
|
cur_prefix = cur_prefix.slice(0..-2)
|
136
156
|
end
|
137
157
|
end
|
@@ -279,8 +299,26 @@ module Toys
|
|
279
299
|
#
|
280
300
|
# @private
|
281
301
|
#
|
282
|
-
def
|
283
|
-
|
302
|
+
def load_path(path, words, remaining_words, priority)
|
303
|
+
load_validated_path(check_path(path), words, remaining_words, priority)
|
304
|
+
end
|
305
|
+
|
306
|
+
##
|
307
|
+
# Load configuration from the given proc.
|
308
|
+
#
|
309
|
+
# @private
|
310
|
+
#
|
311
|
+
def load_proc(proc, words, remaining_words, priority, path)
|
312
|
+
if remaining_words
|
313
|
+
tool_class = get_tool_definition(words, priority).tool_class
|
314
|
+
::Toys::DSL::Tool.prepare(tool_class, remaining_words, path) do
|
315
|
+
::Toys::ContextualError.capture("Error while loading Toys config!") do
|
316
|
+
tool_class.class_eval(&proc)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
else
|
320
|
+
@worklist << [proc, path, words, priority]
|
321
|
+
end
|
284
322
|
end
|
285
323
|
|
286
324
|
##
|
@@ -365,22 +403,27 @@ module Toys
|
|
365
403
|
end
|
366
404
|
|
367
405
|
def load_for_prefix(prefix)
|
368
|
-
cur_worklist = @
|
369
|
-
@
|
370
|
-
cur_worklist.each do |path, words, priority|
|
371
|
-
|
406
|
+
cur_worklist = @worklist
|
407
|
+
@worklist = []
|
408
|
+
cur_worklist.each do |source, path, words, priority|
|
409
|
+
remaining_words = calc_remaining_words(prefix, words)
|
410
|
+
if source.respond_to?(:call)
|
411
|
+
load_proc(source, words, remaining_words, priority, path)
|
412
|
+
elsif source == :file
|
413
|
+
load_validated_path(path, words, remaining_words, priority)
|
414
|
+
end
|
372
415
|
end
|
373
416
|
end
|
374
417
|
|
375
|
-
def
|
418
|
+
def load_validated_path(path, words, remaining_words, priority)
|
376
419
|
if remaining_words
|
377
|
-
|
420
|
+
load_relevant_path(path, words, remaining_words, priority)
|
378
421
|
else
|
379
|
-
@
|
422
|
+
@worklist << [:file, path, words, priority]
|
380
423
|
end
|
381
424
|
end
|
382
425
|
|
383
|
-
def
|
426
|
+
def load_relevant_path(path, words, remaining_words, priority)
|
384
427
|
if ::File.extname(path) == ".rb"
|
385
428
|
tool_class = get_tool_definition(words, priority).tool_class
|
386
429
|
Toys::InputFile.evaluate(tool_class, remaining_words, path)
|
@@ -404,7 +447,7 @@ module Toys
|
|
404
447
|
return unless @index_file_name
|
405
448
|
index_path = ::File.join(path, @index_file_name)
|
406
449
|
index_path = check_path(index_path, type: :file, lenient: true)
|
407
|
-
|
450
|
+
load_relevant_path(index_path, words, remaining_words, priority) if index_path
|
408
451
|
end
|
409
452
|
|
410
453
|
def load_child_in(path, child, words, remaining_words, priority)
|
@@ -414,7 +457,7 @@ module Toys
|
|
414
457
|
child_word = ::File.basename(child, ".rb")
|
415
458
|
next_words = words + [child_word]
|
416
459
|
next_remaining = Loader.next_remaining_words(remaining_words, child_word)
|
417
|
-
|
460
|
+
load_validated_path(child_path, next_words, next_remaining, priority)
|
418
461
|
end
|
419
462
|
|
420
463
|
def check_path(path, lenient: false, type: nil)
|
data/lib/toys/mixin.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# Copyright 2018 Daniel Azuma
|
2
|
+
#
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
14
|
+
# contributors to this software, may be used to endorse or promote products
|
15
|
+
# derived from this software without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
18
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
21
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
22
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
23
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
24
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
25
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
26
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
;
|
29
|
+
|
30
|
+
module Toys
|
31
|
+
##
|
32
|
+
# A mixin definition. Mixin modules should include this module.
|
33
|
+
#
|
34
|
+
# A mixin is a collection of methods that are available to be called from a
|
35
|
+
# tool implementation (i.e. its run method). The mixin is added to the tool
|
36
|
+
# class, so it has access to the same methods that can be called by the tool,
|
37
|
+
# such as {Toys::Tool#option}.
|
38
|
+
#
|
39
|
+
# ## Usage
|
40
|
+
#
|
41
|
+
# To create a mixin, define a module, and include this module. Then define
|
42
|
+
# the methods you want to be available.
|
43
|
+
#
|
44
|
+
# If you want to perform some initialization specific to the mixin, use a
|
45
|
+
# `to_initialize` block. This block is passed any extra arguments that were
|
46
|
+
# passed to the `include` directive. It is called in the context of the tool,
|
47
|
+
# so it also has access to tool methods such as {Toys::Tool#option}. It can
|
48
|
+
# perform any setup required, which often involves initializing some
|
49
|
+
# persistent state and storing it in the tool using {Toys::Tool#set}.
|
50
|
+
#
|
51
|
+
# ## Example
|
52
|
+
#
|
53
|
+
# This is an example that implements a simple counter. Whenever the counter
|
54
|
+
# is incremented, a log message is emitted. The tool can also retrieve the
|
55
|
+
# final counter value.
|
56
|
+
#
|
57
|
+
# # Define a mixin by creating a module that includes Toys::Mixin
|
58
|
+
# module MyCounterMixin
|
59
|
+
# include Toys::Mixin
|
60
|
+
#
|
61
|
+
# # Initialize the counter. Called with self set to the tool so it can
|
62
|
+
# # affect the tool state.
|
63
|
+
# to_initialize do |start = 0|
|
64
|
+
# set(:counter_value, start)
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# # Mixin methods are called with self set to the tool and can affect
|
68
|
+
# # the tool state.
|
69
|
+
# def increment
|
70
|
+
# self[:counter_value] += 1
|
71
|
+
# logger.info("Incremented counter")
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# Now we can use it from a tool:
|
76
|
+
#
|
77
|
+
# tool "count-up" do
|
78
|
+
# # Pass 1 as an extra argument to the mixin initializer
|
79
|
+
# include MyCounterMixin, 1
|
80
|
+
#
|
81
|
+
# def run
|
82
|
+
# 5.times { increment }
|
83
|
+
# puts "Final value is #{get(:counter_value)}"
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
module Mixin
|
88
|
+
## @private
|
89
|
+
def self.included(mod)
|
90
|
+
return if mod.respond_to?(:to_initialize)
|
91
|
+
mod.extend(ClassMethods)
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Class methods that will be added to a mixin module.
|
96
|
+
#
|
97
|
+
module ClassMethods
|
98
|
+
##
|
99
|
+
# Provide the block that initializes this mixin.
|
100
|
+
#
|
101
|
+
def to_initialize(&block)
|
102
|
+
self.initializer = block
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# You may alternately set the initializer block using this accessor.
|
107
|
+
# @return [Proc]
|
108
|
+
#
|
109
|
+
attr_accessor :initializer
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/lib/toys/runner.rb
CHANGED
@@ -61,6 +61,7 @@ module Toys
|
|
61
61
|
data = create_data(args, verbosity)
|
62
62
|
parse_args(args, data) unless @tool_definition.argument_parsing_disabled?
|
63
63
|
tool = @tool_definition.tool_class.new(@cli, data)
|
64
|
+
@tool_definition.run_initializers(tool)
|
64
65
|
|
65
66
|
original_level = @cli.logger.level
|
66
67
|
@cli.logger.level = @cli.base_level - data[Tool::Keys::VERBOSITY]
|
@@ -66,6 +66,36 @@ module Toys
|
|
66
66
|
#
|
67
67
|
DEFAULT_SEARCH_FLAGS = ["-s WORD", "--search=WORD"].freeze
|
68
68
|
|
69
|
+
##
|
70
|
+
# Key set when the show help flag is present
|
71
|
+
# @return [Object]
|
72
|
+
#
|
73
|
+
SHOW_HELP_KEY = Object.new.freeze
|
74
|
+
|
75
|
+
##
|
76
|
+
# Key set when the show usage flag is present
|
77
|
+
# @return [Object]
|
78
|
+
#
|
79
|
+
SHOW_USAGE_KEY = Object.new.freeze
|
80
|
+
|
81
|
+
##
|
82
|
+
# Key for the recursive setting
|
83
|
+
# @return [Object]
|
84
|
+
#
|
85
|
+
RECURSIVE_SUBTOOLS_KEY = Object.new.freeze
|
86
|
+
|
87
|
+
##
|
88
|
+
# Key for the search string
|
89
|
+
# @return [Object]
|
90
|
+
#
|
91
|
+
SEARCH_STRING_KEY = Object.new.freeze
|
92
|
+
|
93
|
+
##
|
94
|
+
# Key for the tool name
|
95
|
+
# @return [Object]
|
96
|
+
#
|
97
|
+
TOOL_NAME_KEY = Object.new.freeze
|
98
|
+
|
69
99
|
##
|
70
100
|
# Create a ShowHelp middleware.
|
71
101
|
#
|
@@ -155,7 +185,7 @@ module Toys
|
|
155
185
|
usage_flags = add_usage_flags(tool_definition)
|
156
186
|
if @allow_root_args && (!help_flags.empty? || !usage_flags.empty?)
|
157
187
|
if tool_definition.root? && tool_definition.arg_definitions.empty?
|
158
|
-
tool_definition.set_remaining_args(
|
188
|
+
tool_definition.set_remaining_args(TOOL_NAME_KEY,
|
159
189
|
display_name: "TOOL_NAME",
|
160
190
|
desc: "The tool for which to display help")
|
161
191
|
end
|
@@ -173,15 +203,15 @@ module Toys
|
|
173
203
|
# Display help text if requested.
|
174
204
|
#
|
175
205
|
def run(tool)
|
176
|
-
if tool[
|
206
|
+
if tool[SHOW_USAGE_KEY]
|
177
207
|
help_text = get_help_text(tool)
|
178
208
|
str = help_text.usage_string(wrap_width: terminal.width)
|
179
209
|
terminal.puts(str)
|
180
210
|
elsif @fallback_execution && !tool[Tool::Keys::TOOL_DEFINITION].runnable? ||
|
181
|
-
tool[
|
211
|
+
tool[SHOW_HELP_KEY]
|
182
212
|
help_text = get_help_text(tool)
|
183
|
-
str = help_text.help_string(recursive: tool[
|
184
|
-
search: tool[
|
213
|
+
str = help_text.help_string(recursive: tool[RECURSIVE_SUBTOOLS_KEY],
|
214
|
+
search: tool[SEARCH_STRING_KEY],
|
185
215
|
show_source_path: @show_source_path,
|
186
216
|
wrap_width: terminal.width)
|
187
217
|
output_help(str)
|
@@ -216,7 +246,7 @@ module Toys
|
|
216
246
|
end
|
217
247
|
|
218
248
|
def get_help_text(tool)
|
219
|
-
tool_name = tool[
|
249
|
+
tool_name = tool[TOOL_NAME_KEY]
|
220
250
|
return Utils::HelpText.from_tool(tool) if tool_name.nil? || tool_name.empty?
|
221
251
|
loader = tool[Tool::Keys::LOADER]
|
222
252
|
tool_definition, rest = loader.lookup(tool_name)
|
@@ -236,7 +266,7 @@ module Toys
|
|
236
266
|
help_flags = resolve_flags_spec(@help_flags, tool_definition, DEFAULT_HELP_FLAGS)
|
237
267
|
unless help_flags.empty?
|
238
268
|
tool_definition.add_flag(
|
239
|
-
|
269
|
+
SHOW_HELP_KEY, help_flags,
|
240
270
|
report_collisions: false,
|
241
271
|
desc: "Display help for this tool"
|
242
272
|
)
|
@@ -248,7 +278,7 @@ module Toys
|
|
248
278
|
usage_flags = resolve_flags_spec(@usage_flags, tool_definition, DEFAULT_USAGE_FLAGS)
|
249
279
|
unless usage_flags.empty?
|
250
280
|
tool_definition.add_flag(
|
251
|
-
|
281
|
+
SHOW_USAGE_KEY, usage_flags,
|
252
282
|
report_collisions: false,
|
253
283
|
desc: "Display a brief usage string for this tool"
|
254
284
|
)
|
@@ -261,7 +291,7 @@ module Toys
|
|
261
291
|
DEFAULT_RECURSIVE_FLAGS)
|
262
292
|
unless recursive_flags.empty?
|
263
293
|
tool_definition.add_flag(
|
264
|
-
|
294
|
+
RECURSIVE_SUBTOOLS_KEY, recursive_flags,
|
265
295
|
report_collisions: false, default: @default_recursive,
|
266
296
|
desc: "Show all subtools recursively (default is #{@default_recursive})"
|
267
297
|
)
|
@@ -272,7 +302,7 @@ module Toys
|
|
272
302
|
search_flags = resolve_flags_spec(@search_flags, tool_definition, DEFAULT_SEARCH_FLAGS)
|
273
303
|
unless search_flags.empty?
|
274
304
|
tool_definition.add_flag(
|
275
|
-
|
305
|
+
SEARCH_STRING_KEY, search_flags,
|
276
306
|
report_collisions: false,
|
277
307
|
desc: "Search subtools for the given regular expression"
|
278
308
|
)
|
@@ -48,6 +48,12 @@ module Toys
|
|
48
48
|
#
|
49
49
|
DEFAULT_VERSION_FLAG_DESC = "Display the version".freeze
|
50
50
|
|
51
|
+
##
|
52
|
+
# Key set when the version flag is present
|
53
|
+
# @return [Object]
|
54
|
+
#
|
55
|
+
SHOW_VERSION_KEY = Object.new.freeze
|
56
|
+
|
51
57
|
##
|
52
58
|
# Create a ShowVersion middleware
|
53
59
|
#
|
@@ -72,7 +78,7 @@ module Toys
|
|
72
78
|
#
|
73
79
|
def config(tool_definition, _loader)
|
74
80
|
if @version_string && tool_definition.root?
|
75
|
-
tool_definition.add_flag(
|
81
|
+
tool_definition.add_flag(SHOW_VERSION_KEY, @version_flags,
|
76
82
|
report_collisions: false, desc: @version_flag_desc)
|
77
83
|
end
|
78
84
|
yield
|
@@ -82,7 +88,7 @@ module Toys
|
|
82
88
|
# This middleware displays the version.
|
83
89
|
#
|
84
90
|
def run(tool)
|
85
|
-
if tool[
|
91
|
+
if tool[SHOW_VERSION_KEY]
|
86
92
|
@terminal.puts(@version_string)
|
87
93
|
else
|
88
94
|
yield
|
@@ -44,6 +44,26 @@ module Toys
|
|
44
44
|
# available in that class's documentation.
|
45
45
|
#
|
46
46
|
module Exec
|
47
|
+
include Mixin
|
48
|
+
|
49
|
+
##
|
50
|
+
# Context key for the executor object.
|
51
|
+
# @return [Object]
|
52
|
+
#
|
53
|
+
KEY = ::Object.new.freeze
|
54
|
+
|
55
|
+
to_initialize do |opts = {}|
|
56
|
+
tool = self
|
57
|
+
tool[KEY] = Utils::Exec.new(opts) do |k|
|
58
|
+
case k
|
59
|
+
when :logger
|
60
|
+
tool[Tool::Keys::LOGGER]
|
61
|
+
when :cli
|
62
|
+
tool[Tool::Keys::CLI]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
47
67
|
##
|
48
68
|
# Set default configuration keys.
|
49
69
|
#
|
@@ -51,7 +71,7 @@ module Toys
|
|
51
71
|
# configuration options in the {Toys::Utils::Exec} docs.
|
52
72
|
#
|
53
73
|
def configure_exec(opts = {})
|
54
|
-
|
74
|
+
self[KEY].configure_defaults(Exec._setup_exec_opts(opts, self))
|
55
75
|
end
|
56
76
|
|
57
77
|
##
|
@@ -71,7 +91,7 @@ module Toys
|
|
71
91
|
# the exit code and any captured output.
|
72
92
|
#
|
73
93
|
def exec(cmd, opts = {}, &block)
|
74
|
-
|
94
|
+
self[KEY].exec(cmd, Exec._setup_exec_opts(opts, self), &block)
|
75
95
|
end
|
76
96
|
|
77
97
|
##
|
@@ -90,7 +110,7 @@ module Toys
|
|
90
110
|
# the exit code and any captured output.
|
91
111
|
#
|
92
112
|
def exec_ruby(args, opts = {}, &block)
|
93
|
-
|
113
|
+
self[KEY].exec_ruby(args, Exec._setup_exec_opts(opts, self), &block)
|
94
114
|
end
|
95
115
|
alias ruby exec_ruby
|
96
116
|
|
@@ -110,7 +130,7 @@ module Toys
|
|
110
130
|
# exit code and any captured output.
|
111
131
|
#
|
112
132
|
def exec_proc(func, opts = {}, &block)
|
113
|
-
|
133
|
+
self[KEY].exec_proc(func, Exec._setup_exec_opts(opts, self), &block)
|
114
134
|
end
|
115
135
|
|
116
136
|
##
|
@@ -131,7 +151,7 @@ module Toys
|
|
131
151
|
#
|
132
152
|
def exec_tool(cmd, opts = {}, &block)
|
133
153
|
func = Exec._make_tool_caller(cmd)
|
134
|
-
|
154
|
+
self[KEY].exec_proc(func, Exec._setup_exec_opts(opts, self), &block)
|
135
155
|
end
|
136
156
|
|
137
157
|
##
|
@@ -147,7 +167,7 @@ module Toys
|
|
147
167
|
# @return [String] What was written to standard out.
|
148
168
|
#
|
149
169
|
def capture(cmd, opts = {})
|
150
|
-
|
170
|
+
self[KEY].capture(cmd, Exec._setup_exec_opts(opts, self))
|
151
171
|
end
|
152
172
|
|
153
173
|
##
|
@@ -162,7 +182,7 @@ module Toys
|
|
162
182
|
# @return [String] What was written to standard out.
|
163
183
|
#
|
164
184
|
def capture_ruby(args, opts = {})
|
165
|
-
|
185
|
+
self[KEY].capture_ruby(args, Exec._setup_exec_opts(opts, self))
|
166
186
|
end
|
167
187
|
|
168
188
|
##
|
@@ -177,7 +197,7 @@ module Toys
|
|
177
197
|
# @return [String] What was written to standard out.
|
178
198
|
#
|
179
199
|
def capture_proc(func, opts = {})
|
180
|
-
|
200
|
+
self[KEY].capture_proc(func, Exec._setup_exec_opts(opts, self))
|
181
201
|
end
|
182
202
|
|
183
203
|
##
|
@@ -194,7 +214,7 @@ module Toys
|
|
194
214
|
#
|
195
215
|
def capture_tool(cmd, opts = {})
|
196
216
|
func = Exec._make_tool_caller(cmd)
|
197
|
-
|
217
|
+
self[KEY].capture_proc(func, Exec._setup_exec_opts(opts, self))
|
198
218
|
end
|
199
219
|
|
200
220
|
##
|
@@ -207,7 +227,7 @@ module Toys
|
|
207
227
|
# @return [Integer] The exit code
|
208
228
|
#
|
209
229
|
def sh(cmd, opts = {})
|
210
|
-
|
230
|
+
self[KEY].sh(cmd, Exec._setup_exec_opts(opts, self))
|
211
231
|
end
|
212
232
|
|
213
233
|
##
|
@@ -222,18 +242,6 @@ module Toys
|
|
222
242
|
0
|
223
243
|
end
|
224
244
|
|
225
|
-
## @private
|
226
|
-
def self._exec(tool)
|
227
|
-
tool[Exec] ||= Utils::Exec.new do |k|
|
228
|
-
case k
|
229
|
-
when :logger
|
230
|
-
tool[Tool::Keys::LOGGER]
|
231
|
-
when :cli
|
232
|
-
tool[Tool::Keys::CLI]
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
245
|
## @private
|
238
246
|
def self._make_tool_caller(cmd)
|
239
247
|
cmd = ::Shellwords.split(cmd) if cmd.is_a?(::String)
|
@@ -27,7 +27,7 @@
|
|
27
27
|
# POSSIBILITY OF SUCH DAMAGE.
|
28
28
|
;
|
29
29
|
|
30
|
-
Toys::Utils::Gems.activate("highline", "~>
|
30
|
+
Toys::Utils::Gems.activate("highline", "~> 2.0")
|
31
31
|
require "highline"
|
32
32
|
|
33
33
|
module Toys
|
@@ -41,15 +41,25 @@ module Toys
|
|
41
41
|
# include :highline
|
42
42
|
#
|
43
43
|
module Highline
|
44
|
+
include Mixin
|
45
|
+
|
46
|
+
##
|
47
|
+
# Context key for the executor object.
|
48
|
+
# @return [Object]
|
49
|
+
#
|
50
|
+
KEY = ::Object.new.freeze
|
51
|
+
|
52
|
+
to_initialize do |*args|
|
53
|
+
self[KEY] = ::HighLine.new(*args)
|
54
|
+
self[KEY].use_color = $stdout.tty?
|
55
|
+
end
|
56
|
+
|
44
57
|
##
|
45
58
|
# Returns a global highline instance
|
46
59
|
# @return [::HighLine]
|
47
60
|
#
|
48
61
|
def highline
|
49
|
-
self[
|
50
|
-
::HighLine.use_color = $stdout.tty?
|
51
|
-
::HighLine.new
|
52
|
-
end
|
62
|
+
self[KEY]
|
53
63
|
end
|
54
64
|
|
55
65
|
##
|
@@ -88,38 +98,52 @@ module Toys
|
|
88
98
|
end
|
89
99
|
|
90
100
|
##
|
91
|
-
# @see https://www.rubydoc.info/gems/highline/HighLine
|
101
|
+
# @see https://www.rubydoc.info/gems/highline/HighLine:indent HighLine#indent
|
92
102
|
#
|
93
|
-
def
|
94
|
-
|
103
|
+
def indent(*args, &block)
|
104
|
+
highline.indent(*args, &block)
|
95
105
|
end
|
96
106
|
|
97
107
|
##
|
98
|
-
# @see https://www.rubydoc.info/gems/highline/HighLine
|
108
|
+
# @see https://www.rubydoc.info/gems/highline/HighLine:newline HighLine#newline
|
99
109
|
#
|
100
|
-
def
|
101
|
-
|
110
|
+
def newline
|
111
|
+
highline.newline
|
102
112
|
end
|
103
113
|
|
104
114
|
##
|
105
|
-
# @see https://www.rubydoc.info/gems/highline/HighLine
|
115
|
+
# @see https://www.rubydoc.info/gems/highline/HighLine:puts HighLine#puts
|
106
116
|
#
|
107
|
-
def
|
108
|
-
|
117
|
+
def puts(*args)
|
118
|
+
highline.puts(*args)
|
109
119
|
end
|
110
120
|
|
111
121
|
##
|
112
|
-
# @see https://www.rubydoc.info/gems/highline/HighLine:
|
122
|
+
# @see https://www.rubydoc.info/gems/highline/HighLine:color HighLine#color
|
113
123
|
#
|
114
|
-
def
|
115
|
-
highline.
|
124
|
+
def color(*args)
|
125
|
+
highline.color(*args)
|
116
126
|
end
|
117
127
|
|
118
128
|
##
|
119
|
-
# @see https://www.rubydoc.info/gems/highline/HighLine:
|
129
|
+
# @see https://www.rubydoc.info/gems/highline/HighLine:color_code HighLine#color_code
|
130
|
+
#
|
131
|
+
def color_code(*args)
|
132
|
+
highline.color_code(*args)
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# @see https://www.rubydoc.info/gems/highline/HighLine:uncolor HighLine#uncolor
|
137
|
+
#
|
138
|
+
def uncolor(*args)
|
139
|
+
highline.uncolor(*args)
|
140
|
+
end
|
141
|
+
|
142
|
+
##
|
143
|
+
# @see https://www.rubydoc.info/gems/highline/HighLine:new_scope HighLine#new_scope
|
120
144
|
#
|
121
|
-
def
|
122
|
-
highline.
|
145
|
+
def new_scope
|
146
|
+
highline.new_scope
|
123
147
|
end
|
124
148
|
end
|
125
149
|
end
|
@@ -32,7 +32,9 @@ module Toys
|
|
32
32
|
##
|
33
33
|
# A mixin that provides a simple terminal. It includes a set of methods
|
34
34
|
# that produce styled output, get user input, and otherwise interact with
|
35
|
-
# the user's terminal.
|
35
|
+
# the user's terminal. This mixin is not as richly featured as other mixins
|
36
|
+
# such as Highline, but it has no gem dependencies so is ideal for basic
|
37
|
+
# cases.
|
36
38
|
#
|
37
39
|
# You may make these methods available to your tool by including the
|
38
40
|
# following directive in your tool configuration:
|
@@ -40,12 +42,24 @@ module Toys
|
|
40
42
|
# include :terminal
|
41
43
|
#
|
42
44
|
module Terminal
|
45
|
+
include Mixin
|
46
|
+
|
47
|
+
##
|
48
|
+
# Context key for the terminal object.
|
49
|
+
# @return [Object]
|
50
|
+
#
|
51
|
+
KEY = ::Object.new.freeze
|
52
|
+
|
53
|
+
to_initialize do |opts = {}|
|
54
|
+
self[KEY] = Utils::Terminal.new(opts)
|
55
|
+
end
|
56
|
+
|
43
57
|
##
|
44
58
|
# Returns a global terminal instance
|
45
59
|
# @return [Toys::Utils::Terminal]
|
46
60
|
#
|
47
61
|
def terminal
|
48
|
-
self[
|
62
|
+
self[KEY]
|
49
63
|
end
|
50
64
|
|
51
65
|
##
|
data/lib/toys/template.rb
CHANGED
@@ -77,7 +77,7 @@ module Toys
|
|
77
77
|
# to_expand do |template|
|
78
78
|
# desc "Prints a greeting to #{template.name}"
|
79
79
|
# tool "templated-greeting" do
|
80
|
-
#
|
80
|
+
# to_run do
|
81
81
|
# puts "Hello, #{template.name}!"
|
82
82
|
# end
|
83
83
|
# end
|
@@ -112,7 +112,7 @@ module Toys
|
|
112
112
|
# Provide the block that implements the template.
|
113
113
|
#
|
114
114
|
def to_expand(&block)
|
115
|
-
|
115
|
+
self.expander = block
|
116
116
|
end
|
117
117
|
|
118
118
|
##
|
data/lib/toys/tool.rb
CHANGED
@@ -257,18 +257,6 @@ module Toys
|
|
257
257
|
end
|
258
258
|
end
|
259
259
|
|
260
|
-
##
|
261
|
-
# Returns the value of the given option. Returns only options with string
|
262
|
-
# or symbol keys; returns `nil` if passed other well-known context keys
|
263
|
-
# such as verbosity.
|
264
|
-
#
|
265
|
-
# @param [String,Symbol] key
|
266
|
-
# @return [Object]
|
267
|
-
#
|
268
|
-
def option(key)
|
269
|
-
key.is_a?(::Symbol) || key.is_a?(::String) ? @__data[key] : nil
|
270
|
-
end
|
271
|
-
|
272
260
|
##
|
273
261
|
# Activate the given gem. If it is not present, attempt to install it (or
|
274
262
|
# inform the user to update the bundle).
|
data/lib/toys-core.rb
CHANGED
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.
|
4
|
+
version: 0.3.10
|
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-
|
11
|
+
date: 2018-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -108,6 +108,7 @@ files:
|
|
108
108
|
- lib/toys/input_file.rb
|
109
109
|
- lib/toys/loader.rb
|
110
110
|
- lib/toys/middleware.rb
|
111
|
+
- lib/toys/mixin.rb
|
111
112
|
- lib/toys/runner.rb
|
112
113
|
- lib/toys/standard_middleware/add_verbosity_flags.rb
|
113
114
|
- lib/toys/standard_middleware/handle_usage_errors.rb
|