Class: Opt::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/opt/command.rb

Direct Known Subclasses

Program

Defined Under Namespace

Classes: Result, Token

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, opts = {}) ⇒ Command

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Command.



31
32
33
34
35
36
# File 'lib/opt/command.rb', line 31

def initialize(name, opts = {})
  @name     = name.to_s.freeze
  @opts     = opts
  @options  = []
  @commands = []
end

Instance Attribute Details

#commandsArray<Command> (readonly)

List of registered subcommands.

Can be used to add manually created Opt::Commands but use with care as no collision or sanity checks are done.

Returns:

  • (Array<Command>)

    Subcommand list.



23
24
25
# File 'lib/opt/command.rb', line 23

def commands
  @commands
end

#nameObject (readonly)

The command name.



27
28
29
# File 'lib/opt/command.rb', line 27

def name
  @name
end

#optionsArray<Option> (readonly)

List of registered options for this command.

Can be used to add manually created Options but use with care as no collision or sanity checks are done.

Returns:

  • (Array<Option>)

    Option list.



14
15
16
# File 'lib/opt/command.rb', line 14

def options
  @options
end

Instance Method Details

#command(name, opts = {}) {|command| ... } ⇒ Command

Add a subcommand.

A command can either have subcommands or free-text options.

Examples:

opt.command 'add' do |cmd|
  cmd.option '--num, -n'
end

Parameters:

  • name (String, Symbol, #to_s)

    The command name. This token will be used to match when parsing arguments.

  • opts (Hash) (defaults to: {})

    Options.

Yields:

Yield Parameters:

  • command (Command)

    The new command.

Returns:

Raises:

  • (ArgumentError)

    An ArgumentError will be raised when the command already has a free-text option or if a command with the same name is already registered.

See Also:



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/opt/command.rb', line 118

def command(name, opts = {})
  if options.any?{|o| o.text? }
    raise ArgumentError.new \
      'Can only have subcommands OR free-text arguments.'
  end

  command = Command.new(name, opts)

  if commands.any?{|c| c.name == command.name }
    raise ArgumentError.new "Command `#{command.name}' already registered."
  end

  yield command if block_given?

  commands << command
  command
end

#defaultsHash<String, Object>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return hash with default values for all options.

Returns:

  • (Hash<String, Object>)

    Hash with option defaults.



142
143
144
# File 'lib/opt/command.rb', line 142

def defaults
  Hash[options.map{|o| [o.name, o.default] }]
end

#option(definition = nil, opts = {}, &block) ⇒ Object

Register a new option.

Examples:

An option named “help” triggered on “–help” or “-h”

command.option '--help, -h'

An option with exactly one argument

command.option '--level, -l', nargs: 1

An option with 2 or more arguments

command.option '--files', nargs: [2, :inf]
command.option '--files', nargs: [2, :infinity]
command.option '--files', nargs: [2, '*']

An option with 2 to 4 arguments and a specific name

command.option '--sum, -s, -a', nargs: (2..4), name: :accumulate

An option with 0 or more arguments

command.option '-x', nargs: '*'

An option with 1 or more arguments

command.option '-x', nargs: '+'

A free-text option

command.option 'file', name: :files, nargs: '*'

Parameters:

  • definition (String) (defaults to: nil)

    The option definition. Usually a command separated list of dashed command line switches. If definition is not dashed a free-text argument will be given. See Option#initialize for more information.

  • opts (Hash) (defaults to: {})

    Option hash passed to Option#initialize. Used to specify a name, number of arguments, etc.

Raises:

  • (ArgumentError)

    An ArgumentError is raised when a colliding option is already registered or you try do define a free-text option while already heaving a subcommand registered.

See Also:



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/opt/command.rb', line 77

def option(definition = nil, opts = {}, &block)
  option = Option.new(definition, opts, &block)

  if commands.any?
    raise ArgumentError.new \
      'Can only have subcommands OR free-text arguments.'
  end

  if (opt = options.find{|o| o.collide?(option) })
    raise "Option `#{definition}' collides with already " \
          "registered option: #{opt}"
  else
    options << option
  end
end

#parse(argv = ARGV) ⇒ Result

Parses given list of command line tokens.

Examples:

opt.parse %w(-fd command -x 56 --fuubar)

Parameters:

  • argv (Array<String>) (defaults to: ARGV)

    List of command line strings. Defaults to ARGV.

Returns:

  • (Result)

    Return a hash-like result object.

See Also:



159
160
161
162
163
164
165
166
# File 'lib/opt/command.rb', line 159

def parse(argv = ARGV)
  result = Result.new
  result.merge! defaults

  parse_argv! parse_tokens(argv.dup), result

  result
end

#parse_argv!(argv, result, options = []) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/opt/command.rb', line 170

def parse_argv!(argv, result, options = [])
  options += self.options

  while argv.any?
    next if options.any?{|o| o.parse!(argv, result) }

    if argv.first.text?
      if (cmd = commands.find{|c| c.name == argv.first.value })
        result.command << argv.shift.value
        cmd.parse_argv!(argv, result, options)
        next
      end
    end

    raise "Unknown option (#{argv.first.type}): #{argv.first}"
  end
end