The complete solution for Ruby command-line executables
The complete solution for Ruby command-line executables
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.
{ |v| options[:recursive] = v } )drupal module install MOD, rather than drupal module_install MODcommander executable to initialize a commander driven programRuby >= 3.1 (tested through Ruby 4.0).
$ gem install commanderTo generate a quick template for a commander app, run:
$ commander init yourfile.rbTo generate a quick modular style template for a commander app, run:
$ commander init --modular yourfile.rbFor 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.
…Example output:
$ foobar bar
# => (bar)
$ foobar bar --suffix '}' --prefix '{'
# => {bar}NOTE: Make sure to use require 'commander' rather than require 'commander/import', otherwise Commander methods will still be imported into the global namespace.
require 'commander'
class MyApplication
include Commander::Methods
def run
program :name, 'Foo Bar'
program :version, '1.0.0'
program :description, 'Stupid command that prints foo or bar.'
command :foo do |c|
c.syntax = 'foobar foo'
c.description = 'Displays foo'
c.action do |args, options|
say 'foo'
end
end
run!
end
end
MyApplication.new.run if $0 == __FILE__require 'commander'
Commander.configure do
program :name, 'Foo Bar'
program :version, '1.0.0'
program :description, 'Stupid command that prints foo or bar.'
# see classic style example for options
endAs 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)In addition to highline's fantastic choice of methods, commander adds the following methods to simplify common tasks:
…The options struct passed to #action provides a #default method, allowing you
to set defaults in a clean manner for options which have not been set.
command :foo do |c|
c.option '--interval SECONDS', Integer, 'Interval in seconds'
c.option '--timeout SECONDS', Integer, 'Timeout in seconds'
c.action do |args, options|
options.default \
:interval => 2,
:timeout => 60
end
endAliases can be created using the #alias_command method like below:
command :'install gem' do |c|
c.action { puts 'foo' }
end
alias_command :'gem install', :'install gem'Or more complicated aliases can be made, passing any arguments as if it was invoked via the command line:
command :'install gem' do |c|
c.syntax = 'install gem [options]'
c.option '--dest DIR', String, 'Destination directory'
c.action { |args, options| puts "installing #{args.first} to #{options.dest}" }
end
alias_command :update, :'install gem', 'rubygems', '--dest', 'some_path'$ foo update
# => installing rubygems to some_pathAlthough 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_pathKeeping 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 toIf you need to have a long command description, keep your short description under summary, and consider multi-line strings for description:
program :summary, 'Stupid command that prints foo or bar.'
program :description, %q(
#{c.summary}
More information about that stupid command that prints foo or bar.
And more
)Arbitrary help can be added using the following #program symbol:
program :help, 'Author', 'TJ Holowaychuk 'Which will output the rest of the help doc, along with:
AUTHOR:
TJ Holowaychuk 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:
global_option('-c', '--config FILE', 'Load config data for your commands to use') { |file| ... }This method accepts the same syntax as Commander::Command#option so check it out for documentation.
All global options regardless of providing a block are accessable at the command level. This means that instead of the following:
global_option('--verbose') { $verbose = true }
...
c.action do |args, options|
say 'foo' if $verbose
...You may:
global_option '--verbose'
...
c.action do |args, options|
say 'foo' if options.verbose
...Two core formatters are currently available, the default Terminal formatter
as well as TerminalCompact. To utilize a different formatter simply use
:help_formatter like below:
program :help_formatter, Commander::HelpFormatter::TerminalCompactOr utilize the help formatter aliases:
program :help_formatter, :compactThis abstraction could be utilized to generate HTML documentation for your executable.
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!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.
global_option '-c', '--config FILE'
global_option '--config FILE'For feature rich ASCII tables for your terminal app check out the terminal-table gem at https://github.com/tj/terminal-table
+----------+-------+----+--------+-----------------------+
| Terminal | Table | Is | Wicked | Awesome |
+----------+-------+----+--------+-----------------------+
| | | | | get it while its hot! |
+----------+-------+----+--------+-----------------------+$ bundle exec rake specOR
$ bundle exec rspecFeel free to fork and request a pull, or submit a ticket https://github.com/commander-rb/commander/issues
This project is available under the MIT license. See LICENSE for details.
No open issues yet, or sync has not completed.