Parent

Clio::Commandline

Commandline

Clio’s Commandline class is a very versitile command line parser. A Command can be used either declaritively, defining usage and help information upfront; or lazily, whereby information about usage is built-up as the commandline actually gets use in one’s program; or you can use a mixture of the two.

Underlying Notation

As you might expect the fluent notation can be broken down into block notation.

cli = Clio::Command.new
cli.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 easier to read, but fluent notation is important to have because it allows the Commandline object to be passed around as an argument and modified easily.

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.

cli.usage.document('*files', '--output=FILE -o')
cli.usage('--verbose -V','--quiet -q')

cli.usage.help(
  'document'     , 'generate documentation',
  'validate'     , 'run tests or specifications',
  '--verbose'    , 'verbose output',
  '--quiet'      , 'run siltently'
)

cli.usage.document.help(
  '--output', 'output directory'
  'file*',    'files to document'
)

This notation is slightly more limited in scope… so…

cli.usage.command(:document, '--output=FILE -o', 'files*')

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.

cli.usage['document']['--output=FILE -o']['FILE*']

Using a little creativity to improve readabilty we can convert the whole example from above using this notation.

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

cli.usage['--verbose -V']['--quiet -q'] \
         ['document']['--output=FILE -o']['FILE*']

cli.usage.help(
  'document'  , 'generate documentation',
  'validate'  , 'run tests or specifications',
  '--verbose' , 'verbose output',
  '--quiet'   , 'run siltently'
)

cli.usage['document'].help(
  '--output', 'output directory'
  'FILE',     'files to docment'
)

A little more verbose, but a bit more intutive.

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.

cli.usage.document['--output=FILE -o']['file*']
cli.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.

Commandline Parsing

With usage in place, call the parse method to process the actual commandline.

cli.parse

If no command arguments are passed to parse, ARGV is used.

Usage Cache

Lastly, Commandline provides a simple means to cache usage information to a configuration file, which then can be used again the next time the same command is used. This allows Commandline to provide high-performane tab completion.

Public Class Methods

argument(*n_type, &block) click to toggle source
# File lib/clio/commandline.rb, line 225
def argument(*n_type, &block)
  usage.argument(*n_type, &block)
end
cmd(name, help=nil, &block) click to toggle source
Alias for: subcommand
command(name, help=nil, &block) click to toggle source
Alias for: subcommand
help(string=nil) click to toggle source
# File lib/clio/commandline.rb, line 230
def help(string=nil)
  usage.help(string)
end
new(argv=nil, opts={}, &block) click to toggle source

New Command.

# File lib/clio/commandline.rb, line 242
def initialize(argv=nil, opts={}, &block)
  argv_set(argv || ARGV)
  #if opts[:usage]
  #  @usage = opts[:usage]
  #else
  #  #@usage = load_cache
  #end
  if self.class == Commandline
    @usage = Usage.new
  else
    @usage = self.class.usage #|| Usage.new
  end
  @usage.instance_eval(&block) if block
end
opt(label, help, &block) click to toggle source
# File lib/clio/commandline.rb, line 219
def opt(label, help, &block)
  usage.opt(label, help, &block)
end
Also aliased as: swt
option(name, *aliases, &block) click to toggle source
# File lib/clio/commandline.rb, line 213
def option(name, *aliases, &block)
  usage.option(name, *aliases, &block)
end
Also aliased as: switch
subcommand(name, help=nil, &block) click to toggle source
# File lib/clio/commandline.rb, line 206
def subcommand(name, help=nil, &block)
  usage.subcommand(name, help, &block)
end
Also aliased as: command, cmd
switch(name, *aliases, &block) click to toggle source
Alias for: option
swt(label, help, &block) click to toggle source
Alias for: opt
usage() click to toggle source

Command usage.

# File lib/clio/commandline.rb, line 190
def usage
  @usage ||= (
    if ancestors[1] < Commandline
      ancestors[1].usage.dup
    else
      Usage.new
    end
  )
