toys-core 0.11.5 → 0.13.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -0
- data/LICENSE.md +1 -1
- data/README.md +5 -2
- data/docs/guide.md +1 -1
- data/lib/toys/acceptor.rb +13 -4
- data/lib/toys/arg_parser.rb +7 -7
- data/lib/toys/cli.rb +170 -120
- data/lib/toys/compat.rb +71 -23
- data/lib/toys/completion.rb +18 -6
- data/lib/toys/context.rb +24 -15
- data/lib/toys/core.rb +6 -2
- data/lib/toys/dsl/base.rb +87 -0
- data/lib/toys/dsl/flag.rb +26 -20
- data/lib/toys/dsl/flag_group.rb +18 -14
- data/lib/toys/dsl/internal.rb +206 -0
- data/lib/toys/dsl/positional_arg.rb +26 -16
- data/lib/toys/dsl/tool.rb +180 -218
- data/lib/toys/errors.rb +64 -8
- data/lib/toys/flag.rb +662 -656
- data/lib/toys/flag_group.rb +24 -10
- data/lib/toys/input_file.rb +13 -7
- data/lib/toys/loader.rb +293 -140
- data/lib/toys/middleware.rb +46 -22
- data/lib/toys/mixin.rb +10 -8
- data/lib/toys/positional_arg.rb +21 -20
- data/lib/toys/settings.rb +914 -0
- data/lib/toys/source_info.rb +147 -35
- data/lib/toys/standard_middleware/add_verbosity_flags.rb +2 -0
- data/lib/toys/standard_middleware/apply_config.rb +6 -4
- data/lib/toys/standard_middleware/handle_usage_errors.rb +1 -0
- data/lib/toys/standard_middleware/set_default_descriptions.rb +19 -18
- data/lib/toys/standard_middleware/show_help.rb +19 -5
- data/lib/toys/standard_middleware/show_root_version.rb +2 -0
- data/lib/toys/standard_mixins/bundler.rb +24 -15
- data/lib/toys/standard_mixins/exec.rb +43 -34
- data/lib/toys/standard_mixins/fileutils.rb +3 -1
- data/lib/toys/standard_mixins/gems.rb +21 -17
- data/lib/toys/standard_mixins/git_cache.rb +46 -0
- data/lib/toys/standard_mixins/highline.rb +8 -8
- data/lib/toys/standard_mixins/terminal.rb +5 -5
- data/lib/toys/standard_mixins/xdg.rb +56 -0
- data/lib/toys/template.rb +11 -9
- data/lib/toys/{tool.rb → tool_definition.rb} +292 -226
- data/lib/toys/utils/completion_engine.rb +7 -2
- data/lib/toys/utils/exec.rb +162 -132
- data/lib/toys/utils/gems.rb +85 -60
- data/lib/toys/utils/git_cache.rb +813 -0
- data/lib/toys/utils/help_text.rb +117 -37
- data/lib/toys/utils/terminal.rb +11 -3
- data/lib/toys/utils/xdg.rb +293 -0
- data/lib/toys/wrappable_string.rb +9 -2
- data/lib/toys-core.rb +18 -6
- metadata +14 -7
data/lib/toys/compat.rb
CHANGED
@@ -5,28 +5,44 @@ require "rbconfig"
|
|
5
5
|
module Toys
|
6
6
|
##
|
7
7
|
# Compatibility wrappers for older Ruby versions.
|
8
|
+
#
|
8
9
|
# @private
|
9
10
|
#
|
10
11
|
module Compat
|
11
12
|
parts = ::RUBY_VERSION.split(".")
|
12
13
|
ruby_version = parts[0].to_i * 10000 + parts[1].to_i * 100 + parts[2].to_i
|
13
14
|
|
15
|
+
##
|
14
16
|
# @private
|
17
|
+
#
|
15
18
|
def self.jruby?
|
16
|
-
::
|
19
|
+
::RUBY_ENGINE == "jruby"
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# @private
|
24
|
+
#
|
25
|
+
def self.truffleruby?
|
26
|
+
::RUBY_ENGINE == "truffleruby"
|
17
27
|
end
|
18
28
|
|
29
|
+
##
|
19
30
|
# @private
|
31
|
+
#
|
20
32
|
def self.windows?
|
21
33
|
::RbConfig::CONFIG["host_os"] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
22
34
|
end
|
23
35
|
|
36
|
+
##
|
24
37
|
# @private
|
38
|
+
#
|
25
39
|
def self.allow_fork?
|
26
|
-
!jruby? && !windows?
|
40
|
+
!jruby? && !truffleruby? && !windows?
|
27
41
|
end
|
28
42
|
|
43
|
+
##
|
29
44
|
# @private
|
45
|
+
#
|
30
46
|
def self.supports_suggestions?
|
31
47
|
unless defined?(@supports_suggestions)
|
32
48
|
begin
|
@@ -44,7 +60,9 @@ module Toys
|
|
44
60
|
@supports_suggestions
|
45
61
|
end
|
46
62
|
|
63
|
+
##
|
47
64
|
# @private
|
65
|
+
#
|
48
66
|
def self.suggestions(word, list)
|
49
67
|
if supports_suggestions?
|
50
68
|
::DidYouMean::SpellChecker.new(dictionary: list).correct(word)
|
@@ -53,50 +71,55 @@ module Toys
|
|
53
71
|
end
|
54
72
|
end
|
55
73
|
|
56
|
-
#
|
57
|
-
if ruby_version >=
|
74
|
+
# The :base argument to Dir.glob requires Ruby 2.5 or later.
|
75
|
+
if ruby_version >= 20500
|
76
|
+
##
|
58
77
|
# @private
|
59
|
-
|
60
|
-
|
61
|
-
|
78
|
+
#
|
79
|
+
def self.glob_in_dir(glob, dir)
|
80
|
+
::Dir.glob(glob, base: dir)
|
62
81
|
end
|
63
82
|
else
|
83
|
+
##
|
64
84
|
# @private
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
begin
|
69
|
-
v.clone
|
70
|
-
rescue ::TypeError
|
71
|
-
v
|
72
|
-
end
|
73
|
-
end
|
74
|
-
hash
|
85
|
+
#
|
86
|
+
def self.glob_in_dir(glob, dir)
|
87
|
+
::Dir.chdir(dir) { ::Dir.glob(glob) }
|
75
88
|
end
|
76
89
|
end
|
77
90
|
|
78
|
-
#
|
91
|
+
# Dir.children requires Ruby 2.5 or later.
|
79
92
|
if ruby_version >= 20500
|
93
|
+
##
|
80
94
|
# @private
|
81
|
-
|
82
|
-
|
95
|
+
#
|
96
|
+
def self.dir_children(dir)
|
97
|
+
::Dir.children(dir)
|
83
98
|
end
|
84
99
|
else
|
100
|
+
##
|
85
101
|
# @private
|
86
|
-
|
87
|
-
|
102
|
+
#
|
103
|
+
def self.dir_children(dir)
|
104
|
+
::Dir.entries(dir) - [".", ".."]
|
88
105
|
end
|
89
106
|
end
|
90
107
|
|
91
108
|
# Due to a bug in Ruby < 2.7, passing an empty **kwargs splat to
|
92
109
|
# initialize will fail if there are no formal keyword args.
|
93
|
-
|
110
|
+
# This also hits TruffleRuby
|
111
|
+
# (see https://github.com/oracle/truffleruby/issues/2567)
|
112
|
+
if ruby_version >= 20700 && !truffleruby?
|
113
|
+
##
|
94
114
|
# @private
|
115
|
+
#
|
95
116
|
def self.instantiate(klass, args, kwargs, block)
|
96
117
|
klass.new(*args, **kwargs, &block)
|
97
118
|
end
|
98
119
|
else
|
120
|
+
##
|
99
121
|
# @private
|
122
|
+
#
|
100
123
|
def self.instantiate(klass, args, kwargs, block)
|
101
124
|
formals = klass.instance_method(:initialize).parameters
|
102
125
|
if kwargs.empty? && formals.all? { |arg| arg.first != :key && arg.first != :keyrest }
|
@@ -106,5 +129,30 @@ module Toys
|
|
106
129
|
end
|
107
130
|
end
|
108
131
|
end
|
132
|
+
|
133
|
+
# File.absolute_path? requires Ruby 2.7 or later. For earlier Rubies, use
|
134
|
+
# an ad-hoc mechanism.
|
135
|
+
if ruby_version >= 20700
|
136
|
+
##
|
137
|
+
# @private
|
138
|
+
#
|
139
|
+
def self.absolute_path?(path)
|
140
|
+
::File.absolute_path?(path)
|
141
|
+
end
|
142
|
+
elsif ::Dir.getwd =~ /^[a-zA-Z]:/
|
143
|
+
##
|
144
|
+
# @private
|
145
|
+
#
|
146
|
+
def self.absolute_path?(path)
|
147
|
+
/^[a-zA-Z]:/.match?(path)
|
148
|
+
end
|
149
|
+
else
|
150
|
+
##
|
151
|
+
# @private
|
152
|
+
#
|
153
|
+
def self.absolute_path?(path)
|
154
|
+
path.start_with?("/")
|
155
|
+
end
|
156
|
+
end
|
109
157
|
end
|
110
158
|
end
|
data/lib/toys/completion.rb
CHANGED
@@ -88,7 +88,7 @@ module Toys
|
|
88
88
|
|
89
89
|
##
|
90
90
|
# The tool being invoked, which should control the completion.
|
91
|
-
# @return [Toys::
|
91
|
+
# @return [Toys::ToolDefinition]
|
92
92
|
#
|
93
93
|
def tool
|
94
94
|
lookup_tool
|
@@ -116,7 +116,9 @@ module Toys
|
|
116
116
|
@arg_parser ||= ArgParser.new(@cli, @tool).parse(@args)
|
117
117
|
end
|
118
118
|
|
119
|
-
##
|
119
|
+
##
|
120
|
+
# @private
|
121
|
+
#
|
120
122
|
def inspect
|
121
123
|
"<Toys::Completion::Context previous=#{previous_words.inspect}" \
|
122
124
|
" prefix=#{fragment_prefix.inspect} fragment=#{fragment.inspect}>"
|
@@ -175,17 +177,23 @@ module Toys
|
|
175
177
|
!@partial
|
176
178
|
end
|
177
179
|
|
178
|
-
##
|
180
|
+
##
|
181
|
+
# @private
|
182
|
+
#
|
179
183
|
def eql?(other)
|
180
184
|
other.is_a?(Candidate) && other.string.eql?(string) && other.partial? == @partial
|
181
185
|
end
|
182
186
|
|
183
|
-
##
|
187
|
+
##
|
188
|
+
# @private
|
189
|
+
#
|
184
190
|
def <=>(other)
|
185
191
|
string <=> other.string
|
186
192
|
end
|
187
193
|
|
188
|
-
##
|
194
|
+
##
|
195
|
+
# @private
|
196
|
+
#
|
189
197
|
def hash
|
190
198
|
string.hash ^ (partial? ? 1 : 0)
|
191
199
|
end
|
@@ -236,6 +244,7 @@ module Toys
|
|
236
244
|
# prefix. Defaults to requiring the prefix be empty.
|
237
245
|
#
|
238
246
|
def initialize(cwd: nil, omit_files: false, omit_directories: false, prefix_constraint: "")
|
247
|
+
super()
|
239
248
|
@cwd = cwd || ::Dir.pwd
|
240
249
|
@include_files = !omit_files
|
241
250
|
@include_directories = !omit_directories
|
@@ -328,6 +337,7 @@ module Toys
|
|
328
337
|
# prefix. Defaults to requiring the prefix be empty.
|
329
338
|
#
|
330
339
|
def initialize(values, prefix_constraint: "")
|
340
|
+
super()
|
331
341
|
@values = values.flatten.map { |v| Candidate.new(v) }.sort
|
332
342
|
@prefix_constraint = prefix_constraint
|
333
343
|
end
|
@@ -424,7 +434,9 @@ module Toys
|
|
424
434
|
end
|
425
435
|
end
|
426
436
|
|
427
|
-
##
|
437
|
+
##
|
438
|
+
# @private
|
439
|
+
#
|
428
440
|
def self.scalarize_spec(spec, options, block)
|
429
441
|
spec ||= block
|
430
442
|
if options.empty?
|
data/lib/toys/context.rb
CHANGED
@@ -33,7 +33,7 @@ module Toys
|
|
33
33
|
# This module is mixed into the runtime context. This means you can
|
34
34
|
# reference any of these constants directly from your run method.
|
35
35
|
#
|
36
|
-
#
|
36
|
+
# ### Example
|
37
37
|
#
|
38
38
|
# tool "my-name" do
|
39
39
|
# def run
|
@@ -78,7 +78,7 @@ module Toys
|
|
78
78
|
LOGGER = ::Object.new.freeze
|
79
79
|
|
80
80
|
##
|
81
|
-
# Context key for the {Toys::
|
81
|
+
# Context key for the {Toys::ToolDefinition} object being executed.
|
82
82
|
# @return [Object]
|
83
83
|
#
|
84
84
|
TOOL = ::Object.new.freeze
|
@@ -133,19 +133,6 @@ module Toys
|
|
133
133
|
VERBOSITY = ::Object.new.freeze
|
134
134
|
end
|
135
135
|
|
136
|
-
##
|
137
|
-
# Create a Context object. Applications generally will not need to create
|
138
|
-
# these objects directly; they are created by the tool when it is preparing
|
139
|
-
# for execution.
|
140
|
-
#
|
141
|
-
# @private
|
142
|
-
#
|
143
|
-
# @param data [Hash]
|
144
|
-
#
|
145
|
-
def initialize(data)
|
146
|
-
@__data = data
|
147
|
-
end
|
148
|
-
|
149
136
|
##
|
150
137
|
# The raw arguments passed to the tool, as an array of strings.
|
151
138
|
# This does not include the tool name itself.
|
@@ -335,5 +322,27 @@ module Toys
|
|
335
322
|
def self.exit(code = 0)
|
336
323
|
throw :result, code
|
337
324
|
end
|
325
|
+
|
326
|
+
##
|
327
|
+
# Create a Context object. Applications generally will not need to create
|
328
|
+
# these objects directly; they are created by the tool when it is preparing
|
329
|
+
# for execution.
|
330
|
+
#
|
331
|
+
# @param data [Hash]
|
332
|
+
#
|
333
|
+
# @private
|
334
|
+
#
|
335
|
+
def initialize(data)
|
336
|
+
@__data = data
|
337
|
+
end
|
338
|
+
|
339
|
+
##
|
340
|
+
# @private
|
341
|
+
#
|
342
|
+
def inspect
|
343
|
+
name = Array(@__data[Key::TOOL_NAME]).join(" ")
|
344
|
+
id = object_id.to_s(16)
|
345
|
+
"#<Toys::Context id=0x#{id} #{name}>"
|
346
|
+
end
|
338
347
|
end
|
339
348
|
end
|
data/lib/toys/core.rb
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
# Create a base class for defining a tool with a given name.
|
5
|
+
#
|
6
|
+
# This method returns a base class for defining a tool with a given name.
|
7
|
+
# This is useful if the naming behavior of {Toys::Tool} is not adequate for
|
8
|
+
# your tool.
|
9
|
+
#
|
10
|
+
# ### Example
|
11
|
+
#
|
12
|
+
# class FooBar < Toys.Tool("Foo_Bar")
|
13
|
+
# desc "This is a tool called Foo_Bar"
|
14
|
+
#
|
15
|
+
# def run
|
16
|
+
# puts "Foo_Bar called"
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# @param name [String] Name of the tool. Defaults to a name inferred from the
|
21
|
+
# class name. (See {Toys::Tool}.)
|
22
|
+
# @param base [Class] Use this tool class as the base class, and inherit helper
|
23
|
+
# methods from it.
|
24
|
+
# @param args [String,Class] Any string-valued positional argument is
|
25
|
+
# interpreted as the name. Any class-valued positional argument is
|
26
|
+
# interpreted as the base class.
|
27
|
+
#
|
28
|
+
def Toys.Tool(*args, name: nil, base: nil) # rubocop:disable Naming/MethodName
|
29
|
+
args.each do |arg|
|
30
|
+
case arg
|
31
|
+
when ::Class
|
32
|
+
raise ::ArgumentError, "Both base keyword argument and class-valud argument received" if base
|
33
|
+
base = arg
|
34
|
+
when ::String, ::Symbol
|
35
|
+
raise ::ArgumentError, "Both name keyword argument and string-valud argument received" if name
|
36
|
+
name = arg
|
37
|
+
else
|
38
|
+
raise ::ArgumentError, "Unrecognized argument: #{arg}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
if base && !base.ancestors.include?(::Toys::Context)
|
42
|
+
raise ::ArgumentError, "Base class must itself be a tool"
|
43
|
+
end
|
44
|
+
return base || ::Toys::Tool if name.nil?
|
45
|
+
::Class.new(base || ::Toys::Context) do
|
46
|
+
base_class = self
|
47
|
+
define_singleton_method(:inherited) do |tool_class|
|
48
|
+
::Toys::DSL::Internal.configure_class(tool_class, base_class == self ? name.to_s : nil)
|
49
|
+
super(tool_class)
|
50
|
+
::Toys::DSL::Internal.setup_class_dsl(tool_class)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module Toys
|
56
|
+
##
|
57
|
+
# Base class for defining tools
|
58
|
+
#
|
59
|
+
# This base class provides an alternative to the {Toys::DSL::Tool#tool}
|
60
|
+
# directive for defining tools in the Toys DSL. Creating a subclass of
|
61
|
+
# `Toys::Tool` will create a tool whose name is the "kebab-case" of the class
|
62
|
+
# name. Subclasses can be created only in the context of a tool configuration
|
63
|
+
# DSL. Furthermore, a class-defined tool can be created only at the top level
|
64
|
+
# of a configuration file, or within another class-defined tool. It cannot
|
65
|
+
# be a subtool of a tool block.
|
66
|
+
#
|
67
|
+
# ### Example
|
68
|
+
#
|
69
|
+
# class FooBar < Toys::Tool
|
70
|
+
# desc "This is a tool called foo-bar"
|
71
|
+
#
|
72
|
+
# def run
|
73
|
+
# puts "foo-bar called"
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
class Tool < Context
|
78
|
+
##
|
79
|
+
# @private
|
80
|
+
#
|
81
|
+
def self.inherited(tool_class)
|
82
|
+
DSL::Internal.configure_class(tool_class)
|
83
|
+
super
|
84
|
+
DSL::Internal.setup_class_dsl(tool_class)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/toys/dsl/flag.rb
CHANGED
@@ -9,7 +9,7 @@ module Toys
|
|
9
9
|
# These directives are available inside a block passed to
|
10
10
|
# {Toys::DSL::Tool#flag}.
|
11
11
|
#
|
12
|
-
#
|
12
|
+
# ### Example
|
13
13
|
#
|
14
14
|
# tool "mytool" do
|
15
15
|
# flag :value do
|
@@ -22,22 +22,6 @@ module Toys
|
|
22
22
|
# end
|
23
23
|
#
|
24
24
|
class Flag
|
25
|
-
## @private
|
26
|
-
def initialize(flags, acceptor, default, handler, flag_completion, value_completion,
|
27
|
-
report_collisions, group, desc, long_desc, display_name)
|
28
|
-
@flags = flags
|
29
|
-
@default = default
|
30
|
-
@handler = handler
|
31
|
-
@report_collisions = report_collisions
|
32
|
-
@group = group
|
33
|
-
@desc = desc
|
34
|
-
@long_desc = long_desc || []
|
35
|
-
@display_name = display_name
|
36
|
-
accept(acceptor)
|
37
|
-
complete_flags(flag_completion, **{})
|
38
|
-
complete_values(value_completion, **{})
|
39
|
-
end
|
40
|
-
|
41
25
|
##
|
42
26
|
# Add flags in OptionParser format. This may be called multiple times,
|
43
27
|
# and the results are cumulative.
|
@@ -212,7 +196,7 @@ module Toys
|
|
212
196
|
# across the strings in the array. In this case, whitespace is not
|
213
197
|
# compacted.
|
214
198
|
#
|
215
|
-
#
|
199
|
+
# ### Examples
|
216
200
|
#
|
217
201
|
# If you pass in a sentence as a simple string, it may be word wrapped
|
218
202
|
# when displayed:
|
@@ -243,7 +227,7 @@ module Toys
|
|
243
227
|
# word-wrapped when displayed. To insert a blank line, include an empty
|
244
228
|
# string as one of the descriptions.
|
245
229
|
#
|
246
|
-
#
|
230
|
+
# ### Example
|
247
231
|
#
|
248
232
|
# long_desc "This initial paragraph might get word wrapped.",
|
249
233
|
# "This next paragraph is followed by a blank line.",
|
@@ -284,7 +268,29 @@ module Toys
|
|
284
268
|
self
|
285
269
|
end
|
286
270
|
|
287
|
-
##
|
271
|
+
##
|
272
|
+
# Called only from DSL::Tool
|
273
|
+
#
|
274
|
+
# @private
|
275
|
+
#
|
276
|
+
def initialize(flags, acceptor, default, handler, flag_completion, value_completion,
|
277
|
+
report_collisions, group, desc, long_desc, display_name)
|
278
|
+
@flags = flags
|
279
|
+
@default = default
|
280
|
+
@handler = handler
|
281
|
+
@report_collisions = report_collisions
|
282
|
+
@group = group
|
283
|
+
@desc = desc
|
284
|
+
@long_desc = long_desc || []
|
285
|
+
@display_name = display_name
|
286
|
+
accept(acceptor)
|
287
|
+
complete_flags(flag_completion, **{})
|
288
|
+
complete_values(value_completion, **{})
|
289
|
+
end
|
290
|
+
|
291
|
+
##
|
292
|
+
# @private
|
293
|
+
#
|
288
294
|
def _add_to(tool, key)
|
289
295
|
tool.add_flag(key, @flags,
|
290
296
|
accept: @acceptor, default: @default, handler: @handler,
|
data/lib/toys/dsl/flag_group.rb
CHANGED
@@ -10,7 +10,7 @@ module Toys
|
|
10
10
|
# {Toys::DSL::Tool#at_most_one}, {Toys::DSL::Tool#at_least_one}, or
|
11
11
|
# {Toys::DSL::Tool#exactly_one}.
|
12
12
|
#
|
13
|
-
#
|
13
|
+
# ### Example
|
14
14
|
#
|
15
15
|
# tool "login" do
|
16
16
|
# all_required do
|
@@ -22,13 +22,6 @@ module Toys
|
|
22
22
|
# end
|
23
23
|
#
|
24
24
|
class FlagGroup
|
25
|
-
## @private
|
26
|
-
def initialize(tool_dsl, tool, flag_group)
|
27
|
-
@tool_dsl = tool_dsl
|
28
|
-
@tool = tool
|
29
|
-
@flag_group = flag_group
|
30
|
-
end
|
31
|
-
|
32
25
|
##
|
33
26
|
# Add a flag to the current group. Each flag must specify a key which
|
34
27
|
# the script may use to obtain the flag value from the context.
|
@@ -43,7 +36,7 @@ module Toys
|
|
43
36
|
# set in a block passed to this method. If you provide a block, you can
|
44
37
|
# use directives in {Toys::DSL::Flag} within the block.
|
45
38
|
#
|
46
|
-
#
|
39
|
+
# ### Flag syntax
|
47
40
|
#
|
48
41
|
# The flags themselves should be provided in OptionParser form. Following
|
49
42
|
# are examples of valid syntax.
|
@@ -98,7 +91,7 @@ module Toys
|
|
98
91
|
# or off. This effectively creates two flags, `--abc` which sets the
|
99
92
|
# value to `true`, and `--no-abc` which sets the falue to `false`.
|
100
93
|
#
|
101
|
-
#
|
94
|
+
# ### Default flag syntax
|
102
95
|
#
|
103
96
|
# If no flag syntax strings are provided, a default syntax will be
|
104
97
|
# inferred based on the key and other options.
|
@@ -123,7 +116,7 @@ module Toys
|
|
123
116
|
# flag :number, accept: Integer
|
124
117
|
# flag :number, "--number=VAL", accept: Integer
|
125
118
|
#
|
126
|
-
#
|
119
|
+
# ### More examples
|
127
120
|
#
|
128
121
|
# A flag that sets its value to the number of times it appears on the
|
129
122
|
# command line:
|
@@ -200,7 +193,7 @@ module Toys
|
|
200
193
|
report_collisions, @flag_group, desc, long_desc, display_name)
|
201
194
|
flag_dsl.instance_exec(flag_dsl, &block) if block
|
202
195
|
flag_dsl._add_to(@tool, key)
|
203
|
-
DSL::
|
196
|
+
DSL::Internal.maybe_add_getter(@tool_dsl, key)
|
204
197
|
self
|
205
198
|
end
|
206
199
|
|
@@ -221,7 +214,7 @@ module Toys
|
|
221
214
|
# across the strings in the array. In this case, whitespace is not
|
222
215
|
# compacted.
|
223
216
|
#
|
224
|
-
#
|
217
|
+
# ### Examples
|
225
218
|
#
|
226
219
|
# If you pass in a sentence as a simple string, it may be word wrapped
|
227
220
|
# when displayed:
|
@@ -252,7 +245,7 @@ module Toys
|
|
252
245
|
# word-wrapped when displayed. To insert a blank line, include an empty
|
253
246
|
# string as one of the descriptions.
|
254
247
|
#
|
255
|
-
#
|
248
|
+
# ### Example
|
256
249
|
#
|
257
250
|
# long_desc "This initial paragraph might get word wrapped.",
|
258
251
|
# "This next paragraph is followed by a blank line.",
|
@@ -268,6 +261,17 @@ module Toys
|
|
268
261
|
@flag_group.append_long_desc(long_desc)
|
269
262
|
self
|
270
263
|
end
|
264
|
+
|
265
|
+
##
|
266
|
+
# Called only from DSL::Tool.
|
267
|
+
#
|
268
|
+
# @private
|
269
|
+
#
|
270
|
+
def initialize(tool_dsl, tool, flag_group)
|
271
|
+
@tool_dsl = tool_dsl
|
272
|
+
@tool = tool
|
273
|
+
@flag_group = flag_group
|
274
|
+
end
|
271
275
|
end
|
272
276
|
end
|
273
277
|
end
|