class CommandLine::Parser

Constants

GLOBAL_SYM

Public Class Methods

new(&block) click to toggle source
# File lib/ejt_command_line.rb, line 108
def initialize(&block)
  @switches = {}
  @global_switches = []
  @value_types = {}
  @commands = Hash.new {|hash, key| Command.new}
  @current_command = @commands[GLOBAL_SYM]

  configure(&block) if block
end

Public Instance Methods

command(sym, &block) click to toggle source
# File lib/ejt_command_line.rb, line 146
def command(sym, &block)
  old = @current_command
  @current_command = @commands[sym] = Command.new

  if block
    release = lambda {@current_command = old}
    bracket_(release) do
      self.instance_eval(&block)
    end
  end
end
configure(&block) click to toggle source
# File lib/ejt_command_line.rb, line 118
def configure(&block)
  self.instance_eval(&block)
end
global(&block) click to toggle source
# File lib/ejt_command_line.rb, line 142
def global(&block)
  command(GLOBAL_SYM, &block)
end
mandatory(sym) click to toggle source
# File lib/ejt_command_line.rb, line 169
def mandatory(sym)
  syms = [sym]
  check_switches_are_defined(syms)
  @current_command.add_switches(syms)
  @current_command.add_mandatory_switch(sym)
end
multivalue_switch(sym, value_sym, *flags) click to toggle source
# File lib/ejt_command_line.rb, line 138
def multivalue_switch(sym, value_sym, *flags)
  @switches[sym] = Switch.new(flags, get_value_parser(value_sym), true)
end
one_of(*syms) click to toggle source
# File lib/ejt_command_line.rb, line 163
def one_of(*syms)
  check_switches_are_defined(syms)
  @current_command.add_switches(syms)
  @current_command.add_mutually_exclusive_set(syms)
end
parse(handler, *args) click to toggle source
# File lib/ejt_command_line.rb, line 176
def parse(handler, *args)
  command, opts, plain_args = parse_(args)
  handler.send(command, opts, plain_args)
end
simple_switch(sym, *flags) click to toggle source
# File lib/ejt_command_line.rb, line 130
def simple_switch(sym, *flags)
  @switches[sym] = Switch.new(flags)
end
switches(*syms) click to toggle source
# File lib/ejt_command_line.rb, line 158
def switches(*syms)
  check_switches_are_defined(syms)
  @current_command.add_switches(syms)
end
value_switch(sym, value_sym, *flags) click to toggle source
# File lib/ejt_command_line.rb, line 134
def value_switch(sym, value_sym, *flags)
  @switches[sym] = Switch.new(flags, get_value_parser(value_sym))
end
value_type(sym, &parser) click to toggle source
# File lib/ejt_command_line.rb, line 122
def value_type(sym, &parser)
  if @value_types.member?(sym)
    raise ConfigureError, "duplicate value type '#{sym}'"
  end

  @value_types[sym] = parser
end

Private Instance Methods

bracket_(release) { || ... } click to toggle source
# File lib/ejt_command_line.rb, line 268
def bracket_(release)
  r = nil
  begin
    r = yield
  ensure
    release.call
  end
  r
end
check_switches_are_defined(syms) click to toggle source
# File lib/ejt_command_line.rb, line 241
def check_switches_are_defined(syms)
  syms.each do |sym|
    raise ConfigureError, "unknown switch '#{sym}'" unless @switches.member?(sym)
  end
end
find_switch(valid_switches, switch) click to toggle source
# File lib/ejt_command_line.rb, line 247
def find_switch(valid_switches, switch)
  catch :found do
    valid_switches.each do |sym|
      s = @switches[sym]
      if s.has_flag?(switch)
        throw :found, [sym, s]
      end
    end

    raise ParseError, "unexpected switch '#{switch}'"
  end
end
get_value_parser(sym) click to toggle source
# File lib/ejt_command_line.rb, line 260
def get_value_parser(sym)
  if @value_types.member?(sym)
    @value_types[sym]
  else
    raise ConfigureError, "unknown value type '#{sym}'"
  end
end
parse_(args) click to toggle source
# File lib/ejt_command_line.rb, line 204
def parse_(args)
  in_command = false
  opts = {}
  plain_args = []
  valid_switches = @commands[GLOBAL_SYM].switches
  command = :global_command

  while args.size > 0 do
    arg = args.shift

    if arg =~ /^-/
      sym, s = find_switch(valid_switches, arg)

      if s.multi
        opts[sym] = parse_value(arg, s, args, opts[sym] || [])
      else
        opts[sym] = parse_value(arg, s, args)
      end

    else
      cmd = arg.intern

      if !in_command && @commands.member?(cmd)
        command = cmd
        valid_switches = @commands[cmd].switches
        in_command = true
      else
        plain_args << arg
      end
    end
  end

  @commands[command].check_mutual_exclusion(opts.keys)
  @commands[command].check_mandatory(opts.keys)
  [command, opts, plain_args]
end
parse_value(arg, s, args, old_value = nil) click to toggle source
# File lib/ejt_command_line.rb, line 182
def parse_value(arg, s, args, old_value = nil)
  if s.parser
    if args.size == 0
      raise ParseError, "no value specified for switch '#{arg}'"
    end

    value = args.shift
    begin
      v = s.parser.call(value)
      if old_value.nil?
        v
      else
        old_value << v
      end
    rescue => e
      raise ParseError, "couldn't parse value '#{arg}=#{value}'\n#{e}"
    end
  else
    true
  end
end