end
usage=(u) click to toggle source
# File lib/clio/commandline.rb, line 200
def usage=(u)
  raise ArgumentError unless u <= Usage
  @usage = u
end

Public Instance Methods

[](i) click to toggle source
# File lib/clio/commandline.rb, line 311
def [](i)
  @cli[i]
end
arguments() click to toggle source
# File lib/clio/commandline.rb, line 322
def arguments  ; cli.arguments  ; end
argv_set(argv) click to toggle source
# File lib/clio/commandline.rb, line 258
def argv_set(argv)
  # reset parser
  @parser = nil
  # convert to array if string
  if String===argv
    argv = Shellwords.shellwords(argv)
  end
  # remove anything subsequent to '--'
  if index = argv.index('--')
    argv = argv[0...index]
  end
  @argv = argv
end
cli() click to toggle source
# File lib/clio/commandline.rb, line 273
def cli
  #parse unless @cli
  @cli
end
command() click to toggle source
# File lib/clio/commandline.rb, line 316
def command    ; cli.command    ; end
commands() click to toggle source
# File lib/clio/commandline.rb, line 319
def commands   ; cli.commands   ; end
completion(argv=nil) click to toggle source

TODO: adding ‘-’ is best idea?

# File lib/clio/commandline.rb, line 347
def completion(argv=nil)
  argv_set(argv) if argv
  @argv << "\t"
  parse
  @argv.pop
  parser.errors[0][1].completion.collect{ |s| s.to_s }
  #@argv.pop if @argv.last == '?'
  #load_cache
  #parse
end
method_missing(s, *a) click to toggle source

Method missing provide passive usage and parsing.

TODO: This reparses the commandline after every query.

Need only parse if usage has change.
# File lib/clio/commandline.rb, line 369
def method_missing(s, *a)
  begin
    s = s.to_s
    case s
    when /[=]$/
      n = s.chomp('=')
      usage.option(n).type(*a)
      parse
      res = @cli.options[n.to_sym]
    when /[!]$/
      n = s.chomp('!')
      cmd = usage.commands[n.to_sym] || usage.command(n, *a)
      res = parse
    when /[?]$/
      n = s.chomp('?')
      u = usage.option(n, *a)
      parse
      res = @cli.options[u.key]
    else
      usage.option(s, *a)
      parse
      res = @cli.options[s.to_sym]
    end
  rescue Usage::ParseError => e
    res = nil
  end
  return res
end
options() click to toggle source
Alias for: switches
parameters() click to toggle source

Parameters

# File lib/clio/commandline.rb, line 332
def parameters ; cli.parameters ; end
parse(argv=nil) click to toggle source
# File lib/clio/commandline.rb, line 300
def parse(argv=nil)
  argv_set(argv) if argv
  @cli = parser.parse
end
parser() click to toggle source
# File lib/clio/commandline.rb, line 306
def parser
  @parser ||= Usage::Parser.new(usage, @argv)
end
switches() click to toggle source
# File lib/clio/commandline.rb, line 325
def switches   ; cli.options    ; end
Also aliased as: options
to_a() click to toggle source
# File lib/clio/commandline.rb, line 335
def to_a
  cli.to_a
end
to_s() click to toggle source
# File lib/clio/commandline.rb, line 290
def to_s
  usage.to_s
end
to_s_help() click to toggle source
# File lib/clio/commandline.rb, line 295
def to_s_help
  usage.to_s_help
end
usage() click to toggle source

def usage(name=nil, &block)

@usage ||= Usage.new(name)
@usage.instance_eval(&block) if block
@usage

end

# File lib/clio/commandline.rb, line 285
def usage
  @usage
end
valid?() click to toggle source

Commandline fully valid?

# File lib/clio/commandline.rb, line 341
def valid?
  @cli.valid?
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.