class Gem::Commands::UpdateCommand - RDoc Documentation

# 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
      super 'update', 'Update installed gems to the latest version',
        :document => %w[rdoc ri],
        :force    => false

      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 91
    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

      updated_names = updated.map {|spec| spec.name }
      not_updated_names = options[:args].uniq - updated_names

      if updated.empty?
        say "Nothing to update"
      else
        say "Gems updated: #{updated_names.join(' ')}"
        say "Gems already up-to-date: #{not_updated_names.join(' ')}" unless not_updated_names.empty?
      end
    end

preparing_gem_layout_for(version) { || ... } click to toggle source

    # File lib/rubygems/commands/update_command.rb, line 187
    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 207
    def rubygems_target_version
      version = options[:system]
      update_latest = version == true

      if update_latest
        version     = Gem::Version.new     Gem::VERSION
        requirement = Gem::Requirement.new ">= #{Gem::VERSION}"
      else
        version     = Gem::Version.new     version
        requirement = Gem::Requirement.new version
      end

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

      hig = {
        'rubygems-update' => rubygems_update,
      }

      gems_to_update = which_to_update hig, options[:args], :system
      up_ver = gems_to_update.first.version

      target = if update_latest
                 up_ver
               else
                 version
               end

      return target, requirement
    end

update_gem(name, version = Gem::Requirement.default) click to toggle source

    # File lib/rubygems/commands/update_command.rb, line 239
    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 259
    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 270
    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

      update_gem 'rubygems-update', version

      installed_gems = Gem::Specification.find_all_by_name 'rubygems-update', requirement
      version        = installed_gems.first.version

      install_rubygems version
    end

which_to_update(highest_installed_gems, gem_names, system = false) click to toggle source

    # File lib/rubygems/commands/update_command.rb, line 304
    def which_to_update(highest_installed_gems, gem_names, system = false)
      result = []

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

        highest_remote_tup = highest_remote_name_tuple l_spec
        highest_remote_ver = highest_remote_tup.version
        highest_installed_ver = l_spec.version

        if system or (highest_installed_ver < highest_remote_ver)
          result << Gem::NameTuple.new(l_spec.name, [highest_installed_ver, highest_remote_ver].max, highest_remote_tup.platform)
        end
      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 331
    def oldest_supported_version
      @oldest_supported_version ||=
        if 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