Merge RubyGems-3.2.14 and Bundler-2.2.14

This commit is contained in:
Hiroshi SHIBATA 2021-03-10 12:08:20 +09:00 committed by NARUSE, Yui
parent 7efc7afcae
commit 0476ce0370
32 changed files with 716 additions and 371 deletions

View file

@ -54,7 +54,7 @@ module Bundler
if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
else
local_temp_path.open("w") {|f| f << content }
local_temp_path.open("wb") {|f| f << content }
end
end

View file

@ -106,6 +106,17 @@ module Bundler
@locked_platforms = []
end
@locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
@disable_multisource = @locked_gem_sources.all?(&:disable_multisource?)
unless @disable_multisource
msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch."
Bundler::SharedHelpers.major_deprecation 2, msg
@sources.merged_gem_lockfile_sections!
end
@unlock[:gems] ||= []
@unlock[:sources] ||= []
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
@ -145,6 +156,10 @@ module Bundler
end
end
def disable_multisource?
@disable_multisource
end
def resolve_with_cache!
raise "Specs already loaded" if @specs
sources.cached!
@ -530,6 +545,9 @@ module Bundler
attr_reader :sources
private :sources
attr_reader :locked_gem_sources
private :locked_gem_sources
def nothing_changed?
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
end
@ -654,10 +672,8 @@ module Bundler
end
def converge_rubygems_sources
return false if Bundler.feature_flag.disable_multisource?
return false if disable_multisource?
# Get the RubyGems sources from the Gemfile.lock
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
return false if locked_gem_sources.empty?
# Get the RubyGems remotes from the Gemfile

View file

@ -460,19 +460,16 @@ repo_name ||= user_name
@sources.add_rubygems_remote(source)
end
if Bundler.feature_flag.disable_multisource?
if Bundler.feature_flag.bundler_3_mode?
msg = "This Gemfile contains multiple primary sources. " \
"Each source after the first must include a block to indicate which gems " \
"should come from that source. To downgrade this error to a warning, run " \
"`bundle config unset disable_multisource`"
"should come from that source"
raise GemfileEvalError, msg
else
Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source. " \
"To upgrade this warning to an error, run `bundle config set --local " \
"disable_multisource true`."
"a block to indicate which gems should come from the secondary source."
end
end

View file

@ -27,13 +27,8 @@ module Bundler
state == :failed
end
def installation_attempted?
installed? || failed?
end
# Only true when spec in neither installed nor already enqueued
def ready_to_enqueue?
!enqueued? && !installation_attempted?
state == :none
end
def has_post_install_message?
@ -93,6 +88,11 @@ module Bundler
def call
check_for_corrupt_lockfile
if @rake
do_install(@rake, 0)
Gem::Specification.reset
end
if @size > 1
install_with_worker
else
@ -217,8 +217,6 @@ module Bundler
# are installed.
def enqueue_specs
@specs.select(&:ready_to_enqueue?).each do |spec|
next if @rake && !@rake.installed? && spec.name != @rake.name
if spec.dependencies_installed? @specs
spec.state = :enqueued
worker_pool.enq spec

View file

@ -131,18 +131,8 @@ module Bundler
@sources << @current_source
end
when GEM
source_remotes = Array(@opts["remote"])
if source_remotes.size == 1
@opts["remotes"] = @opts.delete("remote")
@current_source = TYPES[@type].from_lock(@opts)
else
source_remotes.each do |url|
rubygems_aggregate.add_remote(url)
end
@current_source = rubygems_aggregate
end
@opts["remotes"] = Array(@opts.delete("remote")).reverse
@current_source = TYPES[@type].from_lock(@opts)
@sources << @current_source
when PLUGIN
@current_source = Plugin.source_from_lock(@opts)
@ -245,9 +235,5 @@ module Bundler
def parse_ruby(line)
@ruby_version = line.strip
end
def rubygems_aggregate
@rubygems_aggregate ||= Source::Rubygems.new
end
end
end

View file

@ -140,6 +140,13 @@ module Bundler
end
end
# Set internal representation to fetch the gems/specs locally.
#
# When this is called, the source should try to fetch the specs and
# install from the local system.
def local!
end
# Set internal representation to fetch the gems/specs from remote.
#
# When this is called, the source should try to fetch the specs and

View file

