1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 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 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
|
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'rubygems/command'
require 'rubygems/user_interaction'
##
# The command manager registers and installs all the individual sub-commands
# supported by the gem command.
#
# Extra commands can be provided by writing a rubygems_plugin.rb
# file in an installed gem. You should register your command against the
# Gem::CommandManager instance, like this:
#
# # file rubygems_plugin.rb
# require 'rubygems/command_manager'
#
# Gem::CommandManager.instance.register_command :edit
#
# You should put the implementation of your command in rubygems/commands.
#
# # file rubygems/commands/edit_command.rb
# class Gem::Commands::EditCommand < Gem::Command
# # ...
# end
#
# See Gem::Command for instructions on writing gem commands.
class Gem::CommandManager
include Gem::UserInteraction
BUILTIN_COMMANDS = [ # :nodoc:
:build,
:cert,
:check,
:cleanup,
:contents,
:dependency,
:environment,
:fetch,
:generate_index,
:help,
:install,
:list,
:lock,
:mirror,
:open,
:outdated,
:owner,
:pristine,
:push,
:query,
:rdoc,
:search,
:server,
:sources,
:specification,
:stale,
:uninstall,
:unpack,
:update,
:which,
:yank,
]
##
# Return the authoritative instance of the command manager.
def self.instance
@command_manager ||= new
end
##
# Returns self. Allows a CommandManager instance to stand
# in for the class itself.
def instance
self
end
##
# Reset the authoritative instance of the command manager.
def self.reset
@command_manager = nil
end
##
# Register all the subcommands supported by the gem command.
def initialize
require 'timeout'
@commands = {}
BUILTIN_COMMANDS.each do |name|
register_command name
end
end
##
# Register the Symbol +command+ as a gem command.
def register_command(command, obj=false)
@commands[command] = obj
end
##
# Unregister the Symbol +command+ as a gem command.
def unregister_command(command)
@commands.delete command
end
##
# Returns a Command instance for +command_name+
def [](command_name)
command_name = command_name.intern
return nil if @commands[command_name].nil?
@commands[command_name] ||= load_and_instantiate(command_name)
end
##
# Return a sorted list of all command names as strings.
def command_names
@commands.keys.collect {|key| key.to_s}.sort
end
##
# Run the command specified by +args+.
def run(args, build_args=nil)
process_args(args, build_args)
rescue StandardError, Timeout::Error => ex
alert_error "While executing gem ... (#{ex.class})\n #{ex}"
ui.backtrace ex
terminate_interaction(1)
rescue Interrupt
alert_error "Interrupted"
terminate_interaction(1)
end
def process_args(args, build_args=nil)
if args.empty? then
say Gem::Command::HELP
terminate_interaction 1
end
case args.first
when '-h', '--help' then
say Gem::Command::HELP
terminate_interaction 0
when '-v', '--version' then
say Gem::VERSION
terminate_interaction 0
when /^-/ then
alert_error "Invalid option: #{args.first}. See 'gem --help'."
terminate_interaction 1
else
cmd_name = args.shift.downcase
cmd = find_command cmd_name
cmd.invoke_with_build_args args, build_args
end
end
def find_command(cmd_name)
possibilities = find_command_possibilities cmd_name
if possibilities.size > 1 then
raise Gem::CommandLineError,
"Ambiguous command #{cmd_name} matches [#{possibilities.join(', ')}]"
elsif possibilities.empty? then
raise Gem::CommandLineError, "Unknown command #{cmd_name}"
end
self[possibilities.first]
end
def find_command_possibilities(cmd_name)
len = cmd_name.length
found = command_names.select { |name| cmd_name == name[0, len] }
exact = found.find { |name| name == cmd_name }
exact ? [exact] : found
end
private
def load_and_instantiate(command_name)
command_name = command_name.to_s
const_name = command_name.capitalize.gsub(/_(.)/) { $1.upcase } << "Command"
load_error = nil
begin
begin
require "rubygems/commands/#{command_name}_command"
rescue LoadError => e
load_error = e
end
Gem::Commands.const_get(const_name).new
rescue Exception => e
e = load_error if load_error
alert_error "Loading command: #{command_name} (#{e.class})\n\t#{e}"
ui.backtrace e
end
end
end
|