class Thor::Group


tasks.
invocations to be done at the class method, which are not available to Thor
is that it invokes all tasks at once. It also include some methods that allows
Thor has a special class called Thor::Group. The main difference to Thor class

def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc:

:nodoc:

invoke and invoke_from_option class methods.
Shortcut to invoke with padding and block handling. Use internally by
def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc:
  shell.padding += 1
  result = if block_given?
    if block.arity == 2
      block.call(self, klass)
    else
      block.call(self, klass, task)
    end
  else
    invoke klass, task, *args
  end
  shell.padding -= 1
  result
end

def banner


thor class by another ways which is not the Thor::Runner.
The banner for this class. You can customize it if you are invoking the
def banner
  "#{self.namespace} #{self.arguments.map {|a| a.usage }.join(' ')}"
end

def baseclass #:nodoc:

:nodoc:
def baseclass #:nodoc:
  Thor::Group
end

def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc:

:nodoc:

shown recursively when invoking a generator.
Overwrite class options help to allow invoked generators options to be
def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc:
  group_options = {}
  get_options_from_invocations(group_options, class_options) do |klass|
    klass.send(:get_options_from_invocations, group_options, class_options)
  end
  group_options.merge!(extra_group) if extra_group
  super(shell, ungrouped_name, group_options)
end

def create_task(meth) #:nodoc:

:nodoc:
def create_task(meth) #:nodoc:
  tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil)
  true
end

def desc(description=nil)


description:: The description for this Thor::Group.
==== Parameters

in the superclass.
exists, tries to find the USAGE one folder above it, otherwise searches
The descrition for this Thor::Group. If none is provided, but a source root
def desc(description=nil)
  case description
    when nil
      @desc ||= from_superclass(:desc, nil)
    else
      @desc = description
  end
end

def get_options_from_invocations(group_options, base_options) #:nodoc:

:nodoc:

in base_options are not added twice.
options are added to group_options hash. Options that already exists
Get invocations array and merge options from invocations. Those
def get_options_from_invocations(group_options, base_options) #:nodoc:
  invocations.each do |name, from_option|
    value = if from_option
      option = class_options[name]
      option.type == :boolean ? name : option.default
    else
      name
    end
    next unless value
    klass, task = prepare_for_invocation(name, value)
    next unless klass && klass.respond_to?(:class_options)
    value = value.to_s
    human_name = value.respond_to?(:classify) ? value.classify : value
    group_options[human_name] ||= []
    group_options[human_name] += klass.class_options.values.select do |option|
      base_options[option.name.to_sym].nil? && option.group.nil? &&
      !group_options.values.flatten.any? { |i| i.name == option.name }
    end
    yield klass if block_given?
  end
end

def help(shell, options={})


short:: When true, shows only usage.
==== Options

Prints help information.
def help(shell, options={})
  if options[:short]
    shell.say banner
  else
    shell.say "Usage:"
    shell.say "  #{banner}"
    shell.say
    class_options_help(shell)
    shell.say self.desc if self.desc
  end
end

def invocation_blocks #:nodoc:

:nodoc:

Stores invocation blocks used on invoke_from_option.
def invocation_blocks #:nodoc:
  @invocation_blocks ||= from_superclass(:invocation_blocks, {})
end

def invocations #:nodoc:

:nodoc:

Stores invocations for this class merging with superclass values.
def invocations #:nodoc:
  @invocations ||= from_superclass(:invocations, {})
end

def invoke(*names, &block)


usage. Check invoke_from_option for more information.
The namespace/class given will have its options showed on the help

configure how it will be invoked.
method that will invoke the klass and task. You can give a block to
Invoke the given namespace or class given. It adds an instance
def invoke(*names, &block)
  options = names.last.is_a?(Hash) ? names.pop : {}
  verbose = options.fetch(:verbose, true)
  names.each do |name|
    invocations[name] = false
    invocation_blocks[name] = block if block_given?
    class_eval <<-METHOD, __FILE__, __LINE__
      def _invoke_#{name.to_s.gsub(/\W/, '_')}
        klass, task = self.class.prepare_for_invocation(nil, #{name.inspect})
        if klass
          say_status :invoke, #{name.inspect}, #{verbose.inspect}
          block = self.class.invocation_blocks[#{name.inspect}]
          _invoke_for_class_method klass, task, &block
        else
          say_status :error, %(#{name.inspect} [not found]), :red
        end
      end
    METHOD
  end
end

def invoke_from_option(*names, &block)


class and the klass to be invoked.
invoked. The block receives two parameters, an instance of the current
You can also supply a block to customize how the option is giong to be

==== Custom invocations

and an optional task.
prepare_for_invocation. The class method must necessarily return a klass
invoked. You can do that by overwriting the class method
In some cases you want to customize how a specified hook is going to be

==== Preparing for invocation

option name is used to invoke the generator.
false. This is automatically handled by invoke_from_option. Then the
In some cases, you want to invoke a thor class if some option is true or

==== Boolean options

end
invoke_from_option :test_framework
class_option :test_framework, :type => :string
class GemGenerator < Thor::Group

==== Examples

method is invoked for each name given.
given option named "name". A class option must be created before this
Invoke a thor class based on the value supplied by the user to the
def invoke_from_option(*names, &block)
  options = names.last.is_a?(Hash) ? names.pop : {}
  verbose = options.fetch(:verbose, :white)
  names.each do |name|
    unless class_options.key?(name)
      raise ArgumentError, "You have to define the option #{name.inspect} " << 
                           "before setting invoke_from_option."
    end
    invocations[name] = true
    invocation_blocks[name] = block if block_given?
    class_eval <<-METHOD, __FILE__, __LINE__
      def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
        return unless options[#{name.inspect}]
        value = options[#{name.inspect}]
        value = #{name.inspect} if TrueClass === value
        klass, task = self.class.prepare_for_invocation(#{name.inspect}, value)
        if klass
          say_status :invoke, value, #{verbose.inspect}
          block = self.class.invocation_blocks[#{name.inspect}]
          _invoke_for_class_method klass, task, &block
        else
          say_status :error, %(\#{value} [not found]), :red
        end
      end
    METHOD
  end
end

def remove_invocation(*names)


remove_invocation :test_framework

==== Examples

Remove a previously added invocation.
def remove_invocation(*names)
  names.each do |name|
    remove_task(name)
    remove_class_option(name)
    invocations.delete(name)
    invocation_blocks.delete(name)
  end
end

def start(given_args=ARGV, config={})


inside the class.
Start works differently in Thor::Group, it simply invokes all tasks
def start(given_args=ARGV, config={})
  super do
    if Thor::HELP_MAPPINGS.include?(given_args.first)
      help(config[:shell])
      return
    end
    args, opts = Thor::Options.split(given_args)
    new(args, opts, config).invoke
  end
end