Using ruby's OptionParser to parse sub-commands

后端 未结 4 1201
情话喂你
情话喂你 2021-01-31 04:39

I\'d like to be able to use ruby\'s OptionParser to parse sub-commands of the form

COMMAND [GLOBAL FLAGS] [SUB-COMMAND [SUB-COMMAND FLAGS]]

lik

相关标签:
4条回答
  • 2021-01-31 04:44

    It looks like the OptionParser syntax has changed some. I had to use the following so that the arguments array had all of the options not parsed by the opts object.

    begin
      opts.order!(arguments)
    rescue OptionParser::InvalidOption => io
      # Prepend the invalid option onto the arguments array
      arguments = io.recover(arguments)
    rescue => e
      raise "Argument parsing failed: #{e.to_s()}"
    end
    
    0 讨论(0)
  • 2021-01-31 04:51

    Figured it out. I need to use OptionParser#order!. It will parse all the options from the start of ARGV until it finds a non-option (that isn't an option argument), removing everything it processes from ARGV, and then it will quit.

    So I just need to do something like:

    global = OptionParser.new do |opts|
      # ...
    end
    subcommands = { 
      'foo' => OptionParser.new do |opts|
         # ...
       end,
       # ...
       'baz' => OptionParser.new do |opts|
         # ...
       end
     }
    
     global.order!
     subcommands[ARGV.shift].order!
    
    0 讨论(0)
  • 2021-01-31 04:59

    There are also other gems you can look at such as main.

    0 讨论(0)
  • 2021-01-31 05:04

    GLI is the way to go, https://github.com/davetron5000/gli. An excerpt from a tutorial:

    #!/usr/bin/env ruby
    require 'gli'
    require 'hacer'
    
    include GLI::App
    
    program_desc 'A simple todo list'
    
    flag [:t,:tasklist], :default_value => File.join(ENV['HOME'],'.todolist')
    
    pre do |global_options,command,options,args|
      $todo_list = Hacer::Todolist.new(global_options[:tasklist])
    end
    
    command :add do |c|
      c.action do |global_options,options,args|
        $todo_list.create(args)
      end
    end
    
    command :list do |c|
      c.action do
        $todo_list.list.each do |todo|
          printf("%5d - %s\n",todo.todo_id,todo.text)
        end
      end
    end
    
    command :done do |c|
      c.action do |global_options,options,args|
        id = args.shift.to_i
        $todo_list.list.each do |todo|
          $todo_list.complete(todo) if todo.todo_id == id
        end
      end
    end
    
    exit run(ARGV)
    

    You can find the tutorial at http://davetron5000.github.io/gli/.

    0 讨论(0)
提交回复
热议问题