In Files

  • rubygems/uninstaller.rb

Class/Module Index [+]

Quicksearch

Gem::Uninstaller

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.

Attributes

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

Public Class Methods

new(gem, options = {}) click to toggle source

Constructs an uninstaller that will uninstall gem

 
               # File rubygems/uninstaller.rb, line 44
def initialize(gem, options = {})
  @gem = gem
  @version = options[:version] || Gem::Requirement.default
  gem_home = options[:install_dir] || Gem.dir
  @gem_home = File.expand_path gem_home
  @force_executables = options[:executables]
  @force_all = options[:all]
  @force_ignore = options[:ignore]
  @bin_dir = options[:bin_dir]

  # only add user directory if install_dir is not set
  @user_install = false
  @user_install = options[:user_install] unless options[:install_dir]

  spec_dir = File.join @gem_home, 'specifications'
  @source_index = Gem::SourceIndex.from_gems_in spec_dir

  if @user_install then
    user_dir = File.join Gem.user_dir, 'specifications'
    @user_index = Gem::SourceIndex.from_gems_in user_dir
  end
end
            

Public Instance Methods

ask_if_ok(spec) click to toggle source
 
               # File rubygems/uninstaller.rb, line 247
def ask_if_ok(spec)
  msg = ['']
  msg << 'You have requested to uninstall the gem:'
  msg << "\t#{spec.full_name}"
  spec.dependent_gems.each do |gem,dep,satlist|
    msg <<
      ("#{gem.name}-#{gem.version} depends on " +
      "[#{dep.name} (#{dep.requirement})]")
  end
  msg << 'If you remove this gems, one or more dependencies will not be met.'
  msg << 'Continue with Uninstall?'
  return ask_yes_no(msg.join("\n"), true)
end
            
dependencies_ok?(spec) click to toggle source
 
               # File rubygems/uninstaller.rb, line 239
def dependencies_ok?(spec)
  return true if @force_ignore

  deplist = Gem::DependencyList.from_source_index @source_index
  deplist.add(*@user_index.gems.values) if @user_install
  deplist.ok_to_remove?(spec.full_name) || ask_if_ok(spec)
end
            
path_ok?(gem_dir, spec) click to toggle source

Is spec in gem_dir?

 
               # File rubygems/uninstaller.rb, line 232
def path_ok?(gem_dir, spec)
  full_path = File.join gem_dir, 'gems', spec.full_name
  original_path = File.join gem_dir, 'gems', spec.original_name

  full_path == spec.full_gem_path || original_path == spec.full_gem_path
end
            
remove(spec, list) click to toggle source
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 rubygems/uninstaller.rb, line 181
def remove(spec, list)
  unless dependencies_ok? spec then
    raise Gem::DependencyRemovalException,
          "Uninstallation aborted due to dependent gem(s)"
  end

  unless path_ok?(@gem_home, spec) or
         (@user_install and path_ok?(Gem.user_dir, spec)) then
    e = Gem::GemNotInHomeException.new              "Gem is not installed in directory #{@gem_home}"
    e.spec = spec

    raise e
  end

  raise Gem::FilePermissionError, spec.installation_path unless
    File.writable?(spec.installation_path)

  FileUtils.rm_rf spec.full_gem_path

  original_platform_name = [
    spec.name, spec.version, spec.original_platform].join '-'

  spec_dir = File.join spec.installation_path, 'specifications'
  gemspec = File.join spec_dir, spec.spec_name

  unless File.exist? gemspec then
    gemspec = File.join spec_dir, "#{original_platform_name}.gemspec"
  end

  FileUtils.rm_rf gemspec

  cache_dir = File.join spec.installation_path, 'cache'
  gem = File.join cache_dir, spec.file_name

  unless File.exist? gem then
    gem = File.join cache_dir, "#{original_platform_name}.gem"
  end

  FileUtils.rm_rf gem

  Gem::DocManager.new(spec).uninstall_doc

  say "Successfully uninstalled #{spec.full_name}"

  list.delete spec
end
            
remove_all(list) click to toggle source

Removes all gems in list.

NOTE: removes uninstalled gems from list.

 
               # File rubygems/uninstaller.rb, line 170
def remove_all(list)
  list.dup.each { |spec| uninstall_gem spec, list }
end
            
remove_executables(spec) click to toggle source

Removes installed executables and batch files (windows only) for gemspec.

 
               # File rubygems/uninstaller.rb, line 123
def remove_executables(spec)
  return if spec.nil?

  unless spec.executables.empty? then
    bindir = @bin_dir ? @bin_dir : Gem.bindir(spec.installation_path)

    list = @source_index.find_name(spec.name).delete_if { |s|
      s.version == spec.version
    }

    executables = spec.executables.clone

    list.each do |s|
      s.executables.each do |exe_name|
        executables.delete exe_name
      end
    end

    return if executables.empty?

    answer = if @force_executables.nil? then
               ask_yes_no("Remove executables:\n"                              "\t#{spec.executables.join(", ")}\n\nin addition to the gem?",
                          true) # " # appease ruby-mode - don't ask
             else
               @force_executables
             end

    unless answer then
      say "Executables and scripts will remain installed."
    else
      raise Gem::FilePermissionError, bindir unless File.writable? bindir

      spec.executables.each do |exe_name|
        say "Removing #{exe_name}"
        FileUtils.rm_f File.join(bindir, exe_name)
        FileUtils.rm_f File.join(bindir, "#{exe_name}.bat")
      end
    end
  end
end
            
uninstall() click to toggle source

Performs the uninstall of the gem. This removes the spec, the Gem directory, and the cached .gem file.

 
               # File rubygems/uninstaller.rb, line 71
def uninstall
  list = @source_index.find_name @gem, @version
  list += @user_index.find_name @gem, @version if @user_install

  if list.empty? then
    raise Gem::InstallError, "cannot uninstall, check `gem list -d #{@gem}`"

  elsif list.size > 1 and @force_all then
    remove_all list.dup

  elsif list.size > 1 then
    gem_names = list.collect {|gem| gem.full_name} + ["All versions"]

    say
    gem_name, index = choose_from_list "Select gem to uninstall:", gem_names

    if index == list.size then
      remove_all list.dup
    elsif index >= 0 && index < list.size then
      uninstall_gem list[index], list.dup
    else
      say "Error: must enter a number [1-#{list.size+1}]"
    end
  else
    uninstall_gem list.first, list.dup
  end
end
            
uninstall_gem(spec, specs) click to toggle source

Uninstalls gem spec

 
               # File rubygems/uninstaller.rb, line 102
def uninstall_gem(spec, specs)
  @spec = spec

  Gem.pre_uninstall_hooks.each do |hook|
    hook.call self
  end

  remove_executables @spec
  remove @spec, specs

  Gem.post_uninstall_hooks.each do |hook|
    hook.call self
  end

  @spec = nil
end