summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rodríguez <2887858+deivid-rodriguez@users.noreply.github.com>2025-09-09 19:18:42 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2025-09-16 17:17:32 +0900
commit6adcc5596884619e386d5412e94ef4443868b94f (patch)
treed5076faaa392104e0769c0256c3d0a971a489fa0
parent9878060181d2592c26dce0c314a8b4b6e4826646 (diff)
[rubygems/rubygems] Completely remove multisources support
https://github.com/rubygems/rubygems/commit/8f9d6c54a1
-rw-r--r--lib/bundler/cli/install.rb16
-rw-r--r--lib/bundler/definition.rb16
-rw-r--r--lib/bundler/dsl.rb22
-rw-r--r--lib/bundler/errors.rb5
-rw-r--r--lib/bundler/index.rb7
-rw-r--r--lib/bundler/installer.rb6
-rw-r--r--lib/bundler/source/rubygems.rb13
-rw-r--r--lib/bundler/source_list.rb24
-rw-r--r--lib/bundler/source_map.rb7
-rw-r--r--spec/bundler/bundler/definition_spec.rb4
-rw-r--r--spec/bundler/commands/install_spec.rb18
-rw-r--r--spec/bundler/commands/outdated_spec.rb66
-rw-r--r--spec/bundler/commands/update_spec.rb62
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb908
-rw-r--r--spec/bundler/install/gems/compact_index_spec.rb73
-rw-r--r--spec/bundler/install/gems/dependency_api_spec.rb92
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb67
17 files changed, 73 insertions, 1333 deletions
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index a676e2d6f1..c4063f808a 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -69,8 +69,6 @@ module Bundler
Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
- warn_ambiguous_gems
-
if CLI::Common.clean_after_install?
require_relative "clean"
Bundler::CLI::Clean.new(options).run
@@ -126,19 +124,5 @@ module Bundler
options[:force] = options[:redownload] if options[:redownload]
end
-
- def warn_ambiguous_gems
- # TODO: remove this when we drop Bundler 1.x support
- Installer.ambiguous_gems.to_a.each do |name, installed_from_uri, *also_found_in_uris|
- Bundler.ui.warn "Warning: the gem '#{name}' was found in multiple sources."
- Bundler.ui.warn "Installed from: #{installed_from_uri}"
- Bundler.ui.warn "Also found in:"
- also_found_in_uris.each {|uri| Bundler.ui.warn " * #{uri}" }
- Bundler.ui.warn "You should add a source requirement to restrict this gem to your preferred source."
- Bundler.ui.warn "For example:"
- Bundler.ui.warn " gem '#{name}', :source => '#{installed_from_uri}'"
- Bundler.ui.warn "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again."
- end
- end
end
end
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index ab488e046b..32dd13399e 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -119,16 +119,12 @@ module Bundler
end
locked_gem_sources = @originally_locked_sources.select {|s| s.is_a?(Source::Rubygems) }
- @multisource_lockfile = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes?
+ multisource_lockfile = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes?
- if @multisource_lockfile && Bundler.frozen_bundle?
- unless sources.aggregate_global_source?
- msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
+ if multisource_lockfile
+ msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
- Bundler::SharedHelpers.major_deprecation 2, msg
- end
-
- @sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
+ Bundler::SharedHelpers.feature_removed! msg
end
else
@locked_gems = nil
@@ -765,7 +761,7 @@ module Bundler
end
def precompute_source_requirements_for_indirect_dependencies?
- sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
+ sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
end
def current_platform_locked?
@@ -1139,7 +1135,7 @@ module Bundler
end
def additional_base_requirements_to_prevent_downgrades(resolution_base)
- return resolution_base unless @locked_gems && !@multisource_lockfile
+ return resolution_base unless @locked_gems
@originally_locked_specs.each do |locked_spec|
next if locked_spec.source.is_a?(Source::Path) || locked_spec.source_changed?
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 0e36f52269..3bf5dbc115 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -521,24 +521,10 @@ module Bundler
end
def multiple_global_source_warning
- if Bundler.feature_flag.bundler_4_mode?
- msg = "This Gemfile contains multiple global sources. " \
- "Each source after the first must include a block to indicate which gems " \
- "should come from that source"
- raise GemfileEvalError, msg
- else
- message =
- "Your Gemfile contains multiple global 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."
- removed_message =
- "Your Gemfile contains multiple global sources. " \
- "Using `source` more than once without a block is a security risk, and " \
- "may result in installing unexpected gems. To resolve this error, use " \
- "a block to indicate which gems should come from the secondary source."
- Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
- end
+ msg = "This Gemfile contains multiple global sources. " \
+ "Each source after the first must include a block to indicate which gems " \
+ "should come from that source"
+ raise GemfileEvalError, msg
end
class DSLError < GemfileError
diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb
index 28da892d31..8cd1336356 100644
--- a/lib/bundler/errors.rb
+++ b/lib/bundler/errors.rb
@@ -77,11 +77,6 @@ module Bundler
def mismatch_resolution_instructions
removable, remote = [@existing, @checksum].partition(&:removable?)
case removable.size
- when 0
- msg = +"Mismatched checksums each have an authoritative source:\n"
- msg << " 1. #{@existing.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
- msg << " 2. #{@checksum.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
- msg << "You may need to alter your Gemfile sources to resolve this issue.\n"
when 1
msg = +"If you trust #{remote.first.sources.first}, to resolve this issue you can:\n"
msg << removable.first.removal_instructions
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index d591b34cc7..9aef2dfa12 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -46,13 +46,6 @@ module Bundler
true
end
- def search_all(name, &blk)
- return enum_for(:search_all, name) unless blk
- specs_by_name(name).each(&blk)
- @duplicates[name]&.each(&blk)
- @sources.each {|source| source.search_all(name, &blk) }
- end
-
# Search this index's specs, and any source indexes that this index knows
# about, returning all of the results.
def search(query)
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index d41740a411..c5fd75431f 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -7,12 +7,6 @@ require_relative "installer/gem_installer"
module Bundler
class Installer
- class << self
- attr_accessor :ambiguous_gems
-
- Installer.ambiguous_gems = []
- end
-
attr_reader :post_install_messages, :definition
# Begins the installation process for Bundler.
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 19800e9c58..fdc3a77b24 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -168,12 +168,6 @@ module Bundler
return nil # no post-install message
end
- if spec.remote
- # Check for this spec from other sources
- uris = [spec.remote, *remotes_for_spec(spec)].map(&:anonymized_uri).uniq
- Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
- end
-
path = fetch_gem_if_possible(spec, options[:previous_spec])
raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path
@@ -332,13 +326,6 @@ module Bundler
remotes.map(&method(:remove_auth))
end
- def remotes_for_spec(spec)
- specs.search_all(spec.name).inject([]) do |uris, s|
- uris << s.remote if s.remote
- uris
- end
- end
-
def cached_gem(spec)
global_cache_path = download_cache_path(spec)
caches << global_cache_path if global_cache_path
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index 70b74f6a91..6dba3f35e8 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -21,19 +21,9 @@ module Bundler
@rubygems_sources = []
@metadata_source = Source::Metadata.new
- @merged_gem_lockfile_sections = false
@local_mode = true
end
- def merged_gem_lockfile_sections?
- @merged_gem_lockfile_sections
- end
-
- def merged_gem_lockfile_sections!(replacement_source)
- @merged_gem_lockfile_sections = true
- @global_rubygems_source = replacement_source
- end
-
def aggregate_global_source?
global_rubygems_source.multiple_remotes?
end
@@ -90,10 +80,6 @@ module Bundler
@rubygems_sources
end
- def rubygems_remotes
- rubygems_sources.flat_map(&:remotes).uniq
- end
-
def all_sources
path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
end
@@ -115,11 +101,7 @@ module Bundler
end
def lock_rubygems_sources
- if merged_gem_lockfile_sections?
- [combine_rubygems_sources]
- else
- rubygems_sources.sort_by(&:identifier)
- end
+ rubygems_sources.sort_by(&:identifier)
end
# Returns true if there are changes
@@ -228,10 +210,6 @@ module Bundler
end
end
- def combine_rubygems_sources
- Source::Rubygems.new("remotes" => rubygems_remotes)
- end
-
def warn_on_git_protocol(source)
return if Bundler.settings["git.allow_insecure"]
diff --git a/lib/bundler/source_map.rb b/lib/bundler/source_map.rb
index a8e12d08c3..cb88caf1bd 100644
--- a/lib/bundler/source_map.rb
+++ b/lib/bundler/source_map.rb
@@ -23,15 +23,12 @@ module Bundler
if previous_source.nil?
requirements[indirect_dependency_name] = source
else
- no_ambiguous_sources = Bundler.feature_flag.bundler_4_mode?
-
msg = ["The gem '#{indirect_dependency_name}' was found in multiple relevant sources."]
msg.concat [previous_source, source].map {|s| " * #{s}" }.sort
- msg << "You #{no_ambiguous_sources ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
+ msg << "You must add this gem to the source block for the source you wish it to be installed from."
msg = msg.join("\n")
- raise SecurityError, msg if no_ambiguous_sources
- Bundler.ui.warn "Warning: #{msg}"
+ raise SecurityError, msg
end
end
diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb
index 8f796877fd..67fc51e86a 100644
--- a/spec/bundler/bundler/definition_spec.rb
+++ b/spec/bundler/bundler/definition_spec.rb
@@ -299,10 +299,6 @@ RSpec.describe Bundler::Definition do
[]
end
- def rubygems_remotes
- []
- end
-
def replace_sources!(arg)
nil
end
diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb
index ae2e84766a..65903b3e78 100644
--- a/spec/bundler/commands/install_spec.rb
+++ b/spec/bundler/commands/install_spec.rb
@@ -342,24 +342,6 @@ RSpec.describe "bundle install with gem sources" do
end
end
- it "finds gems in multiple sources" do
- build_repo2 do
- build_gem "myrack", "1.2" do |s|
- s.executables = "myrackup"
- end
- end
-
- install_gemfile <<-G, artifice: "compact_index_extra"
- source "https://gemserver.test"
- source "https://gemserver.test/extra"
-
- gem "activesupport", "1.2.3"
- gem "myrack", "1.2"
- G
-
- expect(the_bundle).to include_gems "myrack 1.2", "activesupport 1.2.3"
- end
-
it "gives useful errors if no global sources are set, and gems not installed locally, with and without a lockfile" do
install_gemfile <<-G, raise_on_error: false
gem "myrack"
diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb
index c7d285cd36..3eeac7f624 100644
--- a/spec/bundler/commands/outdated_spec.rb
+++ b/spec/bundler/commands/outdated_spec.rb
@@ -151,72 +151,6 @@ RSpec.describe "bundle outdated" do
end
end
- describe "with multiple, duplicated sources, with lockfile in old format" do
- before do
- build_repo2 do
- build_gem "dotenv", "2.7.6"
-
- build_gem "oj", "3.11.3"
- build_gem "oj", "3.11.5"
-
- build_gem "vcr", "6.0.0"
- end
-
- build_repo3 do
- build_gem "pkg-gem-flowbyte-with-dep", "1.0.0" do |s|
- s.add_dependency "oj"
- end
- end
-
- gemfile <<~G
- source "https://gem.repo2"
-
- gem "dotenv"
-
- source "https://gem.repo3" do
- gem 'pkg-gem-flowbyte-with-dep'
- end
-
- gem "vcr",source: "https://gem.repo2"
- G
-
- lockfile <<~L
- GEM
- remote: https://gem.repo2/
- remote: https://gem.repo3/
- specs:
- dotenv (2.7.6)
- oj (3.11.3)
- pkg-gem-flowbyte-with-dep (1.0.0)
- oj
- vcr (6.0.0)
-
- PLATFORMS
- #{local_platform}
-
- DEPENDENCIES
- dotenv
- pkg-gem-flowbyte-with-dep!
- vcr!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "works" do
- bundle :install, artifice: "compact_index"
- bundle :outdated, artifice: "compact_index", raise_on_error: false
-
- expected_output = <<~TABLE
- Gem Current Latest Requested Groups
- oj 3.11.3 3.11.5
- TABLE
-
- expect(out).to include(expected_output.strip)
- end
- end
-
describe "with --group option" do
before do
build_repo2 do
diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb
index ef856edf37..f81c557884 100644
--- a/spec/bundler/commands/update_spec.rb
+++ b/spec/bundler/commands/update_spec.rb
@@ -1078,68 +1078,6 @@ RSpec.describe "bundle update" do
L
end
end
-
- context "with multiple, duplicated sources, with lockfile in old format" do
- before do
- build_repo2 do
- build_gem "dotenv", "2.7.6"
-
- build_gem "oj", "3.11.3"
- build_gem "oj", "3.11.5"
-
- build_gem "vcr", "6.0.0"
- end
-
- build_repo3 do
- build_gem "pkg-gem-flowbyte-with-dep", "1.0.0" do |s|
- s.add_dependency "oj"
- end
- end
-
- gemfile <<~G
- source "https://gem.repo2"
-
- gem "dotenv"
-
- source "https://gem.repo3" do
- gem 'pkg-gem-flowbyte-with-dep'
- end
-
- gem "vcr",source: "https://gem.repo2"
- G
-
- lockfile <<~L
- GEM
- remote: https://gem.repo2/
- remote: https://gem.repo3/
- specs:
- dotenv (2.7.6)
- oj (3.11.3)
- pkg-gem-flowbyte-with-dep (1.0.0)
- oj
- vcr (6.0.0)
-
- PLATFORMS
- #{local_platform}
-
- DEPENDENCIES
- dotenv
- pkg-gem-flowbyte-with-dep!
- vcr!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "works" do
- bundle :install, artifice: "compact_index"
- bundle "update oj", artifice: "compact_index"
-
- expect(out).to include("Bundle updated!")
- expect(the_bundle).to include_gems "oj 3.11.5"
- end
- end
end
RSpec.describe "bundle update in more complicated situations" do
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index 406d881541..c2a0905d21 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -4,153 +4,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
# repo1 is built automatically before all of the specs run
# it contains myrack-obama 1.0.0 and myrack 0.9.1 & 1.0.0 amongst other gems
- context "without source affinity" do
- before do
- # Oh no! Someone evil is trying to hijack myrack :(
- # need this to be broken to check for correct source ordering
- build_repo3 do
- build_gem "myrack", repo3_myrack_version do |s|
- s.write "lib/myrack.rb", "MYRACK = 'FAIL'"
- end
- end
- end
-
- context "with multiple toplevel sources" do
- let(:repo3_myrack_version) { "1.0.0" }
-
- before do
- gemfile <<-G
- source "https://gem.repo3"
- source "https://gem.repo1"
- gem "myrack-obama"
- gem "myrack"
- G
- end
-
- it "refuses to install mismatched checksum because one gem has been tampered with" do
- lockfile <<~L
- GEM
- remote: https://gem.repo3/
- remote: https://gem.repo1/
- specs:
- myrack (1.0.0)
-
- PLATFORMS
- #{local_platform}
-
- DEPENDENCIES
- depends_on_myrack!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- bundle :install, artifice: "compact_index", raise_on_error: false
-
- expect(exitstatus).to eq(37)
- expect(err).to eq <<~E.strip
- [DEPRECATED] Your Gemfile contains multiple global 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.
- Bundler found mismatched checksums. This is a potential security risk.
- #{checksum_to_lock(gem_repo1, "myrack", "1.0.0")}
- from the API at https://gem.repo1/
- #{checksum_to_lock(gem_repo3, "myrack", "1.0.0")}
- from the API at https://gem.repo3/
-
- Mismatched checksums each have an authoritative source:
- 1. the API at https://gem.repo1/
- 2. the API at https://gem.repo3/
- You may need to alter your Gemfile sources to resolve this issue.
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
- end
-
- context "when checksum validation is disabled" do
- before do
- bundle "config set --local disable_checksum_validation true"
- end
-
- it "warns about ambiguous gems, but installs anyway, prioritizing sources last to first" do
- bundle :install, artifice: "compact_index"
-
- expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.")
- expect(err).to include("Installed from: https://gem.repo1")
- expect(the_bundle).to include_gems("myrack-obama 1.0.0", "myrack 1.0.0", source: "remote1")
- end
-
- it "does not use the full index unnecessarily" do
- bundle :install, artifice: "compact_index", verbose: true
-
- expect(out).to include("https://gem.repo1/versions")
- expect(out).to include("https://gem.repo3/versions")
- expect(out).not_to include("https://gem.repo1/quick/Marshal.4.8/")
- expect(out).not_to include("https://gem.repo3/quick/Marshal.4.8/")
- end
-
- it "fails", bundler: "4" do
- bundle :install, artifice: "compact_index", 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
-
- context "when different versions of the same gem are in multiple sources" do
- let(:repo3_myrack_version) { "1.2" }
-
- before do
- gemfile <<-G
- source "https://gem.repo3"
- source "https://gem.repo1"
- gem "myrack-obama"
- gem "myrack", "1.0.0" # force it to install the working version in repo1
- G
- end
-
- it "warns about ambiguous gems, but installs anyway" do
- bundle :install, artifice: "compact_index"
- expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.")
- expect(err).to include("Installed from: https://gem.repo1")
- expect(the_bundle).to include_gems("myrack-obama 1.0.0", "myrack 1.0.0", source: "remote1")
- end
-
- it "fails", bundler: "4" do
- bundle :install, artifice: "compact_index", 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
-
- context "without source affinity, and a stdlib gem present in one of the sources", :ruby_repo do
- let(:default_json_version) { ruby "gem 'json'; require 'json'; puts JSON::VERSION" }
-
- before do
- build_repo2 do
- build_gem "json", default_json_version
- end
-
- build_repo4 do
- build_gem "foo" do |s|
- s.add_dependency "json", default_json_version
- end
- end
-
- gemfile <<-G
- source "https://gem.repo2"
- source "https://gem.repo4"
-
- gem "foo"
- G
- end
-
- it "works in standalone mode" do
- gem_checksum = checksum_digest(gem_repo4, "foo", "1.0")
- bundle "install --standalone", artifice: "compact_index", env: { "BUNDLER_SPEC_FOO_CHECKSUM" => gem_checksum }
- end
- end
-
context "with source affinity" do
context "with sources given by a block" do
before do
@@ -313,189 +166,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0")
end
end
-
- context "and in yet another source" do
- before do
- gemfile <<-G
- source "https://gem.repo1"
- source "https://gem.repo2"
- source "https://gem.repo3" do
- gem "depends_on_myrack"
- end
- G
- end
-
- it "fails when the two sources don't have the same checksum" do
- bundle :install, artifice: "compact_index", raise_on_error: false
-
- expect(err).to eq(<<~E.strip)
- [DEPRECATED] Your Gemfile contains multiple global 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.
- Bundler found mismatched checksums. This is a potential security risk.
- #{checksum_to_lock(gem_repo2, "myrack", "1.0.0")}
- from the API at https://gem.repo2/
- #{checksum_to_lock(gem_repo1, "myrack", "1.0.0")}
- from the API at https://gem.repo1/
-
- Mismatched checksums each have an authoritative source:
- 1. the API at https://gem.repo2/
- 2. the API at https://gem.repo1/
- You may need to alter your Gemfile sources to resolve this issue.
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
- expect(exitstatus).to eq(37)
- end
-
- it "fails when the two sources agree, but the local gem calculates a different checksum" do
- myrack_checksum = "c0ffee11" * 8
- bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_MYRACK_CHECKSUM" => myrack_checksum }, raise_on_error: false
-
- expect(err).to eq(<<~E.strip)
- [DEPRECATED] Your Gemfile contains multiple global 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.
- Bundler found mismatched checksums. This is a potential security risk.
- myrack (1.0.0) sha256=#{myrack_checksum}
- from the API at https://gem.repo2/
- and the API at https://gem.repo1/
- #{checksum_to_lock(gem_repo2, "myrack", "1.0.0")}
- from the gem at #{default_bundle_path("cache", "myrack-1.0.0.gem")}
-
- If you trust the API at https://gem.repo2/, to resolve this issue you can:
- 1. remove the gem at #{default_bundle_path("cache", "myrack-1.0.0.gem")}
- 2. run `bundle install`
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
- expect(exitstatus).to eq(37)
- end
-
- it "installs from the other source and warns about ambiguous gems when the sources have the same checksum" do
- gem_checksum = checksum_digest(gem_repo2, "myrack", "1.0.0")
- bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_MYRACK_CHECKSUM" => gem_checksum, "DEBUG" => "1" }
-
- expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.")
- expect(err).to include("Installed from: https://gem.repo2")
-
- checksums = checksums_section_when_enabled do |c|
- c.checksum gem_repo3, "depends_on_myrack", "1.0.1"
- c.checksum gem_repo2, "myrack", "1.0.0"
- end
-
- expect(lockfile).to eq <<~L
- GEM
- remote: https://gem.repo1/
- remote: https://gem.repo2/
- specs:
- myrack (1.0.0)
-
- GEM
- remote: https://gem.repo3/
- specs:
- depends_on_myrack (1.0.1)
- myrack
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- depends_on_myrack!
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- previous_lockfile = lockfile
- expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0")
- expect(lockfile).to eq(previous_lockfile)
- end
-
- it "installs from the other source and warns about ambiguous gems when checksum validation is disabled" do
- bundle "config set --local disable_checksum_validation true"
- bundle :install, artifice: "compact_index"
-
- expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.")
- expect(err).to include("Installed from: https://gem.repo2")
-
- checksums = checksums_section_when_enabled do |c|
- c.no_checksum "depends_on_myrack", "1.0.1"
- c.no_checksum "myrack", "1.0.0"
- end
-
- expect(lockfile).to eq <<~L
- GEM
- remote: https://gem.repo1/
- remote: https://gem.repo2/
- specs:
- myrack (1.0.0)
-
- GEM
- remote: https://gem.repo3/
- specs:
- depends_on_myrack (1.0.1)
- myrack
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- depends_on_myrack!
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
-
- previous_lockfile = lockfile
- expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0")
- expect(lockfile).to eq(previous_lockfile)
- end
-
- it "fails", bundler: "4" do
- bundle :install, artifice: "compact_index", 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 "myrack", "1.0.0" do |s|
- s.write "lib/myrack.rb", "MYRACK = 'FAIL'"
- end
- end
-
- gemfile <<-G
- source "https://gem.repo3" # contains depends_on_myrack
- source "https://gem.repo2" # contains broken myrack
-
- gem "depends_on_myrack" # installed from gem_repo3
- gem "myrack", :source => "https://gem.repo1"
- G
- end
-
- it "installs the dependency from the pinned source without warning" do
- bundle :install, artifice: "compact_index"
-
- expect(err).not_to include("Warning: the gem 'myrack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0")
-
- # In https://github.com/rubygems/bundler/issues/3585 this failed
- # when there is already a lockfile, and the gems are missing, so try again
- system_gems []
- bundle :install, artifice: "compact_index"
-
- expect(err).not_to include("Warning: the gem 'myrack' was found in multiple sources.")
- expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0")
- end
-
- it "fails", bundler: "4" do
- bundle :install, artifice: "compact_index", 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
context "when a top-level gem can only be found in an scoped source" do
@@ -524,39 +194,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
- context "when an indirect dependency can't be found in the aggregate rubygems source" do
- before do
- build_repo2
-
- build_repo3 do
- build_gem "depends_on_missing", "1.0.1" do |s|
- s.add_dependency "missing"
- end
- end
-
- gemfile <<-G
- source "https://gem.repo2"
-
- source "https://gem.repo3"
-
- gem "depends_on_missing"
- G
- end
-
- it "fails" do
- bundle :install, artifice: "compact_index", raise_on_error: false
- expect(err).to end_with <<~E.strip
- Could not find compatible versions
-
- Because every version of depends_on_missing depends on missing >= 0
- and missing >= 0 could not be found in any of the sources,
- depends_on_missing cannot be used.
- So, because Gemfile depends on depends_on_missing >= 0,
- version solving has failed.
- E
- end
- end
-
context "when a top-level gem has an indirect dependency" do
before do
build_repo gem_repo2 do
@@ -714,337 +351,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
- context "when the lockfile has aggregated rubygems sources and newer versions of dependencies are available" do
- before do
- build_repo gem_repo2 do
- build_gem "activesupport", "6.0.3.4" do |s|
- s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
- s.add_dependency "i18n", ">= 0.7", "< 2"
- s.add_dependency "minitest", "~> 5.1"
- s.add_dependency "tzinfo", "~> 1.1"
- s.add_dependency "zeitwerk", "~> 2.2", ">= 2.2.2"
- end
-
- build_gem "activesupport", "6.1.2.1" do |s|
- s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
- s.add_dependency "i18n", ">= 1.6", "< 2"
- s.add_dependency "minitest", ">= 5.1"
- s.add_dependency "tzinfo", "~> 2.0"
- s.add_dependency "zeitwerk", "~> 2.3"
- end
-
- build_gem "concurrent-ruby", "1.1.8"
- build_gem "concurrent-ruby", "1.1.9"
- build_gem "connection_pool", "2.2.3"
-
- build_gem "i18n", "1.8.9" do |s|
- s.add_dependency "concurrent-ruby", "~> 1.0"
- end
-
- build_gem "minitest", "5.14.3"
- build_gem "myrack", "2.2.3"
- build_gem "redis", "4.2.5"
-
- build_gem "sidekiq", "6.1.3" do |s|
- s.add_dependency "connection_pool", ">= 2.2.2"
- s.add_dependency "myrack", "~> 2.0"
- s.add_dependency "redis", ">= 4.2.0"
- end
-
- build_gem "thread_safe", "0.3.6"
-
- build_gem "tzinfo", "1.2.9" do |s|
- s.add_dependency "thread_safe", "~> 0.1"
- end
-
- build_gem "tzinfo", "2.0.4" do |s|
- s.add_dependency "concurrent-ruby", "~> 1.0"
- end
-
- build_gem "zeitwerk", "2.4.2"
- end
-
- build_repo3 do
- build_gem "sidekiq-pro", "5.2.1" do |s|
- s.add_dependency "connection_pool", ">= 2.2.3"
- s.add_dependency "sidekiq", ">= 6.1.0"
- end
- end
-
- gemfile <<-G
- # frozen_string_literal: true
-
- source "https://gem.repo2"
-
- gem "activesupport"
-
- source "https://gem.repo3" do
- gem "sidekiq-pro"
- end
- G
-
- @locked_checksums = checksums_section_when_enabled do |c|
- c.checksum gem_repo2, "activesupport", "6.0.3.4"
- c.checksum gem_repo2, "concurrent-ruby", "1.1.8"
- c.checksum gem_repo2, "connection_pool", "2.2.3"
- c.checksum gem_repo2, "i18n", "1.8.9"
- c.checksum gem_repo2, "minitest", "5.14.3"
- c.checksum gem_repo2, "myrack", "2.2.3"
- c.checksum gem_repo2, "redis", "4.2.5"
- c.checksum gem_repo2, "sidekiq", "6.1.3"
- c.checksum gem_repo3, "sidekiq-pro", "5.2.1"
- c.checksum gem_repo2, "thread_safe", "0.3.6"
- c.checksum gem_repo2, "tzinfo", "1.2.9"
- c.checksum gem_repo2, "zeitwerk", "2.4.2"
- end
-
- lockfile <<~L
- GEM
- remote: https://gem.repo2/
- remote: https://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.8)
- connection_pool (2.2.3)
- i18n (1.8.9)
- concurrent-ruby (~> 1.0)
- minitest (5.14.3)
- myrack (2.2.3)
- redis (4.2.5)
- sidekiq (6.1.3)
- connection_pool (>= 2.2.2)
- myrack (~> 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
- #{lockfile_platforms}
-
- DEPENDENCIES
- activesupport
- sidekiq-pro!
- #{@locked_checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "does not install newer versions but updates the lockfile format when running bundle install in non frozen mode, and doesn't warn" do
- bundle :install, artifice: "compact_index"
- expect(err).to be_empty
-
- 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 <<~L
- GEM
- remote: https://gem.repo2/
- 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.8)
- connection_pool (2.2.3)
- i18n (1.8.9)
- concurrent-ruby (~> 1.0)
- minitest (5.14.3)
- myrack (2.2.3)
- redis (4.2.5)
- sidekiq (6.1.3)
- connection_pool (>= 2.2.2)
- myrack (~> 2.0)
- redis (>= 4.2.0)
- thread_safe (0.3.6)
- tzinfo (1.2.9)
- thread_safe (~> 0.1)
- zeitwerk (2.4.2)
-
- GEM
- remote: https://gem.repo3/
- specs:
- sidekiq-pro (5.2.1)
- connection_pool (>= 2.2.3)
- sidekiq (>= 6.1.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- activesupport
- sidekiq-pro!
- #{@locked_checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "does not install newer versions or generate lockfile changes when running bundle install in frozen mode, and warns" do
- initial_lockfile = lockfile
-
- bundle "config set --local frozen true"
- bundle :install, artifice: "compact_index"
-
- 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 in frozen mode", bundler: "4" do
- initial_lockfile = lockfile
-
- bundle "config set --local frozen true"
- bundle :install, artifice: "compact_index", 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", artifice: "compact_index"
- 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")
- @locked_checksums.checksum gem_repo2, "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")
- @locked_checksums.checksum gem_repo2, "tzinfo", "2.0.4"
- @locked_checksums.delete "thread_safe"
-
- expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
- expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
- @locked_checksums.checksum gem_repo2, "concurrent-ruby", "1.1.9"
-
- expect(lockfile).to eq <<~L
- GEM
- remote: https://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)
- myrack (2.2.3)
- redis (4.2.5)
- sidekiq (6.1.3)
- connection_pool (>= 2.2.2)
- myrack (~> 2.0)
- redis (>= 4.2.0)
- tzinfo (2.0.4)
- concurrent-ruby (~> 1.0)
- zeitwerk (2.4.2)
-
- GEM
- remote: https://gem.repo3/
- specs:
- sidekiq-pro (5.2.1)
- connection_pool (>= 2.2.3)
- sidekiq (>= 6.1.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- activesupport
- sidekiq-pro!
- #{@locked_checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- it "upgrades the lockfile format and upgrades the requested gem when running bundle update with an argument" do
- bundle "update concurrent-ruby", artifice: "compact_index"
- expect(err).to be_empty
-
- 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")
-
- @locked_checksums.checksum gem_repo2, "concurrent-ruby", "1.1.9"
-
- expect(lockfile).to eq <<~L
- GEM
- remote: https://gem.repo2/
- 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)
- myrack (2.2.3)
- redis (4.2.5)
- sidekiq (6.1.3)
- connection_pool (>= 2.2.2)
- myrack (~> 2.0)
- redis (>= 4.2.0)
- thread_safe (0.3.6)
- tzinfo (1.2.9)
- thread_safe (~> 0.1)
- zeitwerk (2.4.2)
-
- GEM
- remote: https://gem.repo3/
- specs:
- sidekiq-pro (5.2.1)
- connection_pool (>= 2.2.3)
- sidekiq (>= 6.1.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- activesupport
- sidekiq-pro!
- #{@locked_checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
context "when a top-level gem has an indirect dependency present in the default source, but with a different version from the one resolved" do
before do
build_lib "activesupport", "7.0.0.alpha", path: lib_path("rails/activesupport")
@@ -1207,112 +513,6 @@ 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: https://gem.repo1/
- remote: https://gem.repo3/
- specs:
- myrack (0.9.1)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- myrack!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- let(:split_gem_section_lockfile) do
- <<~L
- GEM
- remote: https://gem.repo1/
- specs:
-
- GEM
- remote: https://gem.repo3/
- specs:
- myrack (0.9.1)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- myrack!
-
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
-
- before do
- build_repo3 do
- build_gem "myrack", "0.9.1"
- end
-
- gemfile <<-G
- source "https://gem.repo1"
- source "https://gem.repo3" do
- gem 'myrack'
- end
- G
-
- lockfile aggregate_gem_section_lockfile
- end
-
- it "installs the existing lockfile but prints a warning when checksum validation is disabled" do
- bundle "config set --local deployment true"
- bundle "config set --local disable_checksum_validation true"
-
- bundle "install", artifice: "compact_index"
-
- 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("myrack 0.9.1", source: "remote3")
- end
-
- it "prints a checksum warning when the checksums from both sources do not match" do
- bundle "config set --local deployment true"
-
- bundle "install", artifice: "compact_index", raise_on_error: false
-
- api_checksum1 = checksum_digest(gem_repo1, "myrack", "0.9.1")
- api_checksum3 = checksum_digest(gem_repo3, "myrack", "0.9.1")
-
- expect(exitstatus).to eq(37)
- expect(err).to eq(<<~E.strip)
- [DEPRECATED] Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure.
- Bundler found mismatched checksums. This is a potential security risk.
- myrack (0.9.1) sha256=#{api_checksum3}
- from the API at https://gem.repo3/
- myrack (0.9.1) sha256=#{api_checksum1}
- from the API at https://gem.repo1/
-
- Mismatched checksums each have an authoritative source:
- 1. the API at https://gem.repo3/
- 2. the API at https://gem.repo1/
- You may need to alter your Gemfile sources to resolve this issue.
-
- To ignore checksum security warnings, disable checksum validation with
- `bundle config set --local disable_checksum_validation true`
- E
- end
-
- it "refuses to install the existing lockfile and prints an error", bundler: "4" do
- bundle "config set --local deployment true"
-
- bundle "install", artifice: "compact_index", 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"
@@ -1584,37 +784,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
context "when an indirect dependency is available from multiple ambiguous sources" do
- it "succeeds but warns, suggesting a source block" do
- build_repo4 do
- build_gem "depends_on_myrack" do |s|
- s.add_dependency "myrack"
- end
- build_gem "myrack"
- end
-
- install_gemfile <<-G, artifice: "compact_index_extra_api", raise_on_error: false
- source "https://global.source"
-
- source "https://scoped.source/extra" do
- gem "depends_on_myrack"
- end
-
- source "https://scoped.source" do
- gem "thin"
- end
- G
- expect(err).to eq <<~EOS.strip
- Warning: The gem 'myrack' was found in multiple relevant sources.
- * rubygems repository https://scoped.source/
- * rubygems repository https://scoped.source/extra/
- You should add this gem to the source block for the source you wish it to be installed from.
- EOS
- expect(last_command).to be_success
- expect(the_bundle).to be_locked
- end
- end
-
- context "when an indirect dependency is available from multiple ambiguous sources", bundler: "4" do
it "raises, suggesting a source block" do
build_repo4 do
build_gem "depends_on_myrack" do |s|
@@ -1645,83 +814,6 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
- context "when upgrading a lockfile suffering from dependency confusion" do
- before do
- build_repo4 do
- build_gem "mime-types", "3.0.0"
- end
-
- build_repo2 do
- build_gem "capybara", "2.5.0" do |s|
- s.add_dependency "mime-types", ">= 1.16"
- end
-
- build_gem "mime-types", "3.3.1"
- end
-
- gemfile <<~G
- source "https://gem.repo2"
-
- gem "capybara", "~> 2.5.0"
-
- source "https://gem.repo4" do
- gem "mime-types", "~> 3.0"
- end
- G
-
- lockfile <<-L
- GEM
- remote: https://gem.repo2/
- remote: https://gem.repo4/
- specs:
- capybara (2.5.0)
- mime-types (>= 1.16)
- mime-types (3.3.1)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- capybara (~> 2.5.0)
- mime-types (~> 3.0)!
-
- CHECKSUMS
- L
- end
-
- it "upgrades the lockfile correctly" do
- bundle "lock --update", artifice: "compact_index"
-
- checksums = checksums_section_when_enabled do |c|
- c.checksum gem_repo2, "capybara", "2.5.0"
- c.checksum gem_repo4, "mime-types", "3.0.0"
- end
-
- expect(lockfile).to eq <<~L
- GEM
- remote: https://gem.repo2/
- specs:
- capybara (2.5.0)
- mime-types (>= 1.16)
-
- GEM
- remote: https://gem.repo4/
- specs:
- mime-types (3.0.0)
-
- PLATFORMS
- #{lockfile_platforms}
-
- DEPENDENCIES
- capybara (~> 2.5.0)
- mime-types (~> 3.0)!
- #{checksums}
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
- end
-
context "when default source includes old gems with nil required_ruby_version" do
before do
build_repo2 do
diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb
index 3e4b18a188..64c59d4826 100644
--- a/spec/bundler/install/gems/compact_index_spec.rb
+++ b/spec/bundler/install/gems/compact_index_spec.rb
@@ -324,24 +324,6 @@ RSpec.describe "compact index api" do
FileUtils.rm_r Dir[gem_repo2("gems/foo-*.gem")]
end
- gemfile <<-G
- source "#{source_uri}"
- source "#{source_uri}/extra"
- gem "back_deps"
- G
-
- bundle :install, artifice: "compact_index_extra"
- expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
- end
-
- it "fetches again when more dependencies are found in subsequent sources with source blocks" do
- build_repo2 do
- build_gem "back_deps" do |s|
- s.add_dependency "foo"
- end
- FileUtils.rm_r Dir[gem_repo2("gems/foo-*.gem")]
- end
-
install_gemfile <<-G, artifice: "compact_index_extra", verbose: true
source "#{source_uri}"
source "#{source_uri}/extra" do
@@ -375,11 +357,13 @@ RSpec.describe "compact index api" do
expect(the_bundle).to include_gems "myrack 1.2"
end
- it "considers all possible versions of dependencies from all api gem sources" do
- # In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
- # exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
- # of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
- # repo and installs it.
+ it "resolves indirect dependencies to the most scoped source that includes them" do
+ # In this scenario, the gem "somegem" only exists in repo4. It depends on
+ # specific version of activesupport that exists only in repo1. There
+ # happens also be a version of activesupport in repo4, but not the one that
+ # version 1.0.0 of somegem wants. This test makes sure that bundler tries to
+ # use the version in the most scoped source, even if not compatible, and
+ # gives a resolution error
build_repo4 do
build_gem "activesupport", "1.2.0"
build_gem "somegem", "1.0.0" do |s|
@@ -389,14 +373,14 @@ RSpec.describe "compact index api" do
gemfile <<-G
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem 'somegem', '1.0.0'
+ source "#{source_uri}/extra" do
+ gem 'somegem', '1.0.0'
+ end
G
- bundle :install, artifice: "compact_index_extra_api"
+ bundle :install, artifice: "compact_index_extra_api", raise_on_error: false
- expect(the_bundle).to include_gems "somegem 1.0.0"
- expect(the_bundle).to include_gems "activesupport 1.2.3"
+ expect(err).to include("Could not find compatible versions")
end
it "prints API output properly with back deps" do
@@ -481,26 +465,6 @@ RSpec.describe "compact index api" do
gemfile <<-G
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem "back_deps"
- G
-
- bundle :install, artifice: "compact_index_extra"
- bundle "config --set local deployment true"
- bundle :install, artifice: "compact_index_extra"
- expect(the_bundle).to include_gems "back_deps 1.0"
- end
-
- it "fetches again when more dependencies are found in subsequent sources using deployment mode with blocks" do
- build_repo2 do
- build_gem "back_deps" do |s|
- s.add_dependency "foo"
- end
- FileUtils.rm_r Dir[gem_repo2("gems/foo-*.gem")]
- end
-
- gemfile <<-G
- source "#{source_uri}"
source "#{source_uri}/extra" do
gem "back_deps"
end
@@ -583,19 +547,6 @@ RSpec.describe "compact index api" do
expect(the_bundle).to include_gems "myrack 1.0.0"
end
- it "strips http basic auth creds when warning about ambiguous sources" do
- gemfile <<-G
- source "#{basic_auth_source_uri}"
- source "#{file_uri_for(gem_repo1)}"
- gem "myrack"
- G
-
- bundle :install, artifice: "compact_index_basic_authentication"
- expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.")
- expect(err).not_to include("#{user}:#{password}")
- expect(the_bundle).to include_gems "myrack 1.0.0"
- end
-
it "does not pass the user / password to different hosts on redirect" do
gemfile <<-G
source "#{basic_auth_source_uri}"
diff --git a/spec/bundler/install/gems/dependency_api_spec.rb b/spec/bundler/install/gems/dependency_api_spec.rb
index 012e2d3995..1650df3dfb 100644
--- a/spec/bundler/install/gems/dependency_api_spec.rb
+++ b/spec/bundler/install/gems/dependency_api_spec.rb
@@ -264,24 +264,6 @@ RSpec.describe "gemcutter's dependency API" do
gemfile <<-G
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem "back_deps"
- G
-
- bundle :install, artifice: "endpoint_extra"
- expect(the_bundle).to include_gems "back_deps 1.0", "foo 1.0"
- end
-
- it "fetches again when more dependencies are found in subsequent sources using blocks" do
- build_repo2 do
- build_gem "back_deps" do |s|
- s.add_dependency "foo"
- end
- FileUtils.rm_r Dir[gem_repo2("gems/foo-*.gem")]
- end
-
- gemfile <<-G
- source "#{source_uri}"
source "#{source_uri}/extra" do
gem "back_deps"
end
@@ -313,11 +295,13 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "myrack 1.2"
end
- it "considers all possible versions of dependencies from all api gem sources" do
- # In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
- # exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
- # of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
- # repo and installs it.
+ it "resolves indirect dependencies to the most scoped source that includes them" do
+ # In this scenario, the gem "somegem" only exists in repo4. It depends on
+ # specific version of activesupport that exists only in repo1. There
+ # happens also be a version of activesupport in repo4, but not the one that
+ # version 1.0.0 of somegem wants. This test makes sure that bundler tries to
+ # use the version in the most scoped source, even if not compatible, and
+ # gives a resolution error
build_repo4 do
build_gem "activesupport", "1.2.0"
build_gem "somegem", "1.0.0" do |s|
@@ -327,14 +311,14 @@ RSpec.describe "gemcutter's dependency API" do
gemfile <<-G
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem 'somegem', '1.0.0'
+ source "#{source_uri}/extra" do
+ gem 'somegem', '1.0.0'
+ end
G
- bundle :install, artifice: "endpoint_extra_api"
+ bundle :install, artifice: "compact_index_extra_api", raise_on_error: false
- expect(the_bundle).to include_gems "somegem 1.0.0"
- expect(the_bundle).to include_gems "activesupport 1.2.3"
+ expect(err).to include("Could not find compatible versions")
end
it "prints API output properly with back deps" do
@@ -370,25 +354,6 @@ RSpec.describe "gemcutter's dependency API" do
install_gemfile <<-G, artifice: "endpoint_extra_missing"
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem "back_deps"
- G
-
- expect(the_bundle).to include_gems "back_deps 1.0"
- end
-
- it "does not fetch every spec when doing back deps using blocks" do
- build_repo2 do
- build_gem "back_deps" do |s|
- s.add_dependency "foo"
- end
- build_gem "missing"
-
- FileUtils.rm_r Dir[gem_repo2("gems/foo-*.gem")]
- end
-
- install_gemfile <<-G, artifice: "endpoint_extra_missing"
- source "#{source_uri}"
source "#{source_uri}/extra" do
gem "back_deps"
end
@@ -407,26 +372,6 @@ RSpec.describe "gemcutter's dependency API" do
gemfile <<-G
source "#{source_uri}"
- source "#{source_uri}/extra"
- gem "back_deps"
- G
-
- bundle :install, artifice: "endpoint_extra"
- bundle "config set --local deployment true"
- bundle :install, artifice: "endpoint_extra"
- expect(the_bundle).to include_gems "back_deps 1.0"
- end
-
- it "fetches again when more dependencies are found in subsequent sources using deployment mode with blocks" do
- build_repo2 do
- build_gem "back_deps" do |s|
- s.add_dependency "foo"
- end
- FileUtils.rm_r Dir[gem_repo2("gems/foo-*.gem")]
- end
-
- gemfile <<-G
- source "#{source_uri}"
source "#{source_uri}/extra" do
gem "back_deps"
end
@@ -546,19 +491,6 @@ RSpec.describe "gemcutter's dependency API" do
expect(out).not_to include("#{user}:#{password}")
end
- it "strips http basic auth creds when warning about ambiguous sources" do
- gemfile <<-G
- source "#{basic_auth_source_uri}"
- source "#{file_uri_for(gem_repo1)}"
- gem "myrack"
- G
-
- bundle :install, artifice: "endpoint_basic_authentication"
- expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.")
- expect(err).not_to include("#{user}:#{password}")
- expect(the_bundle).to include_gems "myrack 1.0.0"
- end
-
it "does not pass the user / password to different hosts on redirect" do
gemfile <<-G
source "#{basic_auth_source_uri}"
diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb
index bf0fca5ddd..e9d62bc3b8 100644
--- a/spec/bundler/other/major_deprecation_spec.rb
+++ b/spec/bundler/other/major_deprecation_spec.rb
@@ -484,53 +484,62 @@ RSpec.describe "major deprecations" do
context "bundle install with multiple sources" do
before do
- install_gemfile <<-G
+ install_gemfile <<-G, raise_on_error: false
source "https://gem.repo3"
source "https://gem.repo1"
G
end
- it "shows a deprecation" do
- expect(deprecations).to include(
- "Your Gemfile contains multiple global 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."
+ it "fails with a helpful error" do
+ expect(err).to include(
+ "This Gemfile contains multiple global sources. " \
+ "Each source after the first must include a block to indicate which gems " \
+ "should come from that source"
)
end
it "doesn't show lockfile deprecations if there's a lockfile" do
- bundle "install"
+ lockfile <<~L
+ GEM
+ remote: https://gem.repo3/
+ remote: https://gem.repo1/
+ specs:
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
- expect(deprecations).to include(
- "Your Gemfile contains multiple global 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."
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ bundle "install", raise_on_error: false
+
+ expect(err).to include(
+ "This Gemfile contains multiple global sources. " \
+ "Each source after the first must include a block to indicate which gems " \
+ "should come from that source"
)
- expect(deprecations).not_to include(
+ expect(err).not_to include(
"Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. " \
"Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
)
bundle "config set --local frozen true"
- bundle "install"
+ bundle "install", raise_on_error: false
- expect(deprecations).to include(
- "Your Gemfile contains multiple global 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."
+ expect(err).to include(
+ "This Gemfile contains multiple global sources. " \
+ "Each source after the first must include a block to indicate which gems " \
+ "should come from that source"
)
- expect(deprecations).not_to include(
+ expect(err).not_to include(
"Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. " \
"Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
)
end
-
- pending "fails with a helpful error", bundler: "4"
end
- context "bundle install in frozen mode with a lockfile with a single rubygems section with multiple remotes" do
+ context "bundle install with a lockfile with a single rubygems section with multiple remotes" do
before do
build_repo3 do
build_gem "myrack", "0.9.1"
@@ -559,17 +568,13 @@ RSpec.describe "major deprecations" do
BUNDLED WITH
#{Bundler::VERSION}
L
-
- bundle "config set --local frozen true"
end
- it "shows a deprecation" do
- bundle "install"
+ it "shows an error" do
+ bundle "install", raise_on_error: false
- expect(deprecations).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure.")
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure.")
end
-
- pending "fails with a helpful error", bundler: "4"
end
context "when Bundler.setup is run in a ruby script" do