toys-core 0.7.0 → 0.8.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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -0
  3. data/LICENSE.md +16 -24
  4. data/README.md +307 -59
  5. data/docs/guide.md +44 -4
  6. data/lib/toys-core.rb +58 -49
  7. data/lib/toys/acceptor.rb +672 -0
  8. data/lib/toys/alias.rb +106 -0
  9. data/lib/toys/arg_parser.rb +624 -0
  10. data/lib/toys/cli.rb +422 -181
  11. data/lib/toys/compat.rb +83 -0
  12. data/lib/toys/completion.rb +442 -0
  13. data/lib/toys/context.rb +354 -0
  14. data/lib/toys/core_version.rb +18 -26
  15. data/lib/toys/dsl/flag.rb +213 -56
  16. data/lib/toys/dsl/flag_group.rb +237 -51
  17. data/lib/toys/dsl/positional_arg.rb +210 -0
  18. data/lib/toys/dsl/tool.rb +968 -317
  19. data/lib/toys/errors.rb +46 -28
  20. data/lib/toys/flag.rb +821 -0
  21. data/lib/toys/flag_group.rb +282 -0
  22. data/lib/toys/input_file.rb +18 -26
  23. data/lib/toys/loader.rb +110 -100
  24. data/lib/toys/middleware.rb +24 -31
  25. data/lib/toys/mixin.rb +90 -59
  26. data/lib/toys/module_lookup.rb +125 -0
  27. data/lib/toys/positional_arg.rb +184 -0
  28. data/lib/toys/source_info.rb +192 -0
  29. data/lib/toys/standard_middleware/add_verbosity_flags.rb +38 -43
  30. data/lib/toys/standard_middleware/handle_usage_errors.rb +39 -40
  31. data/lib/toys/standard_middleware/set_default_descriptions.rb +111 -89
  32. data/lib/toys/standard_middleware/show_help.rb +130 -113
  33. data/lib/toys/standard_middleware/show_root_version.rb +29 -35
  34. data/lib/toys/standard_mixins/exec.rb +116 -78
  35. data/lib/toys/standard_mixins/fileutils.rb +16 -24
  36. data/lib/toys/standard_mixins/gems.rb +29 -30
  37. data/lib/toys/standard_mixins/highline.rb +34 -41
  38. data/lib/toys/standard_mixins/terminal.rb +72 -26
  39. data/lib/toys/template.rb +51 -35
  40. data/lib/toys/tool.rb +1161 -206
  41. data/lib/toys/utils/completion_engine.rb +171 -0
  42. data/lib/toys/utils/exec.rb +279 -182
  43. data/lib/toys/utils/gems.rb +58 -49
  44. data/lib/toys/utils/help_text.rb +117 -111
  45. data/lib/toys/utils/terminal.rb +69 -62
  46. data/lib/toys/wrappable_string.rb +162 -0
  47. metadata +24 -22
  48. data/lib/toys/definition/acceptor.rb +0 -191
  49. data/lib/toys/definition/alias.rb +0 -112
  50. data/lib/toys/definition/arg.rb +0 -140
  51. data/lib/toys/definition/flag.rb +0 -370
  52. data/lib/toys/definition/flag_group.rb +0 -205
  53. data/lib/toys/definition/source_info.rb +0 -190
  54. data/lib/toys/definition/tool.rb +0 -842
  55. data/lib/toys/dsl/arg.rb +0 -132
  56. data/lib/toys/runner.rb +0 -188
  57. data/lib/toys/standard_middleware.rb +0 -47
  58. data/lib/toys/utils/module_lookup.rb +0 -135
  59. data/lib/toys/utils/wrappable_string.rb +0 -165
@@ -1,32 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright 2018 Daniel Azuma
3
+ # Copyright 2019 Daniel Azuma
4
4
  #
5
- # All rights reserved.
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
6
11
  #
7
- # Redistribution and use in source and binary forms, with or without
8
- # modification, are permitted provided that the following conditions are met:
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
9
14
  #
10
- # * Redistributions of source code must retain the above copyright notice,
11
- # this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above copyright notice,
13
- # this list of conditions and the following disclaimer in the documentation
14
- # and/or other materials provided with the distribution.
15
- # * Neither the name of the copyright holder, nor the names of any other
16
- # contributors to this software, may be used to endorse or promote products
17
- # derived from this software without specific prior written permission.
18
- #
19
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- # POSSIBILITY OF SUCH DAMAGE.
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
30
22
  ;
