lib/rake-commander/options/error.rb in rake-commander-0.1.4 vs lib/rake-commander/options/error.rb in rake-commander-0.2.0
- old
+ new
@@ -1,18 +1,83 @@
-require_relative 'error_rely'
+require_relative 'error/base'
+require_relative 'error/missing_argument'
+require_relative 'error/invalid_argument'
+require_relative 'error/invalid_option'
+require_relative 'error/missing_option'
+require_relative 'error/unknown_argument'
+require_relative 'error/handling'
+
class RakeCommander
module Options
- class MissingOption < RakeCommander::Options::ErrorRely
- def initialize(value)
- super("missing required option: #{to_description(value)}")
+ module Error
+ class << self
+ def included(base)
+ super(base)
+ base.send :include, RakeCommander::Options::Error::Handling
+ base.extend ClassMethods
+ end
end
- end
- class MissingArgument < RakeCommander::Options::ErrorRely
- OPTION_REGEX = /missing (?:required|) argument: (?<option>.+)/i.freeze
- end
+ module ClassMethods
+ # Re-open method to add all the error handling.
+ # @see RakeCommander::Options::Result
+ def parse_options(argv = ARGV, results: {}, leftovers: [], &block)
+ with_error_handling(argv, results, leftovers) do
+ super.tap do |_|
+ check_on_leftovers(leftovers)
+ check_required_presence(results)
+ end
+ rescue OptionParser::InvalidOption => e
+ eklass = RakeCommander::Options::Error::InvalidOption
+ raise eklass.new(e, from: self), nil, cause: nil
+ rescue OptionParser::MissingArgument => e
+ eklass = RakeCommander::Options::Error::MissingArgument
+ opt = error_option(e, eklass)
+ msg = e.message
+ msg = "missing required argument: #{opt.name_hyphen} (#{opt.short_hyphen})" if opt
+ raise eklass.new(from: self, option: opt), msg, cause: nil
+ rescue OptionParser::InvalidArgument => e
+ eklass = RakeCommander::Options::Error::InvalidArgument
+ opt = error_option(e, eklass)
+ raise eklass.new(e, from: self, option: opt), nil, cause: nil unless opt&.argument_required?
+ eklass = RakeCommander::Options::Error::MissingArgument
+ msg = "missing required argument in option: #{opt.name_hyphen} (#{opt.short_hyphen})"
+ raise eklass.new(from: self, option: opt), msg, cause: nil
+ end
+ end
- class InvalidArgument < RakeCommander::Options::ErrorRely
- OPTION_REGEX = /invalid argument: (?<option>.+)/i.freeze
+ protected
+
+ # Helper to retrieve an existing `RakeCommander::Option` out of a
+ # `OptionParser` error.
+ # @param e [OptionParser:Error] containing the original error `message`
+ # @param eklass [RakeCommander::Options::Error:Base::Class] the error class to retrive the option key
+ # @return [RakeCommander::Option, NilClass]
+ def error_option(err, eklass)
+ return false unless option_sym = eklass.option_sym(err.message)
+ options_hash(with_implicit: true)[option_sym]
+ end
+
+ private
+
+ # It implements the logic defined by `error_on_leftovers`.
+ # @param leftovers [Array<String>]
+ # @param results [Hash] the parsed options
+ # @return [Hash] the results (same object)
+ def check_on_leftovers(leftovers)
+ return if leftovers.empty?
+ eklass = RakeCommander::Options::Error::UnknownArgument
+ raise eklass.new(leftovers, from: self)
+ end
+
+ # It throws an exception if any of the required options
+ # is missing in results
+ def check_required_presence(results)
+ missing = options.select(&:required?).reject do |opt|
+ results.key?(opt.short) || results.key?(opt.name)
+ end
+ raise RakeCommander::Options::Error::MissingOption.new(missing, from: self) unless missing.empty?
+ end
+ end
end
end
end