File: README.md

package info (click to toggle)
ruby-commander 4.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 360 kB
  • sloc: ruby: 1,971; makefile: 9
file content (475 lines) | stat: -rw-r--r-- 12,471 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
[<img src="https://api.travis-ci.org/commander-rb/commander.svg" alt="Build Status" />](https://travis-ci.org/commander-rb/commander)
[![Inline docs](https://inch-ci.org/github/commander-rb/commander.svg)](https://inch-ci.org/github/commander-rb/commander)

# 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.

## Features

* Easier than baking cookies
* Parses options using OptionParser
* Auto-populates struct with options ( no more `{ |v| options[:recursive] = v }` )
* Auto-generates help documentation via pluggable help formatters
* Optional default command when none is present
* Global / Command level options
* Packaged with two help formatters (Terminal, TerminalCompact)
* Imports the highline gem for interacting with the terminal
* Adds additional user interaction functionality
* Highly customizable progress bar with intuitive, simple usage
* 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

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

    $ commander init --modular 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

```ruby
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 :foo do |c|
  c.syntax = 'foobar foo'
  c.description = 'Displays foo'
  c.action do |args, options|
    say 'foo'
  end
end

command :bar do |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.action do |args, options|
    options.default :prefix => '(', :suffix => ')'
    say "#{options.prefix}bar#{options.suffix}"
  end
end
```

Example output:

```
$ foobar bar
# => (bar)

$ foobar bar --suffix '}' --prefix '{'
# => {bar}
```

### Modular style

**NOTE:** Make sure to use `require 'commander'` rather than `require 'commander/import'`, otherwise Commander methods will still be imported into the global namespace.

```ruby
require 'rubygems'
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__
```

### Block style

```ruby
require 'rubygems'
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
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:

```ruby
# 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:

```ruby
# 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
]
progress uris do |uri|
  res = open uri
  # 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
io new_input, new_output do
  new_input_contents = $stdin.read
  puts new_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
case converse 'What is the best food?', :cookies => 'Cookies', :unknown => 'Nothing'
when :cookies
  speak 'o.m.g. you are awesome!'
else
  case converse 'That is lame, shall I convince you cookies are the best?', :yes => 'Ok', :no => 'No', :maybe => 'Maybe another time'
  when :yes
    speak 'Well you see, cookies are just fantastic, they melt in your mouth.'
  else
    speak 'Ok then, bye.'
  end
end
```

## Growl Notifications

Commander provides methods for displaying Growl notifications. To use these
methods you need to install https://github.com/tj/growl which utilizes
the [growlnotify](https://growl.info/extras.php#growlnotify) executable. Note that
growl is auto-imported by Commander when available, no need to require.

```ruby
# Display a generic Growl notification
notify 'Something happened'

# Display an 'info' status notification
notify_info 'You have #{emails.length} new email(s)'

# Display an 'ok' status notification
notify_ok 'Gems updated'

# Display a 'warning' status notification
notify_warning '1 gem failed installation'

# Display an 'error' status notification
notify_error "Gem #{name} failed"
```

## Commander Goodies

### Option Defaults

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.

```ruby
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
end
```

### Command Aliasing

Aliases can be created using the `#alias_command` method like below:

```ruby
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:

```ruby
command :'install gem' do |c|
  c.syntax = 'install gem <name> [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_path
```

### 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:

```ruby
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
```

### Long descriptions

If you need to have a long command description, keep your short description under `summary`, and consider multi-line strings for `description`:

```ruby
  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
  )
```

### Additional Global Help

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

```ruby
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:

```ruby
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:

```ruby
global_option('--verbose') { $verbose = true }
...
c.action do |args, options|
  say 'foo' if $verbose
...
```

You may:

```ruby
global_option '--verbose'
...
c.action do |args, options|
  say 'foo' if options.verbose
...
```

### Formatters

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:

```ruby
program :help_formatter, Commander::HelpFormatter::TerminalCompact
```

Or utilize the help formatter aliases:

```ruby
program :help_formatter, :compact
```

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:

```ruby
never_trace!
```

Or make it always on:

```ruby
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.

```ruby
global_option '-c', '--config FILE'
global_option '--config FILE'
```

## ASCII Tables

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! |
    +----------+-------+----+--------+-----------------------+

## Running Specifications

    $ rake spec

OR

    $ spec --color spec

## Contrib

Feel free to fork and request a pull, or submit a ticket
https://github.com/commander-rb/commander/issues

## License

This project is available under the MIT license. See LICENSE for details.