Class | Gem::Uninstaller |
In: |
lib/rubygems/uninstaller.rb
|
Parent: | Object |
An Uninstaller.
The uninstaller fires pre and post uninstall hooks. Hooks can be added either through a rubygems_plugin.rb file in an installed gem or via a rubygems/defaults/#{RUBY_ENGINE}.rb or rubygems/defaults/operating_system.rb file. See Gem.pre_uninstall and Gem.post_uninstall for details.
bin_dir | [R] | The directory a gem‘s executables will be installed into |
gem_home | [R] | The gem repository the gem will be installed into |
spec | [R] | The Gem::Specification for the gem being uninstalled, only set during uninstall_gem |
Constructs an uninstaller that will uninstall gem
# File lib/rubygems/uninstaller.rb, line 44 44: def initialize(gem, options = {}) 45: @gem = gem 46: @version = options[:version] || Gem::Requirement.default 47: gem_home = options[:install_dir] || Gem.dir 48: @gem_home = File.expand_path gem_home 49: @force_executables = options[:executables] 50: @force_all = options[:all] 51: @force_ignore = options[:ignore] 52: @bin_dir = options[:bin_dir] 53: 54: # only add user directory if install_dir is not set 55: @user_install = false 56: @user_install = options[:user_install] unless options[:install_dir] 57: 58: spec_dir = File.join @gem_home, 'specifications' 59: @source_index = Gem::SourceIndex.from_gems_in spec_dir 60: 61: if @user_install then 62: user_dir = File.join Gem.user_dir, 'specifications' 63: @user_index = Gem::SourceIndex.from_gems_in user_dir 64: end 65: end
# File lib/rubygems/uninstaller.rb, line 246 246: def ask_if_ok(spec) 247: msg = [''] 248: msg << 'You have requested to uninstall the gem:' 249: msg << "\t#{spec.full_name}" 250: spec.dependent_gems.each do |gem,dep,satlist| 251: msg << 252: ("#{gem.name}-#{gem.version} depends on " + 253: "[#{dep.name} (#{dep.requirement})]") 254: end 255: msg << 'If you remove this gems, one or more dependencies will not be met.' 256: msg << 'Continue with Uninstall?' 257: return ask_yes_no(msg.join("\n"), true) 258: end
# File lib/rubygems/uninstaller.rb, line 238 238: def dependencies_ok?(spec) 239: return true if @force_ignore 240: 241: deplist = Gem::DependencyList.from_source_index @source_index 242: deplist.add(*@user_index.gems.values) if @user_install 243: deplist.ok_to_remove?(spec.full_name) || ask_if_ok(spec) 244: end
Is spec in gem_dir?
# File lib/rubygems/uninstaller.rb, line 231 231: def path_ok?(gem_dir, spec) 232: full_path = File.join gem_dir, 'gems', spec.full_name 233: original_path = File.join gem_dir, 'gems', spec.original_name 234: 235: full_path == spec.full_gem_path || original_path == spec.full_gem_path 236: end
spec: | the spec of the gem to be uninstalled |
list: | the list of all such gems |
Warning: this method modifies the list parameter. Once it has uninstalled a gem, it is removed from that list.
# File lib/rubygems/uninstaller.rb, line 180 180: def remove(spec, list) 181: unless dependencies_ok? spec then 182: raise Gem::DependencyRemovalException, 183: "Uninstallation aborted due to dependent gem(s)" 184: end 185: 186: unless path_ok?(@gem_home, spec) or 187: (@user_install and path_ok?(Gem.user_dir, spec)) then 188: e = Gem::GemNotInHomeException.new \ 189: "Gem is not installed in directory #{@gem_home}" 190: e.spec = spec 191: 192: raise e 193: end 194: 195: raise Gem::FilePermissionError, spec.installation_path unless 196: File.writable?(spec.installation_path) 197: 198: FileUtils.rm_rf spec.full_gem_path 199: 200: original_platform_name = [ 201: spec.name, spec.version, spec.original_platform].join '-' 202: 203: spec_dir = File.join spec.installation_path, 'specifications' 204: gemspec = File.join spec_dir, spec.spec_name 205: 206: unless File.exist? gemspec then 207: gemspec = File.join spec_dir, "#{original_platform_name}.gemspec" 208: end 209: 210: FileUtils.rm_rf gemspec 211: 212: cache_dir = File.join spec.installation_path, 'cache' 213: gem = File.join cache_dir, spec.file_name 214: 215: unless File.exist? gem then 216: gem = File.join cache_dir, "#{original_platform_name}.gem" 217: end 218: 219: FileUtils.rm_rf gem 220: 221: Gem::DocManager.new(spec).uninstall_doc 222: 223: say "Successfully uninstalled #{spec.full_name}" 224: 225: list.delete spec 226: end
Removes all gems in list.
NOTE: removes uninstalled gems from list.
# File lib/rubygems/uninstaller.rb, line 169 169: def remove_all(list) 170: list.dup.each { |spec| uninstall_gem spec, list } 171: end
Removes installed executables and batch files (windows only) for gemspec.
# File lib/rubygems/uninstaller.rb, line 123 123: def remove_executables(spec) 124: return if spec.nil? or spec.executables.empty? 125: 126: bindir = @bin_dir ? @bin_dir : Gem.bindir(spec.installation_path) 127: 128: list = @source_index.find_name(spec.name).delete_if { |s| 129: s.version == spec.version 130: } 131: 132: executables = spec.executables.clone 133: 134: list.each do |s| 135: s.executables.each do |exe_name| 136: executables.delete exe_name 137: end 138: end 139: 140: return if executables.empty? 141: 142: remove = if @force_executables.nil? then 143: ask_yes_no("Remove executables:\n" \ 144: "\t#{spec.executables.join ', '}\n\n" \ 145: "in addition to the gem?", 146: true) 147: else 148: @force_executables 149: end 150: 151: unless remove then 152: say "Executables and scripts will remain installed." 153: else 154: raise Gem::FilePermissionError, bindir unless File.writable? bindir 155: 156: spec.executables.each do |exe_name| 157: say "Removing #{exe_name}" 158: FileUtils.rm_f File.join(bindir, exe_name) 159: FileUtils.rm_f File.join(bindir, "#{exe_name}.bat") 160: end 161: end 162: end
Performs the uninstall of the gem. This removes the spec, the Gem directory, and the cached .gem file.
# File lib/rubygems/uninstaller.rb, line 71 71: def uninstall 72: list = @source_index.find_name @gem, @version 73: list += @user_index.find_name @gem, @version if @user_install 74: 75: if list.empty? then 76: raise Gem::InstallError, "cannot uninstall, check `gem list -d #{@gem}`" 77: 78: elsif list.size > 1 and @force_all then 79: remove_all list.dup 80: 81: elsif list.size > 1 then 82: gem_names = list.collect {|gem| gem.full_name} + ["All versions"] 83: 84: say 85: _, index = choose_from_list "Select gem to uninstall:", gem_names 86: 87: if index == list.size then 88: remove_all list.dup 89: elsif index >= 0 && index < list.size then 90: uninstall_gem list[index], list.dup 91: else 92: say "Error: must enter a number [1-#{list.size+1}]" 93: end 94: else 95: uninstall_gem list.first, list.dup 96: end 97: end
Uninstalls gem spec
# File lib/rubygems/uninstaller.rb, line 102 102: def uninstall_gem(spec, specs) 103: @spec = spec 104: 105: Gem.pre_uninstall_hooks.each do |hook| 106: hook.call self 107: end 108: 109: remove_executables @spec 110: remove @spec, specs 111: 112: Gem.post_uninstall_hooks.each do |hook| 113: hook.call self 114: end 115: 116: @spec = nil 117: end