class Executable::Parser
The Parser
class does all the heavy lifting for Executable
.
Attributes
cli_class[R]
Public Class Methods
new(cli_class)
click to toggle source
@param [Executable] cli_class
An executabe class.
# File lib/executable/parser.rb, line 11 def initialize(cli_class) @cli_class = cli_class end
Public Instance Methods
find_long_option(obj, char)
click to toggle source
@todo Sort alphabetically?
# File lib/executable/parser.rb, line 182 def find_long_option(obj, char) meths = obj.methods.map{ |m| m.to_s } meths = meths.select do |m| m.start_with?(char) and (m.end_with?('=') or m.end_with?('!')) end meths.first end
invoke(obj, meth, argv)
click to toggle source
# File lib/executable/parser.rb, line 192 def invoke(obj, meth, argv) m = (Method === meth ? meth : obj.method(meth)) a = [] m.arity.abs.times{ a << argv.shift } m.call(*a) end
parse(argv=ARGV)
click to toggle source
Parse command-line.
@param argv [Array,String] command-line arguments
# File lib/executable/parser.rb, line 21 def parse(argv=ARGV) # duplicate to make sure ARGV stay intact. argv = argv.dup argv = parse_shellwords(argv) cmd, argv = parse_subcommand(argv) cli = cmd.new args = parse_arguments(cli, argv) return cli, args end
parse_arguments(obj, argv, args=[])
click to toggle source
Parse command line options based on given object.
@param obj [Object] basis for command-line parsing @param argv [Array,String] command-line arguments @param args [Array] pre-seeded arguments to add to
@return [Array] parsed arguments
# File lib/executable/parser.rb, line 70 def parse_arguments(obj, argv, args=[]) case argv when String require 'shellwords' argv = Shellwords.shellwords(argv) #else # argv = argv.dup end #subc = nil #@args = [] #opts, i = {}, 0 while argv.size > 0 case arg = argv.shift when /=/ parse_equal(obj, arg, argv, args) when /^--/ parse_long(obj, arg, argv, args) when /^-/ parse_flags(obj, arg, argv, args) else #if Executable === obj # if cmd_class = obj.class.subcommands[arg] # cmd = cmd_class.new(obj) # subc = cmd # parse(cmd, argv, args) # else args << arg # end #end end end return args end
parse_equal(obj, opt, argv, args)
click to toggle source
Parse equal setting comman-line option.
# File lib/executable/parser.rb, line 109 def parse_equal(obj, opt, argv, args) if md = /^[-]*(.*?)=(.*?)$/.match(opt) x, v = md[1], md[2] else raise ArgumentError, "#{x}" end if obj.respond_to?("#{x}=") v = true if v == 'true' # yes or on ? v = false if v == 'false' # no or off ? obj.send("#{x}=", v) else obj.__send__(:option_missing, x, v) # argv? end end
parse_flags(obj, opt, argv, args)
click to toggle source
Parse single-dash command-line option.
# File lib/executable/parser.rb, line 150 def parse_flags(obj, opt, argv, args) x = opt[1..-1] c = 0 x.split(//).each do |k| if obj.respond_to?("#{k}=") m = obj.method("#{k}=") if obj.respond_to?("#{x}?") m.call(true) else invoke(obj, m, argv) #m.call(argv.shift) end elsif obj.respond_to?("#{k}!") invoke(obj, "#{k}!", argv) else long = find_long_option(obj, k) if long if long.end_with?('=') && obj.respond_to?(long.chomp('=')+'?') invoke(obj, long, [true]) else invoke(obj, long, argv) end else obj.__send__(:option_missing, x, argv) end end end end
parse_long(obj, opt, argv, args)
click to toggle source
Parse double-dash command-line option.
# File lib/executable/parser.rb, line 127 def parse_long(obj, opt, argv, args) x = opt.sub(/^\-+/, '') # remove '--' if obj.respond_to?("#{x}=") m = obj.method("#{x}=") if obj.respond_to?("#{x}?") m.call(true) else invoke(obj, m, argv) end elsif obj.respond_to?("#{x}!") invoke(obj, "#{x}!", argv) else # call even if private method obj.__send__(:option_missing, x, argv) end end
parse_shellwords(argv)
click to toggle source
Make sure arguments are an array. If argv is a String, then parse using Shellwords module.
@param argv [Array,String] commmand-line arguments
# File lib/executable/parser.rb, line 37 def parse_shellwords(argv) if String === argv require 'shellwords' argv = Shellwords.shellwords(argv) end argv.to_a end
parse_subcommand(argv)
click to toggle source
# File lib/executable/parser.rb, line 48 def parse_subcommand(argv) cmd = cli_class arg = argv.first while c = cmd.subcommands[arg] cmd = c argv.shift arg = argv.first end return cmd, argv end
subcommands()
click to toggle source
Index of subcommands.
@return [Hash] name mapped to subcommnd class
# File lib/executable/parser.rb, line 202 def subcommands @cli_class.subcommands end