Module: Thor::Base

Included in:
Thor, Group
Defined in:
lib/thor/base.rb,
lib/thor/shell.rb,
lib/thor/base/class_methods.rb,
lib/thor/base/common_class_options.rb

Overview

Declarations

Defined Under Namespace

Modules: ClassMethods, CommonClassOptions

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.shellObject

Returns the shell used in all Thor classes. If you are in a Unix platform it will use a colored log, otherwise it will use a basic one without color.



11
12
13
14
15
16
17
18
19
# File 'lib/thor/shell.rb', line 11

def shell
  @shell ||= if ENV["THOR_SHELL"] && !ENV["THOR_SHELL"].empty?
    Thor::Shell.const_get(ENV["THOR_SHELL"])
  elsif RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ && !ENV["ANSICON"]
    Thor::Shell::Basic
  else
    Thor::Shell::Color
  end
end

Instance Attribute Details

#argsObject

Returns the value of attribute args.



51
52
53
# File 'lib/thor/base.rb', line 51

def args
  @args
end

#optionsObject

Returns the value of attribute options.



51
52
53
# File 'lib/thor/base.rb', line 51

def options
  @options
end

#parent_optionsObject

Returns the value of attribute parent_options.



51
52
53
# File 'lib/thor/base.rb', line 51

def parent_options
  @parent_options
end

Class Method Details

.included(base) ⇒ void (protected)

This method returns an undefined value.

Hook called when Thor::Base is mixed in (Thor and Group).

Extends ‘base` with ClassMethods, and includes Invocation and Shell in `base` as well.

Parameters:

  • base (Module)

    Module (or Class) that included Thor::Base.



219
220
221
222
223
224
225
226
227
228
# File 'lib/thor/base.rb', line 219

def self.included base
  base.extend ClassMethods
  base.send :include, Invocation
  base.send :include, Shell
  
  base.no_commands {
    base.send :include, SemanticLogger::Loggable
  }
  
end

.register_klass_file(klass) ⇒ Object (protected)

Whenever a class inherits from Thor or Thor::Group, we should track the class and the file on Thor::Base. This is the method responsible for it.



251
252
253
254
255
256
257
258
259
# File 'lib/thor/base.rb', line 251

def self.register_klass_file(klass) #:nodoc:
  file = caller[1].match(/(.*):\d+/)[1]
  unless Thor::Base.subclasses.include?(klass)
    Thor::Base.subclasses << klass
  end

  file_subclasses = Thor::Base.subclass_files[File.expand_path(file)]
  file_subclasses << klass unless file_subclasses.include?(klass)
end

.subclass_filesObject (protected)

Returns the files where the subclasses are kept.

Returns

Hash[path<String> => Class]



244
245
246
# File 'lib/thor/base.rb', line 244

def self.subclass_files
  @subclass_files ||= Hash.new { |h, k| h[k] = [] }
end

.subclassesObject (protected)

Returns the classes that inherits from Thor or Thor::Group.

Returns

Array



235
236
237
# File 'lib/thor/base.rb', line 235

def self.subclasses
  @subclasses ||= []
end

Instance Method Details

#initialize(args = [], local_options = {}, config = {}) ⇒ Object

It receives arguments in an Array and two hashes, one for options and other for configuration.

Notice that it does not check if all required arguments were supplied. It should be done by the parser.

Parameters

args<Array>

An array of objects. The objects are applied to their respective accessors declared with argument.

options<Hash>

An options hash that will be available as self.options. The hash given is converted to a hash with indifferent access, magic predicates (options.skip?) and then frozen.

config<Hash>

Configuration for this Thor class.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/thor/base.rb', line 70

def initialize(args = [], local_options = {}, config = {})
  logger.debug "#{ self.class.name }#initialize",
    args:           args,
    local_options:  local_options
  
  parse_options = self.class.class_options

  # The start method splits inbound arguments at the first argument
  # that looks like an option (starts with - or --). It then calls
  # new, passing in the two halves of the arguments Array as the
  # first two parameters.

  command_options = config.delete(:command_options) # hook for start
  parse_options = parse_options.merge(command_options) if command_options
  if local_options.is_a?(Array)
    array_options = local_options
    hash_options = {}
  else
    # Handle the case where the class was explicitly instantiated
    # with pre-parsed options.
    array_options = []
    hash_options = local_options
  end

  # Let Thor::Options parse the options first, so it can remove
  # declared options from the array. This will leave us with
  # a list of arguments that weren't declared.
  stop_on_unknown = \
    self.class.stop_on_unknown_option? config[:current_command]
  disable_required_check = \
    self.class.disable_required_check? config[:current_command]
  
  logger.debug "Ready to create options",
    array_options: array_options,
    hash_options: hash_options,
    stop_on_unknown: stop_on_unknown,
    disable_required_check: disable_required_check
  
  opts = Thor::Options.new( parse_options,
                            hash_options,
                            stop_on_unknown,
                            disable_required_check )
  
  self.options = opts.parse(array_options)
  
  if config[:class_options]
    self.options = config[:class_options].merge(options)
  end

  # If unknown options are disallowed, make sure that none of the
  # remaining arguments looks like an option.
  opts.check_unknown! if self.class.check_unknown_options?(config)

  # Add the remaining arguments from the options parser to the
  # arguments passed in to initialize. Then remove any positional
  # arguments declared using #argument (this is primarily used
  # by Thor::Group). Tis will leave us with the remaining
  # positional arguments.
  to_parse  = args
  unless self.class.strict_args_position?(config)
    to_parse += opts.remaining
  end

  thor_args = Thor::Arguments.new(self.class.arguments)
  thor_args.parse(to_parse).each { |k, v| __send__("#{k}=", v) }
  @args = thor_args.remaining
end

#on_run_error(error, command, args) ⇒ Object (protected)

Atli addition: An error handling hook that is called from Command#run when running a command raises an unhandled exception.

I don’t believe errors are recoverable at this point, but this hook allows the Thor subclass to respond to expected errors and gracefully inform the user.

It’s basically ‘goto fail` or whatever.

User overrides should always exit or re-raise the error.

The base implementation here simply re-raises.

Note that ArgumentError and NoMethodError are both rescued in Command#run and passed off to Thor’s relevant ‘.handle_*_error` methods, so you probably won’t be able to intercept any of those.

Generally, it’s best to use this to respond to custom, specific errors so you can easily bail out with a ‘raise` from anywhere in the application and still provide a properly formatted response and exit status to the user.

Errors that are only expected in a single command

Parameters:

  • error (Exception)

    The error the bubbled up to Command#run.

  • command (Thor::Command)

    The command instance that was running when the error occurred.

  • args (Array<String>)

    The arguments to the command that was running.



177
178
179
# File 'lib/thor/base.rb', line 177

def on_run_error error, command, args
  raise error
end

#on_run_success(result, command, args) ⇒ Object (protected)

Hook for processing values return by command methods. So you can format it or print it or whatever.

This implementation just returns the result per the specs.

Parameters:

  • result (Object)

    Whatever the command returned.

  • command (Thor::Command)

    The command instance that was running when the error occurred.

  • args (Array<String>)

    The arguments to the command that was running.

Returns:

  • (Object)

    The ‘result`.



199
200
201
# File 'lib/thor/base.rb', line 199

def on_run_success result, command, args
  result
end