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)

If there is no current ShellOpts object error will look for USAGE to make it possible to use error before the command line is processed and also as a stand-alone error reporting method



122
123
124
125
126
# File 'lib/shellopts.rb', line 122

def self.error(*msgs)
  program = @shellopts&.program_name || PROGRAM
  usage_string = usage || (defined?(USAGE) && USAGE ? Grammar.compile(PROGRAM, USAGE).usage : nil)
  emit_and_exit(program, @usage.nil?, usage_string, *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)



131
132
133
134
# File 'lib/shellopts.rb', line 131

def self.fail(*msgs)
  program = @shellopts&.program_name || PROGRAM
  emit_and_exit(program, false, 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 also use the object methods #error and #fail:

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

Use #shellopts to get the hidden ShellOpts::ShellOpts object



97
98
99
100
101
102
103
104
105
106
# File 'lib/shellopts.rb', line 97

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



110
111
112
113
# File 'lib/shellopts.rb', line 110

def self.reset()
  @shellopts = nil
  @usage = nil
end

.shelloptsObject

Return the hidden ShellOpts::ShellOpts object (see .process)



16
17
18
# File 'lib/shellopts.rb', line 16

def self.shellopts()
  @shellopts
end

.usageObject

Prettified usage string used by #error and #fail. Default is usage of the current ShellOpts::ShellOpts object



22
# File 'lib/shellopts.rb', line 22

def self.usage() @usage || @shellopts&.usage end

.usage=(usage) ⇒ Object

Set the usage string



25
# File 'lib/shellopts.rb', line 25

def self.usage=(usage) @usage = usage end