From a99652216343fa618a1a54d73d901de26f9be741 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sat, 28 Sep 2013 07:03:38 -0500 Subject: [PATCH] ruby: add simpler option parser Signed-off-by: Felipe Contreras --- git-rb-setup.rb | 75 ++++++++++++++++++++++++++++ t/t9710-ruby.sh | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+) diff --git a/git-rb-setup.rb b/git-rb-setup.rb index 6f283da0fe..cd2502f0fb 100644 --- a/git-rb-setup.rb +++ b/git-rb-setup.rb @@ -32,3 +32,78 @@ class String return self[prefix.length..-1] end end + +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 diff --git a/t/t9710-ruby.sh b/t/t9710-ruby.sh index d04c32abf6..082c1b7eb9 100755 --- a/t/t9710-ruby.sh +++ b/t/t9710-ruby.sh @@ -108,4 +108,130 @@ test_expect_success 'test Commit' ' test_cmp expected actual ' +test_expect_success 'test ParseOpt' ' + cat > parse-script <<"EOF" + $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 + + p(ARGV) + p({ :bool => $bool, :str => $str, :num => $num }) + EOF + + git ruby parse-script > actual && + cat > expected <<-EOF && + [] + {:bool=>false, :str=>"default", :num=>0} + EOF + test_cmp expected actual && + + git ruby parse-script --bool > actual && + cat > expected <<-EOF && + [] + {:bool=>true, :str=>"default", :num=>0} + EOF + test_cmp expected actual && + + git ruby parse-script -b > actual && + cat > expected <<-EOF && + [] + {:bool=>true, :str=>"default", :num=>0} + EOF + test_cmp expected actual && + + git ruby parse-script --string=foo > actual && + cat > expected <<-EOF && + [] + {:bool=>false, :str=>"foo", :num=>0} + EOF + test_cmp expected actual && + + git ruby parse-script -sfoo > actual && + cat > expected <<-EOF && + [] + {:bool=>false, :str=>"foo", :num=>0} + EOF + test_cmp expected actual && + + git ruby parse-script --number=10 > actual && + cat > expected <<-EOF && + [] + {:bool=>false, :str=>"default", :num=>10} + EOF + test_cmp expected actual && + + git ruby parse-script --bool --string=bar --number=-20 > actual && + cat > expected <<-EOF && + [] + {:bool=>true, :str=>"bar", :num=>-20} + EOF + test_cmp expected actual && + + git ruby parse-script --help > actual && + cat > expected <<-EOF && + usage: git foo + -b, --bool Boolean + -s, --string String + -n, --number Number + EOF + test_cmp expected actual && + + git ruby parse-script --help > actual && + cat > expected <<-EOF && + usage: git foo + -b, --bool Boolean + -s, --string String + -n, --number Number + EOF + test_cmp expected actual && + + test_must_fail git ruby parse-script --bad > actual && + cat > expected <<-EOF && + usage: git foo + -b, --bool Boolean + -s, --string String + -n, --number Number + EOF + test_cmp expected actual && + + git ruby parse-script one --bool two --string=bar three --number=-20 mambo > actual && + cat > expected <<-EOF && + ["one", "two", "three", "mambo"] + {:bool=>true, :str=>"bar", :num=>-20} + EOF + test_cmp expected actual && + + git ruby parse-script one --bool two -- --three four > actual && + cat > expected <<-EOF && + ["one", "two", "--three", "four"] + {:bool=>true, :str=>"default", :num=>0} + EOF + test_cmp expected actual && + + git ruby parse-script one --bool --no-bool > actual && + cat > expected <<-EOF && + ["one"] + {:bool=>false, :str=>"default", :num=>0} + EOF + cat actual + test_cmp expected actual +' + test_done -- 2.32.0.93.g670b81a890