Permalink
Browse files

Small refactor in invocations.

  • Loading branch information...
1 parent 98b1bad commit 0dddc4a5259f07819dd0f478a5b35d31a290e643 @josevalim josevalim committed Feb 16, 2010
Showing with 21 additions and 30 deletions.
  1. +1 −2 lib/thor.rb
  2. +5 −8 lib/thor/base.rb
  3. +1 −3 lib/thor/group.rb
  4. +13 −16 lib/thor/invocation.rb
  5. +1 −1 lib/thor/task.rb
View
@@ -192,8 +192,7 @@ def printable_tasks(all=true)
# the namespace should be displayed as arguments.
#
def banner(task)
- base = $thor_runner ? "thor" : File.basename($0.split(" ").first)
- "#{base} #{task.formatted_usage(self, base == "thor")}"
+ "#{banner_base} #{task.formatted_usage(self, banner_base == "thor")}"
end
def baseclass #:nodoc:
View
@@ -419,7 +419,6 @@ def print_options(shell, options, group_name=nil)
end
# Raises an error if the word given is a Thor reserved word.
- #
def is_thor_reserved_word?(word, type) #:nodoc:
return false unless THOR_RESERVED_WORDS.include?(word.to_s)
raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
@@ -430,7 +429,6 @@ def is_thor_reserved_word?(word, type) #:nodoc:
# ==== Parameters
# name<Symbol>:: The name of the argument.
# options<Hash>:: Described in both class_option and method_option.
- #
def build_option(name, options, scope) #:nodoc:
scope[name] = Thor::Option.new(name, options[:desc], options[:required],
options[:type], options[:default], options[:banner],
@@ -444,7 +442,6 @@ def build_option(name, options, scope) #:nodoc:
#
# ==== Parameters
# Hash[Symbol => Object]
- #
def build_options(options, scope) #:nodoc:
options.each do |key, value|
scope[key] = Thor::Option.parse(key, value)
@@ -454,7 +451,6 @@ def build_options(options, scope) #:nodoc:
# Finds a task with the given name. If the task belongs to the current
# class, just return it, otherwise dup it and add the fresh copy to the
# current task hash.
- #
def find_and_refresh_task(name) #:nodoc:
task = if task = tasks[name.to_s]
task
@@ -467,14 +463,12 @@ def find_and_refresh_task(name) #:nodoc:
# Everytime someone inherits from a Thor class, register the klass
# and file into baseclass.
- #
def inherited(klass)
Thor::Base.register_klass_file(klass)
end
# Fire this callback whenever a method is added. Added methods are
# tracked as tasks by invoking the create_task method.
- #
def method_added(meth)
meth = meth.to_s
@@ -495,7 +489,6 @@ def method_added(meth)
# Retrieves a value from superclass. If it reaches the baseclass,
# returns default.
- #
def from_superclass(method, default=nil)
if self == baseclass || !superclass.respond_to?(method, true)
default
@@ -506,11 +499,15 @@ def from_superclass(method, default=nil)
end
# A flag that makes the process exit with status 1 if any error happens.
- #
def exit_on_failure?
false
end
+ # Returns the base for banner.
+ def banner_base
+ @banner_base ||= $thor_runner ? "thor" : File.basename($0.split(" ").first)
+ end
+
# SIGNATURE: Sets the baseclass. This is where the superclass lookup
# finishes.
def baseclass #:nodoc:
View
@@ -223,10 +223,8 @@ def printable_tasks(*)
# The banner for this class. You can customize it if you are invoking the
# thor class by another ways which is not the Thor::Runner.
- #
def banner
- base = $thor_runner ? "thor" : File.basename($0.split(" ").first)
- "#{base} #{self_task.formatted_usage(self, false)}"
+ "#{banner_base} #{self_task.formatted_usage(self, false)}"
end
# Represents the whole class as a task.
View
@@ -5,9 +5,9 @@ def self.included(base) #:nodoc:
end
module ClassMethods
- # Prepare for class methods invocations. This method must return a klass to
- # have the invoked class options showed in help messages in generators.
- #
+ # This method is responsible for receiving a name and find the proper
+ # class and task for it. The key is an optional parameter which is
+ # available only in class methods invocations (i.e. in Thor::Group).
def prepare_for_invocation(key, name) #:nodoc:
case name
when Symbol, String
@@ -18,8 +18,7 @@ def prepare_for_invocation(key, name) #:nodoc:
end
end
- # Make initializer aware of invocations and the initializer proc.
- #
+ # 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 ]
@@ -34,6 +33,8 @@ def initialize(args=[], options={}, config={}, &block) #:nodoc:
# the task to be invoked, if none is given, the same values used to
# initialize the invoker are used to initialize the invoked.
#
+ # When no name is given, it will invoke the default task of the current class.
+ #
# ==== Examples
#
# class A < Thor
@@ -92,9 +93,9 @@ def initialize(args=[], options={}, config={}, &block) #:nodoc:
#
# invoke Rspec::RR, [], :style => :foo
#
- def invoke(name=nil, task=nil, args=nil, opts=nil, config=nil)
- task, args, opts, config = nil, task, args, opts if task.nil? || task.is_a?(Array)
- args, opts, config = nil, args, opts if args.is_a?(Hash)
+ def invoke(name=nil, *args)
+ args.unshift(nil) if Array === args.first || NilClass === args.first
+ task, args, opts, config = args
object, task = _prepare_for_invocation(name, task)
klass, instance = _initialize_klass_with_initializer(object, args, opts, config)
@@ -121,15 +122,13 @@ def invoke(name=nil, task=nil, args=nil, opts=nil, config=nil)
protected
# Configuration values that are shared between invocations.
- #
def _shared_configuration #:nodoc:
{ :invocations => @_invocations }
end
- # Prepare for invocation in the instance level. In this case, we have to
- # take into account that a just a task name from the current class was
- # given or even a Thor::Task object.
- #
+ # This method can receive several different types of arguments and it's then
+ # responsible to normalize them by returning the object where the task should
+ # be invoked and a Thor::Task object.
def _prepare_for_invocation(name, sent_task=nil) #:nodoc:
if name.is_a?(Thor::Task)
task = name
@@ -147,18 +146,16 @@ def _prepare_for_invocation(name, sent_task=nil) #:nodoc:
# Check if the object given is a Thor class object and get a task object
# for it.
- #
def _validate_task(object, task) #:nodoc:
klass = object.is_a?(Class) ? object : object.class
raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
- task ||= klass.default_task if klass <= Thor
+ task ||= klass.default_task if klass.respond_to?(:default_task)
task = klass.all_tasks[task.to_s] || Thor::Task::Dynamic.new(task) if task && !task.is_a?(Thor::Task)
task
end
# Initialize klass using values stored in the @_initializer.
- #
def _initialize_klass_with_initializer(object, args, opts, config) #:nodoc:
if object.is_a?(Class)
klass = object
View
@@ -87,7 +87,7 @@ def parse_argument_error(instance, e, caller) #:nodoc:
backtrace = sans_backtrace(e.backtrace, caller)
if backtrace.empty? && e.message =~ /wrong number of arguments/
- if instance.is_a?(Thor::Group)
+ if defined?(Thor::Group) && instance.is_a?(Thor::Group)
raise e, "'#{name}' was called incorrectly. Are you sure it has arity equals to 0?"
else
raise InvocationError, "'#{name}' was called incorrectly. Call as " <<

0 comments on commit 0dddc4a

Please sign in to comment.