31
23
 
32
24
  module Toys
@@ -35,74 +27,268 @@ module Toys
35
27
  # DSL for a flag group definition block. Lets you create flags in a group.
36
28
  #
37
29
  # These directives are available inside a block passed to
38
- # {Toys::DSL::Tool#flag_group} and related methods.
30
+ # {Toys::DSL::Tool#flag_group}, {Toys::DSL::Tool#all_required},
31
+ # {Toys::DSL::Tool#at_most_one}, {Toys::DSL::Tool#at_least_one}, or
32
+ # {Toys::DSL::Tool#exactly_one}.
33
+ #
34
+ # ## Example
35
+ #
36
+ # tool "login" do
37
+ # all_required do
38
+ # # The directives in here are defined by this class
39
+ # flag :username, "--username=VAL", desc: "Set username (required)"
40
+ # flag :password, "--password=VAL", desc: "Set password (required)"
41
+ # end
42
+ # # ...
43
+ # end
39
44
  #
40
45
  class FlagGroup
41
46
  ## @private
42
- def initialize(tool_dsl, tool_definition, flag_group)
47
+ def initialize(tool_dsl, tool, flag_group)
43
48
  @tool_dsl = tool_dsl
44
- @tool_definition = tool_definition
49
+ @tool = tool
45
50
  @flag_group = flag_group
46
51
  end
47
52
 
48
53
  ##
49
- # Add a flag to the current tool. Each flag must specify a key which
54
+ # Add a flag to the current group. Each flag must specify a key which
50
55
  # the script may use to obtain the flag value from the context.
51
56
  # You may then provide the flags themselves in OptionParser form.
52
57
  #
53
58
  # If the given key is a symbol representing a valid method name, then a
54
59
  # helper method is automatically added to retrieve the value. Otherwise,
55
60
  # if the key is a string or does not represent a valid method name, the
56
- # tool can retrieve the value by calling {Toys::Tool#get}.
61
+ # tool can retrieve the value by calling {Toys::Context#get}.
57
62
  #
58
63
  # Attributes of the flag may be passed in as arguments to this method, or
59
64
  # set in a block passed to this method. If you provide a block, you can
60
65
  # use directives in {Toys::DSL::Flag} within the block.
61
66
  #
