Class: Thor::Command
- Inherits:
-
Struct
- Object
- Struct
- Thor::Command
- Includes:
- SemanticLogger::Loggable
- Defined in:
- lib/thor/command.rb
Direct Known Subclasses
Constant Summary collapse
- FILE_REGEXP =
/^#{Regexp.escape(File.dirname(__FILE__))}/
Instance Attribute Summary collapse
-
#ancestor_name ⇒ Object
Returns the value of attribute ancestor_name.
-
#description ⇒ Object
Returns the value of attribute description.
-
#long_description ⇒ Object
Returns the value of attribute long_description.
-
#name ⇒ Object
Returns the value of attribute name.
-
#options ⇒ Object
Returns the value of attribute options.
-
#usage ⇒ Object
Returns the value of attribute usage.
Instance Method Summary collapse
-
#formatted_usage(klass, namespace = true, subcommand = false) ⇒ Object
Returns the formatted usage by injecting given required arguments and required options into the given usage.
- #handle_argument_error?(instance, error, caller) ⇒ Boolean protected
- #handle_no_method_error?(instance, error, caller) ⇒ Boolean protected
- #hidden? ⇒ Boolean
-
#initialize(name, description, long_description, usage, options = nil) ⇒ Command
constructor
A new instance of Command.
-
#initialize_copy(other) ⇒ Object
:nodoc:.
- #local_method?(instance, name) ⇒ Boolean protected
- #not_debugging?(instance) ⇒ Boolean protected
- #private_method?(instance) ⇒ Boolean protected
-
#public_method?(instance) ⇒ Boolean
protected
Given a target, checks if this class name is a public method.
- #required_options ⇒ Object protected
-
#run(instance, args = []) ⇒ Object
By default, a command invokes a method in the thor class.
-
#sans_backtrace(backtrace, caller) ⇒ Object
protected
:nodoc:.
Constructor Details
#initialize(name, description, long_description, usage, options = nil) ⇒ Command
14 15 16 |
# File 'lib/thor/command.rb', line 14 def initialize(name, description, long_description, usage, = nil) super(name.to_s, description, long_description, usage, || {}) end |
Instance Attribute Details
#ancestor_name ⇒ Object
Returns the value of attribute ancestor_name
4 5 6 |
# File 'lib/thor/command.rb', line 4 def ancestor_name @ancestor_name end |
#description ⇒ Object
Returns the value of attribute description
4 5 6 |
# File 'lib/thor/command.rb', line 4 def description @description end |
#long_description ⇒ Object
Returns the value of attribute long_description
4 5 6 |
# File 'lib/thor/command.rb', line 4 def long_description @long_description end |
#name ⇒ Object
Returns the value of attribute name
4 5 6 |
# File 'lib/thor/command.rb', line 4 def name @name end |
#options ⇒ Object
Returns the value of attribute options
4 5 6 |
# File 'lib/thor/command.rb', line 4 def end |
#usage ⇒ Object
Returns the value of attribute usage
4 5 6 |
# File 'lib/thor/command.rb', line 4 def usage @usage end |
Instance Method Details
#formatted_usage(klass, namespace = true, subcommand = false) ⇒ Object
Returns the formatted usage by injecting given required arguments and required options into the given usage.
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 |
# File 'lib/thor/command.rb', line 80 def formatted_usage(klass, namespace = true, subcommand = false) logger.trace "Formatting usage", self: self, klass: klass, namespace: namespace, subcommand: subcommand, ancestor_name: ancestor_name if ancestor_name formatted = "#{ancestor_name} ".dup # add space elsif namespace namespace = klass.namespace formatted = "#{namespace.gsub(/^(default)/, '')}:".dup end formatted ||= "#{klass.namespace.split(':').last} ".dup if subcommand formatted ||= "".dup # Add usage with required arguments formatted << if klass && !klass.arguments.empty? usage.to_s.gsub(/^#{name}/) do |match| match << " " \ << klass.arguments.map(&:usage).compact.join(" ") end else usage.to_s end # Add required options formatted << " #{required_options}" # Strip and go! formatted.strip end |
#handle_argument_error?(instance, error, caller) ⇒ Boolean (protected)
154 155 156 157 158 159 160 161 162 163 |
# File 'lib/thor/command.rb', line 154 def handle_argument_error?(instance, error, caller) not_debugging?(instance) \ && ( error. =~ /wrong number of arguments/ \ || error. =~ /given \d*, expected \d*/ ) \ && begin saned = sans_backtrace(error.backtrace, caller) # Ruby 1.9 always include the called method in the backtrace saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9") end end |
#handle_no_method_error?(instance, error, caller) ⇒ Boolean (protected)
165 166 167 168 169 |
# File 'lib/thor/command.rb', line 165 def handle_no_method_error?(instance, error, caller) not_debugging?(instance) && error. =~ \ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/ end |
#hidden? ⇒ Boolean
23 24 25 |
# File 'lib/thor/command.rb', line 23 def hidden? false end |
#initialize_copy(other) ⇒ Object
:nodoc:
18 19 20 21 |
# File 'lib/thor/command.rb', line 18 def initialize_copy(other) #:nodoc: super(other) self. = other..dup if other. end |
#local_method?(instance, name) ⇒ Boolean (protected)
138 139 140 141 142 143 |
# File 'lib/thor/command.rb', line 138 def local_method?(instance, name) methods = instance.public_methods(false) + instance.private_methods(false) + instance.protected_methods(false) !(methods & [name.to_s, name.to_sym]).empty? end |
#not_debugging?(instance) ⇒ Boolean (protected)
117 118 119 |
# File 'lib/thor/command.rb', line 117 def not_debugging?(instance) !(instance.class.respond_to?(:debugging) && instance.class.debugging) end |
#private_method?(instance) ⇒ Boolean (protected)
134 135 136 |
# File 'lib/thor/command.rb', line 134 def private_method?(instance) !(instance.private_methods & [name.to_s, name.to_sym]).empty? end |
#public_method?(instance) ⇒ Boolean (protected)
Given a target, checks if this class name is a public method.
130 131 132 |
# File 'lib/thor/command.rb', line 130 def public_method?(instance) #:nodoc: !(instance.public_methods & [name.to_s, name.to_sym]).empty? end |
#required_options ⇒ Object (protected)
121 122 123 124 125 126 127 |
# File 'lib/thor/command.rb', line 121 def ||= . map { |_, o| o.usage if o.required? }. compact. sort. join(" ") end |
#run(instance, args = []) ⇒ Object
By default, a command invokes a method in the thor class. You can change this implementation to create custom commands.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/thor/command.rb', line 29 def run(instance, args = []) logger.trace "Command#run", self: self, instance: instance, args: args arity = nil if private_method?(instance) instance.class.handle_no_command_error(name) elsif public_method?(instance) arity = instance.method(name).arity instance.__send__(name, *args) elsif local_method?(instance, :method_missing) instance.__send__(:method_missing, name.to_sym, *args) else instance.class.handle_no_command_error(name) end rescue ArgumentError => e if handle_argument_error?(instance, e, caller) instance.class.handle_argument_error(self, e, args, arity) else raise e end rescue NoMethodError => e if handle_no_method_error?(instance, e, caller) instance.class.handle_no_command_error(name) else raise e 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 |
#sans_backtrace(backtrace, caller) ⇒ Object (protected)
:nodoc:
145 146 147 148 149 150 151 152 |
# File 'lib/thor/command.rb', line 145 def sans_backtrace(backtrace, caller) #:nodoc: saned = backtrace.reject { |frame| (frame =~ FILE_REGEXP) || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) || (frame =~ %r{^kernel/} && RUBY_ENGINE =~ /rbx/) } saned - caller end |