123456789_123456789_123456789_123456789_123456789_

Class: Gem::Doctor

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
Inherits: Object
Defined in: lib/rubygems/doctor.rb

Overview

Cleans up after a partially-failed uninstall or for an invalid 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

  • REPOSITORY_EXTENSION_MAP = Internal use only

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

    # File 'lib/rubygems/doctor.rb', line 22
    [ # :nodoc:
      ["specifications", ".gemspec"],
      ["build_info",     ".info"],
      ["cache",          ".gem"],
      ["doc",            ""],
      ["extensions",     ""],
      ["gems",           ""],
      ["plugins",        ""],
    ].freeze

Class Method Summary

Instance Attribute Summary

Instance Method Summary

UserInteraction - Included

#alert

Displays an alert statement.

#alert_error

Displays an error statement to the error output location.

#alert_warning

Displays a warning statement to the warning output location.

#ask

Asks a question and returns the answer.

#ask_for_password

Asks for a password with a prompt

#ask_yes_no

Asks a yes or no question.

#choose_from_list

Asks the user to answer question with an answer from the given list.

#say

Displays the given statement on the standard output (or equivalent).

#terminate_interaction

Terminates the RubyGems process with the given exit_code

#verbose

Calls say with msg or the results of the block if really_verbose is true.

DefaultUserInteraction - Included

Text - Included

#clean_text

Remove any non-printable characters and make the text suitable for printing.

#format_text

Wraps text to wrap characters and optionally indents by indent characters.

#levenshtein_distance

Returns a value representing the “cost” of transforming str1 into str2 Vendored version of DidYouMean::Levenshtein.distance from the ruby/did_you_mean gem @ 1.4.0 github.com/ruby/did_you_mean/blob/2ddf39b874808685965dbc47d344cf6c7651807c/lib/did_you_mean/levenshtein.rb#L7-L37.

#truncate_text, #min3

Constructor Details

.new(gem_repository, dry_run = false) ⇒ Doctor

Creates a new 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.

[ GitHub ]

  
# 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 Attribute Details

#gem_repository?Boolean (readonly)

Are we doctoring a gem repository?

[ GitHub ]

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

def gem_repository?
  !installed_specs.empty?
end

Instance Method Details

#doctor

Cleans up uninstalled files and invalid gem specifications

[ GitHub ]

  
# 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)

This method is for internal use only.

Removes files in sub_directory with extension

[ GitHub ]

  
# 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_children

This method is for internal use only.

Cleans up children of this gem repository

[ GitHub ]

  
# 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

#installed_specs

This method is for internal use only.

Specs installed in this gem repository

[ GitHub ]

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

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