class Object
Public Class Methods
dispatch(meth, given_args, given_opts, config) { |instance| ... }
click to toggle source
The method responsible for dispatching given the args.
@param [nil | String | Symbol] meth
The method name of the command to run, which I *think* will be `nil` when running the "default command"? haven't messed with that yet...
@param [Array<String>] given_args
# File lib/thor.rb, line 573 def self.dispatch meth, given_args, given_opts, config # rubocop:disable MethodLength logger.trace "START #{ self.safe_name }.#{ __method__ }", meth: meth, given_args: given_args, given_opts: given_opts, config: config meth ||= retrieve_command_name( given_args ).tap { |new_meth| logger.trace "meth set via .retrieve_command_name", meth: new_meth, map: map } normalized_name = normalize_command_name meth command = all_commands[normalized_name] logger.trace "Fetched command", command: command, all_commands: all_commands.keys, normalized_name: normalized_name if !command && config[:invoked_via_subcommand] # We're a subcommand and our first argument didn't match any of our # commands. So we put it back and call our default command. given_args.unshift(meth) command = all_commands[normalize_command_name(default_command)] end if command args, opts = Thor::Options.split(given_args) if stop_on_unknown_option?(command) && !args.empty? # given_args starts with a non-option, so we treat everything as # ordinary arguments args.concat opts opts.clear end else args = given_args opts = nil command = dynamic_command_class.new(meth) end opts = given_opts || opts || [] config[:current_command] = command config[:command_options] = command.options instance = new(args, opts, config) yield instance if block_given? args = instance.args trailing = args[ arguments( command: command ).size..-1 ] instance.invoke_command(command, trailing || []) end
find_command_possibilities(input)
click to toggle source
This is the logic that takes the command name passed in by the user and determines whether it is an unambiguous prefix of a command or alias name.
@param [#to_s] input
Input to match to command names.
# File lib/thor.rb, line 770 def self.find_command_possibilities input input = input.to_s possibilities = all_commands.merge(map).keys.select { |name| name.start_with? input }.sort unique_possibilities = possibilities.map { |k| map[k] || k }.uniq results = if possibilities.include? input [ input ] elsif unique_possibilities.size == 1 unique_possibilities else possibilities end logger.trace "Found #{ results.length } command possibilities", results: results, possibilities: possibilities, unique_possibilities: unique_possibilities results end
retrieve_command_name(args)
click to toggle source
Retrieve the command name from given args.
@note
Ugh... this *mutates* `args`
@param [Array<String>] args
@return [nil]`
# File lib/thor.rb, line 718 def self.retrieve_command_name args meth = args.first.to_s unless args.empty? args.shift if meth && (map[meth] || meth !~ /^\-/) end
subcommand_help(cmd)
click to toggle source
Calls superclass method
# File lib/thor.rb, line 799 def self.subcommand_help(cmd) # logger.trace __method__.to_s, # cmd: cmd, # caller: caller desc "help [COMMAND]", "Describe subcommands or one specific subcommand" # Atli - This used to be {#class_eval} (maybe to support really old # Rubies? Who knows...) but that made it really hard to find in # stack traces, so I switched it to {#define_method}. # define_method :help do |*args| # Add the `is_subcommand = true` trailing arg case args[-1] when true # pass when false # Weird, `false` was explicitly passed... whatever, set it to `true` args[-1] = true else # "Normal" case, append it args << true end super( *args ) end end
Public Instance Methods
help(*args)
click to toggle source
# File lib/thor.rb, line 882 def help(*args) is_subcommand = case args[-1] when true, false args.pop else false end # Will be the {String} command (get help on that command) # or `nil` (get help on this class) command = args.shift # Possibly empty array of string subcommands from something like # # myexe help sub cmd # # in which case it would end up being `['cmd']` and we actually are just # passing through and want to get help on the `cmd` subcommand. # subcommands = args logger.trace "#help", args: args, command: command, is_subcommand: is_subcommand, subcommands: subcommands if command if self.class.subcommands.include? command if subcommands.empty? # Get help on a subcommand *class* self.class.subcommand_classes[command].help(shell, true) else # Atli addition - handle things like `myexe help sub cmd` # Want help on something (class or command) further down the line invoke self.class.subcommand_classes[command], ['help', *subcommands], {}, {:invoked_via_subcommand => true, :class_options => options} end else # Want help on a *command* of this class # # Atli - Now that we've modified {.command_help} to accept # `subcommand`, pass it (it seems to have already been getting # the correct value to here). self.class.command_help(shell, command, is_subcommand) end else # We want help on *this class itself* (list available commands) self.class.help(shell, is_subcommand) end end
namespace(name)
click to toggle source
Calls superclass method
# File lib/thor/rake_compat.rb, line 60 def namespace(name) if klass = Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition const_name = Thor::Util.camel_case(name.to_s).to_sym klass.const_set(const_name, Class.new(Thor)) new_klass = klass.const_get(const_name) Thor::RakeCompat.rake_classes << new_klass end super Thor::RakeCompat.rake_classes.pop end
Also aliased as: rake_namespace
option_kwds(*names, groups: nil)
click to toggle source
Get a Hash mapping option name symbols to their values ready for +**+ usage in a method call for the option names and shared option groups.
@param (see .find_shared_method_options)
@return [Hash<Symbol, V>]
Map of option name to value.
# File lib/thor.rb, line 847 def option_kwds *names, groups: nil # Transform names into a set of strings name_set = Set.new names.map( &:to_s ) # Add groups (if any) if groups groups = Array( groups ) self.class. shared_defs. select { |shared_def| groups.any? { |group| shared_def[ :groups].include? group } }. each do |shared| name_set << shared[:name].to_s end end options.slice( *name_set ).sym_keys end
task(*)
click to toggle source
Calls superclass method
# File lib/thor/rake_compat.rb, line 40 def task(*) task = super if klass = Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition non_namespaced_name = task.name.split(":").last description = non_namespaced_name description << task.arg_names.map { |n| n.to_s.upcase }.join(" ") description.strip! klass.desc description, Rake.application.last_description || non_namespaced_name Rake.application.last_description = nil klass.send :define_method, non_namespaced_name do |*args| Rake::Task[task.name.to_sym].invoke(*args) end end task end