class Gem::Commands::UpdateCommand

Public Class Methods

new() click to toggle source
Calls superclass method Gem::Command::new
# File lib/rubygems/commands/update_command.rb, line 21
def initialize
  options = {
    :force => false,
  }

  options.merge!(install_update_options)

  super "update", "Update installed gems to the latest version", options

  add_install_update_options

  Gem::OptionParser.accept Gem::Version do |value|
    Gem::Version.new value

    value
  end

  add_option("--system [VERSION]", Gem::Version,
             "Update the RubyGems system software") do |value, options|
    value = true unless value

    options[:system] = value
  end

  add_local_remote_options
  add_platform_option
  add_prerelease_option "as update targets"

  @updated   = []
  @installer = nil
end

Public Instance Methods

execute() click to toggle source
# File lib/rubygems/commands/update_command.rb, line 96
def execute
  if options[:system]
    update_rubygems
    return
  end

  gems_to_update = which_to_update(
    highest_installed_gems,
    options[:args].uniq
  )

  if options[:explain]
    say "Gems to update:"

    gems_to_update.each do |name_tuple|
      say "  #{name_tuple.full_name}"
    end

    return
  end

  say "Updating installed gems"

  updated = update_gems gems_to_update

  installed_names = highest_installed_gems.keys
  updated_names = updated.map {|spec| spec.name }
  not_updated_names = options[:args].uniq - updated_names
  not_installed_names = not_updated_names - installed_names
  up_to_date_names = not_updated_names - not_installed_names

  if updated.empty?
    say "Nothing to update"
  else
    say "Gems updated: #{updated_names.join(' ')}"
  end
  say "Gems already up-to-date: #{up_to_date_names.join(' ')}" unless up_to_date_names.empty?
  say "Gems not currently installed: #{not_installed_names.join(' ')}" unless not_installed_names.empty?
end
preparing_gem_layout_for(version) { || ... } click to toggle source
# File lib/rubygems/commands/update_command.rb, line 192
def preparing_gem_layout_for(version)
  if Gem::Version.new(version) >= Gem::Version.new("3.2.a")
    yield
  else
    require "tmpdir"
    tmpdir = Dir.mktmpdir
    FileUtils.mv Gem.plugindir, tmpdir

    status = yield

    if status
      FileUtils.rm_rf tmpdir
    else
      FileUtils.mv File.join(tmpdir, "plugins"), Gem.plugindir
    end

    status
  end
end
rubygems_target_version() click to toggle source
# File lib/rubygems/commands/update_command.rb, line 212
def rubygems_target_version
  version = options[:system]
  update_latest = version == true

  unless update_latest
    version     = Gem::Version.new     version
    requirement = Gem::Requirement.new version

    return version, requirement
  end

  version     = Gem::Version.new     Gem::VERSION
  requirement = Gem::Requirement.new ">= #{Gem::VERSION}"

  rubygems_update         = Gem::Specification.new
  rubygems_update.name    = "rubygems-update"
  rubygems_update.version = version

  highest_remote_tup = highest_remote_name_tuple(rubygems_update)
  target = highest_remote_tup ? highest_remote_tup.version : version

  return target, requirement
end
update_gem(name, version = Gem::Requirement.default) click to toggle source
# File lib/rubygems/commands/update_command.rb, line 236
def update_gem(name, version = Gem::Requirement.default)
  return if @updated.any? {|spec| spec.name == name }

  update_options = options.dup
  update_options[:prerelease] = version.prerelease?

  @installer = Gem::DependencyInstaller.new update_options

  say "Updating #{name}" unless options[:system] && options[:silent]
  begin
    @installer.install name, Gem::Requirement.new(version)
  rescue Gem::InstallError, Gem::DependencyError => e
    alert_error "Error installing #{name}:\n\t#{e.message}"
  end

  @installer.installed_gems.each do |spec|
    @updated << spec
  end
end
update_gems(gems_to_update) click to toggle source
# File lib/rubygems/commands/update_command.rb, line 256
def update_gems(gems_to_update)
  gems_to_update.uniq.sort.each do |name_tuple|
    update_gem name_tuple.name, name_tuple.version
  end

  @updated
end
update_rubygems() click to toggle source

Update RubyGems software to the latest version.

# File lib/rubygems/commands/update_command.rb, line 267
def update_rubygems
  if Gem.disable_system_update_message
    alert_error Gem.disable_system_update_message
    terminate_interaction 1
  end

  check_update_arguments

  version, requirement = rubygems_target_version

  check_latest_rubygems version

  check_oldest_rubygems version

  installed_gems = Gem::Specification.find_all_by_name "rubygems-update", requirement
  installed_gems = update_gem("rubygems-update", version) if installed_gems.empty? || installed_gems.first.version != version
  return if installed_gems.empty?

  install_rubygems installed_gems.first
end
which_to_update(highest_installed_gems, gem_names) click to toggle source
# File lib/rubygems/commands/update_command.rb, line 300
def which_to_update(highest_installed_gems, gem_names)
  result = []

  highest_installed_gems.each do |l_name, l_spec|
    next if !gem_names.empty? &&
            gem_names.none? {|name| name == l_spec.name }

    highest_remote_tup = highest_remote_name_tuple l_spec
    next unless highest_remote_tup

    result << highest_remote_tup
  end

  result
end

Private Instance Methods

oldest_supported_version() click to toggle source

Oldest version we support downgrading to. This is the version that originally ships with the first patch version of each ruby, because we never test each ruby against older rubygems, so we can’t really guarantee it works. Version list can be checked here: stdgems.org/rubygems

# File lib/rubygems/commands/update_command.rb, line 324
def oldest_supported_version
  @oldest_supported_version ||=
    if Gem.ruby_version > Gem::Version.new("3.1.a")
      Gem::Version.new("3.3.3")
    elsif Gem.ruby_version > Gem::Version.new("3.0.a")
      Gem::Version.new("3.2.3")
    elsif Gem.ruby_version > Gem::Version.new("2.7.a")
      Gem::Version.new("3.1.2")
    elsif Gem.ruby_version > Gem::Version.new("2.6.a")
      Gem::Version.new("3.0.1")
    elsif Gem.ruby_version > Gem::Version.new("2.5.a")
      Gem::Version.new("2.7.3")
    elsif Gem.ruby_version > Gem::Version.new("2.4.a")
      Gem::Version.new("2.6.8")
    else
      Gem::Version.new("2.5.2")
    end
end