ruby-changes:51324
From: hsbt <ko1@a...>
Date: Wed, 30 May 2018 22:01:47 +0900 (JST)
Subject: [ruby-changes:51324] hsbt:r63528 (trunk): Merge RubyGems 3.0.0.beta1.
hsbt 2018-05-30 22:01:35 +0900 (Wed, 30 May 2018) New Revision: 63528 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63528 Log: Merge RubyGems 3.0.0.beta1. * It drop to support < Ruby 2.2 * Cleanup deprecated methods and classes. * Mark obsoleted methods to deprecate. * and other enhancements. Added files: trunk/lib/rubygems/commands/info_command.rb trunk/lib/rubygems/specification_policy.rb trunk/test/rubygems/test_gem_commands_info_command.rb Removed files: trunk/test/rubygems/fix_openssl_warnings.rb Modified files: trunk/lib/rubygems/command.rb trunk/lib/rubygems/command_manager.rb trunk/lib/rubygems/commands/build_command.rb trunk/lib/rubygems/commands/environment_command.rb trunk/lib/rubygems/commands/install_command.rb trunk/lib/rubygems/commands/pristine_command.rb trunk/lib/rubygems/commands/setup_command.rb trunk/lib/rubygems/commands/uninstall_command.rb trunk/lib/rubygems/commands/unpack_command.rb trunk/lib/rubygems/commands/update_command.rb trunk/lib/rubygems/compatibility.rb trunk/lib/rubygems/config_file.rb trunk/lib/rubygems/core_ext/kernel_require.rb trunk/lib/rubygems/defaults.rb trunk/lib/rubygems/dependency_installer.rb trunk/lib/rubygems/exceptions.rb trunk/lib/rubygems/ext/builder.rb trunk/lib/rubygems/ext/cmake_builder.rb trunk/lib/rubygems/ext/configure_builder.rb trunk/lib/rubygems/ext/ext_conf_builder.rb trunk/lib/rubygems/ext/rake_builder.rb trunk/lib/rubygems/installer.rb trunk/lib/rubygems/installer_test_case.rb trunk/lib/rubygems/local_remote_options.rb trunk/lib/rubygems/package/old.rb trunk/lib/rubygems/package/tar_header.rb trunk/lib/rubygems/package/tar_reader/entry.rb trunk/lib/rubygems/package/tar_reader.rb trunk/lib/rubygems/package/tar_test_case.rb trunk/lib/rubygems/package/tar_writer.rb trunk/lib/rubygems/package.rb trunk/lib/rubygems/rdoc.rb trunk/lib/rubygems/remote_fetcher.rb trunk/lib/rubygems/request/connection_pools.rb trunk/lib/rubygems/request_set/gem_dependency_api.rb trunk/lib/rubygems/request_set/lockfile/parser.rb trunk/lib/rubygems/request_set.rb trunk/lib/rubygems/requirement.rb trunk/lib/rubygems/resolver/api_specification.rb trunk/lib/rubygems/resolver.rb trunk/lib/rubygems/security/trust_dir.rb trunk/lib/rubygems/specification.rb trunk/lib/rubygems/stub_specification.rb trunk/lib/rubygems/test_case.rb trunk/lib/rubygems/uninstaller.rb trunk/lib/rubygems/user_interaction.rb trunk/lib/rubygems/util/licenses.rb trunk/lib/rubygems/util.rb trunk/lib/rubygems.rb trunk/test/rubygems/test_gem.rb trunk/test/rubygems/test_gem_command_manager.rb trunk/test/rubygems/test_gem_commands_build_command.rb trunk/test/rubygems/test_gem_commands_cert_command.rb trunk/test/rubygems/test_gem_commands_dependency_command.rb trunk/test/rubygems/test_gem_commands_environment_command.rb trunk/test/rubygems/test_gem_commands_help_command.rb trunk/test/rubygems/test_gem_commands_install_command.rb trunk/test/rubygems/test_gem_commands_owner_command.rb trunk/test/rubygems/test_gem_commands_pristine_command.rb trunk/test/rubygems/test_gem_commands_query_command.rb trunk/test/rubygems/test_gem_commands_setup_command.rb trunk/test/rubygems/test_gem_commands_signin_command.rb trunk/test/rubygems/test_gem_commands_specification_command.rb trunk/test/rubygems/test_gem_commands_stale_command.rb trunk/test/rubygems/test_gem_commands_uninstall_command.rb trunk/test/rubygems/test_gem_commands_unpack_command.rb trunk/test/rubygems/test_gem_commands_update_command.rb trunk/test/rubygems/test_gem_dependency_installer.rb trunk/test/rubygems/test_gem_dependency_list.rb trunk/test/rubygems/test_gem_ext_builder.rb trunk/test/rubygems/test_gem_ext_cmake_builder.rb trunk/test/rubygems/test_gem_ext_configure_builder.rb trunk/test/rubygems/test_gem_ext_ext_conf_builder.rb trunk/test/rubygems/test_gem_ext_rake_builder.rb trunk/test/rubygems/test_gem_gemcutter_utilities.rb trunk/test/rubygems/test_gem_installer.rb trunk/test/rubygems/test_gem_local_remote_options.rb trunk/test/rubygems/test_gem_package.rb trunk/test/rubygems/test_gem_package_tar_header.rb trunk/test/rubygems/test_gem_package_tar_writer.rb trunk/test/rubygems/test_gem_path_support.rb trunk/test/rubygems/test_gem_remote_fetcher.rb trunk/test/rubygems/test_gem_request_connection_pools.rb trunk/test/rubygems/test_gem_request_set.rb trunk/test/rubygems/test_gem_request_set_gem_dependency_api.rb trunk/test/rubygems/test_gem_request_set_lockfile_parser.rb trunk/test/rubygems/test_gem_requirement.rb trunk/test/rubygems/test_gem_resolver.rb trunk/test/rubygems/test_gem_resolver_api_specification.rb trunk/test/rubygems/test_gem_resolver_installer_set.rb trunk/test/rubygems/test_gem_security.rb trunk/test/rubygems/test_gem_server.rb trunk/test/rubygems/test_gem_specification.rb trunk/test/rubygems/test_gem_stream_ui.rb trunk/test/rubygems/test_gem_uninstaller.rb trunk/test/rubygems/test_gem_util.rb trunk/test/rubygems/test_require.rb Index: lib/rubygems/commands/info_command.rb =================================================================== --- lib/rubygems/commands/info_command.rb (nonexistent) +++ lib/rubygems/commands/info_command.rb (revision 63528) @@ -0,0 +1,33 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/info_command.rb#L1 +# frozen_string_literal: true + +require 'rubygems/command' +require 'rubygems/commands/query_command' + +class Gem::Commands::InfoCommand < Gem::Commands::QueryCommand + def initialize + super "info", "Show information for the given gem" + + remove_option('--name-matches') + remove_option('-d') + + defaults[:details] = true + defaults[:exact] = true + end + + def description # :nodoc: + "Info prints information about the gem such as name,"\ + " description, website, license and installed paths" + end + + def usage # :nodoc: + "#{program_name} GEMNAME" + end + + def arguments # :nodoc: + "GEMNAME name of the gem to print information about" + end + + def defaults_str + "--local" + end +end Index: lib/rubygems/commands/setup_command.rb =================================================================== --- lib/rubygems/commands/setup_command.rb (revision 63527) +++ lib/rubygems/commands/setup_command.rb (revision 63528) @@ -6,8 +6,10 @@ require 'rubygems/command' https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L6 # RubyGems checkout or tarball. class Gem::Commands::SetupCommand < Gem::Command - HISTORY_HEADER = /^===\s*[\d.]+\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/ - VERSION_MATCHER = /^===\s*([\d.]+)\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/ + HISTORY_HEADER = /^===\s*[\d.a-zA-Z]+\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/ + VERSION_MATCHER = /^===\s*([\d.a-zA-Z]+)\s*\/\s*\d{4}-\d{2}-\d{2}\s*$/ + + ENV_PATHS = %w[/usr/bin/env /bin/env] def initialize require 'tmpdir' @@ -85,6 +87,12 @@ class Gem::Commands::SetupCommand < Gem: https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L87 options[:regenerate_binstubs] = 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 @@ -119,6 +127,13 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L127 EOF end + module MakeDirs + def mkdir_p(path, *opts) + super + (@mkdirs ||= []) << path + end + end + def execute @verbose = Gem.configuration.really_verbose @@ -137,6 +152,7 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L152 else extend FileUtils end + extend MakeDirs lib_dir, bin_dir = make_destination_dirs install_destdir @@ -150,6 +166,11 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L166 install_default_bundler_gem + if mode = options[:dir_mode] + @mkdirs.uniq! + File.chmod(mode, @mkdirs) + end + say "RubyGems #{Gem::VERSION} installed" regenerate_binstubs if options[:regenerate_binstubs] @@ -216,6 +237,8 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L237 def install_executables(bin_dir) @bin_file_names = [] + prog_mode = options[:prog_mode] || 0755 + executables = { 'gem' => 'bin' } executables['bundler'] = 'bundler/exe' if Gem::USE_BUNDLER_FOR_GEMDEPS executables.each do |tool, path| @@ -238,13 +261,13 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L261 begin bin = File.readlines bin_file - bin[0] = "#!#{Gem.ruby}\n" + bin[0] = shebang File.open bin_tmp_file, 'w' do |fp| fp.puts bin.join end - install bin_tmp_file, dest_file, :mode => 0755 + install bin_tmp_file, dest_file, :mode => prog_mode @bin_file_names << dest_file ensure rm bin_tmp_file @@ -266,7 +289,7 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L289 TEXT end - install bin_cmd_file, "#{dest_file}.bat", :mode => 0755 + install bin_cmd_file, "#{dest_file}.bat", :mode => prog_mode ensure rm bin_cmd_file end @@ -275,12 +298,24 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L298 end end + 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 + def install_file file, dest_dir dest_file = File.join dest_dir, file dest_dir = File.dirname dest_file - mkdir_p dest_dir unless File.directory? dest_dir + unless File.directory? dest_dir + mkdir_p dest_dir, :mode => 0700 + end - install file, dest_file, :mode => 0644 + install file, dest_file, :mode => options[:data_mode] || 0644 end def install_lib(lib_dir) @@ -352,7 +387,7 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L387 specs_dir = Gem::Specification.default_specifications_dir specs_dir = File.join(options[:destdir], specs_dir) unless Gem.win_platform? - mkdir_p specs_dir + mkdir_p specs_dir, :mode => 0700 # Workaround for non-git environment. gemspec = File.open('bundler/bundler.gemspec', 'rb'){|f| f.read.gsub(/`git ls-files -z`/, "''") } @@ -387,7 +422,7 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L422 bundler_bin_dir = bundler_spec.bin_dir bundler_bin_dir = File.join(options[:destdir], bundler_bin_dir) unless Gem.win_platform? - mkdir_p bundler_bin_dir + mkdir_p bundler_bin_dir, :mode => 0700 bundler_spec.executables.each do |e| cp File.join("bundler", bundler_spec.bindir, e), File.join(bundler_bin_dir, e) end @@ -411,8 +446,8 @@ By default, this RubyGems will install g https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L446 lib_dir, bin_dir = generate_default_dirs(install_destdir) end - mkdir_p lib_dir - mkdir_p bin_dir + mkdir_p lib_dir, :mode => 0700 + mkdir_p bin_dir, :mode => 0700 return lib_dir, bin_dir end @@ -543,8 +578,7 @@ abort "#{deprecation_message}" https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L578 if File.exist? release_notes then history = File.read release_notes - history.force_encoding Encoding::UTF_8 if - Object.const_defined? :Encoding + history.force_encoding Encoding::UTF_8 history = history.sub(/^# coding:.*?(?=^=)/m, '') @@ -582,8 +616,14 @@ abort "#{deprecation_message}" https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/setup_command.rb#L616 def regenerate_binstubs require "rubygems/commands/pristine_command" say "Regenerating binstubs" + + args = %w[--all --only-executables --silent] + if options[:env_shebang] + args << "--env-shebang" + end + command = Gem::Commands::PristineCommand.new - command.invoke(*%w[--all --only-executables --silent]) + command.invoke(*args) end end Index: lib/rubygems/commands/uninstall_command.rb =================================================================== --- lib/rubygems/commands/uninstall_command.rb (revision 63527) +++ lib/rubygems/commands/uninstall_command.rb (revision 63528) @@ -129,11 +129,7 @@ that is a dependency of an existing gem. https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/uninstall_command.rb#L129 specs.each do |spec| options[:version] = spec.version - - begin - Gem::Uninstaller.new(spec.name, options).uninstall - rescue Gem::InstallError - end + uninstall_gem spec.name end alert "Uninstalled all gems in #{options[:install_dir]}" @@ -153,14 +149,27 @@ that is a dependency of an existing gem. https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/uninstall_command.rb#L149 deps = deplist.strongly_connected_components.flatten.reverse deps.map(&:name).uniq.each do |gem_name| - begin - Gem::Uninstaller.new(gem_name, options).uninstall - rescue Gem::GemNotInHomeException => e - spec = e.spec - alert("In order to remove #{spec.name}, please execute:\n" + - "\tgem uninstall #{spec.name} --install-dir=#{spec.installation_path}") - end + uninstall_gem(gem_name) end end + def uninstall_gem(gem_name) + uninstall(gem_name) + rescue Gem::InstallError + nil + rescue Gem::GemNotInHomeException => e + spec = e.spec + alert("In order to remove #{spec.name}, please execute:\n" + + "\tgem uninstall #{spec.name} --install-dir=#{spec.installation_path}") + rescue Gem::UninstallError => e + spec = e.spec + alert_error("Error: unable to successfully uninstall '#{spec.name}' which is " + + "located at '#{spec.full_gem_path}'. This is most likely because" + + "the current user does not have the appropriate permissions") + terminate_interaction 1 + end + + def uninstall(gem_name) + Gem::Uninstaller.new(gem_name, options).uninstall + end end Index: lib/rubygems/security/trust_dir.rb =================================================================== --- lib/rubygems/security/trust_dir.rb (revision 63527) +++ lib/rubygems/security/trust_dir.rb (revision 63528) @@ -93,8 +93,9 @@ class Gem::Security::TrustDir https://github.com/ruby/ruby/blob/trunk/lib/rubygems/security/trust_dir.rb#L93 destination = cert_path certificate - File.open destination, 'wb', @permissions[:trusted_cert] do |io| + File.open destination, 'wb', 0600 do |io| io.write certificate.to_pem + io.chmod(@permissions[:trusted_cert]) end end Index: lib/rubygems/stub_specification.rb =================================================================== --- lib/rubygems/stub_specification.rb (revision 63527) +++ lib/rubygems/stub_specification.rb (revision 63528) @@ -8,12 +8,8 @@ class Gem::StubSpecification < Gem::Basi https://github.com/ruby/ruby/blob/trunk/lib/rubygems/stub_specification.rb#L8 # :nodoc: PREFIX = "# stub: " - OPEN_MODE = # :nodoc: - if Object.const_defined? :Encoding then - 'r:UTF-8:-' - else - 'r' - end + # :nodoc: + OPEN_MODE = 'r:UTF-8:-' class StubLine # :nodoc: all attr_reader :name, :version, :platform, :require_paths, :extensions, Index: lib/rubygems/command.rb =================================================================== --- lib/rubygems/command.rb (revision 63527) +++ lib/rubygems/command.rb (revision 63528) @@ -152,15 +152,23 @@ class Gem::Command https://github.com/ruby/ruby/blob/trunk/lib/rubygems/command.rb#L152 #-- # TODO: replace +domain+ with a parameter to suppress suggestions - def show_lookup_failure(gem_name, version, errors, domain) + def show_lookup_failure(gem_name, version, errors, domain, required_by = nil) + gem = "'#{gem_name}' (#{version})" + msg = String.new "Could not find a valid gem #{gem}" + if errors and !errors.empty? - msg = "Could not find a valid gem '#{gem_name}' (#{version}), here is why:\n".dup + msg << ", here is why:\n" errors.each { |x| msg << " #{x.wordy}\n" } - alert_error msg else - alert_error "Could not find a valid gem '#{gem_name}' (#{version}) in any repository" + if required_by and gem != required_by then + msg << " (required by #{required_by}) in any repository" + else + msg << " in any repository" + end end + alert_error msg + unless domain == :local then # HACK suggestions = Gem::SpecFetcher.fetcher.suggest_gems_from_name gem_name Index: lib/rubygems/core_ext/kernel_require.rb =================================================================== --- lib/rubygems/core_ext/kernel_require.rb (revision 63527) +++ lib/rubygems/core_ext/kernel_require.rb (revision 63528) @@ -11,13 +11,8 @@ module Kernel https://github.com/ruby/ruby/blob/trunk/lib/rubygems/core_ext/kernel_require.rb#L11 RUBYGEMS_ACTIVATION_MONITOR = Monitor.new # :nodoc: - if defined?(gem_original_require) then - # Ruby ships with a custom_require, override its require - remove_method :require - else - ## - # The Kernel#require from before RubyGems was loaded. - + # Make sure we have a reference to Ruby's original Kernel#require + unless defined?(gem_original_require) alias gem_original_require require private :gem_original_require end Index: lib/rubygems/installer.rb =================================================================== --- lib/rubygems/installer.rb (revision 63527) +++ lib/rubygems/installer.rb (revision 63528) @@ -110,6 +110,10 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L110 class FakePackage attr_accessor :spec + attr_accessor :dir_mode + attr_accessor :prog_mode + attr_accessor :data_mode + def initialize(spec) @spec = spec end @@ -179,6 +183,10 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L183 process_options + @package.dir_mode = options[:dir_mode] + @package.prog_mode = options[:prog_mode] + @package.data_mode = options[:data_mode] + if options[:user_install] and not options[:unpack] then @gem_home = Gem.user_dir @bin_dir = Gem.bindir gem_home unless options[:bin_dir] @@ -298,7 +306,8 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L306 FileUtils.rm_rf gem_dir FileUtils.rm_rf spec.extension_dir - FileUtils.mkdir_p gem_dir + dir_mode = options[:dir_mode] + FileUtils.mkdir_p gem_dir, :mode => dir_mode && 0700 if @options[:install_as_default] then extract_bin @@ -315,6 +324,8 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L324 write_cache_file end + File.chmod(dir_mode, gem_dir) if dir_mode + say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil? Gem::Installer.install_lock.synchronize { Gem::Specification.reset } @@ -468,7 +479,7 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L479 return if spec.executables.nil? or spec.executables.empty? begin - Dir.mkdir @bin_dir + Dir.mkdir @bin_dir, *[options[:dir_mode] && 0700].compact rescue SystemCallError raise unless File.directory? @bin_dir end @@ -486,7 +497,8 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L497 end mode = File.stat(bin_path).mode - FileUtils.chmod mode | 0111, bin_path unless (mode | 0111) == mode + dir_mode = options[:prog_mode] || (mode | 0111) + FileUtils.chmod dir_mode, bin_path unless dir_mode == mode check_executable_overwrite filename @@ -511,8 +523,9 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L523 FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers - File.open bin_script_path, 'wb', 0755 do |file| + File.open bin_script_path, 'wb', 0700 do |file| file.print app_script_text(filename) + file.chmod(options[:prog_mode] || 0755) end verbose bin_script_path @@ -705,7 +718,7 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L718 end def verify_gem_home(unpack = false) # :nodoc: - FileUtils.mkdir_p gem_home + FileUtils.mkdir_p gem_home, :mode => options[:dir_mode] && 0700 raise Gem::FilePermissionError, gem_home unless unpack or File.writable?(gem_home) end @@ -736,7 +749,7 @@ version = "#{Gem::Requirement.default}.a https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L749 if ARGV.first str = ARGV.first - str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + str = str.dup.force_encoding("BINARY") if str =~ /\\A_(.*)_\\z/ and Gem::Version.correct?($1) then version = $1 ARGV.shift @@ -868,7 +881,8 @@ TEXT https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L881 build_info_dir = File.join gem_home, 'build_info' - FileUtils.mkdir_p build_info_dir + dir_mode = options[:dir_mode] + FileUtils.mkdir_p build_info_dir, :mode => dir_mode && 0700 build_info_file = File.join build_info_dir, "#{spec.full_name}.info" @@ -877,6 +891,8 @@ TEXT https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L891 io.puts arg end end + + File.chmod(dir_mode, build_info_dir) if dir_mode end ## Index: lib/rubygems/uninstaller.rb =================================================================== --- lib/rubygems/uninstaller.rb (revision 63527) +++ lib/rubygems/uninstaller.rb (revision 63528) @@ -213,8 +213,8 @@ class Gem::Uninstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/uninstaller.rb#L213 exe_file = File.join bin_dir, exe_name - FileUtils.rm_f exe_file - FileUtils.rm_f "#{exe_file}.bat" + safe_delete { FileUtils.rm exe_file } + safe_delete { FileUtils.rm "#{exe_file}.bat" } end else say "Executables and scripts will remain installed." @@ -250,26 +250,26 @@ class Gem::Uninstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/uninstaller.rb#L250 raise Gem::FilePermissionError, spec.base_dir unless File.writable?(spec.base_dir) - FileUtils.rm_rf spec.full_gem_path - FileUtils.rm_rf spec.extension_dir + safe_delete { FileUtils.rm_r spec.full_gem_path } + safe_delete { FileUtils.rm_r spec.extension_dir } old_platform_name = spec.original_name - gemspec = spec.spec_file - - unless File.exist? gemspec then - gemspec = File.join(File.dirname(gemspec), "#{old_platform_name}.gemspec") - end - - FileUtils.rm_rf gemspec gem = spec.cache_file gem = File.join(spec.cache_dir, "#{old_platform_name}.gem") unless File.exist? gem - FileUtils.rm_rf gem + safe_delete { FileUtils.rm_r gem } Gem::RDoc.new(spec).remove + gemspec = spec.spec_file + + unless File.exist? gemspec then + gemspec = File.join(File.dirname(gemspec), "#{old_platform_name}.gemspec") + end + + safe_delete { FileUtils.rm_r gemspec } say "Successfully uninstalled #{spec.full_name}" Gem::Specification.reset @@ -343,4 +343,15 @@ class Gem::Uninstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/uninstaller.rb#L343 filename end end + + def safe_delete(&block) + block.call + rescue Errno::ENOENT + nil + rescue Errno::EPERM + e = Gem::UninstallError.new + e.spec = @spec + + raise e + end end Index: lib/rubygems/command_manager.rb =================================================================== --- lib/rubygems/command_manager.rb (revision 63527) +++ lib/rubygems/command_manager.rb (revision 63528) @@ -45,6 +45,7 @@ class Gem::CommandManager https://github.com/ruby/ruby/blob/trunk/lib/rubygems/command_manager.rb#L45 :fetch, :generate_index, :help, + :inf (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/