![show/hide quicksearch [+]](../../images/find.png)
Installs RubyGems itself. This command is ordinarily only available from a RubyGems checkout or tarball.
 
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 14
def initialize
  super 'setup', 'Install RubyGems',
        :format_executable => false, :document => %w[ri],
        :force => true,
        :site_or_vendor => 'sitelibdir',
        :destdir => '', :prefix => '', :previous_version => '',
        :regenerate_binstubs => true,
        :regenerate_plugins => true
  add_option '--previous-version=VERSION',
             'Previous version of RubyGems',
             'Used for changelog processing' do |version, options|
    options[:previous_version] = version
  end
  add_option '--prefix=PREFIX',
             'Prefix path for installing RubyGems',
             'Will not affect gem repository location' do |prefix, options|
    options[:prefix] = File.expand_path prefix
  end
  add_option '--destdir=DESTDIR',
             'Root directory to install RubyGems into',
             'Mainly used for packaging RubyGems' do |destdir, options|
    options[:destdir] = File.expand_path destdir
  end
  add_option '--[no-]vendor',
             'Install into vendorlibdir not sitelibdir' do |vendor, options|
    options[:site_or_vendor] = vendor ? 'vendorlibdir' : 'sitelibdir'
  end
  add_option '--[no-]format-executable',
             'Makes `gem` match ruby',
             'If Ruby is ruby18, gem will be gem18' do |value, options|
    options[:format_executable] = value
  end
  add_option '--[no-]document [TYPES]', Array,
             'Generate documentation for RubyGems',
             'List the documentation types you wish to',
             'generate.  For example: rdoc,ri' do |value, options|
    options[:document] = case value
    when nil   then %w[rdoc ri]
    when false then []
    else            value
    end
  end
  add_option '--[no-]rdoc',
             'Generate RDoc documentation for RubyGems' do |value, options|
    if value
      options[:document] << 'rdoc'
    else
      options[:document].delete 'rdoc'
    end
    options[:document].uniq!
  end
  add_option '--[no-]ri',
             'Generate RI documentation for RubyGems' do |value, options|
    if value
      options[:document] << 'ri'
    else
      options[:document].delete 'ri'
    end
    options[:document].uniq!
  end
  add_option '--[no-]regenerate-binstubs',
             'Regenerate gem binstubs' do |value, options|
    options[:regenerate_binstubs] = value
  end
  add_option '--[no-]regenerate-plugins',
             'Regenerate gem plugins' do |value, options|
    options[:regenerate_plugins] = value
  end
  add_option '-f', '--[no-]force',
             'Forcefully overwrite binstubs' do |value, options|
    options[:force] = 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
  @verbose = nil
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 676
def bin_file_names
  @bin_file_names ||= []
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 109
def check_ruby_version
  required_version = Gem::Requirement.new '>= 2.3.0'
  unless required_version.satisfied_by? Gem.ruby_version
    alert_error "Expected Ruby version #{required_version}, is #{Gem.ruby_version}"
    terminate_interaction 1
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 621
def default_dir
  prefix = options[:prefix]
  if prefix.empty?
    dir = Gem.default_dir
  else
    dir = prefix
  end
  prepend_destdir_if_present(dir)
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 147
def execute
  @verbose = Gem.configuration.really_verbose
  check_ruby_version
  require 'fileutils'
  if Gem.configuration.really_verbose
    extend FileUtils::Verbose
  else
    extend FileUtils
  end
  extend MakeDirs
  lib_dir, bin_dir = make_destination_dirs
  man_dir = generate_default_man_dir
  install_lib lib_dir
  install_executables bin_dir
  remove_old_bin_files bin_dir
  remove_old_lib_files lib_dir
  # Can be removed one we drop support for bundler 2.2.3 (the last version installing man files to man_dir)
  remove_old_man_files man_dir if man_dir && File.exist?(man_dir)
  install_default_bundler_gem bin_dir
  if mode = options[:dir_mode]
    @mkdirs.uniq!
    File.chmod(mode, @mkdirs)
  end
  say "RubyGems #{Gem::VERSION} installed"
  regenerate_binstubs(bin_dir) if options[:regenerate_binstubs]
  regenerate_plugins(bin_dir) if options[:regenerate_plugins]
  uninstall_old_gemcutter
  documentation_success = install_rdoc
  say
  if @verbose
    say "-" * 78
    say
  end
  if options[:previous_version].empty?
    options[:previous_version] = Gem::VERSION.sub(/[0-9]+$/, '0')
  end
  options[:previous_version] = Gem::Version.new(options[:previous_version])
  show_release_notes
  say
  say "-" * 78
  say
  say "RubyGems installed the following executables:"
  say bin_file_names.map {|name| "\t#{name}\n" }
  say
  unless bin_file_names.grep(/#{File::SEPARATOR}gem$/)
    say "If `gem` was installed by a previous RubyGems installation, you may need"
    say "to remove it by hand."
    say
  end
  if documentation_success
    if options[:document].include? 'rdoc'
      say "Rdoc documentation was installed. You may now invoke:"
      say "  gem server"
      say "and then peruse beautifully formatted documentation for your gems"
      say "with your web browser."
      say "If you do not wish to install this documentation in the future, use the"
      say "--no-document flag, or set it as the default in your ~/.gemrc file. See"
      say "'gem help env' for details."
      say
    end
    if options[:document].include? 'ri'
      say "Ruby Interactive (ri) documentation was installed. ri is kind of like man "
      say "pages for Ruby libraries. You may access it like this:"
      say "  ri Classname"
      say "  ri Classname.class_method"
      say "  ri Classname#instance_method"
      say "If you do not wish to install this documentation in the future, use the"
      say "--no-document flag, or set it as the default in your ~/.gemrc file. See"
      say "'gem help env' for details."
      say
    end
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 475
def files_in(dir)
  Dir.chdir dir do
    Dir.glob(File.join('**', '*'), File::FNM_DOTMATCH).
      select{|f| !File.directory?(f) }
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 460
def generate_default_dirs
  prefix = options[:prefix]
  site_or_vendor = options[:site_or_vendor]
  if prefix.empty?
    lib_dir = RbConfig::CONFIG[site_or_vendor]
    bin_dir = RbConfig::CONFIG['bindir']
  else
    lib_dir = File.join prefix, 'lib'
    bin_dir = File.join prefix, 'bin'
  end
  [prepend_destdir_if_present(lib_dir), prepend_destdir_if_present(bin_dir)]
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 447
def generate_default_man_dir
  prefix = options[:prefix]
  if prefix.empty?
    man_dir = RbConfig::CONFIG['mandir']
    return unless man_dir
  else
    man_dir = File.join prefix, 'man'
  end
  prepend_destdir_if_present(man_dir)
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 362
def install_default_bundler_gem(bin_dir)
  specs_dir = File.join(default_dir, "specifications", "default")
  mkdir_p specs_dir, :mode => 0755
  bundler_spec = Dir.chdir("bundler") { Gem::Specification.load("bundler.gemspec") }
  # Remove bundler-*.gemspec in default specification directory.
  Dir.entries(specs_dir).
    select {|gs| gs.start_with?("bundler-") }.
    each {|gs| File.delete(File.join(specs_dir, gs)) }
  default_spec_path = File.join(specs_dir, "#{bundler_spec.full_name}.gemspec")
  Gem.write_binary(default_spec_path, bundler_spec.to_ruby)
  bundler_spec = Gem::Specification.load(default_spec_path)
  # The base_dir value for a specification is inferred by walking up from the
  # folder where the spec was `loaded_from`. In the case of default gems, we
  # walk up two levels, because they live at `specifications/default/`, whereas
  # in the case of regular gems we walk up just one level because they live at
  # `specifications/`. However, in this case, the gem we are installing is
  # misdetected as a regular gem, when it's a default gem in reality. This is
  # because when there's a `:destdir`, the `loaded_from` path has changed and
  # doesn't match `Gem.default_specifications_dir` which is the criteria to
  # tag a gem as a default gem. So, in that case, write the correct
  # `@base_dir` directly.
  bundler_spec.instance_variable_set(:@base_dir, File.dirname(File.dirname(specs_dir)))
  # Remove gemspec that was same version of vendored bundler.
  normal_gemspec = File.join(default_dir, "specifications", "bundler-#{bundler_spec.version}.gemspec")
  if File.file? normal_gemspec
    File.delete normal_gemspec
  end
  # Remove gem files that were same version of vendored bundler.
  if File.directory? bundler_spec.gems_dir
    Dir.entries(bundler_spec.gems_dir).
      select {|default_gem| File.basename(default_gem) == "bundler-#{bundler_spec.version}" }.
      each {|default_gem| rm_r File.join(bundler_spec.gems_dir, default_gem) }
  end
  bundler_bin_dir = bundler_spec.bin_dir
  mkdir_p bundler_bin_dir, :mode => 0755
  bundler_spec.executables.each do |e|
    cp File.join("bundler", bundler_spec.bindir, e), File.join(bundler_bin_dir, e)
  end
  require_relative '../installer'
  Dir.chdir("bundler") do
    built_gem = Gem::Package.build(bundler_spec)
    begin
      Gem::Installer.at(
        built_gem,
        env_shebang: options[:env_shebang],
        format_executable: options[:format_executable],
        force: options[:force],
        install_as_default: true,
        bin_dir: bin_dir,
        install_dir: default_dir,
        wrappers: true
      ).install
    ensure
      FileUtils.rm_f built_gem
    end
  end
  bundler_spec.executables.each {|executable| bin_file_names << target_bin_path(bin_dir, executable) }
  say "Bundler #{bundler_spec.version} installed"
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 244
  def install_executables(bin_dir)
    prog_mode = options[:prog_mode] || 0755
    executables = { 'gem' => 'bin' }
    executables.each do |tool, path|
      say "Installing #{tool} executable" if @verbose
      Dir.chdir path do
        bin_file = "gem"
        require 'tmpdir'
        dest_file = target_bin_path(bin_dir, bin_file)
        bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
        begin
          bin = File.readlines bin_file
          bin[0] = shebang
          File.open bin_tmp_file, 'w' do |fp|
            fp.puts bin.join
          end
          install bin_tmp_file, dest_file, :mode => prog_mode
          bin_file_names << dest_file
        ensure
          rm bin_tmp_file
        end
        next unless Gem.win_platform?
        begin
          bin_cmd_file = File.join Dir.tmpdir, "#{bin_file}.bat"
          File.open bin_cmd_file, 'w' do |file|
            file.puts <<-TEXT
  @ECHO OFF
  IF NOT "%~f0" == "~f0" GOTO :WinNT
  @"#{File.basename(Gem.ruby).chomp('"')}" "#{dest_file}" %1 %2 %3 %4 %5 %6 %7 %8 %9
  GOTO :EOF
  :WinNT
  @"#{File.basename(Gem.ruby).chomp('"')}" "%~dpn0" %*
  TEXT
          end
          install bin_cmd_file, "#{dest_file}.bat", :mode => prog_mode
        ensure
          rm bin_cmd_file
        end
      end
    end
  end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 646
def install_file(file, dest_dir)
  dest_file = File.join dest_dir, file
  dest_dir = File.dirname dest_file
  unless File.directory? dest_dir
    mkdir_p dest_dir, :mode => 0755
  end
  install file, dest_file, :mode => options[:data_mode] || 0644
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 640
def install_file_list(files, dest_dir)
  files.each do |file|
    install_file file, dest_dir
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 307
def install_lib(lib_dir)
  libs = { 'RubyGems' => 'lib' }
  libs['Bundler'] = 'bundler/lib'
  libs.each do |tool, path|
    say "Installing #{tool}" if @verbose
    lib_files = files_in path
    Dir.chdir path do
      install_file_list(lib_files, lib_dir)
    end
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 321
def install_rdoc
  gem_doc_dir = File.join Gem.dir, 'doc'
  rubygems_name = "rubygems-#{Gem::VERSION}"
  rubygems_doc_dir = File.join gem_doc_dir, rubygems_name
  begin
    Gem.ensure_gem_subdirectories Gem.dir
  rescue SystemCallError
    # ignore
  end
  if File.writable? gem_doc_dir and
     (not File.exist? rubygems_doc_dir or
      File.writable? rubygems_doc_dir)
    say "Removing old RubyGems RDoc and ri" if @verbose
    Dir[File.join(Gem.dir, 'doc', 'rubygems-[0-9]*')].each do |dir|
      rm_rf dir
    end
    require_relative '../rdoc'
    fake_spec = Gem::Specification.new 'rubygems', Gem::VERSION
    def fake_spec.full_gem_path
      File.expand_path '../../../..', __FILE__
    end
    generate_ri   = options[:document].include? 'ri'
    generate_rdoc = options[:document].include? 'rdoc'
    rdoc = Gem::RDoc.new fake_spec, generate_rdoc, generate_ri
    rdoc.generate
    return true
  elsif @verbose
    say "Skipping RDoc generation, #{gem_doc_dir} not writable"
    say "Set the GEM_HOME environment variable if you want RDoc generated"
  end
  return false
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 434
def make_destination_dirs
  lib_dir, bin_dir = Gem.default_rubygems_dirs
  unless lib_dir
    lib_dir, bin_dir = generate_default_dirs
  end
  mkdir_p lib_dir, :mode => 0755
  mkdir_p bin_dir, :mode => 0755
  return lib_dir, bin_dir
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 633
def prepend_destdir_if_present(path)
  destdir = options[:destdir]
  return path if destdir.empty?
  File.join(options[:destdir], path.gsub(/^[a-zA-Z]:/, ''))
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 593
def regenerate_binstubs(bindir)
  require_relative "pristine_command"
  say "Regenerating binstubs"
  args = %w[--all --only-executables --silent]
  args << "--bindir=#{bindir}"
  if options[:env_shebang]
    args << "--env-shebang"
  end
  command = Gem::Commands::PristineCommand.new
  command.invoke(*args)
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 607
def regenerate_plugins(bindir)
  require_relative "pristine_command"
  say "Regenerating plugins"
  args = %w[--all --only-plugins --silent]
  args << "--bindir=#{bindir}"
  args << "--install-dir=#{default_dir}"
  command = Gem::Commands::PristineCommand.new
  command.invoke(*args)
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 656
def remove_file_list(files, dir)
  Dir.chdir dir do
    files.each do |file|
      FileUtils.rm_f file
      warn "unable to remove old file #{file} please remove it by hand" if
        File.exist? file
    end
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 482
  def remove_old_bin_files(bin_dir)
    old_bin_files = {
      'gem_mirror' => 'gem mirror',
      'gem_server' => 'gem server',
      'gemlock' => 'gem lock',
      'gemri' => 'ri',
      'gemwhich' => 'gem which',
      'index_gem_repository.rb' => 'gem generate_index',
    }
    old_bin_files.each do |old_bin_file, new_name|
      old_bin_path = File.join bin_dir, old_bin_file
      next unless File.exist? old_bin_path
      deprecation_message = "`#{old_bin_file}` has been deprecated. Use `#{new_name}` instead."
      File.open old_bin_path, 'w' do |fp|
        fp.write <<-EOF
#!#{Gem.ruby}
abort "#{deprecation_message}"
    EOF
      end
      next unless Gem.win_platform?
      File.open "#{old_bin_path}.bat", 'w' do |fp|
        fp.puts %(@ECHO.#{deprecation_message})
      end
    end
  end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 514
def remove_old_lib_files(lib_dir)
  lib_dirs = { File.join(lib_dir, 'rubygems') => 'lib/rubygems' }
  lib_dirs[File.join(lib_dir, 'bundler')] = 'bundler/lib/bundler'
  lib_dirs.each do |old_lib_dir, new_lib_dir|
    lib_files = files_in(new_lib_dir)
    old_lib_files = files_in(old_lib_dir)
    to_remove = old_lib_files - lib_files
    gauntlet_rubygems = File.join(lib_dir, 'gauntlet_rubygems.rb')
    to_remove << gauntlet_rubygems if File.exist? gauntlet_rubygems
    to_remove.delete_if do |file|
      file.start_with? 'defaults'
    end
    remove_file_list(to_remove, old_lib_dir)
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 535
def remove_old_man_files(old_man_dir)
  old_man1_dir = "#{old_man_dir}/man1"
  if File.exist?(old_man1_dir)
    man1_to_remove = Dir.chdir(old_man1_dir) { Dir["bundle*.1{,.txt,.ronn}"] }
    remove_file_list(man1_to_remove, old_man1_dir)
  end
  old_man5_dir = "#{old_man_dir}/man5"
  if File.exist?(old_man5_dir)
    man5_to_remove = Dir.chdir(old_man5_dir) { Dir["gemfile.5{,.txt,.ronn}"] }
    remove_file_list(man5_to_remove, old_man5_dir)
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 297
def shebang
  if options[:env_shebang]
    ruby_name = RbConfig::CONFIG['ruby_install_name']
    @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
    "#!#{@env_path} #{ruby_name}\n"
  else
    "#!#{Gem.ruby}\n"
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 553
  def show_release_notes
    release_notes = File.join Dir.pwd, 'CHANGELOG.md'
    release_notes =
      if File.exist? release_notes
        history = File.read release_notes
        history.force_encoding Encoding::UTF_8
        text = history.split(HISTORY_HEADER)
        text.shift # correct an off-by-one generated by split
        version_lines = history.scan(HISTORY_HEADER)
        versions = history.scan(VERSION_MATCHER).flatten.map do |x|
          Gem::Version.new(x)
        end
        history_string = ""
        until versions.length == 0 or
              versions.shift <= options[:previous_version] do
          history_string += version_lines.shift + text.shift
        end
        history_string
      else
        "Oh-no! Unable to find release notes!"
      end
    say release_notes
  end
  def uninstall_old_gemcutter
    require_relative '../uninstaller'
    ui = Gem::Uninstaller.new('gemcutter', :all => true, :ignore => true,
                              :version => '< 0.4')
    ui.uninstall
  rescue Gem::InstallError
  end
  def regenerate_binstubs(bindir)
    require_relative "pristine_command"
    say "Regenerating binstubs"
    args = %w[--all --only-executables --silent]
    args << "--bindir=#{bindir}"
    if options[:env_shebang]
      args << "--env-shebang"
    end
    command = Gem::Commands::PristineCommand.new
    command.invoke(*args)
  end
  def regenerate_plugins(bindir)
    require_relative "pristine_command"
    say "Regenerating plugins"
    args = %w[--all --only-plugins --silent]
    args << "--bindir=#{bindir}"
    args << "--install-dir=#{default_dir}"
    command = Gem::Commands::PristineCommand.new
    command.invoke(*args)
  end
  private
  def default_dir
    prefix = options[:prefix]
    if prefix.empty?
      dir = Gem.default_dir
    else
      dir = prefix
    end
    prepend_destdir_if_present(dir)
  end
  def prepend_destdir_if_present(path)
    destdir = options[:destdir]
    return path if destdir.empty?
    File.join(options[:destdir], path.gsub(/^[a-zA-Z]:/, ''))
  end
  def install_file_list(files, dest_dir)
    files.each do |file|
      install_file file, dest_dir
    end
  end
  def install_file(file, dest_dir)
    dest_file = File.join dest_dir, file
    dest_dir = File.dirname dest_file
    unless File.directory? dest_dir
      mkdir_p dest_dir, :mode => 0755
    end
    install file, dest_file, :mode => options[:data_mode] || 0644
  end
  def remove_file_list(files, dir)
    Dir.chdir dir do
      files.each do |file|
        FileUtils.rm_f file
        warn "unable to remove old file #{file} please remove it by hand" if
          File.exist? file
      end
    end
  end
  def target_bin_path(bin_dir, bin_file)
    bin_file_formatted = if options[:format_executable]
      Gem.default_exec_format % bin_file
    else
      bin_file
    end
    File.join bin_dir, bin_file_formatted
  end
  def bin_file_names
    @bin_file_names ||= []
  end
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 667
def target_bin_path(bin_dir, bin_file)
  bin_file_formatted = if options[:format_executable]
    Gem.default_exec_format % bin_file
  else
    bin_file
  end
  File.join bin_dir, bin_file_formatted
end
             
             
               # File ruby-3.1.2/lib/rubygems/commands/setup_command.rb, line 584
def uninstall_old_gemcutter
  require_relative '../uninstaller'
  ui = Gem::Uninstaller.new('gemcutter', :all => true, :ignore => true,
                            :version => '< 0.4')
  ui.uninstall
rescue Gem::InstallError
end