Method: Thor::Command#run
- Defined in:
- lib/thor/command.rb
#run(instance, args = []) ⇒ Object
Run a command by calling the actual method on the Base instance.
By default, a command invokes a method in the thor class. You can change this implementation to create custom commands.
64 65 66 67 68 69 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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/thor/command.rb', line 64 def run instance, args = [] logger.debug "Command#run", name: self.name, args: args # raise "BAD!!!" unless args.include? '--' # Declaration for arity of the method, which is set in (2) below and # used when handling raised {ArgumentError} arity = nil # Method invocation switch - figure out how to make the method call to # `instance`, or error out. # # Cases: # # 1. Protect from calling private methods by error'ing out if {#name} # is the name of a private method of `instance`. # result = if private_method? instance instance.class.handle_no_command_error name # 2. The success case - if {#name} is a public method of `instance` # than call it with `args`. # elsif public_method? instance # Save the arity to use when handling {ArgumentError} below # # TODO Why does it fetch the {Method} *then* use {#__send__} instead # of just `#call` it? # arity = instance.method( name ).arity # Unless the method is a subcommand, remove any '--' separators # since we know we're done option parsin' unless subcommand? instance, name args = args.reject { |arg| arg == '--' } end # Do that call instance.__send__ name, *args # 3. If the {Thor} instance has a `#method_missing` defined in *itself* # (not any super class) than call that. # elsif local_method? instance, :method_missing instance.__send__ :method_missing, name.to_sym, *args # 4. We got nothing... pass of to # {Thor::Base::ClassMethods.handle_no_command_error} # which will raise. # else instance.class.handle_no_command_error name end # Method invocation switch instance.__send__ :on_run_success, result, self, args rescue ArgumentError => error if handle_argument_error? instance, error, caller # NOTE I *believe* `arity` could still be `nil`, assuming that # (3) could raise {ArgumentError} and end up here. # # However... instance.class.handle_argument_error self, error, args, arity else raise error end rescue NoMethodError => error if handle_no_method_error? instance, error, caller instance.class.handle_no_command_error name else raise error end rescue Exception => error # NOTE Need to use `#__send__` because the instance may define a # command (method) `#send` - and one of the test fixtures **does**: # # //spec/fixtures/script.thor:100 # # That's why the Thor code above uses `#__send__`, and we need to # too. # instance.__send__ :on_run_error, error, self, args # We should not get here!!! # {Thor::Base#on_run_error} should exit or re-raise :( logger.error "#on_run_error failed to exit or re-raise", error: error # If you want something done right... raise error end |