Module: Thor::Base
- Defined in:
- lib/thor/base.rb,
lib/thor/shell.rb,
lib/thor/base/class_methods.rb,
lib/thor/base/shared_concern.rb,
lib/thor/base/arguments_concern.rb,
lib/thor/base/common_class_options.rb
Overview
Declarations
Defined Under Namespace
Modules: ArgumentsConcern, ClassMethods, CommonClassOptions, SharedConcern
Class Attribute Summary collapse
-
.shell ⇒ Object
Returns the shell used in all Thor classes.
Instance Attribute Summary collapse
-
#args ⇒ Object
Attributes ========================================================================.
-
#options ⇒ Object
Attributes ========================================================================.
-
#parent_options ⇒ Object
Attributes ========================================================================.
Class Method Summary collapse
- .included(base) ⇒ void
-
.register_klass_file(klass) ⇒ Object
Whenever a class inherits from Thor or Thor::Group, we should track the class and the file on Thor::Base.
-
.subclass_files ⇒ Object
Returns the files where the subclasses are kept.
-
.subclasses ⇒ Object
Returns the classes that inherits from Thor or Thor::Group.
Instance Method Summary collapse
-
#initialize(args = [], options_args_or_defaults = {}, config = {}) ⇒ Object
It receives arguments in an Array and two hashes, one for options and other for configuration.
-
#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.
-
#on_run_success(result, command, args) ⇒ Object
protected
Hook for processing values return by command methods.
Class Attribute Details
.shell ⇒ Object
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
#args ⇒ Object
Attributes
114 115 116 |
# File 'lib/thor/base.rb', line 114 def args @args end |
#options ⇒ Object
Attributes
114 115 116 |
# File 'lib/thor/base.rb', line 114 def @options end |
#parent_options ⇒ Object
Attributes
114 115 116 |
# File 'lib/thor/base.rb', line 114 def @parent_options end |
Class Method Details
.included(base) ⇒ void
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.
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/thor/base.rb', line 66 def self.included base base.extend ClassMethods base.send :include, Invocation base.send :include, Shell base.send :include, ArgumentsConcern base.send :include, SharedConcern base.no_commands { base.send :include, NRSER::Log::Mixin } end |
.register_klass_file(klass) ⇒ Object
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.
100 101 102 103 104 105 106 107 108 |
# File 'lib/thor/base.rb', line 100 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.(file)] file_subclasses << klass unless file_subclasses.include?(klass) end |
.subclass_files ⇒ Object
Returns the files where the subclasses are kept.
Returns
Hash[path<String> => Class]
93 94 95 |
# File 'lib/thor/base.rb', line 93 def self.subclass_files @subclass_files ||= Hash.new { |h, k| h[k] = [] } end |
.subclasses ⇒ Object
84 85 86 |
# File 'lib/thor/base.rb', line 84 def self.subclasses @subclasses ||= [] end |
Instance Method Details
#initialize(args = [], options_args_or_defaults = {}, 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.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/thor/base.rb', line 137 def initialize args = [], = {}, config = {} # Before {#initialize} is called arguments have been split out into # either: # # 1. Positional `args` and args that need to be parsed for options. # # 2. Positional `args` and already parsed option values that we call # "defaults". if .is_a? Array # Case (1) # # 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. # # In this case the first Array stays as `args` and the second Array # gets assigned to `args_to_parse_for_options` to be parsed for # options: # = option_defaults = {} else # Case (2) # # Handle the case where the class was explicitly instantiated # with pre-parsed options. # = [] option_defaults = end logger.debug "#{ self.class.name }#initialize", args: args, options_args_or_defaults: , args_to_parse_for_options: , option_defaults: option_defaults # 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. # Hash of {Thor::Option} that we can parse from the CLI args # keyed by their {Thor::Option#name}. # # @type [HashWithIndifferentAccess<String, Thor::Option>] # = [ # Add class-level options self.class., # Options passed in by {Thor.dispatch} for the command to be # invoked. May be `nil`, though I'm not totally sure when... in that # case those options won't be parsed. # # This was # # config.delete( :command_options ), # # though I can't figure out why. Specs still pass without it.. # config[:command_options], ].compact.reduce( HashWithIndifferentAccess.new, :merge! ) stop_on_unknown = \ self.class.stop_on_unknown_option? config[:current_command] disable_required_check = \ self.class.disable_required_check? config[:current_command] logger.trace "Ready to create options", options_to_parse_by_name: , option_defaults: option_defaults, stop_on_unknown: stop_on_unknown, disable_required_check: disable_required_check, args: args, args_to_parse_for_options: = Thor::Options.new \ , option_defaults, stop_on_unknown, disable_required_check self. = .parse if config[:class_options] self. = config[:class_options].merge() end # If unknown options are disallowed, make sure that none of the # remaining arguments looks like an option. if self.class. config .check_unknown! end # 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 += .remaining end thor_args = Thor::Arguments.new [ *self.class.class_arguments, *config[:current_command]&.arguments, ] # Set the arguments as instance variables. thor_args.parse( to_parse ).each { |k, v| __send__ "#{k}=", v } # Set whatever is left as args @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
298 299 300 |
# File 'lib/thor/base.rb', line 298 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.
320 321 322 |
# File 'lib/thor/base.rb', line 320 def on_run_success result, command, args result end |