How to generate OptionParser require arguments

26,921

Solution 1

There's a similar question with an answer that may help you: "How do you specify a required switch (not argument) with Ruby OptionParser?"

In short: there doesn't seem to be a way to make an option required (they are called options after all).

There is an OptionParser::MissingArgument exception that you could raise rather than the ArgumentError you're currently throwing.

Solution 2

Faced with the same situation, I ended up with an option like this. If not all of my mandatory options are provided, output the user-friendly help text generated by OptionParser based on my defined options. Feels cleaner than throwing an exception and printing a stack trace to the user.

options = {}
option_parser = OptionParser.new do |opts|
  opts.banner = "Usage: #{$0} --data-dir DATA_DIR [options]"

  # A non-mandatory option
  opts.on('-p', '--port PORT', Integer, 'Override port number') do |v|
    options[:port] = v
  end

  # My mandatory option
  opts.on('-d', '--data-dir DATA_DIR', '[Mandatory] Specify the path to the data dir.') do |d|
    options[:data_dir] = d
  end
end

option_parser.parse!

if options[:data_dir].nil?
  puts option_parser.help
  exit 1
end
Share:
26,921

Related videos on Youtube

lukemh
Author by

lukemh

Updated on July 09, 2022

Comments

  • lukemh
    lukemh almost 2 years

    The code below works, but I am manually raising argument errors for the required arguments using fetch, when I want to build the required arguments into the native OptionParser sytax for required parameters:

    # ocra script.rb -- --type=value
    options = {}
    OptionParser.new do |opts|
      opts.banner = "Usage: example.rb [options]"
    
      opts.on("--type [TYPE]",String, [:gl, :time], "Select Exception file type (gl, time)") do |t|
        options["type"] = t
      end
    
      opts.on("--company [TYPE]",String, [:jaxon, :doric], "Select Company (jaxon, doric)") do |t|
        options["company"] = t
      end
    
    end.parse!
    
    opts = {}
    opts['type'] = options.fetch('type') do
      raise ArgumentError,"no 'type' option specified  as a parameter (gl or time)"
    end
    
    opts['company'] = options.fetch('company') do
      raise ArgumentError,"no 'company' option specified  as a parameter (doric or jaxon)"
    end
    
    • xxjjnn
      xxjjnn over 2 years
      I found that "--type [TYPE]" means TYPE is optional, but "--type TYPE" means TYPE is required. So don't type the brackets f(ಠ‿↼)z
  • lukemh
    lukemh about 11 years
    I have settled on using a ruby gem called github.com/JEG2/highline this has a cli menu dsl and required params.
  • Mario Visic
    Mario Visic about 11 years
    Nice work. A colleague of mine also wrote a gem called escort which can set required parameters for CLI apps: github.com/skorks/escort#required-arguments