@ -33,6 +33,12 @@ module Bundler
spec.source == self
end
def local!; end
def cached!; end
def remote!; end
# it's possible that gems from one source depend on gems from some
# other source, so now we download gemspecs and iterate over those
# dependencies, looking for gems we don't have info on yet.

View file

@ -33,10 +33,6 @@ module Bundler
end
end
def cached!; end
def remote!; end
def options
{}
end

View file

@ -20,17 +20,29 @@ module Bundler
@dependency_names = []
@allow_remote = false
@allow_cached = false
@allow_local = options["allow_local"] || false
@caches = [cache_path, *Bundler.rubygems.gem_cache]
Array(options["remotes"] || []).reverse_each {|r| add_remote(r) }
Array(options["remotes"]).reverse_each {|r| add_remote(r) }
end
def local!
return if @allow_local
@specs = nil
@allow_local = true
end
def remote!
return if @allow_remote
@specs = nil
@allow_remote = true
end
def cached!
return if @allow_cached
@specs = nil
@allow_cached = true
end
@ -49,8 +61,12 @@ module Bundler
o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
end
def disable_multisource?
@remotes.size <= 1
end
def can_lock?(spec)
return super if Bundler.feature_flag.disable_multisource?
return super if disable_multisource?
spec.source.is_a?(Rubygems)
end
@ -87,7 +103,7 @@ module Bundler
# small_idx.use large_idx.
idx = @allow_remote ? remote_specs.dup : Index.new
idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
idx.use(installed_specs, :override_dupes)
idx.use(installed_specs, :override_dupes) if @allow_local
idx
end
end
@ -365,7 +381,7 @@ module Bundler
def cached_specs
@cached_specs ||= begin
idx = installed_specs.dup
idx = @allow_local ? installed_specs.dup : Index.new
Dir["#{cache_path}/*.gem"].each do |gemfile|
next if gemfile =~ /^bundler\-[\d\.]+?\.gem/

View file

@ -9,7 +9,7 @@ module Bundler
:metadata_source
def global_rubygems_source
@global_rubygems_source ||= rubygems_aggregate_class.new
@global_rubygems_source ||= rubygems_aggregate_class.new("allow_local" => true)
end
def initialize
@ -20,6 +20,16 @@ module Bundler
@global_path_source = nil
@rubygems_sources = []
@metadata_source = Source::Metadata.new
@disable_multisource = true
end
def disable_multisource?
@disable_multisource
end
def merged_gem_lockfile_sections!
@disable_multisource = false
end
def add_path_source(options = {})
@ -47,7 +57,7 @@ module Bundler
end
def global_rubygems_source=(uri)
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri, "allow_local" => true)
end
def add_rubygems_remote(uri)
@ -77,7 +87,7 @@ module Bundler
def lock_sources
lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
if Bundler.feature_flag.disable_multisource?
if disable_multisource?
lock_sources + rubygems_sources.sort_by(&:to_s)
else
lock_sources << combine_rubygems_sources
@ -94,7 +104,7 @@ module Bundler
end
end
replacement_rubygems = !Bundler.feature_flag.disable_multisource? &&
replacement_rubygems = !disable_multisource? &&
replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
@global_rubygems_source = replacement_rubygems if replacement_rubygems

View file

@ -82,6 +82,7 @@ module Bundler
materialized.map! do |s|
next s unless s.is_a?(LazySpecification)
s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=)
s.source.local!
spec = s.__materialize__
unless spec
unless missing_specs
@ -102,6 +103,7 @@ module Bundler
@specs.map do |s|
next s unless s.is_a?(LazySpecification)
s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
s.source.local!
s.source.remote!
spec = s.__materialize__
raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec

View file

@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
VERSION = "2.2.13".freeze
VERSION = "2.2.14".freeze
def self.bundler_major_version
@bundler_major_version ||= VERSION.split(".").first.to_i

View file

@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
VERSION = "3.2.13".freeze
VERSION = "3.2.14".freeze
end
# Must be first since it unloads the prelude from 1.9.2

View file

@ -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
##

View file

@ -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)

View file

