module Bundler::Thor::Base::ClassMethods

def all_commands


objects as values.
OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command
==== Returns

Returns the commands for this Bundler::Thor class and all subclasses.
def all_commands
  @all_commands ||= from_superclass(:all_commands, Bundler::Thor::CoreExt::OrderedHash.new)
  @all_commands.merge(commands)
end

def argument(name, options = {}) # rubocop:disable MethodLength

rubocop:disable MethodLength

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:: Described below.
name:: The name of the argument.
==== 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 command --name=NAME

Instead of:

thor command 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 = {}) # rubocop:disable MethodLength
  is_thor_reserved_word?(name, :argument)
  no_commands { 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?
    fail ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " <<
                         "the non-required argument #{argument.human_name.inspect}."
  end if required
  options[:required] = required
  arguments << Bundler::Thor::Argument.new(name, options)
end

def arguments


Array[Bundler::Thor::Argument]
==== Returns

Returns this class arguments, looking up in the ancestors chain.
def arguments
  @arguments ||= from_superclass(:arguments, [])
end

def attr_accessor(*) #:nodoc:

:nodoc:
def attr_accessor(*) #:nodoc:
  no_commands { super }
end

def attr_reader(*) #:nodoc:

:nodoc:
def attr_reader(*) #:nodoc:
  no_commands { super }
end

def attr_writer(*) #:nodoc:

:nodoc:
def attr_writer(*) #:nodoc:
  no_commands { super }
end

def baseclass #:nodoc:

: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($PROGRAM_NAME).split(" ").first
end

def build_option(name, options, scope) #:nodoc:

:nodoc:
scope:: Options hash that is being built up
options:: Described in both class_option and method_option.
name:: The name of the argument.
==== Parameters

Build an option and adds it to the given scope.
def build_option(name, options, scope) #:nodoc:
  scope[name] = Bundler::Thor::Option.new(name, options)
end

def build_options(options, scope) #:nodoc:

: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] = Bundler::Thor::Option.parse(key, value)
  end
end

def check_unknown_options #:nodoc:

:nodoc:
def check_unknown_options #:nodoc:
  @check_unknown_options ||= from_superclass(:check_unknown_options, false)
end

def check_unknown_options!

This is disabled by default to allow dynamic invocations.
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:

:nodoc:
def check_unknown_options?(config) #:nodoc:
  !!check_unknown_options
end

def class_option(name, options = {})


:hide:: -- If you want to hide this option from the help.
: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. Note: Bundler::Thor follows a convention of one-dash-one-letter options. Thus aliases like "-something" wouldn't be parsed; use either "\--something" or "-s" instead.
: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:: Described below.
name:: The name of the argument.
==== 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:

: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 commands


objects as values.
OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command
==== Returns

Returns the commands for this Bundler::Thor class.
def commands
  @commands ||= Bundler::Thor::CoreExt::OrderedHash.new
end

def create_command(meth) #:nodoc:

:nodoc:
called when a new method is added to the class.
SIGNATURE: Creates a new command if valid_command? is true. This method is
def create_command(meth) #:nodoc:
end

def dispatch(command, given_args, given_opts, config) #:nodoc:

:nodoc:
SIGNATURE: The hook invoked by start.
def dispatch(command, given_args, given_opts, config) #:nodoc:
  fail NotImplementedError
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_command(name) #:nodoc:

:nodoc:
current command hash.
class, just return it, otherwise dup it and add the fresh copy to the
Finds a command with the given name. If the command belongs to the current
def find_and_refresh_command(name) #:nodoc:
  if commands[name.to_s]
    commands[name.to_s]
  elsif command = all_commands[name.to_s] # rubocop:disable AssignmentInCondition
    commands[name.to_s] = command.clone
  else
    fail ArgumentError, "You supplied :for => #{name.inspect}, but the command #{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)
    # Ruby implements `dup` on Object, but raises a `TypeError`
    # if the method is called on immediates. As a result, we
    # don't have a good way to check whether dup will succeed
    # without calling it and rescuing the TypeError.
    begin
      value.dup
    rescue TypeError
      value
    end
  end
end

def group(name = nil)


name
==== Parameters

that only commands 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)
  if name
    @group = name.to_s
  else
    @group ||= from_superclass(:group, "standard")
  end
end

def handle_argument_error(command, error, args, arity) #:nodoc:

:nodoc:
def handle_argument_error(command, error, args, arity) #:nodoc:
  msg = "ERROR: \"#{basename} #{command.name}\" was called with "
  msg << "no arguments"               if     args.empty?
  msg << "arguments " << args.inspect unless args.empty?
  msg << "\nUsage: #{banner(command).inspect}"
  fail InvocationError, msg
end

def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:

:nodoc:
def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
  if has_namespace
    fail UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
  else
    fail UndefinedCommandError, "Could not find command #{command.inspect}."
  end
end

def inherited(klass)

