Clint, a Ruby command line argument parser
I’m programming in Ruby these days and feel more strongly than ever that DSLs are (usually) evil. The only DSL I’ve ever met that I liked is Sinatra. So I arrived to the menagerie of Ruby command line argument parsers ready to be let down. For the sake of documentation, here’s a list of libraries I rejected:
- OptionParser: the undocumented, documentation-generating standard.
- Choice: Chris Wanstrath’s DSL.
- Trollop: generates documentation, too!
- Array: seriously, just use
Array#delete, dude.
I won’t insult the authors by debunking their hard work individually. I prefer to use the language syntax over DSL methods. I prefer to hand-craft usage and help messages rather than sprinkle partial documentation throughout my code. Finally, I want some support in implementing subcommand-style interfaces a la git, svn, and apt-get. With that, here’s Clint.
This example will create a command line tool for this class.
class FooBar
def initialize(foo)
@foo = foo
end
def foo
puts "FooBar#foo @foo: #{@foo}"
end
def self.bar(options={})
puts "FooBar.bar options[:thing]: #{options[:thing]}"
end
end
The command line tool first sets up usage and help messages. Next, it reacts to the global -h and --help options, which are bundled into options[:help] because of the :h => :help alias. Finally, it executes subcommands from the FooBar class, declaring the -t and --thing options for the bar subcommand.
require 'clint'
c = Clint.new
c.usage do
$stderr.puts <<EOF
Usage: #{File.basename(__FILE__)} foo <foo>
#{File.basename(__FILE__)} bar [-t <thing>] [--thing=<thing>]
#{File.basename(__FILE__)} [-h|--help]
EOF
end
c.help do
$stderr.puts <<EOF
-t <thing>, --thing=<thing> OH HAI
-h, --help show this help message
EOF
end
c.options :help => false, :h => :help
c.parse ARGV
if c.options[:help]
c.help
exit 1
end
c.subcommand FooBar do |subcommand|
if :bar == subcommand
c.options :thing => String, :t => :thing
end
c.parse
end
The README goes into more detail. Read the code on GitHub or gem install clint from Gemcutter.