Module: ShellOpts

Defined in:
lib/shellopts.rb,
lib/shellopts/utils.rb,
lib/shellopts/parser.rb,
lib/shellopts/ast/node.rb,
lib/shellopts/compiler.rb,
lib/shellopts/ast/option.rb,
lib/shellopts/ast/command.rb,
lib/shellopts/ast/program.rb,
lib/shellopts/grammar/node.rb,
lib/shellopts/grammar/option.rb,
lib/shellopts/grammar/command.rb,
lib/shellopts/grammar/program.rb

Overview

ShellOpts is a library for parsing command line options and sub-commands. The library API consists of the methods ShellOpts.process, ShellOpts#error, and ShellOpts#fail and the result class ShellOpts

ShellOpts inject the constant PROGRAM into the global scope. It contains the name of the program

Defined Under Namespace

Modules: Ast, Grammar, Utils Classes: CompilerError, Error, InternalError, ShellOpts

Class Method Summary collapse

Class Method Details

.error(*msgs) ⇒ Object

Print error message and usage string and exit with status 1. It use the current ShellOpts object if defined. This method should be called in response to user-errors (eg. specifying an illegal option)



103
104
105
106
107
# File 'lib/shellopts.rb', line 103

def self.error(*msgs)
  program = @shellopts&.program_name || PROGRAM
  usage = @shellopts&.usage || (defined?(USAGE) && USAGE ? Grammar.compile(PROGRAM, USAGE).usage : nil)
  emit_and_exit(program, usage, *msgs)
end

.fail(*msgs) ⇒ Object

Print error message and exit with status 1. It use the current ShellOpts object if defined. This method should not be called in response to user-errors but system errors (like disk full)



112
113
114
115
# File 'lib/shellopts.rb', line 112

def self.fail(*msgs)
  program = @shellopts&.program_name || PROGRAM
  emit_and_exit(program, nil, *msgs)
end

.process(usage, argv, program_name: PROGRAM, &block) ⇒ Object

Process command line options and arguments. #process takes a usage string defining the options and the array of command line arguments to be parsed as arguments

If called with a block, the block is called with name and value of each option or command and #process returns a list of remaining command line arguments. If called without a block a ShellOpts::ShellOpts object is returned

The value of an option is its argument, the value of a command is an array of name/value pairs of options and subcommands. Option values are converted to the target type (String, Integer, Float) if specified

Example

# Define options
USAGE = 'a,all g,global +v,verbose h,help save! snapshot f,file=FILE h,help'

# Define defaults
all = false
global = false
verbose = 0
save = false
snapshot = false
file = nil

# Process options
argv = ShellOpts.process(USAGE, ARGV) do |name, value|
  case name
    when '-a', '--all'; all = true
    when '-g', '--global'; global = value
    when '-v', '--verbose'; verbose += 1
    when '-h', '--help'; print_help(); exit(0)
    when 'save'
      save = true
      value.each do |name, value|
        case name
          when '--snapshot'; snapshot = true
          when '-f', '--file'; file = value
          when '-h', '--help'; print_save_help(); exit(0)
        end
      end
  else
    raise "Not a user error. The developer forgot or misspelled an option"
  end
end

# Process remaining arguments
argv.each { |arg| ... }

If an error is encountered while compiling the usage string, a ShellOpts::Compiler exception is raised. If the error happens while parsing the command line arguments, the program prints an error message and exits with status 1. Failed assertions raise a ShellOpts::InternalError exception

Note that you can’t process more than one command line at a time because #process saves a hidden ShellOpts class variable used by the class methods #error and #fail. Call #reset to clear the global object if you really need to parse more than one command line. Alternatively you can create ShellOpts::ShellOpts objects yourself and use the object methods #error and #fail instead:

shellopts = ShellOpts::ShellOpts.new(USAGE, ARGS)
shellopts.each { |name, value| ... }
shellopts.args.each { |arg| ... }
shellopts.error("Something went wrong")


83
84
85
86
87
88
89
90
91
92
# File 'lib/shellopts.rb', line 83

def self.process(usage, argv, program_name: PROGRAM, &block)
  if !block_given?
    ShellOpts.new(usage, argv, program_name: program_name)
  else
    @shellopts.nil? or raise InternalError, "ShellOpts class variable already initialized"
    @shellopts = ShellOpts.new(usage, argv, program_name: program_name)
    @shellopts.each(&block)
    @shellopts.args
  end
end

.resetObject

Reset the hidden ShellOpts::ShellOpts class variable so that you can process another command line



96
97
98
# File 'lib/shellopts.rb', line 96

def self.reset()
  @shellopts = nil
end