@ -46,4 +46,25 @@ RSpec.describe Bundler::CompactIndexClient::Updater do
end.to raise_error(Bundler::PermissionError)
end
end
context "when receiving non UTF-8 data and default internal encoding set to ASCII" do
let(:response) { double(:response, :body => "\x8B".b) }
it "works just fine" do
old_verbose = $VERBOSE
previous_internal_encoding = Encoding.default_internal
begin
$VERBOSE = false
Encoding.default_internal = "ASCII"
expect(response).to receive(:[]).with("ETag") { nil }
expect(fetcher).to receive(:call) { response }
updater.update(local_path, remote_path)
ensure
Encoding.default_internal = previous_internal_encoding
$VERBOSE = old_verbose
end
end
end
end

View file

@ -372,26 +372,7 @@ RSpec.describe Bundler::SourceList do
source_list.add_git_source("uri" => "git://first-git.org/path.git")
end
it "combines the rubygems sources into a single instance, removing duplicate remotes from the end", :bundler => "< 3" do
expect(source_list.lock_sources).to eq [
Bundler::Source::Git.new("uri" => "git://first-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://second-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://third-git.org/path.git"),
ASourcePlugin.new("uri" => "https://second-plugin.org/random"),
ASourcePlugin.new("uri" => "https://third-bar.org/foo"),
Bundler::Source::Path.new("path" => "/first/path/to/gem"),
Bundler::Source::Path.new("path" => "/second/path/to/gem"),
Bundler::Source::Path.new("path" => "/third/path/to/gem"),
Bundler::Source::Rubygems.new("remotes" => [
"https://duplicate-rubygems.org",
"https://first-rubygems.org",
"https://second-rubygems.org",
"https://third-rubygems.org",
]),
]
end
it "returns all sources, without combining rubygems sources", :bundler => "3" do
it "returns all sources, without combining rubygems sources" do
expect(source_list.lock_sources).to eq [
Bundler::Source::Git.new("uri" => "git://first-git.org/path.git"),
Bundler::Source::Git.new("uri" => "git://second-git.org/path.git"),

View file

@ -86,7 +86,7 @@ RSpec.describe "bundle lock" do
it "does not fetch remote specs when using the --local option" do
bundle "lock --update --local", :raise_on_error => false
expect(err).to match(/sources listed in your Gemfile|installed locally/)
expect(err).to match(/installed locally/)
end
it "works with --gemfile flag" do

View file

@ -126,21 +126,21 @@ RSpec.describe "install in deployment or frozen mode" do
bundle "config --local path vendor/bundle"
bundle "install"
gemfile <<-G
source "http://user_name:password@localgemserver.test/"
gem "rack"
source "http://user_name:password@localgemserver.test/"
gem "rack"
G
lockfile <<-G
GEM
remote: http://localgemserver.test/
specs:
rack (1.0.0)
GEM
remote: http://localgemserver.test/
specs:
rack (1.0.0)
PLATFORMS
#{local}
PLATFORMS
#{local}
DEPENDENCIES
rack
DEPENDENCIES
rack
G
bundle "config set --local deployment true"

View file

@ -141,23 +141,84 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "when a pinned gem has an indirect dependency" do
context "when a pinned gem has an indirect dependency in the pinned source" do
before do
build_repo gem_repo3 do
build_gem "depends_on_rack", "1.0.1" do |s|
s.add_dependency "rack"
end
end
# we need a working rack gem in repo3
update_repo gem_repo3 do
build_gem "rack", "1.0.0"
end
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
end
G
end
context "when the indirect dependency is in the pinned source" do
context "and not in any other sources" do
before do
# we need a working rack gem in repo3
update_repo gem_repo3 do
build_gem "rack", "1.0.0"
end
build_repo(gem_repo2) {}
end
gemfile <<-G
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
context "and in another source" do
before do
# need this to be broken to check for correct source ordering
build_repo gem_repo2 do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
end
end
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
# In https://github.com/bundler/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
end
context "when a pinned gem has an indirect dependency in a different source" do
before do
# In these tests, we need a working rack gem in repo2 and not repo3
build_repo gem_repo3 do
build_gem "depends_on_rack", "1.0.1" do |s|
s.add_dependency "rack"
end
end
build_repo gem_repo2 do
build_gem "rack", "1.0.0"
end
end
context "and not in any other sources" do
before do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
@ -165,132 +226,74 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
context "and not in any other sources" do
before do
build_repo(gem_repo2) {}
end
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
context "and in another source" do
before do
# need this to be broken to check for correct source ordering
build_repo gem_repo2 do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
end
end
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
# In https://github.com/bundler/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
it "installs from the other source without any warning" do
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
end
context "when the indirect dependency is in a different source" do
context "and in yet another source" do
before do
# In these tests, we need a working rack gem in repo2 and not repo3
build_repo gem_repo2 do
build_gem "rack", "1.0.0"
end
end
context "and not in any other sources" do
before do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
end
G
end
it "installs from the other source without any warning" do
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
end
context "and in yet another source" do
before do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
end
G
end
it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
bundle :install
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
expect(err).to include("Installed from: #{file_uri_for(gem_repo2)}")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
it "fails", :bundler => "3" do
bundle :install, :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
end
context "and only the dependency is pinned" do
before do
# need this to be broken to check for correct source ordering
build_repo gem_repo2 do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "depends_on_rack"
end
G
end
gemfile <<-G
source "#{file_uri_for(gem_repo3)}" # contains depends_on_rack
source "#{file_uri_for(gem_repo2)}" # contains broken rack
it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
bundle :install
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
expect(err).to include("Installed from: #{file_uri_for(gem_repo2)}")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
gem "depends_on_rack" # installed from gem_repo3
gem "rack", :source => "#{file_uri_for(gem_repo1)}"
G
it "fails", :bundler => "3" do
bundle :install, :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
end
context "and only the dependency is pinned" do
before do
# need this to be broken to check for correct source ordering
build_repo gem_repo2 do
build_gem "rack", "1.0.0" do |s|
s.write "lib/rack.rb", "RACK = 'FAIL'"
end
end
it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
bundle :install
gemfile <<-G
source "#{file_uri_for(gem_repo3)}" # contains depends_on_rack
source "#{file_uri_for(gem_repo2)}" # contains broken rack
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
gem "depends_on_rack" # installed from gem_repo3
gem "rack", :source => "#{file_uri_for(gem_repo1)}"
G
end
# In https://github.com/rubygems/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
it "fails", :bundler => "3" do
bundle :install, :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
# In https://github.com/rubygems/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
it "fails", :bundler => "3" do
bundle :install, :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
end
end
@ -511,9 +514,149 @@ RSpec.describe "bundle install with gems on multiple sources" do
L
end
it "upgrades gems when running bundle update, without printing any warnings or errors" do
it "does not install newer versions or generate lockfile changes when running bundle install, and warns", :bundler => "< 3" do
initial_lockfile = lockfile
bundle :install
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(the_bundle).to include_gems("activesupport 6.0.3.4")
expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
expect(the_bundle).to include_gems("tzinfo 1.2.9")
expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
expect(the_bundle).to include_gems("concurrent-ruby 1.1.8")
expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9")
expect(lockfile).to eq(initial_lockfile)
end
it "fails when running bundle install", :bundler => "3" do
initial_lockfile = lockfile
bundle :install, :raise_on_error => false
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(lockfile).to eq(initial_lockfile)
end
it "splits sections and upgrades gems when running bundle update, and doesn't warn" do
bundle "update --all"
expect(err).to be_empty
expect(the_bundle).not_to include_gems("activesupport 6.0.3.4")
expect(the_bundle).to include_gems("activesupport 6.1.2.1")
expect(the_bundle).not_to include_gems("tzinfo 1.2.9")
expect(the_bundle).to include_gems("tzinfo 2.0.4")
expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
activesupport (6.1.2.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
concurrent-ruby (1.1.9)
connection_pool (2.2.3)
i18n (1.8.9)
concurrent-ruby (~> 1.0)
minitest (5.14.3)
rack (2.2.3)
redis (4.2.5)
sidekiq (6.1.3)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
zeitwerk (2.4.2)
GEM
remote: #{file_uri_for(gem_repo3)}/
specs:
sidekiq-pro (5.2.1)
connection_pool (>= 2.2.3)
sidekiq (>= 6.1.0)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
activesupport
sidekiq-pro!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "it keeps the currrent lockfile format and upgrades the requested gem when running bundle update with an argument, and warns", :bundler => "< 3" do
bundle "update concurrent-ruby"
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(the_bundle).to include_gems("activesupport 6.0.3.4")
expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
expect(the_bundle).to include_gems("tzinfo 1.2.9")
expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo2)}/
remote: #{file_uri_for(gem_repo3)}/
specs:
activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
concurrent-ruby (1.1.9)
connection_pool (2.2.3)
i18n (1.8.9)
concurrent-ruby (~> 1.0)
minitest (5.14.3)
rack (2.2.3)
redis (4.2.5)
sidekiq (6.1.3)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
sidekiq-pro (5.2.1)
connection_pool (>= 2.2.3)
sidekiq (>= 6.1.0)
thread_safe (0.3.6)
tzinfo (1.2.9)
thread_safe (~> 0.1)
zeitwerk (2.4.2)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
activesupport
sidekiq-pro!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "fails when running bundle update with an argument", :bundler => "3" do
initial_lockfile = lockfile
bundle "update concurrent-ruby", :raise_on_error => false
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(lockfile).to eq(initial_lockfile)
end
end
end
@ -551,7 +694,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source ", :bundler => "< 3" do
context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source " do
before do
build_repo gem_repo3 do
build_gem "handsoap", "0.2.5.5" do |s|
@ -578,12 +721,38 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
it "installs from the proper sources without any warnings or errors" do
it "installs from the default source without any warnings or errors and generates a proper lockfile" do
expected_lockfile = <<~L
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
nokogiri (1.11.1)
racca (~> 1.4)
racca (1.5.2)
GEM
remote: #{file_uri_for(gem_repo3)}/
specs:
handsoap (0.2.5.5)
nokogiri (>= 1.2.3)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
handsoap!
nokogiri
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install --verbose"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
expect(lockfile).to eq(expected_lockfile)
# Even if the gems are already installed
FileUtils.rm bundled_app_lock
@ -592,6 +761,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
expect(lockfile).to eq(expected_lockfile)
end
end
@ -619,6 +789,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo1)}
specs:
GEM
remote: #{file_uri_for(gem_repo3)}
specs:
rack (0.9.1)
@ -644,6 +817,84 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "with a lockfile with aggregated rubygems sources" do
let(:aggregate_gem_section_lockfile) do
<<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
remote: #{file_uri_for(gem_repo3)}/
specs:
rack (0.9.1)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
rack!
BUNDLED WITH
#{Bundler::VERSION}
L
end
let(:split_gem_section_lockfile) do
<<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
specs:
GEM
remote: #{file_uri_for(gem_repo3)}/
specs:
rack (0.9.1)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
rack!
BUNDLED WITH
#{Bundler::VERSION}
L
end
before do
build_repo gem_repo3 do
build_gem "rack", "0.9.1"
end
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo3)}" do
gem 'rack'
end
G
lockfile aggregate_gem_section_lockfile
end
it "installs the existing lockfile but prints a warning", :bundler => "< 3" do
bundle "config set --local deployment true"
bundle "install"
expect(lockfile).to eq(aggregate_gem_section_lockfile)
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(the_bundle).to include_gems("rack 0.9.1", :source => "remote3")
end
it "refuses to install the existing lockfile and prints an error", :bundler => "3" do
bundle "config set --local deployment true"
bundle "install", :raise_on_error =>false
expect(lockfile).to eq(aggregate_gem_section_lockfile)
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
expect(out).to be_empty
end
end
context "with a path gem in the same Gemfile" do
before do
build_lib "foo"
@ -825,15 +1076,36 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
end
it "keeps the old version", :bundler => "< 3" do
expect(the_bundle).to include_gems("rack 1.0.0")
end
it "installs the higher version in the new repo", :bundler => "3" do
it "installs the higher version in the new repo" do
expect(the_bundle).to include_gems("rack 1.2")
end
end
it "doesn't update version when a gem uses a source block but a higher version from another source is already installed locally" do
build_repo2 do
build_gem "example", "0.1.0"
end
build_repo4 do
build_gem "example", "1.0.2"
end
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "example", :source => "#{file_uri_for(gem_repo2)}"
G
bundle "info example"
expect(out).to include("example (0.1.0)")
system_gems "example-1.0.2", :path => default_bundle_path, :gem_repo => gem_repo4
bundle "update example --verbose"
expect(out).not_to include("Using example 1.0.2")
expect(out).to include("Using example 0.1.0")
end
context "when a gem is available from multiple ambiguous sources", :bundler => "3" do
it "raises, suggesting a source block" do
build_repo4 do

