def self.fill_arguments(cmd, options, args, opts, arguments)
defaults = {}
covers = {}
(opts + args).each do |option_meta|
arg = option_meta[:option_symbol] || option_meta[:name] || option_meta[:arg] or next
if arg && option_meta[:type] != :list && options[arg].is_a?(Array)
options[arg] = options[arg].last
end
Array(option_meta[:covered_by]).each{ |sym| (covers[sym] ||= []) << arg }
case v = option_meta[:default]
when Symbol
cmd.send(v, defaults, arg)
when Proc
v.call(defaults, arg)
when nil
else
defaults[arg] = v
end
end
options.default(defaults)
opts.each do |option_meta|
raise ArgumentError.new("Missing required option '#{option_meta[:arg]}'.") if option_meta[:required] && options[option_meta[:arg]].nil?
end
slots = Array.new(args.count)
available = arguments.dup
args.each_with_index do |arg, i|
value = argument_to_slot(options, available, arg)
if value.nil?
if arg[:allow_nil] != true && !arg[:optional]
raise ArgumentError, "Missing required argument '#{arg[:name]}'."
end
end
slots[i] = value
end
raise ArgumentError, "Too many arguments passed in: #{available.reverse.join(" ")}" unless available.empty?
options.__explicit__.keys.each do |k|
if covered = covers[k]
covered.each do |sym|
raise ArgumentError, "The options '#{sym}' and '#{k}' cannot both be provided" unless options.__explicit__[sym].nil?
options[sym] = nil
end
end
end
slots
end