/subcommand

A tiny ruby wrapper over OptionParser giving simple, elegant subcommand facility for command line programs (CLI)

Primary LanguageShellMIT LicenseMIT

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'
  1. 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

http://subcommand.rubyforge.org/doc/

== Copyright

Copyright (c) 2010-2019 Rahul Kumar. See LICENSE for details.

== Others

This simple gem is still working fine. No need for a new release.
Working with ruby 1.9 through 2.6. And now ruby 3.1.2p20.