62
- # @param [String,Symbol] key The key to use to retrieve the value from
67
+ # ## Flag syntax
68
+ #
69
+ # The flags themselves should be provided in OptionParser form. Following
70
+ # are examples of valid syntax.
71
+ #
72
+ # * `-a` : A short boolean switch. When this appears as an argument,
73
+ # the value is set to `true`.
74
+ # * `--abc` : A long boolean switch. When this appears as an argument,
75
+ # the value is set to `true`.
76
+ # * `-aVAL` or `-a VAL` : A short flag that takes a required value.
77
+ # These two forms are treated identically. If this argument appears
78
+ # with a value attached (e.g. `-afoo`), the attached string (e.g.
79
+ # `"foo"`) is taken as the value. Otherwise, the following argument
80
+ # is taken as the value (e.g. for `-a foo`, the value is set to
81
+ # `"foo"`.) The following argument is treated as the value even if it
82
+ # looks like a flag (e.g. `-a -a` causes the string `"-a"` to be
83
+ # taken as the value.)
84
+ # * `-a[VAL]` : A short flag that takes an optional value. If this
85
+ # argument appears with a value attached (e.g. `-afoo`), the attached
86
+ # string (e.g. `"foo"`) is taken as the value. Otherwise, the value
87
+ # is set to `true`. The following argument is never interpreted as
88
+ # the value. (Compare with `-a [VAL]`.)
89
+ # * `-a [VAL]` : A short flag that takes an optional value. If this
90
+ # argument appears with a value attached (e.g. `-afoo`), the attached
91
+ # string (e.g. `"foo"`) is taken as the value. Otherwise, if the
92
+ # following argument does not look like a flag (i.e. it does not
93
+ # begin with a hyphen), it is taken as the value. (e.g. `-a foo`
94
+ # causes the string `"foo"` to be taken as the value.). If there is
95
+ # no following argument, or the following argument looks like a flag,
96
+ # the value is set to `true`. (Compare with `-a[VAL]`.)
97
+ # * `--abc=VAL` or `--abc VAL` : A long flag that takes a required
98
+ # value. These two forms are treated identically. If this argument
99
+ # appears with a value attached (e.g. `--abc=foo`), the attached
100
+ # string (e.g. `"foo"`) is taken as the value. Otherwise, the
101
+ # following argument is taken as the value (e.g. for `--abc foo`, the
102
+ # value is set to `"foo"`.) The following argument is treated as the
103
+ # value even if it looks like a flag (e.g. `--abc --abc` causes the
104
+ # string `"--abc"` to be taken as the value.)
105
+ # * `--abc[=VAL]` : A long flag that takes an optional value. If this
106
+ # argument appears with a value attached (e.g. `--abc=foo`), the
107
+ # attached string (e.g. `"foo"`) is taken as the value. Otherwise,
108
+ # the value is set to `true`. The following argument is never
109
+ # interpreted as the value. (Compare with `--abc [VAL]`.)
110
+ # * `--abc [VAL]` : A long flag that takes an optional value. If this
111
+ # argument appears with a value attached (e.g. `--abc=foo`), the
112
+ # attached string (e.g. `"foo"`) is taken as the value. Otherwise, if
113
+ # the following argument does not look like a flag (i.e. it does not
114
+ # begin with a hyphen), it is taken as the value. (e.g. `--abc foo`
115
+ # causes the string `"foo"` to be taken as the value.). If there is
116
+ # no following argument, or the following argument looks like a flag,
117
+ # the value is set to `true`. (Compare with `--abc=[VAL]`.)
118
+ # * `--[no-]abc` : A long boolean switch that can be turned either on
119
+ # or off. This effectively creates two flags, `--abc` which sets the
120
+ # value to `true`, and `--no-abc` which sets the falue to `false`.
121
+ #
122
+ # ## Default flag syntax
123
+ #
124
+ # If no flag syntax strings are provided, a default syntax will be
125
+ # inferred based on the key and other options.
126
+ #
127
+ # Specifically, if the key has one character, then that character will be
128
+ # chosen as a short flag. If the key has multiple characters, a long flag
129
+ # will be generated.
130
+ #
131
+ # Furthermore, if a custom completion, a non-boolean acceptor, or a
132
+ # non-boolean default value is provided in the options, then the flag
133
+ # will be considered to take a value. Otherwise, it will be considered to
134
+ # be a boolean switch.
135
+ #
136
+ # For example, the following pairs of flags are identical:
137
+ #
138
+ # flag :a
139
+ # flag :a, "-a"
140
+ #
141
+ # flag :abc_def
142
+ # flag :abc_def, "--abc-def"
143
+ #
144
+ # flag :number, accept: Integer
145
+ # flag :number, "--number=VAL", accept: Integer
146
+ #
147
+ # ## More examples
148
+ #
149
+ # A flag that sets its value to the number of times it appears on the
150
+ # command line:
151
+ #
152
+ # flag :verbose, "-v", "--verbose",
153
+ # default: 0, handler: ->(_val, count) { count + 1 }
154
+ #
155
+ # An example using block form:
156
+ #
157
+ # flag :shout do
158
+ # flags "-s", "--shout"
159
+ # default false
160
+ # desc "Say it louder"
161
+ # long_desc "This flag says it lowder.",
162
+ # "You might use this when people can't hear you.",
163
+ # "",
164
+ # "Example:",
165
+ # [" toys say --shout hello"]
166
+ # end
167
+ #
168
+ # @param key [String,Symbol] The key to use to retrieve the value from
63
169
  # the execution context.
64
- # @param [String...] flags The flags in OptionParser format.
65
- # @param [Object] accept An acceptor that validates and/or converts the
170
+ # @param flags [String...] The flags in OptionParser format.
171
+ # @param accept [Object] An acceptor that validates and/or converts the
66
172
  # value. You may provide either the name of an acceptor you have
67
173
  # defined, or one of the default acceptors provided by OptionParser.
68
174
  # Optional. If not specified, accepts any value as a string.
69
- # @param [Object] default The default value. This is the value that will
175
+ # @param default [Object] The default value. This is the value that will
70
176
  # be set in the context if this flag is not provided on the command
71
177
  # line. Defaults to `nil`.
