Class: Gem::Uninstaller

Inherits:
Object
  • Object
show all
Includes:
UserInteraction
Defined in:
lib/rubygems/installer.rb

Overview

The Uninstaller class uninstalls a Gem

Instance Method Summary collapse

Methods included from DefaultUserInteraction

#ui, ui, #ui=, ui=, #use_ui, use_ui

Constructor Details

#initialize(gem, options) ⇒ Uninstaller

Constructs an Uninstaller instance

gem
String

The Gem name to uninstall



386
387
388
389
390
391
392
# File 'lib/rubygems/installer.rb', line 386

def initialize(gem, options)
  @gem = gem
  @version = options[:version] || "> 0"
  @force_executables = options[:executables]
  @force_all = options[:all]
  @force_ignore = options[:ignore]
end

Instance Method Details

#ask_if_ok(spec) ⇒ Object



518
519
520
521
522
523
524
525
526
527
528
529
530
# File 'lib/rubygems/installer.rb', line 518

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.version_requirements})]")
  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

#ok_to_remove?(spec) ⇒ Boolean

Returns:

  • (Boolean)


510
511
512
513
514
515
516
# File 'lib/rubygems/installer.rb', line 510

def ok_to_remove?(spec)
  return true if @force_ignore
  srcindex= Gem::SourceIndex.from_installed_gems
  deplist = Gem::DependencyList.from_source_index(srcindex)
  deplist.ok_to_remove?(spec.full_name) ||
    ask_if_ok(spec)
end

#remove(spec, list) ⇒ Object

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.



488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
# File 'lib/rubygems/installer.rb', line 488

def remove(spec, list)
  if( ! ok_to_remove?(spec)) then
    raise DependencyRemovalException.new(
      "Uninstallation aborted due to dependent gem(s)")
  end
  raise Gem::FilePermissionError.new(spec.installation_path) unless
    File.writable?(spec.installation_path)
  FileUtils.rm_rf spec.full_gem_path
  FileUtils.rm_rf File.join(
    spec.installation_path,
    'specifications',
    "#{spec.full_name}.gemspec")
  FileUtils.rm_rf File.join(
    spec.installation_path,
    'cache',
    "#{spec.full_name}.gem")
  DocManager.new(spec).uninstall_doc
  #remove_stub_files(spec, list - [spec])
  say "Successfully uninstalled #{spec.name} version #{spec.version}"
  list.delete(spec)
end

#remove_all(list) ⇒ Object

list

the list of all gems to remove

Warning: this method modifies the list parameter. Once it has uninstalled a gem, it is removed from that list.



477
478
479
# File 'lib/rubygems/installer.rb', line 477

def remove_all(list)
  list.dup.each { |gem| remove(gem, list) }
end

#remove_executables(gemspec) ⇒ Object

Remove executables and batch files (windows only) for the gem as it is being installed

gemspec:: the gem whose executables need to be removed.



439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'lib/rubygems/installer.rb', line 439

def remove_executables(gemspec)
  return if gemspec.nil?
  if(gemspec.executables.size > 0)
    raise Gem::FilePermissionError.new(Gem.bindir) unless
      File.writable?(Gem.bindir)
    list = Gem.source_index.search(gemspec.name).delete_if { |spec|
      spec.version == gemspec.version
    }
    executables = gemspec.executables.clone
    list.each do |spec|
      spec.executables.each do |exe_name|
        executables.delete(exe_name)
      end
    end
    return if executables.size == 0
    answer = @force_executables || ask_yes_no(
      "Remove executables and scripts for\n" +
      "'#{gemspec.executables.join(", ")}' in addition to the gem?",
      true) # " # appease ruby-mode - don't ask
    unless answer
      say "Executables and scripts will remain installed."
      return
    else
      gemspec.executables.each do |exe_name|
        say "Removing #{exe_name}"
        File.unlink File.join(Gem.bindir, exe_name) rescue nil
        File.unlink File.join(Gem.bindir, exe_name + ".cmd") rescue nil
      end
    end
  end
end

#uninstallObject

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

Application stubs are (or should be) removed according to what is still installed.

XXX: Application stubs refer to specific gem versions, which means things may get inconsistent after an uninstall (i.e. referring to a version that no longer exists).



405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# File 'lib/rubygems/installer.rb', line 405

def uninstall
  list = Gem.source_index.search(/^#{@gem}$/, @version)
  if list.empty?
    raise Gem::InstallError, "Unknown gem #{@gem}-#{@version}"
  elsif list.size > 1 && @force_all
    remove_all(list.dup) 
    remove_executables(list.last)
  elsif list.size > 1 
    say 
    gem_names = list.collect {|gem| gem.full_name} + ["All versions"]
    gem_name, index =
      choose_from_list("Select gem to uninstall:", gem_names)
    if index == list.size
      remove_all(list.dup) 
      remove_executables(list.last)
    elsif index >= 0 && index < list.size
      to_remove = list[index]
      remove(to_remove, list)
      remove_executables(to_remove)
    else
      say "Error: must enter a number [1-#{list.size+1}]"
    end
  else
    remove(list[0], list.dup)
    remove_executables(list.last)
  end
end