View file

@ -245,37 +245,7 @@ RSpec.describe "bundle flex_install" do
end
describe "when adding a new source" do
it "updates the lockfile", :bundler => "< 3" do
build_repo2
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
lockfile_should_be <<-L
GEM
remote: #{file_uri_for(gem_repo1)}/
remote: #{file_uri_for(gem_repo2)}/
specs:
rack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rack
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "updates the lockfile", :bundler => "3" do
it "updates the lockfile" do
build_repo2
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"

View file

@ -3,6 +3,32 @@
RSpec.describe "bundle install with install-time dependencies" do
before do
build_repo2 do
build_gem "with_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/implicit_rake_dep.rb", "w") do |f|
f.puts "IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
build_gem "another_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
# Test complicated gem dependencies for install
build_gem "net_a" do |s|
s.add_dependency "net_b"
@ -55,6 +81,25 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(out).to eq("YES\nYES")
end
it "installs gems with implicit rake dependencies without rake previously installed" do
with_path_as("") do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "with_implicit_rake_dep"
gem "another_implicit_rake_dep"
gem "rake"
G
end
run <<-R
require 'implicit_rake_dep'
require 'another_implicit_rake_dep'
puts IMPLICIT_RAKE_DEP
puts ANOTHER_IMPLICIT_RAKE_DEP
R
expect(out).to eq("YES\nYES")
end
it "installs gems with a dependency with no type" do
skip "incorrect data check error" if Gem.win_platform?

