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',           ''],
    ].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

This code is based directly on the Text gem implementation Returns a value representing the “cost” of transforming str1 into str2.

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

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 61

def gem_repository?
  not installed_specs.empty?
end

Instance Method Details

#doctor

Cleans up uninstalled files and invalid gem specifications

[ GitHub ]

  
# 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?
    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 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
               '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 93

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 54

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