module Thor::Invocation
def self.included(base) #:nodoc:
def self.included(base) #:nodoc: base.extend ClassMethods end
def _parse_initialization_options(args, opts, config) #:nodoc:
Initialize klass using values stored in the @_initializer.
def _parse_initialization_options(args, opts, config) #:nodoc: stored_args, stored_opts, stored_config = @_initializer args ||= stored_args.dup opts ||= stored_opts.dup config ||= {} config = stored_config.merge(_shared_configuration).merge!(config) [ args, opts, config ] end
def _retrieve_class_and_task(name, sent_task=nil) #:nodoc:
prepare_for_invocation in the current class.
use the given name and return self as class. Otherwise, call
If the name is nil or the given name is a task in the current class,
This method simply retrieves the class and task to be invoked.
def _retrieve_class_and_task(name, sent_task=nil) #:nodoc: case when name.nil? [self.class, nil] when self.class.all_tasks[name.to_s] [self.class, name.to_s] else klass, task = self.class.prepare_for_invocation(nil, name) [klass, task || sent_task] end end
def _shared_configuration #:nodoc:
Configuration values that are shared between invocations.
def _shared_configuration #:nodoc: { :invocations => @_invocations } end
def initialize(args=[], options={}, config={}, &block) #:nodoc:
Make initializer aware of invocations and the initialization args.
def initialize(args=[], options={}, config={}, &block) #:nodoc: @_invocations = config[:invocations] || Hash.new { |h,k| h[k] = [] } @_initializer = [ args, options, config ] super end
def invoke(name=nil, *args)
invoke Rspec::RR, [], :style => :foo
Besides giving an instance, you can also give a class to invoke:
invoke "rspec:rr", [], :style => :foo
have to do that explicitely:
If you want Rspec::RR to be initialized with its own set of options, you
that it's going to use.
is invoked all options are parsed again, so RR can extract only the options
Since it's not rspec concern to parse mock framework options, when RR
end
class_option :style, :type => :string, :default => :mock
class Rspec::RR < Thor::Group
own options:
As you noticed, it invokes the given mock framework, which might have its
end
end
invoke "rspec:#{options[:mock_framework]}"
def invoke_mock_framework
class_option :mock_framework, :type => :string, :default => :rr
class Rspec < Thor::Group
some rspec tasks:
supplied to B. This allows lazy parse of options. Let's suppose you have
When class A invokes class B, all arguments used on A initialization are
if it's invoked later by "bar" method.
In the example above, invoking "foo" will invoke "b:hello" just once, even
By using an invocation system you ensure that a task is invoked only once.
which belongs to the same class and "hello" which belongs to the class B.
You can notice that the method "foo" above invokes two tasks: "bar",
end
end
puts "hello #{name}"
def hello(name)
class B < Thor
end
end
invoke "b:hello", ["José"]
def bar
end
invoke "b:hello", ["José"]
invoke :bar
def foo
class A < Thor
==== Examples
When no name is given, it will invoke the default task of the current class.
initialize the invoker are used to initialize the invoked.
the task to be invoked, if none is given, the same values used to
You can also supply the arguments, options and configuration values for
cannot be guessed by name, it can also be supplied as second argument.
"namespace:task"), a Thor::Task, a Class or a Thor instance. If the task
Receives a name and invokes it. The name can be a string (either "task" or
def invoke(name=nil, *args) if name.nil? warn "[Thor] Calling invoke() without argument is deprecated. Please use invoke_all instead.\n#{caller.join("\n")}" return invoke_all end args.unshift(nil) if Array === args.first || NilClass === args.first task, args, opts, config = args klass, task = _retrieve_class_and_task(name, task) raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base args, opts, config = _parse_initialization_options(args, opts, config) klass.send(:dispatch, task, args, opts, config) end
def invoke_all #:nodoc:
Invoke all tasks for the current instance.
def invoke_all #:nodoc: self.class.all_tasks.map { |_, task| invoke_task(task) } end
def invoke_task(task, *args) #:nodoc:
Invoke the given task if the given args.
def invoke_task(task, *args) #:nodoc: current = @_invocations[self.class] unless current.include?(task.name) current << task.name task.run(self, *args) end end
def invoke_with_padding(*args)
def invoke_with_padding(*args) with_padding { invoke(*args) } end