class Gem::Commands::PristineCommand

Public Class Methods

new() click to toggle source
Calls superclass method Gem::Command.new
# File lib/rubygems/commands/pristine_command.rb, line 10
def initialize
  super 'pristine',
        'Restores installed gems to pristine condition from files located in the gem cache',
        :version => Gem::Requirement.default,
        :extensions => true,
        :extensions_set => false,
        :all => false

  add_option('--all',
             'Restore all installed gems to pristine',
             'condition') do |value, options|
    options[:all] = value
  end

  add_option('--skip=gem_name',
             'used on --all, skip if name == gem_name') do |value, options|
    options[:skip] = value
  end

  add_option('--[no-]extensions',
             'Restore gems with extensions',
             'in addition to regular gems') do |value, options|
    options[:extensions_set] = true
    options[:extensions]     = value
  end

  add_option('--only-executables',
             'Only restore executables') do |value, options|
    options[:only_executables] = value
  end

  add_option('-E', '--[no-]env-shebang',
             'Rewrite executables with a shebang',
             'of /usr/bin/env') do |value, options|
    options[:env_shebang] = value
  end

  add_version_option('restore to', 'pristine condition')
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/pristine_command.rb, line 82
def execute
  specs = if options[:all] then
            Gem::Specification.map

          # `--extensions` must be explicitly given to pristine only gems
          # with extensions.
          elsif options[:extensions_set] and
                options[:extensions] and options[:args].empty? then
            Gem::Specification.select do |spec|
              spec.extensions and not spec.extensions.empty?
            end
          else
            get_all_gem_names.map do |gem_name|
              Gem::Specification.find_all_by_name gem_name, options[:version]
            end.flatten
          end

  if specs.to_a.empty? then
    raise Gem::Exception,
          "Failed to find gems #{options[:args]} #{options[:version]}"
  end

  install_dir = Gem.dir # TODO use installer option

  raise Gem::FilePermissionError.new(install_dir) unless
    File.writable?(install_dir)

  say "Restoring gems to pristine condition..."

  specs.each do |spec|
    if spec.default_gem?
      say "Skipped #{spec.full_name}, it is a default gem"
      next
    end

    if spec.name == options[:skip]
      say "Skipped #{spec.full_name}, it was given through options"
      next
    end

    if spec.bundled_gem_in_old_ruby?
      say "Skipped #{spec.full_name}, it is bundled with old Ruby"
      next
    end

    unless spec.extensions.empty? or options[:extensions] then
      say "Skipped #{spec.full_name}, it needs to compile an extension"
      next
    end

    gem = spec.cache_file

    unless File.exist? gem then
      require 'rubygems/remote_fetcher'

      say "Cached gem for #{spec.full_name} not found, attempting to fetch..."

      dep = Gem::Dependency.new spec.name, spec.version
      found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep

      if found.empty?
        say "Skipped #{spec.full_name}, it was not found from cache and remote sources"
        next
      end

      spec_candidate, source = found.first
      Gem::RemoteFetcher.fetcher.download spec_candidate, source.uri.to_s, spec.base_dir
    end

    env_shebang =
      if options.include? :env_shebang then
        options[:env_shebang]
      else
        install_defaults = Gem::ConfigFile::PLATFORM_DEFAULTS['install']
        install_defaults.to_s['--env-shebang']
      end

    installer = Gem::Installer.at(gem,
                                   :wrappers => true,
                                   :force => true,
                                   :install_dir => spec.base_dir,
                                   :env_shebang => env_shebang,
                                   :build_args => spec.build_args)

    if options[:only_executables] then
      installer.generate_bin
    else
      installer.install
    end

    say "Restored #{spec.full_name}"
  end
end