module Thor::Base::ClassMethods
def all_tasks
objects as values.
OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
==== Returns
Returns the tasks for this Thor class and all subclasses.
def all_tasks @all_tasks ||= from_superclass(:all_tasks, Thor::CoreExt::OrderedHash.new) @all_tasks.merge(tasks) end
def argument(name, options={})
ArgumentError:: Raised if you supply a required argument after a non required one.
==== Errors
:banner - String to show on usage notes.
:default - Default value for this argument. It cannot be required and have default values.
:type - The type of the argument, can be :string, :hash, :array, :numeric.
:optional - If the argument is optional or not.
:required - If the argument is required or not.
:desc - Description for the argument.
==== Options
options
name
==== Parameters
try it, an error is raised.
you cannot have a required argument after a non-required argument. If you
optional (supplying :optional => :true or :required => false), although
Finally, arguments cannot have type :default or :boolean but can be
while options are all kept in a hash (self.options).
Besides, arguments are used inside your code as an accessor (self.argument),
thor task --name=NAME
Instead of:
thor task NAME
from position:
is how they are parsed from the command line, arguments are retrieved
Arguments are different from options in several aspects. The first one
Adds an argument to the class and creates an attr_accessor for it.
def argument(name, options={}) is_thor_reserved_word?(name, :argument) no_tasks { attr_accessor name } required = if options.key?(:optional) !options[:optional] elsif options.key?(:required) options[:required] else options[:default].nil? end remove_argument name arguments.each do |argument| next if argument.required? raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " << "the non-required argument #{argument.human_name.inspect}." end if required arguments << Thor::Argument.new(name, options[:desc], required, options[:type], options[:default], options[:banner]) end
def arguments
Array[Thor::Argument]
==== Returns
Returns this class arguments, looking up in the ancestors chain.
def arguments @arguments ||= from_superclass(:arguments, []) end
def baseclass #:nodoc:
finishes.
SIGNATURE: Sets the baseclass. This is where the superclass lookup
def baseclass #:nodoc: end
def build_option(name, options, scope) #:nodoc:
options
name
==== Parameters
Build an option and adds it to the given scope.
def build_option(name, options, scope) #:nodoc: scope[name] = Thor::Option.new(name, options[:desc], options[:required], options[:type], options[:default], options[:banner], options[:group], options[:aliases]) end
def build_options(options, scope) #:nodoc:
Hash[Symbol => Object]
==== Parameters
build_options :foo => true, :bar => :required, :baz => :string
fast way to set a bunch of options:
Receives a hash of options, parse them and add to the scope. This is a
def build_options(options, scope) #:nodoc: options.each do |key, value| scope[key] = Thor::Option.parse(key, value) end end
def class_option(name, options={})
:banner - String to show on usage notes.
:type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
:aliases - Aliases for this option.
:group - The group for this options. Use by class options to output options in different levels.
:default - Default value for this argument.
:required - If the argument is required or not.
:desc - Description for the argument.
==== Options
options
name
==== Parameters
Adds an option to the set of class options
def class_option(name, options={}) build_option(name, options, class_options) end
def class_options(options=nil)
Hash[Symbol => Object]
==== Parameters
If you prefer more detailed declaration, check class_option.
class_options :foo => false, :bar => :required, :baz => :string
Adds a bunch of options to the set of class options.
def class_options(options=nil) @class_options ||= from_superclass(:class_options, {}) build_options(options, @class_options) if options @class_options end
def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc:
requires two options: the group name and the array of options.
The second is by returning a lambda used to print values. The lambda
extra_group that should be a hash in the format :group => Array[Options].
hooks to add extra options, one of them if the third argument called
any group, it uses the ungrouped name value. This method provide to
Prints the class options per group. If an option does not belong to
def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc: groups = {} class_options.each do |_, value| groups[value.group] ||= [] groups[value.group] << value end printer = proc do |group_name, options| list = [] padding = options.collect{ |o| o.aliases.size }.max.to_i * 4 options.each do |option| item = [ option.usage(padding) ] item.push(option.description ? "# #{option.description}" : "") list << item list << [ "", "# Default: #{option.default}" ] if option.show_default? end unless list.empty? shell.say(group_name ? "#{group_name} options:" : "Options:") shell.print_table(list, :ident => 2) shell.say "" end end # Deal with default group global_options = groups.delete(nil) || [] printer.call(ungrouped_name, global_options) if global_options # Print all others groups = extra_group.merge(groups) if extra_group groups.each(&printer) printer end
def create_task(meth) #:nodoc:
called when a new method is added to the class.
SIGNATURE: Creates a new task if valid_task? is true. This method is
def create_task(meth) #:nodoc: end
def exit_on_failure?
A flag that makes the process exit with status 1 if any error happens.
def exit_on_failure? false end
def find_and_refresh_task(name) #:nodoc:
current task hash.
class, just return it, otherwise dup it and add the fresh copy to the
Finds a task with the given name. If the task belongs to the current
def find_and_refresh_task(name) #:nodoc: task = if task = tasks[name.to_s] task elsif task = all_tasks[name.to_s] tasks[name.to_s] = task.clone else raise ArgumentError, "You supplied :for => #{name.inspect}, but the task #{name.inspect} could not be found." end end
def from_superclass(method, default=nil)
returns default.
Retrieves a value from superclass. If it reaches the baseclass,
def from_superclass(method, default=nil) if self == baseclass || !superclass.respond_to?(method, true) default else value = superclass.send(method) value.dup if value end end
def group(name=nil)
name
==== Parameters
that only tasks from a pre-defined group will be shown. Defaults to standard.
Defines the group. This is used when thor list is invoked so you can specify
def group(name=nil) case name when nil @group ||= from_superclass(:group, 'standard') else @group = name.to_s end end
def inherited(klass)
and file into baseclass.
Everytime someone inherits from a Thor class, register the klass
def inherited(klass) Thor::Base.register_klass_file(klass) end
def initialize_added #:nodoc:
class.
SIGNATURE: Defines behavior when the initialize method is added to the
def initialize_added #:nodoc: end
def is_thor_reserved_word?(word, type) #:nodoc:
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}" end
def method_added(meth)
tracked as tasks by invoking the create_task method.
Fire this callback whenever a method is added. Added methods are
def method_added(meth) meth = meth.to_s if meth == "initialize" initialize_added return end # Return if it's not a public instance method return unless public_instance_methods.include?(meth) || public_instance_methods.include?(meth.to_sym) return if @no_tasks || !create_task(meth) is_thor_reserved_word?(meth, :task) Thor::Base.register_klass_file(self) end
def namespace(name=nil)
thor :my_task
Your tasks can be invoked with a shortcut. Instead of:
namespace :default
Finally, if you change your namespace to default:
thor my_scripts -h
You change how your tasks are invoked:
namespace :my_scripts
If you change the namespace:
thor scripts:my_script -h
Scripts::MyScript, the help method, for example, will be called as:
namespace is retrieved from the class name. If your Thor class is named
Sets the namespace for the Thor or Thor::Group class. By default the
def namespace(name=nil) case name when nil @namespace ||= Thor::Util.namespace_from_thor_class(self, false) else @namespace = name.to_s end end
def no_tasks
end
remove_task :this_is_not_a_task
end
def this_is_not_a_task
class MyScript < Thor
You can also add the method and remove it from the task list:
end
end
end
def this_is_not_a_task
no_tasks do
class MyScript < Thor
So you can do:
All methods defined inside the given block are not added as tasks.
def no_tasks @no_tasks = true yield @no_tasks = false end
def remove_argument(*names)
remove_argument :foo, :bar, :baz, :undefine => true
remove_argument :foo
==== Examples
names
==== Paremeters
accessors as well.
Removes a previous defined argument. If :undefine is given, undefine
def remove_argument(*names) options = names.last.is_a?(Hash) ? names.pop : {} names.each do |name| arguments.delete_if { |a| a.name == name.to_s } undef_method name, "#{name}=" if options[:undefine] end end
def remove_class_option(*names)
remove_class_option :foo, :bar, :baz
remove_class_option :foo
==== Examples
names
==== Paremeters
Removes a previous defined class option.
def remove_class_option(*names) names.each do |name| class_options.delete(name) end end
def remove_task(*names)
to be undefined from the class as well.
options
name
==== Parameters
:undefine => true to undefine the method from the class as well.
By default it only remove the mapping to the task. But you can supply
anymore.
are inheriting from another class and don't want it to be available
Removes a given task from this Thor class. This is usually done if you
def remove_task(*names) options = names.last.is_a?(Hash) ? names.pop : {} names.each do |name| tasks.delete(name.to_s) all_tasks.delete(name.to_s) undef_method name if options[:undefine] end end
def start(given_args=ARGV, config={})
Default way to start generators from the command line.
def start(given_args=ARGV, config={}) config[:shell] ||= Thor::Base.shell.new yield rescue Thor::Error => e if given_args.include?("--debug") raise e else config[:shell].error e.message end exit(1) if exit_on_failure? end
def tasks
objects as values.
OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
==== Returns
Returns the tasks for this Thor class.
def tasks @tasks ||= Thor::CoreExt::OrderedHash.new end