public
Created

Simple option parser

  • Download Gist
parseopt.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
class ParseOpt
attr_writer :usage
 
class Option
attr_reader :short, :long, :help
 
def initialize(short, long, help, &block)
@block = block
@short = short
@long = long
@help = help
end
 
def call(v)
@block.call(v)
end
end
 
def initialize
@list = {}
end
 
def on(short = nil, long = nil, help: nil, &block)
opt = Option.new(short, long, help, &block)
@list[short] = opt if short
@list[long] = opt if long
end
 
def parse
if ARGV.member?('-h') or ARGV.member?('--help')
usage
exit 0
end
seen_dash = false
ARGV.delete_if do |cur|
opt = val = nil
next false if cur[0] != '-' or seen_dash
case cur
when '--'
seen_dash = true
next true
when /^--no-(.+)$/
opt = @list[$1]
val = false
when /^-([^-])(.+)?$/, /^--(.+?)(?:=(.+))?$/
opt = @list[$1]
val = $2 || true
end
if opt
opt.call(val)
true
else
usage
exit 1
end
end
end
 
def usage
def fmt(prefix, str)
return str ? prefix + str : nil
end
puts 'usage: %s' % @usage
@list.values.uniq.each do |opt|
s = ' '
s << ''
s << [fmt('-', opt.short), fmt('--', opt.long)].compact.join(', ')
s << ''
s << '%*s%s' % [26 - s.size, '', opt.help] if opt.help
puts s
end
end
 
end
 
$str = "default"
$num = 0
$bool = false
 
opts = ParseOpt.new
opts.usage = "git foo"
 
opts.on("b", "bool", help: "Boolean") do |v|
$bool = v
end
 
opts.on("s", "string", help: "String") do |v|
$str = v
end
 
opts.on("n", "number", help: "Number") do |v|
$num = v.to_i
end
 
opts.parse

Really nice and usefull. Thanks!

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.