mirror of
https://github.com/ruby/ruby.git
synced 2025-09-19 18:43:59 +02:00
Merge RubyGems-3.2.14 and Bundler-2.2.14
This commit is contained in:
parent
7efc7afcae
commit
0476ce0370
32 changed files with 716 additions and 371 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -33,10 +33,6 @@ module Bundler
|
|||
end
|
||||
end
|
||||
|
||||
def cached!; end
|
||||
|
||||
def remote!; end
|
||||
|
||||
def options
|
||||
{}
|
||||
end
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
##
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)}"
|
||||
|
|
|
@ -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?
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -89,6 +89,8 @@ RSpec.configure do |config|
|
|||
end
|
||||
|
||||
config.before :all do
|
||||
check_test_gems!
|
||||
|
||||
build_repo1
|
||||
|
||||
reset_paths!
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue