rake-commander 0.3.6 → 0.4.1

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.
@@ -4,6 +4,7 @@ class RakeCommander
4
4
  extend RakeCommander::Base::ClassHelpers
5
5
  extend RakeCommander::Options::Name
6
6
  include RakeCommander::Options::Description
7
+ include RakeCommander::Options::Type
7
8
 
8
9
  attr_reader :name_full, :desc, :default
9
10
 
@@ -13,12 +14,14 @@ class RakeCommander
13
14
 
14
15
  @name_full = name.freeze
15
16
  super(short.freeze, @name_full)
17
+
16
18
  @default = kargs[:default] if kargs.key?(:default)
17
19
  @desc = kargs[:desc] if kargs.key?(:desc)
18
20
  @required = kargs[:required] if kargs.key?(:required)
19
21
  @type_coercion = kargs[:type] if kargs.key?(:type)
20
22
  @other_args = args
21
23
  @original_block = block
24
+
22
25
  configure_other
23
26
  end
24
27
 
@@ -33,7 +36,9 @@ class RakeCommander
33
36
  # Creates a new option, result of merging this `opt` with this option,
34
37
  # @return [RakeCommander::Option] where opt has been merged
35
38
  def merge(opt, **kargs)
36
- raise "Expecting RakeCommander::Option. Given: #{opt.class}" unless opt.is_a?(RakeCommander::Option)
39
+ msg = "Expecting RakeCommander::Option. Given: #{opt.class}"
40
+ raise msg unless opt.is_a?(RakeCommander::Option)
41
+
37
42
  dup(**opt.dup_key_arguments.merge(kargs), &opt.original_block)
38
43
  end
39
44
 
@@ -81,7 +86,8 @@ class RakeCommander
81
86
 
82
87
  # @param [String, Nil] the argument, may it exist
83
88
  def argument
84
- return nil unless argument?
89
+ return unless argument?
90
+
85
91
  self.class.name_argument(name_full)
86
92
  end
87
93
 
@@ -93,10 +99,23 @@ class RakeCommander
93
99
  # @return [Class, NilClass]
94
100
  def type_coercion
95
101
  value = @type_coercion || (default? && default.class)
96
- return nil unless value.is_a?(Class)
102
+ return unless allowed_type?(value)
103
+
97
104
  value
98
105
  end
99
106
 
107
+ # @return [Boolean] whether the option is an enum with fixed values.
108
+ def enum?
109
+ type_coercion.is_a?(Array)
110
+ end
111
+
112
+ # @return [Array, NilClass] the valid options when is `enum?`
113
+ def enum_options
114
+ return unless enum?
115
+
116
+ type_coercion
117
+ end
118
+
100
119
  # @return [Boolean]
101
120
  def default?
102
121
  instance_variable_defined?(:@default)
@@ -107,9 +126,12 @@ class RakeCommander
107
126
  # @param opt_parser [OptionParser] the option parser to add this option's switch.
108
127
  # @param implicit_short [Boolean] whether the implicit short of this option is active in the opts_parser.
109
128
  def add_switch(opts_parser, where: :base, implicit_short: false, &middleware)
110
- raise "Expecting OptionParser. Given: #{opts_parser.class}" unless opts_parser.is_a?(OptionParser)
129
+ msg = "Expecting OptionParser. Given: #{opts_parser.class}"
130
+ raise msg unless opts_parser.is_a?(OptionParser)
131
+
111
132
  args = switch_args(implicit_short: implicit_short)
112
133
  block = option_block(&middleware)
134
+
113
135
  case where
114
136
  when :head, :top
115
137
  opts_parser.on_head(*args, &block)
@@ -127,13 +149,14 @@ class RakeCommander
127
149
 
128
150
  # @return [Hash] keyed arguments to create a new object
129
151
  def dup_key_arguments
130
- configure_other
131
152
  {}.tap do |kargs|
153
+ configure_other
154
+
132
155
  kargs.merge!(short: short.dup.freeze) if short
133
156
  kargs.merge!(name: name_full.dup.freeze) if name_full
134
157
  kargs.merge!(desc: @desc.dup) if @desc
135
158
  kargs.merge!(default: @default.dup) if default?
136
- kargs.merge!(type: @type_coercion) if @type_coercion.is_a?(Class)
159
+ kargs.merge!(type: @type_coercion) if allowed_type?(@type_coercion)
137
160
  kargs.merge!(required: required?)
138
161
  end
139
162
  end
@@ -141,6 +164,7 @@ class RakeCommander
141
164
  # @return [Array<Variant>]
142
165
  def switch_args(implicit_short: false)
143
166
  configure_other
167
+
144
168
  args = [short_hyphen, name_hyphen]
145
169
  args.push(*switch_desc(implicit_short: implicit_short))
146
170
  args << type_coercion if type_coercion
@@ -152,10 +176,13 @@ class RakeCommander
152
176
  # Called on parse runtime
153
177
  def option_block(&middleware)
154
178
  block_extra_args = [default, short, name, self]
179
+
155
180
  proc do |value|
156
181
  value = !value if type_coercion == FalseClass
157
182
  args = block_extra_args.dup.unshift(value)
183
+
158
184
  original_block&.call(*args)
185
+
159
186
  middleware&.call(*args)
160
187
  end
161
188
  end
@@ -165,8 +192,9 @@ class RakeCommander
165
192
  # @return [Array<String>]
166
193
  def switch_desc(implicit_short: false, line_width: DESC_MAX_LENGTH)
167
194
  ishort = implicit_short ? "( -#{short_implicit} ) " : ''
168
- str = "#{required_desc}#{ishort}#{desc}#{default_desc}"
195
+ str = "#{required_desc}#{ishort}#{desc}#{enum_desc}#{default_desc}"
169
196
  return [] if str.empty?
197
+
170
198
  string_to_lines(str, max: line_width)
171
199
  end
172
200
 
@@ -175,12 +203,15 @@ class RakeCommander
175
203
  end
176
204
 
177
205
  def default_desc
178
- return nil unless default?
179
- str = "{ Default: '#{default}' }"
180
- if desc && !desc.downcase.include?('default')
181
- str = desc.end_with?('.') ? " #{str}" : ". #{str}"
182
- end
183
- str
206
+ return unless default?
207
+
208
+ " { Default: '#{default}' }"
209
+ end
210
+
211
+ def enum_desc
212
+ return unless enum?
213
+
214
+ " Options: [ #{enum_options.join(' | ')} ]."
184
215
  end
185
216
 
186
217
  # Helper to simplify `short` and `name` capture from arguments and keyed arguments.
@@ -191,8 +222,11 @@ class RakeCommander
191
222
  name ||= capture_arguments_name!(args, sample_n_short: sample && short)
192
223
 
193
224
  unless sample
194
- raise ArgumentError, "A short of one letter should be provided. Given: #{short}" unless self.class.valid_short?(short)
195
- raise ArgumentError, "A name should be provided. Given: #{name}" unless self.class.valid_name?(name)
225
+ msg = "A short of one letter should be provided. Given: #{short}"
226
+ raise ArgumentError, msg unless self.class.valid_short?(short)
227
+
228
+ msg = "A name should be provided. Given: #{name}"
229
+ raise ArgumentError, msg unless self.class.valid_name?(name)
196
230
  end
197
231
 
198
232
  [short, name]
@@ -213,41 +247,40 @@ class RakeCommander
213
247
  # @note if found it removes it from args.
214
248
  # @return [String, Symbol, NilClass]
215
249
  def capture_arguments_name!(args, sample_n_short: false)
216
- name = nil
250
+ name = nil
217
251
  name ||= self.class.capture_arguments_name!(args, symbol: true)
218
252
  name ||= self.class.capture_arguments_name!(args, symbol: true, strict: false)
219
253
  name ||= self.class.capture_arguments_name!(args)
220
- name || self.class.capture_arguments_name!(args, strict: false) unless sample_n_short
254
+ name ||= self.class.capture_arguments_name!(args, strict: false) unless sample_n_short
255
+ name
221
256
  end
222
257
 
223
258
  # The remaining `args` received in the initialization
224
259
  def other_args(*args)
225
260
  @other_args ||= []
226
- if args.empty?
227
- @other_args
228
- else
229
- @other_args.push(*args)
230
- end
261
+ return @other_args if args.empty?
262
+
263
+ @other_args.push(*args)
231
264
  end
232
265
 
233
266
  # It consumes `other_args`, to prevent direct overrides to be overriden by it.
267
+ # @note at the end we will pass the switch arguments to OptsParser.
234
268
  def configure_other
235
- @type_coercion ||= fetch_type_from_other
236
- @desc ||= fetch_desc_from_other
269
+ @type_coercion = fetch_type_from_other(@type_coercion)
270
+ @desc = fetch_desc_from_other(@desc)
237
271
  nil
238
272
  end
239
273
 
240
- def fetch_type_from_other
241
- return nil unless type = other_args.find {|arg| arg.is_a?(Class)}
242
- type.tap { other_args.delete(type) }
274
+ def fetch_type_from_other(original = nil)
275
+ other_type = fetch_type!(other_args)
276
+
277
+ return original if original
278
+
279
+ other_type
243
280
  end
244
281
 
245
- def fetch_desc_from_other
246
- return nil unless value = other_args.find {|arg| arg.is_a?(String)}
247
- other_args.dup.each do |val|
248
- other_args.delete(val) if val.is_a?(String)
249
- end
250
- value
282
+ def fetch_desc_from_other(original = nil)
283
+ joined_lines(original, fetch_desc!(other_args))
251
284
  end
252
285
  end
253
286
  end
@@ -3,12 +3,12 @@ class RakeCommander
3
3
  # Offers helpers to treat `ARGV`
4
4
  module Arguments
5
5
  RAKE_COMMAND_EXTENDED_OPTIONS_START = '--'.freeze
6
- NAME_ARGUMENT = /^--(?<option>[\w_-]*).*?$/.freeze
7
- BOOLEAN_ARGUMENT = /(?:^|--)no-(?<option>[\w_-]*).*?$/.freeze
6
+ NAME_ARGUMENT = /^--(?<option>[\w_-]*).*?$/
7
+ BOOLEAN_ARGUMENT = /(?:^|--)no-(?<option>[\w_-]*).*?$/
8
8
 
9
9
  class << self
10
10
  def included(base)
11
- super(base)
11
+ super
12
12
  base.extend ClassMethods
13
13
  end
14
14
  end
@@ -20,6 +20,7 @@ class RakeCommander
20
20
  # @return [Boolean] whether enhanced parsing should be switched on or off.
21
21
  def argv_with_enhanced_syntax?(argv = ARGV)
22
22
  return false unless argv.is_a?(Array)
23
+
23
24
  argv.include?(RAKE_COMMAND_EXTENDED_OPTIONS_START)
24
25
  end
25
26
 
@@ -41,6 +42,7 @@ class RakeCommander
41
42
  def argv_cropping_for_rake(value = :not_used)
42
43
  @argv_cropping_for_rake = true if @argv_cropping_for_rake.nil?
43
44
  return @argv_cropping_for_rake if value == :not_used
45
+
44
46
  @argv_cropping_for_rake = !!value
45
47
  end
46
48
 
@@ -51,8 +53,8 @@ class RakeCommander
51
53
  # @param argv [Array<String>] the command line arguments array.
52
54
  # @return [Array<String>] the target arguments to be parsed by `RakeCommander::Options`
53
55
  def argv_extended_options(argv = ARGV.dup)
54
- if idx = argv.index(RAKE_COMMAND_EXTENDED_OPTIONS_START)
55
- argv[idx+1..-1]
56
+ if (idx = argv.index(RAKE_COMMAND_EXTENDED_OPTIONS_START))
57
+ argv[idx + 1..]
56
58
  else
57
59
  []
58
60
  end
@@ -63,9 +65,11 @@ class RakeCommander
63
65
  # @return [Array<String>] the argv without the extended options of this gem.
64
66
  def argv_rake_native_arguments(argv = ARGV.dup)
65
67
  return argv unless argv_cropping_for_rake
66
- if idx = argv.index(RAKE_COMMAND_EXTENDED_OPTIONS_START)
68
+
69
+ if (idx = argv.index(RAKE_COMMAND_EXTENDED_OPTIONS_START))
67
70
  argv = argv[0..idx]
68
71
  end
72
+
69
73
  argv
70
74
  end
71
75
 
@@ -77,10 +81,10 @@ class RakeCommander
77
81
  # - So some tidy up is necessary and the head of the command (i.e. `rake some:task --`)
78
82
  # should be excluded from arguments to input to the options parser.
79
83
  # @see `RakeCommander::Options#parse_options`
80
- def parse_options(argv = ARGV, *args, **kargs, &block)
84
+ def parse_options(argv = ARGV, *_args, **_kargs)
81
85
  argv = argv_extended_options(argv)
82
86
  argv = argv_pre_parsed(argv, options: options_hash(with_implicit: true))
83
- super(argv, *args, **kargs, &block)
87
+ super
84
88
  end
85
89
 
86
90
  # Options with arguments should not take another option as value.
@@ -95,22 +99,31 @@ class RakeCommander
95
99
  # 2. To overcome this limitation, you may enclose in double quotes and argument with
96
100
  # that start (i,e, `"--argument"`).
97
101
  # @example
98
- # 1. `-abc ARGUMENT` where only `c` receives the argument becomes `-ab -c ARGUMENT`
99
- # 3. `-abc ARGUMENT` where `b` and `c` are argument receivers becomes `-a -b nil -c ARGUMENT`
100
- # 2. `-acb ARGUMENT` where only `c` receives the argument becomes `-a -c nil -b ARGUMENT`
101
- # 4. `-c --some-option ARGUMENT` where both options receive argument, becomes `-c nil --some-option ARGUMENT`
102
- # 5. `-c --some-option -d ARGUMENT` where both options receive argument, becomes `-c nil --some-option nil -d ARGUMENT`
103
- # 6. `-cd ARGUMENT` where `c` default is `"yeah"`, becomes `-c yeah -d ARGUMENT`
102
+ # 1. `-abc ARGUMENT` where only `c` receives the argument
103
+ # becomes `-ab -c ARGUMENT`
104
+ # 2. `-abc ARGUMENT` where `b` and `c` are argument receivers
105
+ # becomes `-a -b nil -c ARGUMENT`
106
+ # 3. `-acb ARGUMENT` where only `c` receives the argument
107
+ # becomes `-a -c nil -b ARGUMENT`
108
+ # 4. `-c --some-option ARGUMENT` where both options receive argument,
109
+ # becomes `-c nil --some-option ARGUMENT`
110
+ # 5. `-c --some-option -d ARGUMENT` where both options receive argument,
111
+ # becomes `-c nil --some-option nil -d ARGUMENT`
112
+ # 6. `-cd ARGUMENT` where `c` default is `"yeah"`,
113
+ # becomes `-c yeah -d ARGUMENT`
104
114
  # @param argv [Array<String>]
105
115
  # @param options [Hash] the defined `RakeCommander::Option` to re-arrange `argv` with.
106
116
  # @return [Array<String>] the re-arranged `argv`
107
117
  def argv_pre_parsed(argv = ARGV, options:)
108
- pre_parsed = explicit_argument_options(argv, options)
118
+ pre_parsed = explicit_argument_options(argv, options)
109
119
  compact_short = ''
120
+
110
121
  pre_parsed.each_with_object([]) do |(opt_ref, args), out|
111
122
  next out.push(*args) unless opt_ref.is_a?(Symbol)
123
+
112
124
  is_short = opt_ref.to_s.length == 1
113
125
  next compact_short << opt_ref.to_s if is_short && args.empty?
126
+
114
127
  out.push("-#{compact_short}") unless compact_short.empty?
115
128
  compact_short = ''
116
129
  opt_str = is_short ? "-#{opt_ref}" : name_hyphen(opt_ref)
@@ -139,17 +152,24 @@ class RakeCommander
139
152
  private
140
153
 
141
154
  # @example the output is actually a Hash, keyed by the Symbol of the option (short or name)
142
- # 1. `-abc ARGUMENT` where only `c` receives the argument becomes `:a :b :c ARGUMENT`
143
- # 3. `-abc ARGUMENT` where `b` and `c` are argument receivers becomes `:a :b nil :c ARGUMENT`
144
- # 2. `-acb ARGUMENT` where only `c` receives the argument becomes `:a :c nil :b ARGUMENT`
145
- # 4. `-c --some-option ARGUMENT` where both options receive argument, becomes `:c nil :some_option ARGUMENT`
146
- # 5. `-c --some-option -d ARGUMENT` where first two options receive argument, becomes `:c nil :some_option nil :d ARGUMENT`
147
- # 6. `-cd ARGUMENT` where `c` default is `"yeah"`, becomes `:c yeah :d ARGUMENT`
155
+ # 1. `-abc ARGUMENT` where only `c` receives the argument
156
+ # becomes `:a :b :c ARGUMENT`
157
+ # 2. `-abc ARGUMENT` where `b` and `c` are argument receivers
158
+ # becomes `:a :b nil :c ARGUMENT`
159
+ # 3. `-acb ARGUMENT` where only `c` receives the argument
160
+ # becomes `:a :c nil :b ARGUMENT`
161
+ # 4. `-c --some-option ARGUMENT` where both options receive argument,
162
+ # becomes `:c nil :some_option ARGUMENT`
163
+ # 5. `-c --some-option -d ARGUMENT` where first two options receive argument,
164
+ # becomes `:c nil :some_option nil :d ARGUMENT`
165
+ # 6. `-cd ARGUMENT` where `c` default is `"yeah"`,
166
+ # becomes `:c yeah :d ARGUMENT`
148
167
  # @return [Hash<Symbol, Array>]
149
168
  def explicit_argument_options(argv, options)
150
169
  decoupled = decluster_shorts_n_names_to_sym(argv)
151
170
  grouped = group_symbols_with_strings(decoupled)
152
171
  normalized = insert_missing_argument_to_groups(grouped, options)
172
+
153
173
  normalized.each_with_object({}) do |group, pre_parsed|
154
174
  opt_ref = group.first.is_a?(Symbol)? group.shift : nil
155
175
  pre_parsed[opt_ref] = group
@@ -163,14 +183,17 @@ class RakeCommander
163
183
  # @param groups [@see #pair_symbols_with_strings]
164
184
  def insert_missing_argument_to_groups(groups, options)
165
185
  groups.each do |group|
166
- args = group.dup
186
+ args = group.dup
167
187
  opt_ref = args.shift
188
+
168
189
  next unless args.empty?
169
190
  next unless opt_ref.is_a?(Symbol)
170
- next unless opt = _retrieve_option_ref(opt_ref, options)
191
+ next unless (opt = _retrieve_option_ref(opt_ref, options))
171
192
  next unless opt.argument?
193
+
172
194
  next group.push(opt.default) if opt.default?
173
- next unless opt.argument_required?
195
+ next unless opt.argument_required?
196
+
174
197
  group.push(nil)
175
198
  end
176
199
  end
@@ -180,11 +203,13 @@ class RakeCommander
180
203
  # @return [RakeCommander::Option, NilClass]
181
204
  def _retrieve_option_ref(opt_ref, options)
182
205
  opt = options[opt_ref]
183
- return opt if opt
184
- return nil unless match = opt_ref.to_s.match(BOOLEAN_ARGUMENT)
185
- return nil unless opt_ref = match[:option]
186
- return nil unless opt = options[opt_ref.to_sym]
187
- return nil unless opt.boolean_name?
206
+
207
+ return opt if opt
208
+ return unless (match = opt_ref.to_s.match(BOOLEAN_ARGUMENT))
209
+ return unless (opt_ref = match[:option])
210
+ return unless (opt = options[opt_ref.to_sym])
211
+ return unless opt.boolean_name?
212
+
188
213
  opt
189
214
  end
190
215
 
@@ -193,6 +218,7 @@ class RakeCommander
193
218
  def group_symbols_with_strings(argv)
194
219
  [].tap do |out|
195
220
  curr_ary = nil
221
+
196
222
  argv.each do |arg|
197
223
  if arg.is_a?(Symbol)
198
224
  out << (curr_ary = [arg])
@@ -5,12 +5,39 @@ class RakeCommander
5
5
 
6
6
  private
7
7
 
8
+ def fetch_desc!(args)
9
+ descs = args.dup.select do |arg|
10
+ arg.is_a?(String).tap do |is_string|
11
+ next unless is_string
12
+
13
+ args.delete(arg)
14
+ end
15
+ end.uniq
16
+
17
+ joined_lines(*descs)
18
+ end
19
+
8
20
  def string_to_lines(str, max: DESC_MAX_LENGTH)
9
21
  str.scan(liner_regex(max)).map(&:strip)
10
22
  end
11
23
 
12
24
  def liner_regex(len = DESC_MAX_LENGTH)
13
- /.{0,#{len}}[^ ](?:\s|$)/mi
25
+ /[^\n\r]{0,#{len}}[^ ](?:\s|$)/mi
26
+ end
27
+
28
+ def joined_lines(*lines, join: "\n")
29
+ lines = lines.compact.map(&:strip).reject(&:empty?)
30
+ return unless lines.count.positive?
31
+
32
+ first = lines.first
33
+ first = "#{first}." unless first.end_with?('.')
34
+
35
+ (lines[1..] || []).reduce(first) do |mem, line|
36
+ mem = "#{mem}." unless mem.end_with?('.')
37
+ line = "#{line}." unless line.end_with?('.')
38
+
39
+ "#{mem}#{join}#{line}"
40
+ end
14
41
  end
15
42
  end
16
43
  end
@@ -4,7 +4,7 @@ class RakeCommander
4
4
  # Base error class that does a rely between OptionParser and RakeCommander errors
5
5
  class Base < RakeCommander::Base::CustomError
6
6
  extend RakeCommander::Options::Name
7
- OPTION_REGEX = /(?:argument|option): (?<option>.+)/i.freeze
7
+ OPTION_REGEX = /(?:argument|option): (?<option>.+)/i
8
8
 
9
9
  class << self
10
10
  # Helper to check if `error` is this class or any children class
@@ -20,14 +20,17 @@ class RakeCommander
20
20
  def option_regex(value = :not_used)
21
21
  @option_regex ||= OPTION_REGEX
22
22
  return @option_regex if value == :not_used
23
+
23
24
  @option_regex = value
24
25
  end
25
26
 
26
27
  # Identifies the option `Symbol` (short or name) for a given message
27
28
  def option_sym(message)
28
- return nil unless match = message.match(option_regex)
29
+ return unless (match = message.match(option_regex))
30
+
29
31
  option = match[:option]
30
32
  return name_word_sym(option) if option.length > 1
33
+
31
34
  short_sym(option)
32
35
  end
33
36
  end
@@ -59,6 +62,7 @@ class RakeCommander
59
62
 
60
63
  def from_desc
61
64
  return '' unless from
65
+
62
66
  if from.respond_to?(:name)
63
67
  "(#{from.name}) "
64
68
  elsif from.respond_to?(:to_s)
@@ -4,7 +4,8 @@ class RakeCommander
4
4
  module Handling
5
5
  class << self
6
6
  def included(base)
7
- super(base)
7
+ super
8
+
8
9
  base.extend RakeCommander::Base::ClassHelpers
9
10
  base.extend RakeCommander::Base::ClassInheritable
10
11
  base.extend ClassMethods
@@ -40,6 +41,7 @@ class RakeCommander
40
41
  # @return [Boolean] whether this error is enabled.
41
42
  def error_on_options(action = :not_used, error: RakeCommander::Options::Error::Base, &handler)
42
43
  RakeCommander::Options::Error::Base.require_argument!(error, :error, accept_children: true)
44
+
43
45
  @options_latest_error = nil
44
46
  @error_on_options ||= {}
45
47
  @error_on_options[error] = action if action != :not_used
@@ -82,9 +84,10 @@ class RakeCommander
82
84
  action = error_on_options(error: eklass)
83
85
 
84
86
  # here is where we ignore the handler (when !action == `true`)
85
- raise unless !action || handler = error_on_options_handler(eklass)
87
+ raise unless !action || (handler = error_on_options_handler(eklass))
86
88
  raise if handler&.call(e, argv, results, leftovers)
87
89
  return leftovers if action == :continue
90
+
88
91
  puts e.message
89
92
  # https://stackoverflow.com/a/23340693/4352306
90
93
  exit 1
@@ -95,7 +98,13 @@ class RakeCommander
95
98
  def error_on_options_handler(error = :not_used, &handler)
96
99
  @error_on_options_handler ||= {}
97
100
  return @error_on_options_handler if error == :not_used
98
- RakeCommander::Options::Error::Base.require_argument!(error, :error, accept_children: true)
101
+
102
+ RakeCommander::Options::Error::Base.require_argument!(
103
+ error,
104
+ :error,
105
+ accept_children: true
106
+ )
107
+
99
108
  @error_on_options_handler[error] = handler if block_given?
100
109
  @error_on_options_handler[error]
101
110
  end
@@ -2,12 +2,13 @@ class RakeCommander
2
2
  module Options
3
3
  module Error
4
4
  class InvalidArgument < RakeCommander::Options::Error::Base
5
- option_regex(/invalid argument: (?<option>.+)/i.freeze)
5
+ option_regex(/invalid argument: (?<option>.+)/i)
6
6
 
7
7
  private
8
8
 
9
9
  def to_message(value)
10
- return super unless opt = option
10
+ return super unless (opt = option)
11
+
11
12
  case value
12
13
  when OptionParser::InvalidArgument
13
14
  super("invalid option argument: #{opt.name_hyphen} (#{opt.short_hyphen})")
@@ -2,7 +2,7 @@ class RakeCommander
2
2
  module Options
3
3
  module Error
4
4
  class InvalidOption < RakeCommander::Options::Error::Base
5
- option_regex(/invalid option: (?<option>.+)/i.freeze)
5
+ option_regex(/invalid option: (?<option>.+)/i)
6
6
  end
7
7
  end
8
8
  end
@@ -3,7 +3,7 @@ class RakeCommander
3
3
  module Error
4
4
  # Relates to options with missing required argument (when there's no `default` value)
5
5
  class MissingArgument < RakeCommander::Options::Error::Base
6
- option_regex(/missing(?: required|) argument: (?<option>.+)/i.freeze)
6
+ option_regex(/missing(?: required|) argument: (?<option>.+)/i)
7
7
  end
8
8
  end
9
9
  end
@@ -11,7 +11,7 @@ class RakeCommander
11
11
  module Error
12
12
  class << self
13
13
  def included(base)
14
- super(base)
14
+ super
15
15
  base.send :include, RakeCommander::Options::Error::Handling
16
16
  base.extend ClassMethods
17
17
  end
@@ -22,7 +22,7 @@ class RakeCommander
22
22
  # @see RakeCommander::Options::Result
23
23
  def parse_options(argv = ARGV, results: {}, leftovers: [], &block)
24
24
  with_error_handling(argv, results, leftovers) do
25
- super.tap do |_|
25
+ super.tap do
26
26
  check_on_leftovers(leftovers)
27
27
  check_required_presence(results)
28
28
  end
@@ -37,11 +37,21 @@ class RakeCommander
37
37
  raise eklass.new(from: self, option: opt), msg, cause: nil
38
38
  rescue OptionParser::InvalidArgument => e
39
39
  eklass = RakeCommander::Options::Error::InvalidArgument
40
+ src_e = nil
41
+ msg = nil
40
42
  opt = error_option(e, eklass)
41
- raise eklass.new(e, from: self, option: opt), nil, cause: nil unless opt&.argument_required?
42
- eklass = RakeCommander::Options::Error::MissingArgument
43
- msg = "missing required argument in option: #{opt.name_hyphen} (#{opt.short_hyphen})"
44
- raise eklass.new(from: self, option: opt), msg, cause: nil
43
+
44
+ if opt&.enum?
45
+ msg = "argument in option #{opt.name_hyphen} (#{opt.short_hyphen}) "
46
+ msg << "should be any of [#{opt.enum_options.join(' | ')}]"
47
+ elsif opt&.argument_required?
48
+ eklass = RakeCommander::Options::Error::MissingArgument
49
+ msg = "missing required argument in option: #{opt.name_hyphen} (#{opt.short_hyphen})"
50
+ else
51
+ src_e = e
52
+ end
53
+
54
+ raise eklass.new(src_e, from: self, option: opt), msg, cause: nil
45
55
  end
46
56
  end
47
57
 
@@ -53,7 +63,8 @@ class RakeCommander
53
63
  # @param eklass [RakeCommander::Options::Error:Base::Class] the error class to retrive the option key
54
64
  # @return [RakeCommander::Option, NilClass]
55
65
  def error_option(err, eklass)
56
- return false unless option_sym = eklass.option_sym(err.message)
66
+ return false unless (option_sym = eklass.option_sym(err.message))
67
+
57
68
  options_hash(with_implicit: true)[option_sym]
58
69
  end
59
70
 
@@ -65,6 +76,7 @@ class RakeCommander
65
76
  # @return [Hash] the results (same object)
66
77
  def check_on_leftovers(leftovers)
67
78
  return if leftovers.empty?
79
+
68
80
  eklass = RakeCommander::Options::Error::UnknownArgument
69
81
  raise eklass.new(leftovers, from: self)
70
82
  end