Method: CommandMapper::Command.subcommand

Defined in:
lib/command_mapper/command.rb

.subcommand(name) {|subcommand| ... } ⇒ Object

Note:

Also defines a class within the command class using the subcommand's name.

Defines a subcommand.

Examples:

Defining a sub-command:

class Git
  command 'git' do
    subcommand 'clone' do
      option '--bare'
      # ...
    end
  end
end

Parameters:

  • name (String)

    The name of the subcommand.

Yields:

  • (subcommand)

    The given block will be used to populate the subcommand's options.

Yield Parameters:

  • subcommand (Command)

    The newly created subcommand class.

Raises:

  • (ArgumentError)

    The subcommand name conflicts with a pre-existing internal method, or another option or argument.


585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
# File 'lib/command_mapper/command.rb', line 585

def self.subcommand(name,&block)
  name            = name.to_s
  method_name     = name.tr('-','_')
  class_name      = name.split(/[_-]+/).map(&:capitalize).join
  subcommand_name = method_name.to_sym

  if is_internal_method?(method_name)
    raise(ArgumentError,"subcommand #{name.inspect} maps to method name ##{method_name} and cannot override the internal method with same name: ##{method_name}")
  elsif has_option?(subcommand_name)
    raise(ArgumentError,"subcommand #{name.inspect} conflicts with another option with the same name")
  elsif has_argument?(subcommand_name)
    raise(ArgumentError,"subcommand #{name.inspect} conflicts with another argument with the same name")
  end

  subcommand_class = Class.new(Command)
  subcommand_class.command(name)
  subcommand_class.class_eval(&block)

  self.subcommands[subcommand_name] = subcommand_class
  const_set(class_name,subcommand_class)

  define_method(method_name) do |&block|
    if block then @command_subcommand = subcommand_class.new(&block)
    else          @command_subcommand
    end
  end

  define_method(:"#{method_name}=") do |options|
    @command_subcommand = if options
                            subcommand_class.new(options)
                          end
  end
end