class Rbkb::Cli::Executable

Rbkb::Cli::Executable is an abstract class for creating command line executables using the Ruby Black Bag framework.

Attributes

argv[RW]
exit_status[R]
oparse[RW]
opts[RW]
stderr[RW]
stdin[RW]
stdout[RW]

Public Class Methods

new(param={}) { |self| ... } click to toggle source

Instantiates a new Executable object.

The ‘param’ argument is a named value hash. The following keys are significant:

:argv   - An array of cli arguments (default ARGV)
:opts    - executable/function options for use when running 'go'
:stdout, - IO redirection (mostly for unit tests)
:stderr,   
:stdin

The above keys are deleted from the ‘param’ hash and stored as instance variables with attr_accessors. All other parameters are ignored.

# File lib/rbkb/cli.rb, line 35
def initialize(param={})
  @argv   ||= param.delete(:argv) || ARGV
  @stdout ||= param.delete(:stdout) || STDOUT
  @stderr ||= param.delete(:stderr) || STDERR
  @stdin  ||= param.delete(:stdin) || STDIN
  @opts   ||= param.delete(:opts) || {}
  @parser_got_range=nil
  yield self if block_given?
  make_parser()
end
run(param={}) click to toggle source
# File lib/rbkb/cli.rb, line 14
def self.run(param={})
  new(param).go
end

Public Instance Methods

bail(msg) click to toggle source

This method exits with a message on stderr

# File lib/rbkb/cli.rb, line 59
def bail(msg)
  @stderr.puts msg if msg
  self.exit(1)
end
bail_args(arg_err) click to toggle source

This method wraps a ‘bail’ with a basic argument error mesage and hint for the ‘-h or –help’ flag The ‘arg_err’ parameter is a string with the erroneous arguments

# File lib/rbkb/cli.rb, line 68
def bail_args(arg_err)
  bail "Error: bad arguments - #{arg_err}\n  Hint: Use -h or --help"
end
exit(ret) click to toggle source

Wrapper for Kernel.exit() so we can unit test cli tools

# File lib/rbkb/cli.rb, line 48
def exit(ret)
  @exit_status = ret
  if defined? Rbkb::Cli::TESTING
    throw(((ret==0)? :exit_zero : :exit_err), ret)
  else
    Kernel.exit(ret)
  end
end
go(argv=nil) click to toggle source

Abstract ‘runner’. Override this method with super() from inherited executables. The base method just slurps in an optional argv and runs ‘parse’ if it hasn’t already

# File lib/rbkb/cli.rb, line 110
def go(argv=nil)
  @exit_status = nil
  @argv = argv if argv 

  parse

  # the overriding class implements actual functionality beyond here
end
make_parser() click to toggle source

Prepares an OptionsParser object with blackbag standard options This is called from within initialize() and should be overridden in inherited classes to add additional OptionParser-based parsers.

See parse for actual parsing.

# File lib/rbkb/cli.rb, line 78
def make_parser
  @oparse ||= OptionParser.new 
  @oparse.banner = "Usage: #{File.basename $0} [options]"

  @oparse.on("-h", "--help", "Show this message") do
    bail(@oparse)
  end

  @oparse.on("-v", "--version", "Show version and exit") do
    @stdout.puts("Ruby BlackBag version #{Rbkb::VERSION}")
    self.exit(0)
  end

  return @oparse
end
parse() click to toggle source

Abstract argument parser. Override this method with super() from inherited executables. The base method just calls OptionParser.parse! on the internal @oparse object.

# File lib/rbkb/cli.rb, line 98
def parse
  # parse flag arguments
  @oparse.parse!(@argv) rescue(bail_args($!))
  @parsed=true

  # the overriding class may implement additional arguments from here
end

Private Instance Methods

add_range_opts(fkey, lkey) click to toggle source

Implements numeric and hex range options via ‘-r’ and ‘-x’

Takes two arguments which are the @opts hash key names for first and last parameters.

(Used commonly throughout several executables)

# File lib/rbkb/cli.rb, line 148
def add_range_opts(fkey, lkey)
  @oparse.on("-r", "--range=START[:END]", 
             "Start and optional end range") do |r|

    raise "-x and -r are mutually exclusive" if @parser_got_range
    @parser_got_range=true

    unless /^(-?[0-9]+)(?::(-?[0-9]+))?$/.match(r)
      raise "invalid range #{r.inspect}"
    end

    @opts[fkey] = $1.to_i
    @opts[lkey] = $2.to_i if $2
  end

  @oparse.on("-x", "--hexrange=START[:END]", 
             "Start and optional end range in hex") do |r|

    raise "-x and -r are mutually exclusive" if @parser_got_range
    @parser_got_range=true

    unless /^(-?[0-9a-f]+)(?::(-?[0-9a-f]+))?$/i.match(r)
      raise "invalid range #{r.inspect}"
    end

    @opts[fkey] = 
      if ($1[0,1] == '-')
        ($1[1..-1]).hex_to_num * -1
      else
        $1.hex_to_num
      end

    if $2
      @opts[lkey] = 
        if($2[0,1] == '-')
          $2[1..-1].hex_to_num * -1
        else
          $2.hex_to_num
        end
    end
  end
end
add_std_file_opt(inkey) click to toggle source

Implements a basic input file argument. File reading is handled by do_file_read().

Takes one argument, which is the @opts hash keyname to store the file data into. (Used commonly throughout several executables)

# File lib/rbkb/cli.rb, line 134
def add_std_file_opt(inkey)
  @oparse.on("-f", "--file FILENAME", "Input from FILENAME") do |f|
    @opts[inkey] = do_file_read(f)
  end
  return @oparse
end
do_file_read(f) click to toggle source

Wraps a file read with a standard bail error message

# File lib/rbkb/cli.rb, line 123
def do_file_read(f)
  File.read(f) rescue(bail "File Read Error: #{$!}")
end
parse_catchall() click to toggle source

For use at the end of a parser - calls bail_args with remaining arguments if there are extra arguments. (Used commonly throughout several executables)

# File lib/rbkb/cli.rb, line 214
def parse_catchall
  bail_args(@argv.join(' ')) if(@argv.length != 0)
end
parse_file_argument(key) click to toggle source

Conditionally parses a file argument. Uses ‘key’ to first check for then store it in @opts hash if it is not yet there. (Used commonly throughout several executables)

# File lib/rbkb/cli.rb, line 205
def parse_file_argument(key)
  if @opts[key].nil? and f=@argv.shift
    @opts[key] = do_file_read(f)
  end
end
parse_string_argument(key) click to toggle source

Conditionally parses a string argument. Uses ‘key’ to first check for then store it in @opts hash if it is not yet there. (Used commonly throughout several executables)

# File lib/rbkb/cli.rb, line 195
def parse_string_argument(key)
  if @opts[key].nil? and s=@argv.shift
    @opts[key] = s.dup 
  end
end