diff options
-rw-r--r-- | lib/rubygems.rb | 4 | ||||
-rw-r--r-- | lib/rubygems/commands/update_command.rb | 24 | ||||
-rw-r--r-- | lib/rubygems/defaults.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/indexer.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/installer.rb | 7 | ||||
-rw-r--r-- | lib/rubygems/package.rb | 9 | ||||
-rw-r--r-- | lib/rubygems/platform.rb | 10 | ||||
-rw-r--r-- | lib/rubygems/remote_fetcher.rb | 11 | ||||
-rw-r--r-- | lib/rubygems/security/trust_dir.rb | 1 | ||||
-rw-r--r-- | lib/rubygems/test_utilities.rb | 2 | ||||
-rw-r--r-- | test/rubygems/packages/ascii_binder-0.1.10.1.gem | bin | 0 -> 244736 bytes | |||
-rw-r--r-- | test/rubygems/test_gem_commands_setup_command.rb | 2 | ||||
-rw-r--r-- | test/rubygems/test_gem_commands_update_command.rb | 29 | ||||
-rw-r--r-- | test/rubygems/test_gem_installer.rb | 22 | ||||
-rw-r--r-- | test/rubygems/test_gem_package.rb | 4 | ||||
-rw-r--r-- | test/rubygems/test_gem_platform.rb | 29 | ||||
-rw-r--r-- | test/rubygems/test_gem_remote_fetcher.rb | 38 | ||||
-rw-r--r-- | test/rubygems/test_gem_server.rb | 8 |
18 files changed, 133 insertions, 71 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 3c85284ff2..76d86ee6c9 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -813,7 +813,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} ## # Safely write a file in binary mode on all platforms. def self.write_binary(path, data) - open(path, 'wb') do |io| + File.open(path, 'wb') do |io| begin io.flock(File::LOCK_EX) rescue *WRITE_BINARY_ERRORS @@ -824,7 +824,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]} if Thread.main != Thread.current raise else - open(path, 'wb') do |io| + File.open(path, 'wb') do |io| io.write data end end diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb index 41770d9805..91d93e398c 100644 --- a/lib/rubygems/commands/update_command.rb +++ b/lib/rubygems/commands/update_command.rb @@ -81,7 +81,7 @@ command to remove old versions. def check_oldest_rubygems(version) # :nodoc: if oldest_supported_version > version - alert_error "rubygems #{version} is not supported. The oldest supported version is #{oldest_supported_version}" + alert_error "rubygems #{version} is not supported on #{RUBY_VERSION}. The oldest version supported by this ruby is #{oldest_supported_version}" terminate_interaction 1 end end @@ -327,8 +327,26 @@ command to remove old versions. private + # + # 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: https://stdgems.org/rubygems + # def oldest_supported_version - # for Ruby 2.3 - @oldest_supported_version ||= Gem::Version.new("2.5.2") + @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 end diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index 8aae67cd6b..e95bc06792 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -198,7 +198,7 @@ module Gem def self.default_bindir if defined? RUBY_FRAMEWORK_VERSION # mac framework support - '/usr/bin' + '/usr/local/bin' else # generic install RbConfig::CONFIG['bindir'] end diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb index 31285ca962..e595459c87 100644 --- a/lib/rubygems/indexer.rb +++ b/lib/rubygems/indexer.rb @@ -136,7 +136,7 @@ class Gem::Indexer say "Generating #{name} index" Gem.time "Generated #{name} index" do - open(file, 'wb') do |io| + File.open(file, 'wb') do |io| specs = index.map do |*spec| # We have to splat here because latest_specs is an array, while the # others are hashes. diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 3ec6d743a2..7af51056b7 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -484,8 +484,11 @@ class Gem::Installer bin_path = File.join gem_dir, spec.bindir, filename unless File.exist? bin_path - # TODO change this to a more useful warning - warn "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?" + if File.symlink? bin_path + alert_warning "`#{bin_path}` is dangling symlink pointing to `#{File.readlink bin_path}`" + else + alert_warning "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?" + end next end diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index 0587cd212b..a4ae3e9ea5 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -252,14 +252,7 @@ class Gem::Package stat = File.lstat file if stat.symlink? - target_path = File.readlink(file) - - unless target_path.start_with? '.' - relative_dir = File.dirname(file).sub("#{Dir.pwd}/", '') - target_path = File.join(relative_dir, target_path) - end - - tar.add_symlink file, target_path, stat.mode + tar.add_symlink file, File.readlink(file), stat.mode end next unless stat.file? diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb index e01d0494d6..fd1c0a62ac 100644 --- a/lib/rubygems/platform.rb +++ b/lib/rubygems/platform.rb @@ -66,7 +66,7 @@ class Gem::Platform when String then arch = arch.split '-' - if arch.length > 2 and arch.last !~ /\d+(\.\d+)?$/ # reassemble x86-linux-{libc} + if arch.length > 2 and arch.last !~ /\d/ # reassemble x86-linux-gnu extra = arch.pop arch.last << "-#{extra}" end @@ -146,8 +146,7 @@ class Gem::Platform ## # Does +other+ match this platform? Two platforms match if they have the # same CPU, or either has a CPU of 'universal', they have the same OS, and - # they have the same version, or either has no version (except for 'linux' - # where the version is the libc name, with no version standing for 'gnu') + # they have the same version, or either has no version. # # Additionally, the platform will match if the local CPU is 'arm' and the # other CPU starts with "arm" (for generic ARM family support). @@ -163,10 +162,7 @@ class Gem::Platform @os == other.os and # version - ( - (@os != 'linux' and (@version.nil? or other.version.nil?)) or - @version == other.version - ) + (@version.nil? or other.version.nil? or @version == other.version) end ## diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb index a14c42f00e..e3d4bfbeba 100644 --- a/lib/rubygems/remote_fetcher.rb +++ b/lib/rubygems/remote_fetcher.rb @@ -51,6 +51,7 @@ class Gem::RemoteFetcher class UnknownHostError < FetchError end + deprecate_constant(:UnknownHostError) @fetcher = nil @@ -262,15 +263,9 @@ class Gem::RemoteFetcher end data - rescue Timeout::Error - raise UnknownHostError.new('timed out', uri) - rescue IOError, SocketError, SystemCallError, + rescue Timeout::Error, IOError, SocketError, SystemCallError, *(OpenSSL::SSL::SSLError if Gem::HAVE_OPENSSL) => e - if e.message =~ /getaddrinfo/ - raise UnknownHostError.new('no such name', uri) - else - raise FetchError.new("#{e.class}: #{e}", uri) - end + raise FetchError.new("#{e.class}: #{e}", uri) end def fetch_s3(uri, mtime = nil, head = false) diff --git a/lib/rubygems/security/trust_dir.rb b/lib/rubygems/security/trust_dir.rb index 1d93ceabd1..456947274c 100644 --- a/lib/rubygems/security/trust_dir.rb +++ b/lib/rubygems/security/trust_dir.rb @@ -104,6 +104,7 @@ class Gem::Security::TrustDir # permissions. def verify + require 'fileutils' if File.exist? @dir raise Gem::Security::Exception, "trust directory #{@dir} is not a directory" unless diff --git a/lib/rubygems/test_utilities.rb b/lib/rubygems/test_utilities.rb index 1371ae9b14..08faef6578 100644 --- a/lib/rubygems/test_utilities.rb +++ b/lib/rubygems/test_utilities.rb @@ -76,7 +76,7 @@ class Gem::FakeFetcher def cache_update_path(uri, path = nil, update = true) if data = fetch_path(uri) - open(path, 'wb') {|io| io.write data } if path and update + File.open(path, 'wb') {|io| io.write data } if path and update data else Gem.read_binary(path) if path diff --git a/test/rubygems/packages/ascii_binder-0.1.10.1.gem b/test/rubygems/packages/ascii_binder-0.1.10.1.gem Binary files differnew file mode 100644 index 0000000000..19c505395e --- /dev/null +++ b/test/rubygems/packages/ascii_binder-0.1.10.1.gem diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb index 29850c9074..7a40136070 100644 --- a/test/rubygems/test_gem_commands_setup_command.rb +++ b/test/rubygems/test_gem_commands_setup_command.rb @@ -48,7 +48,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase io.puts gemspec.to_ruby end - open(File.join(Gem.default_specifications_dir, "bundler-1.15.4.gemspec"), 'w') do |io| + File.open(File.join(Gem.default_specifications_dir, "bundler-1.15.4.gemspec"), 'w') do |io| gemspec.version = "1.15.4" io.puts gemspec.to_ruby end diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb index 13cc10c298..9b590f0022 100644 --- a/test/rubygems/test_gem_commands_update_command.rb +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -168,6 +168,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:args] = [] @cmd.options[:system] = "2.5.1" + oldest_version_mod = Module.new do + def oldest_supported_version + Gem::Version.new("2.5.2") + end + private :oldest_supported_version + end + + @cmd.extend(oldest_version_mod) + assert_raises Gem::MockGemUi::TermError do use_ui @ui do @cmd.execute @@ -175,7 +184,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase end assert_empty @ui.output - assert_equal "ERROR: rubygems 2.5.1 is not supported. The oldest supported version is 2.5.2\n", @ui.error + assert_equal "ERROR: rubygems 2.5.1 is not supported on #{RUBY_VERSION}. The oldest version supported by this ruby is 2.5.2\n", @ui.error end def test_execute_system_specific_older_than_3_2_removes_plugins_dir @@ -185,6 +194,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase end end + oldest_version_mod = Module.new do + def oldest_supported_version + Gem::Version.new("2.5.2") + end + private :oldest_supported_version + end + + @cmd.extend(oldest_version_mod) + @cmd.options[:args] = [] @cmd.options[:system] = "3.1" @@ -203,6 +221,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase end end + oldest_version_mod = Module.new do + def oldest_supported_version + Gem::Version.new("2.5.2") + end + private :oldest_supported_version + end + + @cmd.extend(oldest_version_mod) + @cmd.options[:args] = [] @cmd.options[:system] = "3.2.a" diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 5652d86331..88d54901eb 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -730,11 +730,31 @@ gem 'other', version installer.generate_bin default_shebang = Gem.ruby - shebang_line = open("#{@gemhome}/bin/executable") {|f| f.readlines.first } + shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first } assert_match(/\A#!/, shebang_line) assert_match(/#{default_shebang}/, shebang_line) end + def test_generate_bin_with_dangling_symlink + gem_with_dangling_symlink = File.expand_path("packages/ascii_binder-0.1.10.1.gem", __dir__) + + installer = Gem::Installer.at( + gem_with_dangling_symlink, + :install_dir => @gem_home, + :user_install => false, + :force => true + ) + + build_rake_in do + use_ui @ui do + installer.install + end + end + + assert_match %r{bin/ascii_binder` is dangling symlink pointing to `bin/asciibinder`}, @ui.error + assert_empty @ui.output + end + def test_generate_plugins installer = util_setup_installer do |spec| write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index fd28f9a2a5..3000333b9c 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -218,7 +218,7 @@ class TestGemPackage < Gem::Package::TarTestCase end assert_equal %w[lib/code.rb], files - assert_equal [{'lib/code_sym.rb' => 'lib/code.rb'}, {'lib/code_sym2.rb' => '../lib/code.rb'}], symlinks + assert_equal [{'lib/code_sym.rb' => 'code.rb'}, {'lib/code_sym2.rb' => '../lib/code.rb'}], symlinks end def test_build @@ -937,7 +937,7 @@ class TestGemPackage < Gem::Package::TarTestCase build = Gem::Package.new @gem build.spec = @spec build.setup_signer - open @gem, 'wb' do |gem_io| + File.open @gem, 'wb' do |gem_io| Gem::Package::TarWriter.new gem_io do |gem| build.add_metadata gem build.add_contents gem diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb index ad7285c082..84754402ad 100644 --- a/test/rubygems/test_gem_platform.rb +++ b/test/rubygems/test_gem_platform.rb @@ -134,9 +134,7 @@ class TestGemPlatform < Gem::TestCase 'i386-solaris2.8' => ['x86', 'solaris', '2.8'], 'mswin32' => ['x86', 'mswin32', nil], 'x86_64-linux' => ['x86_64', 'linux', nil], - 'x86_64-linux-gnu' => ['x86_64', 'linux', nil], 'x86_64-linux-musl' => ['x86_64', 'linux', 'musl'], - 'x86_64-linux-uclibc' => ['x86_64', 'linux', 'uclibc'], 'x86_64-openbsd3.9' => ['x86_64', 'openbsd', '3.9'], 'x86_64-openbsd4.0' => ['x86_64', 'openbsd', '4.0'], 'x86_64-openbsd' => ['x86_64', 'openbsd', nil], @@ -145,7 +143,6 @@ class TestGemPlatform < Gem::TestCase test_cases.each do |arch, expected| platform = Gem::Platform.new arch assert_equal expected, platform.to_a, arch.inspect - assert_equal expected, Gem::Platform.new(platform.to_s).to_a, arch.inspect end end @@ -264,32 +261,6 @@ class TestGemPlatform < Gem::TestCase assert((with_x86_arch === with_nil_arch), 'x86 =~ nil') end - def test_nil_version_is_treated_as_any_version - x86_darwin_8 = Gem::Platform.new 'i686-darwin8.0' - x86_darwin_nil = Gem::Platform.new 'i686-darwin' - - assert((x86_darwin_8 === x86_darwin_nil), '8.0 =~ nil') - assert((x86_darwin_nil === x86_darwin_8), 'nil =~ 8.0') - end - - def test_nil_version_is_stricter_for_linux_os - x86_linux = Gem::Platform.new 'i686-linux' - x86_linux_gnu = Gem::Platform.new 'i686-linux-gnu' - x86_linux_musl = Gem::Platform.new 'i686-linux-musl' - x86_linux_uclibc = Gem::Platform.new 'i686-linux-uclibc' - - assert((x86_linux === x86_linux_gnu), 'linux =~ linux-gnu') - assert((x86_linux_gnu === x86_linux), 'linux-gnu =~ linux') - assert(!(x86_linux_gnu === x86_linux_musl), 'linux-gnu =~ linux-musl') - assert(!(x86_linux_musl === x86_linux_gnu), 'linux-musl =~ linux-gnu') - assert(!(x86_linux_uclibc === x86_linux_musl), 'linux-uclibc =~ linux-musl') - assert(!(x86_linux_musl === x86_linux_uclibc), 'linux-musl =~ linux-uclibc') - assert(!(x86_linux === x86_linux_musl), 'linux =~ linux-musl') - assert(!(x86_linux_musl === x86_linux), 'linux-musl =~ linux') - assert(!(x86_linux === x86_linux_uclibc), 'linux =~ linux-uclibc') - assert(!(x86_linux_uclibc === x86_linux), 'linux-uclibc =~ linux') - end - def test_equals3_cpu_arm arm = Gem::Platform.new 'arm-linux' armv5 = Gem::Platform.new 'armv5-linux' diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index 1c88e8d3e8..b032f1613b 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -496,6 +496,44 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== assert_equal url, e.uri end + def test_fetch_path_timeout_error + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + def fetcher.fetch_http(uri, mtime = nil, head = nil) + raise Timeout::Error, 'timed out' + end + + url = 'http://example.com/uri' + + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_path url + end + + assert_match %r{Timeout::Error: timed out \(#{Regexp.escape url}\)\z}, + e.message + assert_equal url, e.uri + end + + def test_fetch_path_getaddrinfo_error + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + def fetcher.fetch_http(uri, mtime = nil, head = nil) + raise SocketError, 'getaddrinfo: nodename nor servname provided' + end + + url = 'http://example.com/uri' + + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_path url + end + + assert_match %r{SocketError: getaddrinfo: nodename nor servname provided \(#{Regexp.escape url}\)\z}, + e.message + assert_equal url, e.uri + end + def test_fetch_path_openssl_ssl_sslerror fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb index 0e283da5a4..38a381570d 100644 --- a/test/rubygems/test_gem_server.rb +++ b/test/rubygems/test_gem_server.rb @@ -365,7 +365,7 @@ class TestGemServer < Gem::TestCase specs_dir = File.join dir, 'specifications' FileUtils.mkdir_p specs_dir - open File.join(specs_dir, spec.spec_name), 'w' do |io| + File.open File.join(specs_dir, spec.spec_name), 'w' do |io| io.write spec.to_ruby end @@ -420,7 +420,7 @@ class TestGemServer < Gem::TestCase specs_dir = File.join dir, 'specifications' FileUtils.mkdir_p specs_dir - open File.join(specs_dir, spec.spec_name), 'w' do |io| + File.open File.join(specs_dir, spec.spec_name), 'w' do |io| io.write spec.to_ruby end @@ -475,7 +475,7 @@ class TestGemServer < Gem::TestCase specs_dir = File.join dir, 'specifications' FileUtils.mkdir_p specs_dir - open File.join(specs_dir, spec.spec_name), 'w' do |io| + File.open File.join(specs_dir, spec.spec_name), 'w' do |io| io.write spec.to_ruby end @@ -502,7 +502,7 @@ class TestGemServer < Gem::TestCase specs_dir = File.join dir, 'specifications' FileUtils.mkdir_p specs_dir - open File.join(specs_dir, spec.spec_name), 'w' do |io| + File.open File.join(specs_dir, spec.spec_name), 'w' do |io| io.write spec.to_ruby end |