Class: Gem::Doctor

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

Overview

Cleans up after a partially-failed uninstall or for an invalid Gem::Specification.

If a specification was removed by hand this will remove any remaining files.

If a corrupt specification was installed this will clean up warnings by removing the bogus specification.

Constant Summary collapse

REPOSITORY_EXTENSION_MAP =

Maps a gem subdirectory to the files that are expected to exist in the subdirectory.

[ # :nodoc:
  ['specifications', '.gemspec'],
  ['build_info',     '.info'],
  ['cache',          '.gem'],
  ['doc',            ''],
  ['extensions',     ''],
  ['gems',           ''],
].freeze

Instance Method Summary collapse

Methods included from UserInteraction

#alert, #alert_error, #alert_warning, #ask, #ask_for_password, #ask_yes_no, #choose_from_list, #say, #terminate_interaction, #verbose

Methods included from DefaultUserInteraction

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

Constructor Details

#initialize(gem_repository, dry_run = false) ⇒ Doctor

Creates a new Gem::Doctor that will clean up gem_repository. Only one gem repository may be cleaned at a time.

If dry_run is true no files or directories will be removed.


44
45
46
47
48
49
# File 'lib/rubygems/doctor.rb', line 44

def initialize gem_repository, dry_run = false
  @gem_repository = gem_repository
  @dry_run        = dry_run

  @installed_specs = nil
end

Instance Method Details

#doctorObject

Cleans up uninstalled files and invalid gem specifications


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/rubygems/doctor.rb', line 68

def doctor
  @orig_home = Gem.dir
  @orig_path = Gem.path

  say "Checking #{@gem_repository}"

  Gem.use_paths @gem_repository.to_s

  unless gem_repository? then
    say 'This directory does not appear to be a RubyGems repository, ' +
        'skipping'
    say
    return
  end

  doctor_children

  say
ensure
  Gem.use_paths @orig_home, *@orig_path
end

#doctor_child(sub_directory, extension) ⇒ Object

Removes files in sub_directory with extension


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
# File 'lib/rubygems/doctor.rb', line 102

def doctor_child sub_directory, extension # :nodoc:
  directory = File.join(@gem_repository, sub_directory)

  Dir.entries(directory).sort.each do |ent|
    next if ent == "." || ent == ".."

    child = File.join(directory, ent)
    next unless File.exist?(child)

    basename = File.basename(child, extension)
    next if installed_specs.include? basename
    next if /^rubygems-\d/ =~ basename
    next if 'specifications' == sub_directory and 'default' == basename

    type = File.directory?(child) ? 'directory' : 'file'

    action = if @dry_run then
               'Extra'
             else
               FileUtils.rm_r(child)
               'Removed'
             end

    say "#{action} #{type} #{sub_directory}/#{File.basename(child)}"
  end
rescue Errno::ENOENT
  # ignore
end

#doctor_childrenObject

Cleans up children of this gem repository


93
94
95
96
97
# File 'lib/rubygems/doctor.rb', line 93

def doctor_children # :nodoc:
  REPOSITORY_EXTENSION_MAP.each do |sub_directory, extension|
    doctor_child sub_directory, extension
  end
end

#gem_repository?Boolean

Are we doctoring a gem repository?


61
62
63
# File 'lib/rubygems/doctor.rb', line 61

def gem_repository?
  not installed_specs.empty?
end

#installed_specsObject

Specs installed in this gem repository


54
55
56
# File 'lib/rubygems/doctor.rb', line 54

def installed_specs # :nodoc:
  @installed_specs ||= Gem::Specification.map { |s| s.full_name }
end