and file into baseclass.
Everytime someone inherits from a Bundler::Thor class, register the klass
def inherited(klass)
  Bundler::Thor::Base.register_klass_file(klass)
  klass.instance_variable_set(:@no_commands, false)
end

def initialize_added #:nodoc:

: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:

:nodoc:
Raises an error if the word given is a Bundler::Thor reserved word.
def is_thor_reserved_word?(word, type) #:nodoc:
  return false unless THOR_RESERVED_WORDS.include?(word.to_s)
  fail "#{word.inspect} is a Bundler::Thor reserved word and cannot be defined as #{type}"
end

def method_added(meth)

tracked as commands by invoking the create_command 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_method_defined?(meth.to_sym)
  @no_commands ||= false
  return if @no_commands || !create_command(meth)
  is_thor_reserved_word?(meth, :command)
  Bundler::Thor::Base.register_klass_file(self)
end

def namespace(name = nil)


thor :my_command

Your commands 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 commands 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 Bundler::Thor class is named
Sets the namespace for the Bundler::Thor or Bundler::Thor::Group class. By default the
def namespace(name = nil)
  if name
    @namespace = name.to_s
  else
    @namespace ||= Bundler::Thor::Util.namespace_from_thor_class(self)
  end
end

def no_commands


end
remove_command :this_is_not_a_command
end
def this_is_not_a_command
class MyScript < Bundler::Thor

You can also add the method and remove it from the command list:

end
end
end
def this_is_not_a_command
no_commands do
class MyScript < Bundler::Thor

So you can do:

All methods defined inside the given block are not added as commands.
def no_commands
  @no_commands = true
  yield
ensure
  @no_commands = false
end

def print_options(shell, options, group_name = nil)

Receives a set of options and print them.
def print_options(shell, options, group_name = nil)
  return if options.empty?
  list = []
  padding = options.map { |o| o.aliases.size }.max.to_i * 4
  options.each do |option|
    unless option.hide
      item = [option.usage(padding)]
      item.push(option.description ? "# #{option.description}" : "")
      list << item
      list << ["", "# Default: #{option.default}"] if option.show_default?
      list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum
    end
  end
  shell.say(group_name ? "#{group_name} options:" : "Options:")
  shell.print_table(list, :indent => 2)
  shell.say ""
end

def public_command(*names)


public_command :foo, :bar, :baz
public_command :foo

==== Examples

names:: Method names to be used as commands
==== Parameters

Allows to use private methods from parent in child classes as commands.
def public_command(*names)
  names.each do |name|
    class_eval "def #{name}(*); super end"
  end
end

def remove_argument(*names)


remove_argument :foo, :bar, :baz, :undefine => true
remove_argument :foo

==== Examples

names:: Arguments to be removed
==== Parameters

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:: Class options to be removed
==== Parameters

Removes a previous defined class option.
def remove_class_option(*names)
  names.each do |name|
    class_options.delete(name)
  end
end

def remove_command(*names)


to be undefined from the class as well.
options:: You can give :undefine => true if you want commands the method
name:: The name of the command to be removed
==== Parameters

:undefine => true to undefine the method from the class as well.
By default it only remove the mapping to the command. But you can supply

anymore.
are inheriting from another class and don't want it to be available
Removes a given command from this Bundler::Thor class. This is usually done if you
def remove_command(*names)
  options = names.last.is_a?(Hash) ? names.pop : {}
  names.each do |name|
    commands.delete(name.to_s)
    all_commands.delete(name.to_s)
    undef_method name if options[:undefine]
  end
end

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


script.invoke(:command, 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 Bundler::Thor class, you
and invoke the command. This method is used when the arguments must be parsed
Parses the command and options from the given args, instantiate the class
def start(given_args = ARGV, config = {})
  config[:shell] ||= Bundler::Thor::Base.shell.new
  dispatch(nil, given_args.dup, nil, config)
rescue Bundler::Thor::Error => e
  config[:debug] || ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
  exit(1) if exit_on_failure?
rescue Errno::EPIPE
  # This happens if a thor command is piped to something like `head`,
  # which closes the pipe when it's done reading. This will also
  # mean that if the pipe is closed, further unnecessary
  # computation will not occur.
  exit(0)
end

def stop_on_unknown_option?(command_name) #:nodoc:

:nodoc:
the command as regular arguments.
regular argument is encountered. All remaining arguments are passed to
If true, option parsing is suspended as soon as an unknown option or a
def stop_on_unknown_option?(command_name) #:nodoc:
  false
end

def strict_args_position #:nodoc:

:nodoc:
def strict_args_position #:nodoc:
  @strict_args_position ||= from_superclass(:strict_args_position, false)
end

def strict_args_position!

invocations.
call strict_args_position! This is disabled by default to allow dynamic
If you want only strict string args (useful when cascading thor classes),
def strict_args_position!
  @strict_args_position = true
end

def strict_args_position?(config) #:nodoc:

:nodoc:
def strict_args_position?(config) #:nodoc:
  !!strict_args_position
end