View file

@ -49,8 +49,23 @@ RSpec.describe "when using sudo", :sudo => true do
end
it "installs rake and a gem dependent on rake in the same session" do
build_repo2 do
build_gem "another_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
end
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo2)}"
gem "rake"
gem "another_implicit_rake_dep"
G

View file

@ -318,40 +318,7 @@ RSpec.describe "the lockfile format" do
G
end
it "generates a lockfile without credentials for a configured source", :bundler => "< 3" do
bundle "config set http://localgemserver.test/ user:pass"
install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
source "http://localgemserver.test/" do
end
source "http://user:pass@othergemserver.test/" do
gem "rack-obama", ">= 1.0"
end
G
lockfile_should_be <<-G
GEM
remote: http://localgemserver.test/
remote: http://user:pass@othergemserver.test/
specs:
rack (1.0.0)
rack-obama (1.0)
rack
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rack-obama (>= 1.0)!
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "generates a lockfile without credentials for a configured source", :bundler => "3" do
it "generates a lockfile without credentials for a configured source" do
bundle "config set http://localgemserver.test/ user:pass"
install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)

View file

@ -383,15 +383,53 @@ RSpec.describe "major deprecations" do
"Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source. " \
"To upgrade this warning to an error, run `bundle config set --local " \
"disable_multisource true`."
"a block to indicate which gems should come from the secondary source."
)
end
pending "fails with a helpful error", :bundler => "3"
end
context "bundle install with a lockfile with a single rubygems section with multiple remotes" do
before do
build_repo gem_repo3 do
build_gem "rack", "0.9.1"
end
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
source "#{file_uri_for(gem_repo3)}" do
gem 'rack'
end
G
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo1)}/
remote: #{file_uri_for(gem_repo3)}/
specs:
rack (0.9.1)
PLATFORMS
ruby
DEPENDENCIES
rack!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "shows a deprecation", :bundler => "< 3" do
bundle "install"
expect(deprecations).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch.")
end
pending "fails with a helpful error", :bundler => "3"
end
context "when Bundler.setup is run in a ruby script" do
before do
create_file "gems.rb"

