toys-core 0.11.5 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|