module Clio::Usage
Usage¶ ↑
Uasge provides a verstile but easy to use system of describing a commandline interface.
Underlying Fluent and Block Notation¶ ↑
Underlying all usage is a fluent interface for decalaring a commandline's structure. Here is an example of using this DSL, albeit rather brutely.
usage = Clio::Usage.new usage.command(:document).help('generate documentation') usage.command(:document).option(:output, :o).type('FILE') usage.command(:document).option(:output).help('output directory') usage.option(:verbose, :V).help('verbose output') usage.option(:quiet, :q).help('run silently').xor(:V)
The example defines a subcommand 'document' that can take an 'output' option, and two mutually excluive universal options, 'verbose' and 'quiet', with respective one-letter aliases.
As you might expect the fluent notation can be broken down into block notation which is easier to read.
usage = Usage.new usage do option(:verbose, :v) do help('verbose output') end option(:quiet, :q) do help('run silently') xor(:V) end command(:document) do help('generate documentation') option(:output, :o) do type('FILE') help('output directory') end argument('files') do multiple end end end
Clearly block notation is DRY and more elegant the the previous fluent version, but fluent notation is important because it allows the usage object to be easily passed around and augmented as needed.
Method Notation¶ ↑
This notation is very elegant, but slightly more limited in scope. For instance, subcommands that use non-letter characters, such as ':', can not be described with this notation.
usage.document('<file*>', '--output=FILE -o') usage('--verbose -V','--quiet -q') usage.help( 'document' , 'generate documentation', 'validate' , 'run tests or specifications', '--verbose' , 'verbose output', '--quiet' , 'run siltently' ) usage.document.help( '--output', 'output directory' 'file*', 'files to document' )
This notation is slightly more limited in scope… so…
usage.command(:document, '--output=FILE -o', '<file*>')
Bracket Shorthand Notation¶ ↑
The core notation can be somewhat verbose. As a further convenience commandline usage can be defined with a brief bracket shorthand. This is especailly useful when the usage is simple and statically defined.
usage['document']['--output=FILE -o']['FILE*']
Using a little creativity to improve readabilty we can convert the whole example from above using this notation.
usage['--verbose -V', 'verbose output' ] ['--quiet -q', 'run silently' ] ['document', 'generate documention' ] [ '--output=FILE -o', 'output directory' ] [ 'FILE*', 'files to document' ]
Alternately the help information can be left out and defined in a seprate set of usage calls.
usage['--verbose -V']['--quiet -q'] \ ['document']['--output=FILE -o']['FILE*'] usage.help( 'document' , 'generate documentation', 'validate' , 'run tests or specifications', '--verbose' , 'verbose output', '--quiet' , 'run siltently' ) usage['document'].help( '--output', 'output directory' 'FILE', 'files to docment' )
A little more verbose, but a bit more intutive.
“Alien” Notation¶ ↑
As a side note, it is easy enough to alias [] to #_, so alternatively one code create a variant shorthand written as:
usage do _ '--verbose -V', 'verbose output' _ '--quiet -q', 'run silently' _ 'document', 'generate documentation' do _ '--output=FILE -o', 'output directory' _ 'FILE*', 'files to document' end end
To demonsrtate it's equvalence to bracket shorthand, it can be chained as well.
usage._('document')._('--output=FILE -o')._('FILE*')
This notation is not supported by default, but if it is more your style it is easy enough to implement by extending Clio::Usage::Command like this:
class Clio::Usage::Command alias_method :_, :[] end
Combining Notations¶ ↑
Since the various notations all translate to same underlying structures, they can be mixed and matched as suites ones taste. For example we could mix Method Notation and Bracket Notation.
usage.document['--output=FILE -o']['file*'] usage['--verbose -V']['--quiet -q']
The important thing to keep in mind when doing this is what is returned by each type of usage call.
Public Class Methods
# File lib/clio/usage.rb, line 177 def self.new(name=nil, &block) Command.new(name, &block) end