Commander

The complete solution for Ruby command-line executables.
Commander bridges the gap between other terminal related libraries
you know and love (OptionParser, HighLine), while providing many new
features, and an elegant API.

Multi-word command name support such as drupal module install MOD, rather than drupal module_install MOD

Sexy paging for long bodies of text

Support for MacOS text-to-speech

Command aliasing (very powerful, as both switches and arguments can be used)

Growl notification support for MacOS

Use the commander executable to initialize a commander driven program

Installation

$ gem install commander

Quick Start

To generate a quick template for a commander app, run:

$ commander init yourfile.rb

Example

For more option examples view the Commander::Command#option method. Also
an important feature to note is that action may be a class to instantiate,
as well as an object, specifying a method to call, so view the RDoc for more information.

Classic style

require'rubygems'require'commander/import'# :name is optional, otherwise uses the basename of this executable
program:name,'Foo Bar'program:version,'1.0.0'program:description,'Stupid command that prints foo or bar.'command:foodo|c|c.syntax='foobar foo'c.description='Displays foo'c.actiondo|args,options|say'foo'endendcommand:bardo|c|c.syntax='foobar bar [options]'c.description='Display bar with optional prefix and suffix'c.option'--prefix STRING',String,'Adds a prefix to bar'c.option'--suffix STRING',String,'Adds a suffix to bar'c.actiondo|args,options|options.default:prefix=>'(',:suffix=>')'say"#{options.prefix}bar#{options.suffix}"endend

Block style

require'rubygems'require'commander'Commander.configuredoprogram:name,'Foo Bar'program:version,'1.0.0'program:description,'Stupid command that prints foo or bar.'# see classic style example for options
end

HighLine

As mentioned above, the highline gem is imported into the global scope. Here
are some quick examples for how to utilize highline in your commands:

# Ask for password masked with '*' character
ask("Password: "){|q|q.echo="*"}# Ask for password
ask("Password: "){|q|q.echo=false}# Ask if the user agrees (yes or no)
agree("Do something?")# Asks on a single line (note the space after ':')
ask("Name: ")# Asks with new line after "Description:"
ask("Description:")# Calls Date#parse to parse the date string passed
ask("Birthday? ",Date)# Ensures Integer is within the range specified
ask("Age? ",Integer){|q|q.in=0..105}# Asks for a list of strings, converts to array
ask("Fav colors?",Array)

HighLine & Interaction Additions

In addition to highline's fantastic choice of methods, commander adds the
following methods to simplify common tasks:

# Ask for password
password# Ask for password with specific message and mask character
password"Enter your password please:",'-'# Ask for CLASS, which may be any valid class responding to #parse. Date, Time, Array, etc
names=ask_for_array'Names: 'bday=ask_for_date'Birthday?: '# Simple progress bar (Commander::UI::ProgressBar)
uris=%w[
http://vision-media.ca http://google.com http://yahoo.com]progressurisdo|uri|res=openuri# Do something with response
end# 'Log' action to stdout
log"create","path/to/file.rb"# Enable paging of output after this point
enable_paging# Ask editor for input (EDITOR environment variable or whichever is available: TextMate, vim, vi, emacs, nano, pico)
ask_editor# Ask editor, supplying initial text
ask_editor'previous data to update'# Ask editor, preferring a specific editor
ask_editor'previous data','vim'# Choose from an array of elements
choice=choose("Favorite language?",:ruby,:perl,:js)# Alter IO for the duration of the block
ionew_input,new_outputdonew_input_contents=$stdin.readputsnew_input_contents# outputs to new_output stream
end# $stdin / $stdout reset back to original streams
# Speech synthesis
speak'What is your favorite food? 'food=ask'favorite food?: 'speak"Wow, I like #{food} too. We have so much in common."speak"I like #{food} as well!","Victoria",190# Execute arbitrary applescript
applescript'foo'# Converse with speech recognition server
caseconverse'What is the best food?',:cookies=>'Cookies',:unknown=>'Nothing'when:cookiesspeak'o.m.g. you are awesome!'elsecaseconverse'That is lame, shall I convince you cookies are the best?',:yes=>'Ok',:no=>'No',:maybe=>'Maybe another time'when:yesspeak'Well you see, cookies are just fantastic, they melt in your mouth.'elsespeak'Ok then, bye.'endend

Growl Notifications

Commander provides methods for displaying Growl notifications. To use these
methods you need to install http://github.com/tj/growl which utilizes
the growlnotify executable. Note that
growl is auto-imported by Commander when available, no need to require.

Command Defaults

Although working with a command executable framework provides many
benefits over a single command implementation, sometimes you still
want the ability to create a terse syntax for your command. With that
in mind we may use #default_command to help with this. Considering
our previous :'install gem' example:

default_command:update

$ foo
# => installing rubygems to some_path

Keeping in mind that commander searches for the longest possible match
when considering a command, so if you were to pass arguments to foo
like below, expecting them to be passed to :update, this would be incorrect,
and would end up calling :'install gem', so be careful that the users do
not need to use command names within the arguments.

$ foo install gem
# => installing to

Additional Global Help

Arbitrary help can be added using the following #program symbol:

program:help,'Author','TJ Holowaychuk <tj@vision-media.ca>'

Which will output the rest of the help doc, along with:

AUTHOR:
TJ Holowaychuk <tj@vision-media.ca>

Global Options

Although most switches will be at the command level, several are available by
default at the global level, such as --version, and --help. Using
#global_option you can add additional global options:

This abstraction could be utilized to generate HTML documentation for your executable.

Tracing

By default the -t and --trace global options are provided to allow users to get a backtrace to aid debugging.

You can disable these options:

never_trace!

Or make it always on:

always_trace!

Tips

When adding a global or command option, OptionParser implicitly adds a small
switch even when not explicitly created, for example -c will be the same as
--config in both examples, however -c will only appear in the documentation
when explicitly assigning it.