command_kit 0.2.2 → 0.3.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.
@@ -40,6 +40,13 @@ module CommandKit
40
40
  # @return [Proc, nil]
41
41
  attr_reader :block
42
42
 
43
+ # The optional category to group the option under.
44
+ #
45
+ # @return [String, nil]
46
+ #
47
+ # @since 0.3.0
48
+ attr_reader :category
49
+
43
50
  #
44
51
  # Initializes the option.
45
52
  #
@@ -65,9 +72,12 @@ module CommandKit
65
72
  # @option value [String, nil] usage
66
73
  # The usage string for the option's value.
67
74
  #
68
- # @param [String] desc
75
+ # @param [String, Array<String>] desc
69
76
  # The description for the option.
70
77
  #
78
+ # @param [String, nil] category
79
+ # The optional category to group the option under.
80
+ #
71
81
  # @yield [(value)]
72
82
  # If a block is given, it will be called when the option is parsed.
73
83
  #
@@ -78,25 +88,27 @@ module CommandKit
78
88
  # The `value` keyword argument was not a `Hash`, `true`, `false`, or
79
89
  # `nil`.
80
90
  #
81
- def initialize(name, short: nil,
82
- long: self.class.default_long_opt(name),
83
- equals: false,
84
- value: nil,
85
- desc: ,
91
+ def initialize(name, short: nil,
92
+ long: self.class.default_long_opt(name),
93
+ equals: false,
94
+ value: nil,
95
+ desc: ,
96
+ category: nil,
86
97
  &block)
87
- @name = name
88
- @short = short
89
- @long = long
90
- @equals = equals
91
- @value = case value
92
- when Hash then OptionValue.new(**value)
93
- when true then OptionValue.new()
94
- when false, nil then nil
95
- else
96
- raise(TypeError,"value: keyword must be Hash, true, false, or nil")
97
- end
98
- @desc = desc
99
- @block = block
98
+ @name = name
99
+ @short = short
100
+ @long = long
101
+ @equals = equals
102
+ @value = case value
103
+ when Hash then OptionValue.new(**value)
104
+ when true then OptionValue.new()
105
+ when false, nil then nil
106
+ else
107
+ raise(TypeError,"value: keyword must be Hash, true, false, or nil")
108
+ end
109
+ @desc = desc
110
+ @category = category
111
+ @block = block
100
112
  end
101
113
 
102
114
  #
@@ -179,7 +191,7 @@ module CommandKit
179
191
  #
180
192
  # The option description.
181
193
  #
182
- # @return [String]
194
+ # @return [String, Array<String>]
183
195
  #
184
196
  # @note
185
197
  # If {#default_value} returns a value, the description will contain the
@@ -187,7 +199,14 @@ module CommandKit
187
199
  #
188
200
  def desc
189
201
  if (value = default_value)
190
- "#{@desc} (Default: #{value})"
202
+ default_text = "(Default: #{value})"
203
+
204
+ case @desc
205
+ when Array
206
+ @desc + [default_text]
207
+ else
208
+ "#{@desc} #{default_text}"
209
+ end
191
210
  else
192
211
  @desc
193
212
  end
@@ -78,9 +78,6 @@ module CommandKit
78
78
  @option_parser = OptionParser.new do |opts|
79
79
  opts.banner = "Usage: #{usage}"
80
80
 
81
- opts.separator ''
82
- opts.separator 'Options:'
83
-
84
81
  opts.on_tail('-h','--help','Print help information') do
85
82
  help
86
83
  exit(0)
@@ -23,6 +23,25 @@ module CommandKit
23
23
  # @bar = arg.split(':')
24
24
  # end
25
25
  #
26
+ # ### Multi-line Descriptions
27
+ #
28
+ # option :opt, value: {type: String},
29
+ # desc: [
30
+ # 'line1',
31
+ # 'line2',
32
+ # '...'
33
+ # ]
34
+ #
35
+ # ### Option Categories
36
+ #
37
+ # option :opt1, value: {type: String},
38
+ # category: 'Foo Category',
39
+ # desc: 'Option 1'
40
+ #
41
+ # option :opt2, value: {type: String},
42
+ # category: 'Foo Category',
43
+ # desc: 'Option 2'
44
+ #
26
45
  # ### initialize and using instance variables
27
46
  #
28
47
  # option :number, value: {type: Integer},
@@ -111,9 +130,12 @@ module CommandKit
111
130
  # @option value [String, nil] usage
112
131
  # The usage string for the option's value.
113
132
  #
114
- # @option kwargs [String] desc
133
+ # @option kwargs [String, Array<String>] desc
115
134
  # The description for the option.
116
135
  #
136
+ # @option kwargs [String, nil] category
137
+ # The optional category to group the option under.
138
+ #
117
139
  # @yield [(value)]
118
140
  # If a block is given, it will be passed the parsed option value.
119
141
  #
@@ -129,6 +151,19 @@ module CommandKit
129
151
  # @example Define an option:
130
152
  # option :foo, desc: "Foo option"
131
153
  #
154
+ # @example Define an option with a multi-line description:
155
+ # option :foo, desc: [
156
+ # "Line 1",
157
+ # "Line 2"
158
+ # ]
159
+ #
160
+ # @example Defines multiple options within a category:
161
+ # option :foo, desc: "Foo option",
162
+ # category: 'Other Options'
163
+ #
164
+ # option :bar, desc: "Bar option",
165
+ # category: 'Other Options'
166
+ #
132
167
  # @example With a custom short option:
133
168
  # option :foo, short: '-f',
134
169
  # desc: "Foo option"
@@ -212,19 +247,7 @@ module CommandKit
212
247
 
213
248
  super(**kwargs)
214
249
 
215
- self.class.options.each_value do |option|
216
- default_value = option.default_value
217
-
218
- @options[option.name] = default_value unless default_value.nil?
219
-
220
- option_parser.on(*option.usage,option.type,option.desc) do |arg,*captures|
221
- @options[option.name] = arg
222
-
223
- if option.block
224
- instance_exec(*arg,*captures,&option.block)
225
- end
226
- end
227
- end
250
+ define_option_categories
228
251
  end
229
252
 
230
253
  #
@@ -237,5 +260,57 @@ module CommandKit
237
260
  help_options
238
261
  help_arguments
239
262
  end
263
+
264
+ private
265
+
266
+ #
267
+ # Defines all of the options, grouped by category.
268
+ #
269
+ def define_option_categories
270
+ categories = self.class.options.values.group_by(&:category)
271
+
272
+ categories.each do |category,options|
273
+ if category
274
+ define_options_category(category,options)
275
+ end
276
+ end
277
+
278
+ define_options_category('Options',categories.fetch(nil,[]))
279
+ end
280
+
281
+ #
282
+ # Defines a new category of options with a header.
283
+ #
284
+ # @param [String] category
285
+ # The category name.
286
+ #
287
+ # @param [Array<Option>, nil] options
288
+ # The options to define.
289
+ #
290
+ def define_options_category(category,options)
291
+ option_parser.separator ''
292
+ option_parser.separator "#{category}:"
293
+
294
+ options.each(&method(:define_option))
295
+ end
296
+
297
+ #
298
+ # Defines an individual option.
299
+ #
300
+ # @param [Option] option
301
+ #
302
+ def define_option(option)
303
+ default_value = option.default_value
304
+
305
+ @options[option.name] = default_value unless default_value.nil?
306
+
307
+ option_parser.on(*option.usage,option.type,option.desc) do |arg,*captures|
308
+ @options[option.name] = arg
309
+
310
+ if option.block
311
+ instance_exec(*arg,*captures,&option.block)
312
+ end
313
+ end
314
+ end
240
315
  end
241
316
  end
@@ -60,5 +60,14 @@ module CommandKit
60
60
  def program_name
61
61
  self.class.program_name
62
62
  end
63
+
64
+ #
65
+ # @see #program_name
66
+ #
67
+ # @since 0.3.0
68
+ #
69
+ def command_name
70
+ program_name
71
+ end
63
72
  end
64
73
  end
@@ -1,4 +1,4 @@
1
1
  module CommandKit
2
2
  # command_kit version
3
- VERSION = "0.2.2"
3
+ VERSION = "0.3.0"
4
4
  end
@@ -233,6 +233,39 @@ describe CommandKit::Arguments do
233
233
  ].join($/)
