command_kit 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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