lib/gli/command_finder.rb in gli-2.12.3 vs lib/gli/command_finder.rb in gli-2.13.0
- old
+ new
@@ -1,41 +1,58 @@
module GLI
class CommandFinder
- # Initialize a finder on the given list of commands, using default_command as the default if none found
- def initialize(commands,default_command)
- @default_command = default_command
- @names_to_commands = {}
- commands.each do |command_name,command|
- @names_to_commands[command_name.to_s] = command
- Array(command.aliases).each do |command_alias|
- @names_to_commands[command_alias.to_s] = command
- end
- end
+ attr_accessor :options
+
+ DEFAULT_OPTIONS = {
+ default_command: nil,
+ autocomplete: true
+ }
+
+ def initialize(commands, options = {})
+ self.options = DEFAULT_OPTIONS.merge(options)
+ self.commands_with_aliases = expand_with_aliases(commands)
end
- # Finds the command with the given name, allowing for partial matches. Returns the command named by
- # the default command if no command with +name+ matched
def find_command(name)
- name ||= @default_command
+ name = String(name || options[:default_command]).strip
+ raise UnknownCommand.new("No command name given nor default available") if name == ''
- raise UnknownCommand.new("No command name given nor default available") if String(name).strip == ''
-
- command_found = @names_to_commands.fetch(name.to_s) do |command_to_match|
- find_command_by_partial_name(@names_to_commands, command_to_match)
+ command_found = commands_with_aliases.fetch(name) do |command_to_match|
+ if options[:autocomplete]
+ found_match = find_command_by_partial_name(commands_with_aliases, command_to_match)
+ if found_match.kind_of? GLI::Command
+ if ENV["GLI_DEBUG"] == 'true'
+ $stderr.puts "Using '#{name}' as it's is short for #{found_match.name}."
+ $stderr.puts "Set autocomplete false for any command you don't want matched like this"
+ end
+ elsif found_match.kind_of?(Array) && !found_match.empty?
+ raise AmbiguousCommand.new("Ambiguous command '#{name}'. It matches #{found_match.sort.join(',')}")
+ end
+ found_match
+ end
end
- if Array(command_found).empty?
- raise UnknownCommand.new("Unknown command '#{name}'")
- elsif command_found.kind_of? Array
- raise AmbiguousCommand.new("Ambiguous command '#{name}'. It matches #{command_found.sort.join(',')}")
- end
+
+ raise UnknownCommand.new("Unknown command '#{name}'") if Array(command_found).empty?
command_found
end
private
+ attr_accessor :commands_with_aliases
- def find_command_by_partial_name(names_to_commands, command_to_match)
- partial_matches = names_to_commands.keys.select { |command_name| command_name =~ /^#{command_to_match}/ }
- return names_to_commands[partial_matches[0]] if partial_matches.size == 1
+ def expand_with_aliases(commands)
+ expanded = {}
+ commands.each do |command_name, command|
+ expanded[command_name.to_s] = command
+ Array(command.aliases).each do |command_alias|
+ expanded[command_alias.to_s] = command
+ end
+ end
+ expanded
+ end
+
+ def find_command_by_partial_name(commands_with_aliases, command_to_match)
+ partial_matches = commands_with_aliases.keys.select { |command_name| command_name =~ /^#{command_to_match}/ }
+ return commands_with_aliases[partial_matches[0]] if partial_matches.size == 1
partial_matches
end
end
end