lib/core/util/cli.rb in nucleon-0.2.0 vs lib/core/util/cli.rb in nucleon-0.2.1

- old
+ new

@@ -20,42 +20,40 @@ end def self.decode(encoded_string) Util::Data.symbol_map(Util::Data.parse_json(Base64.urlsafe_decode64(encoded_string))) end - + #------------------------------------------------------------------------- # Parser class Parser - attr_accessor :parser - attr_accessor :options - attr_accessor :arguments - attr_accessor :processed - + attr_accessor :parser, :options, :arguments, :extra, :processed, :strict + #--- include Mixin::Colors #--- def initialize(args, banner = '', help = '', split_help = false) - @parser = OptionParser.new - + self.options = {} self.arguments = {} + self.extra = {} self.processed = false + self.strict = true @arg_settings = [] self.banner = banner self.help = help yield(self) if block_given? - + parse_command(args, split_help) end #--- @@ -146,14 +144,20 @@ else parser.on_tail('-h', '--help', CLI.message('nucleon.core.util.cli.options.short_help')) do options[:help] = true end end - parser.parse!(args) + if strict + parser.parse!(args) + extra_args = {} + else + args, extra_args = parse_known_args(parser, args) + end + # Now we can act on options given - Util::Console.use_colors = options[:color] unless split_help + options[:color] = Util::Console.use_colors if options[:version] puts version exit 0 end @@ -161,10 +165,12 @@ return if options[:help] parse_encoded Nucleon.log_level = options[:log_level] if options[:log_level] + + self.extra = normalize_extra_options(extra_args) unless extra_args.empty? remaining_args = args.dup arg_messages = [] if arguments.empty? @@ -250,9 +256,69 @@ end end options.delete(:encoded_params) end + #--- + + def parse_known_args(parser, args) + extra_args = [] + + parse_args = lambda do |arg_list| + begin + original_list = arg_list.clone + + parser.parse! arg_list + args = arg_list + + rescue OptionParser::InvalidOption => e + extra_args += e.args + while arg_list[0] && arg_list[0][0] != '-' + extra_args << arg_list.shift + end + parse_args.call original_list - extra_args + end + end + parse_args.call args + [ args, extra_args ] + end + + #--- + + def normalize_extra_options(arg_list) + options = {} + last_option = nil + + Util::Data.array(arg_list).each do |arg| + components = arg.split('=') + value = nil + + if components.size > 1 + arg = components[0] + value = components[1] + end + + if arg[0] == '-' + last_option = arg.sub(/^\-+/, '').to_sym + options[last_option] = Util::Data.value(value) if value + else + if last_option + if options[last_option] + options[last_option] = [ options[last_option] ] unless options[last_option].is_a?(Array) + options[last_option] << Util::Data.value(arg) + else + options[last_option] = Util::Data.value(arg) + end + else + parser.warn(CLI.message('nucleon.core.util.cli.parse.error') + "\n\n" + parser.help) + break + end + end + end + options + end + protected :normalize_extra_options + #--- def option(name, default, option_str, allowed_values, message_id, config = {}) config = Config.ensure(config) name = name.to_sym