72
- # @param [Proc,nil] handler An optional handler for setting/updating the
73
- # value. If given, it should take two arguments, the new given value
74
- # and the previous value, and it should return the new value that
75
- # should be set. The default handler simply replaces the previous
76
- # value. i.e. the default is effectively `-> (val, _prev) { val }`.
77
- # @param [Boolean] report_collisions Raise an exception if a flag is
178
+ # @param handler [Proc,nil,:set,:push] An optional handler for
179
+ # setting/updating the value. A handler is a proc taking two
180
+ # arguments, the given value and the previous value, returning the
181
+ # new value that should be set. You may also specify a predefined
182
+ # named handler. The `:set` handler (the default) replaces the
183
+ # previous value (effectively `-> (val, _prev) { val }`). The
184
+ # `:push` handler expects the previous value to be an array and
185
+ # pushes the given value onto it; it should be combined with setting
186
+ # `default: []` and is intended for "multi-valued" flags.
187
+ # @param complete_flags [Object] A specifier for shell tab completion
188
+ # for flag names associated with this flag. By default, a
189
+ # {Toys::Flag::DefaultCompletion} is used, which provides the flag's
190
+ # names as completion candidates. To customize completion, set this
191
+ # to the name of a previously defined completion, a hash of options
192
+ # to pass to the constructor for {Toys::Flag::DefaultCompletion}, or
193
+ # any other spec recognized by {Toys::Completion.create}.
194
+ # @param complete_values [Object] A specifier for shell tab completion
195
+ # for flag values associated with this flag. This is the empty
196
+ # completion by default. To customize completion, set this to the
197
+ # name of a previously defined completion, or any spec recognized by
198
+ # {Toys::Completion.create}.
199
+ # @param report_collisions [Boolean] Raise an exception if a flag is
78
200
  # requested that is already in use or marked as unusable. Default is
79
201
  # true.
80
- # @param [String,Array<String>,Toys::Utils::WrappableString] desc Short
202
+ # @param desc [String,Array<String>,Toys::WrappableString] Short
81
203
  # description for the flag. See {Toys::DSL::Tool#desc} for a
82
204
  # description of the allowed formats. Defaults to the empty string.
83
- # @param [Array<String,Array<String>,Toys::Utils::WrappableString>] long_desc
205
+ # @param long_desc [Array<String,Array<String>,Toys::WrappableString>]
84
206
  # Long description for the flag. See {Toys::DSL::Tool#long_desc} for
85
207
  # a description of the allowed formats. (But note that this param
86
208
  # takes an Array of description lines, rather than a series of
87
209
  # arguments.) Defaults to the empty array.
88
- # @param [String] display_name A display name for this flag, used in help
210
+ # @param display_name [String] A display name for this flag, used in help
89
211
  # text and error messages.
90
- # @yieldparam flag_dsl [Toys::DSL::Flag] An object that lets you
91
- # configure this flag in a block.
92
- # @return [Toys::DSL::Tool] self, for chaining.
212
+ # @param block [Proc] Configures the flag. See {Toys::DSL::Flag} for the
213
+ # directives that can be called in this block.
214
+ # @return [self]
93
215
  #
94
216
  def flag(key, *flags,
95
- accept: nil, default: nil, handler: nil,
96
- report_collisions: true,
97
- desc: nil, long_desc: nil, display_name: nil,
217
+ accept: nil, default: nil, handler: nil, complete_flags: nil, complete_values: nil,
218
+ report_collisions: true, desc: nil, long_desc: nil, display_name: nil,
98
219
  &block)
99
- flag_dsl = DSL::Flag.new(flags, accept, default, handler, report_collisions,
100
- @flag_group, desc, long_desc, display_name)
220
+ flag_dsl = DSL::Flag.new(flags, accept, default, handler, complete_flags, complete_values,
221
+ report_collisions, @flag_group, desc, long_desc, display_name)
101
222
  flag_dsl.instance_exec(flag_dsl, &block) if block
102
- flag_dsl._add_to(@tool_definition, key)
223
+ flag_dsl._add_to(@tool, key)
103
224
  DSL::Tool.maybe_add_getter(@tool_dsl, key)
104
225
  self
105
226
  end
