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",           ""],
  ["plugins",        ""],
].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

Methods included from Text

#clean_text, #format_text, #levenshtein_distance, #min3, #truncate_text

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.



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

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



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

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

  say "Checking #{@gem_repository}"

  Gem.use_paths @gem_repository.to_s

  unless gem_repository?
    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



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

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

  Dir.entries(directory).sort.each do |ent|
    next if [".", ".."].include?(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/.match?(basename)
    next if sub_directory == "specifications" && basename == "default"
    next if sub_directory == "plugins" && Gem.plugin_suffix_regexp =~ (basename)

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

    action = if @dry_run
      "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



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

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?

Returns:

  • (Boolean)


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

def gem_repository?
  !installed_specs.empty?
end

#installed_specsObject

Specs installed in this gem repository



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

def installed_specs # :nodoc:
  @installed_specs ||= Gem::Specification.map(&:full_name)
end