Method: Puppet::Util::CommandLine::Trollop::Parser#parse
- Defined in:
- lib/puppet/util/command_line/trollop.rb
#parse(cmdline = ARGV) ⇒ Object
Parses the commandline. Typically called by Trollop::options, but you can call it directly if you need more control.
throws CommandlineError, HelpNeeded, and VersionNeeded exceptions.
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
# File 'lib/puppet/util/command_line/trollop.rb', line 308 def parse cmdline=ARGV vals = {} required = {} if handle_help_and_version opt :version, _("Print version and exit") if @version unless @specs[:version] || @long["version"] opt :help, _("Show this message") unless @specs[:help] || @long["help"] end @specs.each do |sym, opts| required[sym] = true if opts[:required] vals[sym] = opts[:default] vals[sym] = [] if opts[:multi] && !opts[:default] # multi arguments default to [], not nil end if ## resolve symbols given_args = {} @leftovers = each_arg cmdline do |arg, params| sym = case arg when /^-([^-])$/ @short[$1] when /^--no-([^-]\S*)$/ @long["[no-]#{$1}"] when /^--([^-]\S*)$/ @long[$1] ? @long[$1] : @long["[no-]#{$1}"] else raise CommandlineError, _("invalid argument syntax: '%{arg}'") % { arg: arg } end unless sym next 0 if raise CommandlineError, _("unknown argument '%{arg}'") % { arg: arg } unless sym end if given_args.include?(sym) && !@specs[sym][:multi] raise CommandlineError, _("option '%{arg}' specified multiple times") % { arg: arg } end given_args[sym] ||= {} given_args[sym][:arg] = arg given_args[sym][:params] ||= [] # The block returns the number of parameters taken. num_params_taken = 0 unless params.nil? if SINGLE_ARG_TYPES.include?(@specs[sym][:type]) given_args[sym][:params] << params[0, 1] # take the first parameter num_params_taken = 1 elsif MULTI_ARG_TYPES.include?(@specs[sym][:type]) given_args[sym][:params] << params # take all the parameters num_params_taken = params.size end end num_params_taken end if handle_help_and_version ## check for version and help args raise VersionNeeded if given_args.include? :version raise HelpNeeded if given_args.include? :help end ## check constraint satisfaction @constraints.each do |type, syms| constraint_sym = syms.find { |sym| given_args[sym] } next unless constraint_sym case type when :depends syms.each { |sym| raise CommandlineError, _("--%{value0} requires --%{value1}") % { value0: @specs[constraint_sym][:long], value1: @specs[sym][:long] } unless given_args.include? sym } when :conflicts syms.each { |sym| raise CommandlineError, _("--%{value0} conflicts with --%{value1}") % { value0: @specs[constraint_sym][:long], value1: @specs[sym][:long] } if given_args.include?(sym) && (sym != constraint_sym) } end end required.each do |sym, val| raise CommandlineError, _("option --%{opt} must be specified") % { opt: @specs[sym][:long] } unless given_args.include? sym end ## parse parameters given_args.each do |sym, given_data| arg = given_data[:arg] params = given_data[:params] opts = @specs[sym] raise CommandlineError, _("option '%{arg}' needs a parameter") % { arg: arg } if params.empty? && opts[:type] != :flag vals["#{sym}_given".intern] = true # mark argument as specified on the commandline case opts[:type] when :flag if arg =~ /^--no-/ and sym.to_s =~ /^--\[no-\]/ vals[sym] = opts[:default] else vals[sym] = !opts[:default] end when :int, :ints vals[sym] = params.map { |pg| pg.map { |p| parse_integer_parameter p, arg } } when :float, :floats vals[sym] = params.map { |pg| pg.map { |p| parse_float_parameter p, arg } } when :string, :strings vals[sym] = params.map { |pg| pg.map { |p| p.to_s } } when :io, :ios vals[sym] = params.map { |pg| pg.map { |p| parse_io_parameter p, arg } } when :date, :dates vals[sym] = params.map { |pg| pg.map { |p| parse_date_parameter p, arg } } end if SINGLE_ARG_TYPES.include?(opts[:type]) unless opts[:multi] # single parameter vals[sym] = vals[sym][0][0] else # multiple options, each with a single parameter vals[sym] = vals[sym].map { |p| p[0] } end elsif MULTI_ARG_TYPES.include?(opts[:type]) && !opts[:multi] vals[sym] = vals[sym][0] # single option, with multiple parameters end # else: multiple options, with multiple parameters opts[:callback].call(vals[sym]) if opts.has_key?(:callback) end ## modify input in place with only those ## arguments we didn't process cmdline.clear @leftovers.each { |l| cmdline << l } ## allow openstruct-style accessors class << vals def method_missing(m, *args) self[m] || self[m.to_s] end end vals end |