227
+
228
+ ##
229
+ # Set the short description for the current flag group. The short
230
+ # description is displayed as the group title in online help.
231
+ #
232
+ # The description is a {Toys::WrappableString}, which may be word-wrapped
233
+ # when displayed in a help screen. You may pass a {Toys::WrappableString}
234
+ # directly to this method, or you may pass any input that can be used to
235
+ # construct a wrappable string:
236
+ #
237
+ # * If you pass a String, its whitespace will be compacted (i.e. tabs,
238
+ # newlines, and multiple consecutive whitespace will be turned into a
239
+ # single space), and it will be word-wrapped on whitespace.
240
+ # * If you pass an Array of Strings, each string will be considered a
241
+ # literal word that cannot be broken, and wrapping will be done
242
+ # across the strings in the array. In this case, whitespace is not
243
+ # compacted.
244
+ #
245
+ # ## Examples
246
+ #
247
+ # If you pass in a sentence as a simple string, it may be word wrapped
248
+ # when displayed:
249
+ #
250
+ # desc "This sentence may be wrapped."
251
+ #
252
+ # To specify a sentence that should never be word-wrapped, pass it as the
253
+ # sole element of a string array:
254
+ #
255
+ # desc ["This sentence will not be wrapped."]
256
+ #
257
+ # @param desc [String,Array<String>,Toys::WrappableString]
258
+ # @return [self]
259
+ #
260
+ def desc(desc)
261
+ @flag_group.desc = desc
262
+ self
263
+ end
264
+
265
+ ##
266
+ # Add to the long description for the current flag group. The long
267
+ # description is displayed with the flag group in online help. This
268
+ # directive may be given multiple times, and the results are cumulative.
269
+ #
270
+ # A long description is a series of descriptions, which are generally
271
+ # displayed in a series of lines/paragraphs. Each individual description
272
+ # uses the form described in the {#desc} documentation, and may be
273
+ # word-wrapped when displayed. To insert a blank line, include an empty
274
+ # string as one of the descriptions.
275
+ #
276
+ # ## Example
277
+ #
278
+ # long_desc "This initial paragraph might get word wrapped.",
279
+ # "This next paragraph is followed by a blank line.",
280
+ # "",
281
+ # ["This line will not be wrapped."],
282
+ # [" This indent is preserved."]
283
+ # long_desc "This line is appended to the description."
284
+ #
285
+ # @param long_desc [String,Array<String>,Toys::WrappableString...]
286
+ # @return [self]
287
+ #
288
+ def long_desc(*long_desc)
289
+ @flag_group.append_long_desc(long_desc)
290
+ self
291
+ end
106
292
  end
107
293
  end
108
294
  end
