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.