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 attr_accessor(*) #:nodoc:
def attr_accessor(*) #:nodoc: no_tasks { super } end
def attr_reader(*) #:nodoc:
def attr_reader(*) #:nodoc: no_tasks { super } end
def attr_writer(*) #:nodoc:
def attr_writer(*) #:nodoc: no_tasks { super } end
def baseclass #:nodoc:
finishes.
SIGNATURE: Sets the baseclass. This is where the superclass lookup
def baseclass #:nodoc: end
def basename
The basename of the program invoking the thor class.
def basename File.basename($0).split(' ').first 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[:lazy_default], 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 check_unknown_options #:nodoc:
def check_unknown_options #:nodoc: @check_unknown_options ||= from_superclass(:check_unknown_options, false) end
def check_unknown_options!
If you want to raise an error for unknown options, call check_unknown_options!
def check_unknown_options! @check_unknown_options = true end
def check_unknown_options?(config) #:nodoc:
def check_unknown_options?(config) #:nodoc: !!check_unknown_options 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, groups={}) #:nodoc:
any group, it's printed as Class option.
Prints the class options per group. If an option does not belong to
def class_options_help(shell, groups={}) #:nodoc: # Group options by group class_options.each do |_, value| groups[value.group] ||= [] groups[value.group] << value end # Deal with default group global_options = groups.delete(nil) || [] print_options(shell, global_options) # Print all others groups.each do |group_name, options| print_options(shell, options, group_name) end 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 dispatch(task, given_args, given_opts, config) #:nodoc:
SIGNATURE: The hook invoked by start.
def dispatch(task, given_args, given_opts, config) #:nodoc: raise NotImplementedError end
def exit_on_failure?
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)
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 handle_argument_error(task, error) #:nodoc:
def handle_argument_error(task, error) #:nodoc: raise InvocationError, "#{task.name.inspect} was called incorrectly. Call as #{self.banner(task).inspect}." end
def handle_no_task_error(task) #:nodoc:
def handle_no_task_error(task) #:nodoc: if $thor_runner raise UndefinedTaskError, "Could not find task #{task.inspect} in #{namespace.inspect} namespace." else raise UndefinedTaskError, "Could not find task #{task.inspect}." end end
def inherited(klass)
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)
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) 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 ensure @no_tasks = false end
def print_options(shell, options, group_name=nil)
def print_options(shell, options, group_name=nil) return if options.empty? 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 shell.say(group_name ? "#{group_name} options:" : "Options:") shell.print_table(list, :ident => 2) shell.say "" 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={})
script.invoke(:task, first_arg, second_arg, third_arg)
script = MyScript.new(args, options, config)
can simply initialize it:
from an array. If you are inside Ruby and want to use a Thor class, you
and invoke the task. This method is used when the arguments must be parsed
Parses the task and options from the given args, instantiate the class
def start(given_args=ARGV, config={}) self.debugging = given_args.delete("--debug") config[:shell] ||= Thor::Base.shell.new dispatch(nil, given_args.dup, nil, config) rescue Thor::Error => e debugging ? (raise e) : config[:shell].error(e.message) 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