@@ -0,0 +1,210 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2019 Daniel Azuma
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
22
+ ;
23
+
24
+ module Toys
25
+ module DSL
26
+ ##
27
+ # DSL for an arg definition block. Lets you set arg attributes in a block
28
+ # instead of a long series of keyword arguments.
29
+ #
30
+ # These directives are available inside a block passed to
31
+ # {Toys::DSL::Tool#required_arg}, {Toys::DSL::Tool#optional_arg}, or
32
+ # {Toys::DSL::Tool#remaining_args}.
33
+ #
34
+ # ## Example
35
+ #
36
+ # tool "mytool" do
37
+ # optional_arg :value do
38
+ # # The directives in here are defined by this class
39
+ # accept Integer
40
+ # desc "An integer value"
41
+ # end
42
+ # # ...
43
+ # end
44
+ #
45
+ class PositionalArg
46
+ ## @private
47
+ def initialize(acceptor, default, completion, display_name, desc, long_desc)
48
+ @default = default
49
+ @display_name = display_name
50
+ @desc = desc
51
+ @long_desc = long_desc || []
52
+ accept(acceptor)
53
+ complete(completion)
54
+ end
55
+
56
+ ##
57
+ # Set the acceptor for this argument's values.
58
+ # You can pass either the string name of an acceptor defined in this tool
59
+ # or any of its ancestors, or any other specification recognized by
60
+ # {Toys::Acceptor.create}.
61
+ #
62
+ # @param spec [Object]
63
+ # @param options [Hash]
64
+ # @param block [Proc]
65
+ # @return [self]
66
+ #
67
+ def accept(spec = nil, **options, &block)
68
+ @acceptor_spec = spec
69
+ @acceptor_options = options
70
+ @acceptor_block = block
71
+ self
72
+ end
73
+
74
+ ##
75
+ # Set the default value.
76
+ #
77
+ # @param default [Object]
78
+ # @return [self]
79
+ #
80
+ def default(default)
81
+ @default = default
82
+ self
83
+ end
84
+
85
+ ##
86
+ # Set the shell completion strategy for arg values.
87
+ # You can pass either the string name of a completion defined in this
88
+ # tool or any of its ancestors, or any other specification recognized by
89
+ # {Toys::Completion.create}.
90
+ #
91
+ # @param spec [Object]
92
+ # @param options [Hash]
93
+ # @param block [Proc]
94
+ # @return [self]
95
+ #
96
+ def complete(spec = nil, **options, &block)
97
+ @completion_spec = spec
98
+ @completion_options = options
99
+ @completion_block = block
100
+ self
101
+ end
102
+
103
+ ##
104
+ # Set the name of this arg as it appears in help screens.
105
+ #
106
+ # @param display_name [String]
107
+ # @return [self]
108
+ #
109
+ def display_name(display_name)
110
+ @display_name = display_name
111
+ self
112
+ end
113
+
114
+ ##
115
+ # Set the short description for the current positional argument. The
116
+ # short description is displayed with the argument in online help.
117
+ #
118
+ # The description is a {Toys::WrappableString}, which may be word-wrapped
119
+ # when displayed in a help screen. You may pass a {Toys::WrappableString}
120
+ # directly to this method, or you may pass any input that can be used to
121
+ # construct a wrappable string:
122
+ #
123
+ # * If you pass a String, its whitespace will be compacted (i.e. tabs,
124
+ # newlines, and multiple consecutive whitespace will be turned into a
125
+ # single space), and it will be word-wrapped on whitespace.
126
+ # * If you pass an Array of Strings, each string will be considered a
127
+ # literal word that cannot be broken, and wrapping will be done
128
+ # across the strings in the array. In this case, whitespace is not
129
+ # compacted.
130
+ #
131
+ # ## Examples
132
+ #
133
+ # If you pass in a sentence as a simple string, it may be word wrapped
134
+ # when displayed:
135
+ #
136
+ # desc "This sentence may be wrapped."
137
+ #
138
+ # To specify a sentence that should never be word-wrapped, pass it as the
139
+ # sole element of a string array:
140
+ #
141
+ # desc ["This sentence will not be wrapped."]
142
+ #
143
+ # @param desc [String,Array<String>,Toys::WrappableString]
144
+ # @return [self]
145
+ #
146
+ def desc(desc)
147
+ @desc = desc
148
+ self
149
+ end
150
+
151
+ ##
152
+ # Add to the long description for the current positional argument. The
153
+ # long description is displayed with the argument in online help. This
154
+ # directive may be given multiple times, and the results are cumulative.
155
+ #
156
+ # A long description is a series of descriptions, which are generally
157
+ # displayed in a series of lines/paragraphs. Each individual description
158
+ # uses the form described in the {#desc} documentation, and may be
159
+ # word-wrapped when displayed. To insert a blank line, include an empty
160
+ # string as one of the descriptions.
161
+ #
162
+ # ## Example
163
+ #
164
+ # long_desc "This initial paragraph might get word wrapped.",
165
+ # "This next paragraph is followed by a blank line.",
166
+ # "",
167
+ # ["This line will not be wrapped."],
168
+ # [" This indent is preserved."]
169
+ # long_desc "This line is appended to the description."
170
+ #
171
+ # @param long_desc [String,Array<String>,Toys::WrappableString...]
172
+ # @return [self]
173
+ #
174
+ def long_desc(*long_desc)
175
+ @long_desc += long_desc
176
+ self
177
+ end
178
+
179
+ ## @private
180
+ def _add_required_to(tool, key)
181
+ acceptor = tool.scalar_acceptor(@acceptor_spec, @acceptor_options, &@acceptor_block)
182
+ completion = tool.scalar_completion(@completion_spec, @completion_options,
183
+ &@completion_block)
184
+ tool.add_required_arg(key,
185
+ accept: acceptor, complete: completion,
186
+ display_name: @display_name, desc: @desc, long_desc: @long_desc)
187
+ end
188
+
189
+ ## @private
190
+ def _add_optional_to(tool, key)
191
+ acceptor = tool.scalar_acceptor(@acceptor_spec, @acceptor_options, &@acceptor_block)
192
+ completion = tool.scalar_completion(@completion_spec, @completion_options,
193
+ &@completion_block)
194
+ tool.add_optional_arg(key,
195
+ accept: acceptor, default: @default, complete: completion,
196
+ display_name: @display_name, desc: @desc, long_desc: @long_desc)
197
+ end
198
+
199
+ ## @private
200
+ def _set_remaining_on(tool, key)
201
+ acceptor = tool.scalar_acceptor(@acceptor_spec, @acceptor_options, &@acceptor_block)
202
+ completion = tool.scalar_completion(@completion_spec, @completion_options,
203
+ &@completion_block)
204
+ tool.set_remaining_args(key,
205
+ accept: acceptor, default: @default, complete: completion,
206
+ display_name: @display_name, desc: @desc, long_desc: @long_desc)
207
+ end
208
+ end
209
+ end
210
+ end