View file

@ -6,7 +6,7 @@ PATH
GEM
remote: https://rubygems.org/
specs:
jruby-jars (9.2.14.0)
jruby-jars (9.2.16.0)
jruby-rack (1.1.21)
rake (13.0.1)
rubyzip (1.3.0)
@ -19,6 +19,7 @@ GEM
PLATFORMS
java
ruby
universal-java-11
DEPENDENCIES
demo!
@ -26,4 +27,4 @@ DEPENDENCIES
warbler (~> 2.0)
BUNDLED WITH
2.2.0.rc.2
2.3.0.dev

View file

@ -89,6 +89,8 @@ RSpec.configure do |config|
end
config.before :all do
check_test_gems!
build_repo1
reset_paths!

View file

@ -30,7 +30,11 @@ module Spec
end
def build_repo1
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
build_repo gem_repo1 do
FileUtils.cp rake_path, "#{gem_repo1}/gems/"
build_gem "rack", %w[0.9.1 1.0.0] do |s|
s.executables = "rackup"
s.post_install_message = "Rack's post install message"
@ -150,32 +154,6 @@ module Spec
build_gem "duradura", "7.0"
build_gem "with_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/implicit_rake_dep.rb", "w") do |f|
f.puts "IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
build_gem "another_implicit_rake_dep" do |s|
s.extensions << "Rakefile"
s.write "Rakefile", <<-RUBY
task :default do
path = File.expand_path("../lib", __FILE__)
FileUtils.mkdir_p(path)
File.open("\#{path}/another_implicit_rake_dep.rb", "w") do |f|
f.puts "ANOTHER_IMPLICIT_RAKE_DEP = 'YES'"
end
end
RUBY
end
build_gem "very_simple_binary", &:add_c_extension
build_gem "simple_binary", &:add_c_extension
@ -255,6 +233,13 @@ module Spec
def build_repo(path, &blk)
return if File.directory?(path)
FileUtils.mkdir_p("#{path}/gems")
update_repo(path, &blk)
end
def check_test_gems!
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
if rake_path.nil?
@ -263,14 +248,9 @@ module Spec
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first
end
if rake_path
FileUtils.mkdir_p("#{path}/gems")
FileUtils.cp rake_path, "#{path}/gems/"
else
if rake_path.nil?
abort "Your test gems are missing! Run `rm -rf #{tmp}` and try again."
end
update_repo(path, &blk)
end
def update_repo(path)