234
234
  ).to_stdout
235
235
  end
236
+
237
+ context "when one the argument has an Array for a description" do
238
+ module TestArguments
239
+ class MultiLineArgumentDescription
240
+ include CommandKit::Arguments
241
+
242
+ argument :foo, desc: "Foo option"
243
+ argument :bar, desc: [
244
+ "Bar option",
245
+ "Line 2",
246
+ "Line 3"
247
+ ]
248
+ argument :baz, desc: "Baz option"
249
+ end
250
+ end
251
+
252
+ let(:command_class) { TestArguments::MultiLineArgumentDescription }
253
+
254
+ it "must print out each line of a multi-line argument description" do
255
+ expect { subject.help_arguments }.to output(
256
+ [
257
+ '',
258
+ "Arguments:",
259
+ " #{foo_argument.usage.ljust(33)}#{foo_argument.desc}",
260
+ " #{bar_argument.usage.ljust(33)}#{bar_argument.desc[0]}",
261
+ " #{' '.ljust(33)}#{bar_argument.desc[1]}",
262
+ " #{' '.ljust(33)}#{bar_argument.desc[2]}",
263
+ " #{baz_argument.usage.ljust(33)}#{baz_argument.desc}",
264
+ ''
265
+ ].join($/)
266
+ ).to_stdout
267
+ end
268
+ end
236
269
  end
237
270
  end
238
271