Signed-off-by: Felipe Contreras <[email protected]>
---
Notes:
We could use Git's internap parseopt, but the resulting code in Ruby
wouldn't
look very good, and the complexity to bind it wouldn't be trivial either (I
tried).
Instead, let's use the advantage of Ruby blocks to set the variables to
their
right values and try to keep the code simple, and add more features as they
are
needed later on.
git-rb-setup.rb | 75 ++++++++++++++++++++++++++++++++
t/t10000-ruby.sh | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 203 insertions(+)
diff --git a/git-rb-setup.rb b/git-rb-setup.rb
index 6f283da..cd2502f 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/t10000-ruby.sh b/t/t10000-ruby.sh
index e5a397c..a365849 100755
--- a/t/t10000-ruby.sh
+++ b/t/t10000-ruby.sh
@@ -102,4 +102,132 @@ 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 &&
+
+ true
+'
+
test_done
--
1.8.4-fc
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html