View file

@ -130,7 +130,7 @@ module Spec
def ruby(ruby, options = {})
ruby_cmd = build_ruby_cmd
escaped_ruby = RUBY_PLATFORM == "java" ? ruby.shellescape.dump : ruby.shellescape
escaped_ruby = ruby.shellescape
sys_exec(%(#{ruby_cmd} -w -e #{escaped_ruby}), options)
end

View file

@ -114,30 +114,49 @@ module Spec
match do
opts = names.last.is_a?(Hash) ? names.pop : {}
source = opts.delete(:source)
groups = Array(opts[:groups])
groups = Array(opts.delete(:groups)).map(&:inspect).join(", ")
opts[:raise_on_error] = false
groups << opts
@errors = names.map do |name|
name, version, platform = name.split(/\s+/)
@errors = names.map do |full_name|
name, version, platform = full_name.split(/\s+/)
require_path = name == "bundler" ? "#{lib_dir}/bundler" : name.tr("-", "/")
version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name)
code = []
code << "require '#{require_path}.rb'"
code << "puts #{version_const}"
run code.join("; "), *groups
actual_version, actual_platform = out.strip.split(/\s+/, 2)
unless Gem::Version.new(actual_version) == Gem::Version.new(version)
source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
ruby <<~R, opts
require '#{lib_dir}/bundler'
Bundler.setup(#{groups})
require '#{require_path}.rb'
actual_version, actual_platform = #{version_const}.split(/\s+/, 2)
unless Gem::Version.new(actual_version) == Gem::Version.new('#{version}')
puts actual_version
exit 64
end
unless actual_platform.to_s == '#{platform}'
puts actual_platform
exit 65
end
require '#{require_path}/source'
exit 0 if #{source.nil?}
actual_source = #{source_const}
unless actual_source == '#{source}'
puts actual_source
exit 66
end
R
next if exitstatus == 0
if exitstatus == 64
actual_version = out.split("\n").last
next "#{name} was expected to be at version #{version} but was #{actual_version}"
end
unless actual_platform == platform
if exitstatus == 65
actual_platform = out.split("\n").last
next "#{name} was expected to be of platform #{platform} but was #{actual_platform}"
end
next unless source
source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
run "require '#{require_path}/source'; puts #{source_const}", *groups
unless out.strip == source
next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{out}`"
if exitstatus == 66
actual_source = out.split("\n").last
next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{actual_source}`"
end
next "Command to check forgem inclusion of gem #{full_name} failed"
end.compact
@errors.empty?

View file

@ -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'

View file

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