Argvector provides a very simple means of parsing command line arguments.
Unlike other more complex libs this provides only the most basic and standard parsing functionality. In many cases that's all one really needs.
Usage is straight foward. Simply instantiate the class and query it for the particular "views" of the command line you want.
cargs = Argvector.new("-a foo -b=2") cargs.parameters #=> [['foo'],{'a'=>true,'b'=>'2'}] cargs.flags #=> ['a'] cargs.preoptions #=> {'a'=>true} cargs.preflags #=> ['a'] cargs.subcommand #=> ['foo', [], {'b'=>'2'}]
Takes the command line string (or array) and options. Options have flags and end with a hash of option arity.
# File lib/facets/supplemental/facets/argvector.rb, line 81 def initialize(line=nil, arity=nil) @line, @argv = parse_line(line) @arity = parse_arity(arity||{}) parse end
Parse flags takes the command line and transforms it such that flags (eg. -x and --x) are elemental associative arrays.
line = "--foo hello --try=this" argv = Argvector.new(line) args = line.split(/\s/) argv.assoc_options(args) #=> [ ["foo",true], "hello", ["try","this"] ]
# File lib/facets/supplemental/facets/argvector.rb, line 286 def assoc_options(args) ##args = args.dup args = multi_flag(args) #unless opts.include?(:simple) i = 0 while i < args.size arg = args[i] case arg when /^-/ arg = arg.sub(/^-{1,2}/,'') if arg.index('=') key, val = arg.split('=') args[i] = [key, val||true] elsif arity.key?(arg) cnt = arity[arg] key = arg val = args[i+1,cnt] args[i,cnt+1] = [[key, *val]] i += (cnt - 1) else key = arg args[i] = [key,true] end end i += 1 end return args end
Return flags, which are true options.
# File lib/facets/supplemental/facets/argvector.rb, line 109 def flags f = [] @options.each do |k, v| if TrueClass===v or FalseClass===v # not that it's ever false f << k end end return f end
Format flag options. This converts the associative array of options/flags into a hash. Repeat options will be placed in arrays.
# File lib/facets/supplemental/facets/argvector.rb, line 329 def format_options(assoc_options) opts = {} assoc_options.each do |k,v| if opts.key?(k) opts[k] = [opts[k]].flatten << v else opts[k] = v end end return opts end
Split single letter option groupings into separate options. ie. -xyz => -x -y -z
# File lib/facets/supplemental/facets/argvector.rb, line 316 def multi_flag(args=nil) args ||= argv args.collect { |arg| if md = /^-(\w{2,})/.match( arg ) md[1].split(//).collect { |c| "-#{c}" } else arg.dup end }.flatten end
Returns operand array.
# File lib/facets/supplemental/facets/argvector.rb, line 90 def operands @operands end
Returns options hash.
# File lib/facets/supplemental/facets/argvector.rb, line 98 def options @options end
Returns [operands, options], which is good for plugging directly into a method.
# File lib/facets/supplemental/facets/argvector.rb, line 104 def parameters return @operands, @options end
Like parameters but without allowing for duplicate options.
# File lib/facets/supplemental/facets/argvector.rb, line 181 def parameters_without_duplicates opts = {} @options.each do |k,v| if Array===v opts[k] = v[0] else opts[k] = v end end return @operands, opts end
Basic parser partitions the command line into options and operands. Options are converted to a hash and the two parts are returned.
line = "--trace stamp --file=VERSION" argv = Argvector.new(line) args, keys = *argv.parse args #=> ["stamp"] keys #=> {"trace"=>true, "file"=>"VERSION"}
# File lib/facets/supplemental/facets/argvector.rb, line 207 def parse args = assoc_options(argv) #, *opts_arity) opts, opds = args.partition{ |a| Array === a } @operands = opds @options = format_options(opts) return @operands, @options end
Ensure arity is uniform.
# File lib/facets/supplemental/facets/argvector.rb, line 245 def parse_arity(arity) arity2 = {} arity.each{ |k,v| arity2[k.to_s] = v.to_i } return arity2 end
First pass parser to split the command line into an array using Shellwords, if not already so divided.
# File lib/facets/supplemental/facets/argvector.rb, line 220 def parse_line(line=nil) if line case line when String argv = Shellwords.shellwords(line) else argv = line.to_ary.dup line = argv.join(' ') end else argv = ARGV.dup line = argv.join(' ') end return line, argv end
Parse preoptions. A "preoption" is one that occurs before the first operans (if any).
# File lib/facets/supplemental/facets/argvector.rb, line 253 def parse_preoptions(args) ##args = args.dup args = multi_flag(args) #unless opts.include?(:simple) flags = [] while args.first =~ /^-/ key = args.shift key.sub!(/^-{1,2}/,'') if key.index('=') key, val = key.split('=') elsif a = arity[key] val = args.slice!(0,a) val = val.first if a == 1 else val = true end flags << [key, val] end flags = format_options(flags) return flags, args end
Same as flags but only returns flags in the preoptions.
# File lib/facets/supplemental/facets/argvector.rb, line 169 def preflags preopts, remainder = *parse_preoptions(argv) f = [] preopts.each do |k, v| if TrueClass===v or FalseClass===v # not that it's ever false f << k end end return f end
Returns a hash of options that occur before the first operand. This works well with subcommand to get the main command's options.
line = "--trace stamp --file VERSION" cargs = Argvector.new(line) opts = cargs.preoptions opts #=> {"trace"=>true}
# File lib/facets/supplemental/facets/argvector.rb, line 162 def preoptions preopts, remainder = *parse_preoptions(argv) return preopts end
Assumes the first operand is a "subcommand" and returns it and the argments following it as another Arguments object.
TODO: This probably should be called 'subcommand'.
# File lib/facets/supplemental/facets/argvector.rb, line 146 def subcommand_with_arguments opts, args = *parse_preoptions(argv) cmd = args.shift subargs = self.class.new(args, @arity) return cmd, subargs end
Assumes the first operand is a "subcommand" and returns it and the argments following it as parameters.
# File lib/facets/supplemental/facets/argvector.rb, line 122 def subcommand_with_parameters opts, args = *parse_preoptions(argv) cmd = args.shift subargs = self.class.new(args, @arity) return [cmd, *subargs.parameters] end
# File lib/facets/supplemental/facets/argvector.rb, line 132 def subcommand_with_preoptions pre, args = *parse_preoptions(argv) cmd = args.shift subargs = self.class.new(args, @arity) args, opts = *subargs.parameters return [cmd, args, pre.merge(opts)] end
Generated with the Darkfish Rdoc Generator 2.