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 11
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] ||= []
    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_option('-n', '--bindir DIR',
             'Directory where executables are',
             'located') do |value, options|
    options[:bin_dir] = File.expand_path(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 90
def execute
  specs = if options[:all]
            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?
            Gem::Specification.select do |spec|
              spec.extensions and not spec.extensions.empty?
            end
          else
            get_all_gem_names.sort.map do |gem_name|
              Gem::Specification.find_all_by_name(gem_name, options[:version]).reverse
            end.flatten
          end

  if specs.to_a.empty?
    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 options.has_key? :skip
      if options[:skip].include? spec.name
        say "Skipped #{spec.full_name}, it was given through options"
        next
      end
    end

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

    gem = spec.cache_file

    unless File.exist? gem or options[:only_executables]
      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
        options[:env_shebang]
      else
        install_defaults = Gem::ConfigFile::PLATFORM_DEFAULTS['install']
        install_defaults.to_s['--env-shebang']
      end

    bin_dir = options[:bin_dir] if options[:bin_dir]

    installer_options = {
      :wrappers => true,
      :force => true,
      :install_dir => spec.base_dir,
      :env_shebang => env_shebang,
      :build_args => spec.build_args,
      :bin_dir => bin_dir
    }

    if options[:only_executables]
      installer = Gem::Installer.for_spec(spec, installer_options)
      installer.generate_bin
    else
      installer = Gem::Installer.at(gem, installer_options)
      installer.install
    end

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