Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

152 lines (100 sloc) 4.075 kb

Subcommand

A tiny wrapper over ruby's awesome OptionParser (standard) which gives easy facility of subcommands. It has a similar interface to git and prints subcommands summary as well.

Options parsers are lazy-loaded thanks to a suggestion and sample code by Robert Klemme on ruby-forum.org. If your program already uses OptionParser, then one merely needs to add a line above each option declaration – no rewriting required since all OptionParser syntax is valid syntax for `subcommand`.

This wrapper adds the `description` attr to what OptionParser already provides.

Features

  1. subcommands using all of OptionParser's features

  2. aliases for subcommands

e.g Assuming a program “prog” with subcommands “del” and “add”

prog help
prog --help

prog help del
prog del --help

prog del --force file.a
prog --verbose del --force file.a

Examples

if a program has subcommands foo and baz

    ruby subcommand.rb help
    ruby subcommand.rb --help
    ruby subcommand.rb help foo
    ruby subcommand.rb foo --help
    ruby subcommand.rb baz --quiet "some text"
    ruby subcommand.rb --verbose foo --force file.zzz

STEPS

1. define global_options (optional)

 global_options do |opts|
   opts.banner = "Usage: subcommand.rb [options] [subcommand [options]]"
   opts.description = "Stupid program that does something"
   opts.separator ""
   opts.separator "Global options are:"
   opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
     options[:verbose] = v
   end
 end

2. define commands using command(). Send multiple names for aliases.

 command :foo do |opts|
   opts.banner = "Usage: foo [options]"
   opts.description = "desc for foo"
   opts.on("-f", "--[no-]force", "force action") do |v|
     options[:force] = v
   end
 end

 # aliases init and create
 command :init, :create do |opts| ...

 alias_command :zoo, 'foo' , '-f'
 alias_command :bar, 'baz' , 'ruby.txt'

3. call opt_parse()

selected_command_name = opt_parse()

Custom Completion

 The command list_actions can be called from your application, so that the user
 can have custom completion.

  opts.on("--list-actions", "list actions for autocompletion ") do |v|
    Subcommands::list_actions
    exit 0
  end

Now we can place something like this in a configuration file. Here's what i placed
in .zshrc for bugzyrb.

  _bugzyrb() {
          reply=(`bugzyrb --list-actions`)
      }
  compctl -K _bugzyrb bugzyrb

Now, on the command line when I type "bugzyrb <TAB>" the actions are prompted in a menu.

Sample Output

$ ruby subcommand.rb help

Usage: subcommand.rb [options] [subcommand [options]]
Stupid program that does something

Global options are:
    -v, --[no-]verbose               Run verbosely

Commands are:
   foo : desc for foo
   baz : desc for baz

Aliases: 
   goo - foo

See 'subcommand.rb help COMMAND' for more information on a specific command.

$ ruby subcommand.rb help foo

Usage: foo [options]
desc for foo
    -f, --[no-]force                 force action

Install

sudo gem install subcommand

Or, copy into your lib directory and require (see source for sample usage)

Testing

This comes with a bunch of test cases, that I think cover all cases including printing help for aliases.

make test

You should have no errors. The test cases are in the *tests* folder.

RDOC

subcommand.rubyforge.org/doc/

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don't break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Copyright

Copyright © 2010 Rahul Kumar. See LICENSE for details.

Jump to Line
Something went wrong with that request. Please try again.