1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Merge RubyGems 3.2.6 and Bundler 2.2.6 (#4103)

This commit is contained in:
Hiroshi SHIBATA 2021-01-21 14:35:56 +09:00 committed by GitHub
parent 41d0c70812
commit 151e469a62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 236 additions and 51 deletions

View file

@ -818,11 +818,6 @@ module Bundler
# commonly happens if the version changed in the gemspec
next unless new_spec
new_runtime_deps = new_spec.dependencies.select {|d| d.type != :development }
old_runtime_deps = s.dependencies.select {|d| d.type != :development }
# If the dependencies of the path source have changed and locked spec can't satisfy new dependencies, unlock it
next unless new_runtime_deps.sort == old_runtime_deps.sort || new_runtime_deps.all? {|d| satisfies_locked_spec?(d) }
s.dependencies.replace(new_spec.dependencies)
end
@ -897,7 +892,7 @@ module Bundler
def expand_dependency_with_platforms(dep, platforms)
platforms.map do |p|
DepProxy.new(dep, p)
DepProxy.get_proxy(dep, p)
end
end
@ -977,7 +972,7 @@ module Bundler
next requirements if @locked_gems.dependencies[name] != dependency
next requirements if dependency.source.is_a?(Source::Path)
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
requirements[name] = DepProxy.new(dep, locked_spec.platform)
requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
requirements
end.values
end

View file

@ -4,19 +4,18 @@ module Bundler
class DepProxy
attr_reader :__platform, :dep
@proxies = {}
def self.get_proxy(dep, platform)
@proxies[[dep, platform]] ||= new(dep, platform).freeze
end
def initialize(dep, platform)
@dep = dep
@__platform = platform
end
def hash
@hash ||= [dep, __platform].hash
end
def ==(other)
return false if other.class != self.class
dep == other.dep && __platform == other.__platform
end
private_class_method :new
alias_method :eql?, :==
@ -39,6 +38,14 @@ module Bundler
s
end
def dup
raise NoMethodError.new("DepProxy cannot be duplicated")
end
def clone
raise NoMethodError.new("DepProxy cannot be cloned")
end
private
def method_missing(*args, &blk)

View file

@ -81,8 +81,8 @@ module Bundler
sort_dep_specs(spec_groups, locked_spec)
end.tap do |specs|
if DEBUG
warn before_result
warn " after sort_versions: #{debug_format_result(dep, specs).inspect}"
puts before_result
puts " after sort_versions: #{debug_format_result(dep, specs).inspect}"
end
end
end

View file

@ -32,7 +32,7 @@ module Bundler
@base_dg = Molinillo::DependencyGraph.new
@base.each do |ls|
dep = Dependency.new(ls.name, ls.version)
@base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
end
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
@platforms = platforms
@ -75,7 +75,7 @@ module Bundler
return unless debug?
debug_info = yield
debug_info = debug_info.inspect unless debug_info.is_a?(String)
puts debug_info.split("\n").map {|s| "BUNDLER: " + " " * depth + s }
puts debug_info.split("\n").map {|s| depth == 0 ? "BUNDLER: #{s}" : "BUNDLER(#{depth}): #{s}" }
end
def debug?

View file

@ -99,7 +99,7 @@ module Bundler
spec.dependencies.each do |dep|
next if dep.type == :development
next if @ignores_bundler_dependencies && dep.name == "bundler".freeze
dependencies[platform] << DepProxy.new(dep, platform)
dependencies[platform] << DepProxy.get_proxy(dep, platform)
end
end
dependencies[platform]
@ -110,10 +110,10 @@ module Bundler
return [] unless spec && spec.is_a?(Gem::Specification)
dependencies = []
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
dependencies << DepProxy.new(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
end
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
dependencies << DepProxy.new(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
dependencies << DepProxy.get_proxy(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
end
dependencies
end

View file

@ -158,6 +158,22 @@ module Gem
end
end
if Gem::Requirement.new("~> 2.0").hash == Gem::Requirement.new("~> 2.0.0").hash
class Requirement
module CorrectHashForLambdaOperator
def hash
if requirements.any? {|r| r.first == "~>" }
requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
else
super
end
end
end
prepend CorrectHashForLambdaOperator
end
end
class Platform
JAVA = Gem::Platform.new("java") unless defined?(JAVA)
MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)

View file

@ -28,7 +28,7 @@ module Bundler
specs_for_dep.first.dependencies.each do |d|
next if d.type == :development
d = DepProxy.new(d, dep.__platform) unless match_current_platform
d = DepProxy.get_proxy(d, dep.__platform) unless match_current_platform
deps << d
end
elsif check

View file

@ -329,11 +329,11 @@ module Bundler::Molinillo
# Look for past conflicts that could be unwound to affect the
# requirement tree for the current conflict
all_reqs = last_detail_for_current_unwind.all_requirements
all_reqs_size = all_reqs.size
relevant_unused_unwinds = unused_unwind_options.select do |alternative|
intersecting_requirements =
last_detail_for_current_unwind.all_requirements &
alternative.requirements_unwound_to_instead
next if intersecting_requirements.empty?
diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
next if diff_reqs.size == all_reqs_size
# Find the highest index unwind whilst looping through
current_detail = alternative if alternative > current_detail
alternative
@ -344,8 +344,12 @@ module Bundler::Molinillo
state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
# Update the requirements_unwound_to_instead on any relevant unused unwinds
relevant_unused_unwinds.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
unwind_details.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
relevant_unused_unwinds.each do |d|
(d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
end
unwind_details.each do |d|
(d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
end
current_detail
end

View file

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

View file

@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
VERSION = "3.2.5".freeze
VERSION = "3.2.6".freeze
end
# Must be first since it unloads the prelude from 1.9.2
@ -469,7 +469,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
next if File.exist? subdir
begin
FileUtils.mkdir_p subdir, **options
rescue Errno::EACCES
rescue SystemCallError
end
end
ensure

View file

@ -28,13 +28,14 @@ class Gem::Ext::Builder
unless make_program
make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
end
make_program = Shellwords.split(make_program)
destdir = 'DESTDIR=%s' % ENV['DESTDIR']
['clean', '', 'install'].each do |target|
# Pass DESTDIR via command line to override what's in MAKEFLAGS
cmd = [
make_program,
*make_program,
destdir,
target,
].reject(&:empty?)

View file

@ -121,10 +121,6 @@ class Gem::Platform
end
end
def inspect
"%s @cpu=%p, @os=%p, @version=%p>" % [super[0..-2], *to_a]
end
def to_a
[@cpu, @os, @version]
end

View file

@ -190,7 +190,7 @@ class Gem::Requirement
end
def hash # :nodoc:
requirements.sort.hash
requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
end
def marshal_dump # :nodoc:

View file

@ -2,10 +2,10 @@
RSpec.describe Bundler::DepProxy do
let(:dep) { Bundler::Dependency.new("rake", ">= 0") }
subject { described_class.new(dep, Gem::Platform::RUBY) }
subject { described_class.get_proxy(dep, Gem::Platform::RUBY) }
let(:same) { subject }
let(:other) { subject.dup }
let(:different) { described_class.new(dep, Gem::Platform::JAVA) }
let(:other) { described_class.get_proxy(dep, Gem::Platform::RUBY) }
let(:different) { described_class.get_proxy(dep, Gem::Platform::JAVA) }
describe "#eql?" do
it { expect(subject.eql?(same)).to be true }
@ -15,8 +15,18 @@ RSpec.describe Bundler::DepProxy do
it { expect(subject.eql?("foobar")).to be false }
end
describe "#hash" do
it { expect(subject.hash).to eq(same.hash) }
it { expect(subject.hash).to eq(other.hash) }
describe "must use factory methods" do
it { expect { described_class.new(dep, Gem::Platform::RUBY) }.to raise_error NoMethodError }
it { expect { subject.dup }.to raise_error NoMethodError }
it { expect { subject.clone }.to raise_error NoMethodError }
end
describe "frozen" do
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.5.0")
error = Object.const_get("FrozenError")
else
error = RuntimeError
end
it { expect { subject.instance_variable_set(:@__platform, {}) }.to raise_error error }
end
end

View file

@ -170,7 +170,7 @@ RSpec.describe Bundler::GemVersionPromoter do
context "debug output" do
it "should not kerblooie on its own debug output" do
gvp = unlocking(:level => :patch)
dep = Bundler::DepProxy.new(dep("foo", "1.2.0").first, "ruby")
dep = Bundler::DepProxy.get_proxy(dep("foo", "1.2.0").first, "ruby")
result = gvp.send(:debug_format_result, dep, build_spec_groups("foo", %w[1.2.0 1.3.0]))
expect(result.class).to eq Array
end

View file

@ -581,6 +581,71 @@ RSpec.describe "bundle install with explicit source paths" do
expect(the_bundle).to include_gems "rack 0.9.1"
end
it "keeps using the same version even when another dependency is added" do
build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack", "0.9.1"
end
bundle "install"
expect(the_bundle).to include_gems "rack 0.9.1"
lockfile_should_be <<-G
PATH
remote: #{lib_path("foo")}
specs:
foo (1.0)
rack (= 0.9.1)
GEM
remote: #{file_uri_for(gem_repo1)}/
specs:
rack (0.9.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
BUNDLED WITH
#{Bundler::VERSION}
G
build_lib "foo", "1.0", :path => lib_path("foo") do |s|
s.add_dependency "rack"
s.add_dependency "rake", "13.0.1"
end
bundle "install"
lockfile_should_be <<-G
PATH
remote: #{lib_path("foo")}
specs:
foo (1.0)
rack
rake (= 13.0.1)
GEM
remote: #{file_uri_for(gem_repo1)}/
specs:
rack (0.9.1)
rake (13.0.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
BUNDLED WITH
#{Bundler::VERSION}
G
expect(the_bundle).to include_gems "rack 0.9.1"
end
end
describe "switching sources" do

View file

@ -88,7 +88,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
it "installs plugins depended on by other plugins" do
install_gemfile <<-G
install_gemfile <<-G, :env => { "DEBUG" => "1" }
source "#{file_uri_for(gem_repo2)}"
gem "net_a"
G
@ -97,7 +97,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
it "installs multiple levels of dependencies" do
install_gemfile <<-G
install_gemfile <<-G, :env => { "DEBUG" => "1" }
source "#{file_uri_for(gem_repo2)}"
gem "net_c"
gem "net_e"
@ -114,7 +114,7 @@ RSpec.describe "bundle install with install-time dependencies" do
gem "net_e"
G
bundle :install, :env => { "BUNDLER_DEBUG_RESOLVER" => "1" }
bundle :install, :env => { "BUNDLER_DEBUG_RESOLVER" => "1", "DEBUG" => "1" }
expect(out).to include("BUNDLER: Starting resolution")
end
@ -128,7 +128,7 @@ RSpec.describe "bundle install with install-time dependencies" do
gem "net_e"
G
bundle :install, :env => { "DEBUG_RESOLVER" => "1" }
bundle :install, :env => { "DEBUG_RESOLVER" => "1", "DEBUG" => "1" }
expect(out).to include("BUNDLER: Starting resolution")
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe "bundle install with complex dependencies", :realworld => true do
it "resolves quickly" do
start_time = Time.now
install_gemfile <<-G
source 'https://rubygems.org'
gem "actionmailer"
gem "mongoid", ">= 0.10.2"
G
duration = Time.now - start_time
expect(duration.to_f).to be < 120 # seconds
end
end

View file

@ -176,7 +176,7 @@ Bundler could not find compatible versions for gem "a":
deps = []
@deps.each do |d|
deps << Bundler::DepProxy.new(d, "ruby")
deps << Bundler::DepProxy.get_proxy(d, "ruby")
end
should_resolve_and_include %w[foo-1.0.0 bar-1.0.0], [[]]

View file

@ -22,7 +22,7 @@ module Spec
@deps.each do |d|
@platforms.each do |p|
source_requirements[d.name] = d.source = default_source
deps << Bundler::DepProxy.new(d, p)
deps << Bundler::DepProxy.get_proxy(d, p)
end
end
source_requirements ||= {}

View file

@ -692,6 +692,11 @@ class TestGem < Gem::TestCase
ensure
FileUtils.chmod 0600, parent
end
def test_self_ensure_gem_directories_non_existent_paths
Gem.ensure_gem_subdirectories '/proc/0123456789/bogus' # should not raise
Gem.ensure_gem_subdirectories 'classpath:/bogus/x' # JRuby embed scenario
end
end
def test_self_extension_dir_shared

View file

@ -14,6 +14,7 @@ class TestGemExtBuilder < Gem::TestCase
FileUtils.mkdir_p @dest_path
@orig_DESTDIR = ENV['DESTDIR']
@orig_make = ENV['make']
@spec = util_spec 'a'
@ -22,6 +23,7 @@ class TestGemExtBuilder < Gem::TestCase
def teardown
ENV['DESTDIR'] = @orig_DESTDIR
ENV['make'] = @orig_make
super
end
@ -81,6 +83,28 @@ install:
assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} install$}, results
end
def test_custom_make_with_options
ENV['make'] = 'make V=1'
results = []
File.open File.join(@ext, 'Makefile'), 'w' do |io|
io.puts <<-MAKEFILE
all:
\t@#{Gem.ruby} -e "puts 'all: OK'"
clean:
\t@#{Gem.ruby} -e "puts 'clean: OK'"
install:
\t@#{Gem.ruby} -e "puts 'install: OK'"
MAKEFILE
end
Gem::Ext::Builder.make @dest_path, results, @ext
results = results.join("\n").b
assert_match %r{clean: OK}, results
assert_match %r{all: OK}, results
assert_match %r{install: OK}, results
end
def test_build_extensions
@spec.extensions << 'ext/extconf.rb'

View file

@ -356,6 +356,14 @@ class TestGemPlatform < Gem::TestCase
assert_local_match 'sparc-solaris2.8-mq5.3'
end
def test_inspect
result = Gem::Platform.new("universal-java11").inspect
assert_equal 1, result.scan(/@cpu=/).size
assert_equal 1, result.scan(/@os=/).size
assert_equal 1, result.scan(/@version=/).size
end
def assert_local_match(name)
assert_match Gem::Platform.local, name
end

View file

@ -402,6 +402,27 @@ class TestGemRequirement < Gem::TestCase
assert_equal r1.hash, r2.hash
end
def test_hash_returns_equal_hashes_for_equivalent_requirements
refute_requirement_hash_equal "= 1.2", "= 1.3"
refute_requirement_hash_equal "= 1.3", "= 1.2"
refute_requirement_hash_equal "~> 1.3", "~> 1.3.0"
refute_requirement_hash_equal "~> 1.3.0", "~> 1.3"
assert_requirement_hash_equal ["> 2", "~> 1.3", "~> 1.3.1"], ["~> 1.3.1", "~> 1.3", "> 2"]
assert_requirement_hash_equal ["> 2", "~> 1.3"], ["> 2.0", "~> 1.3"]
assert_requirement_hash_equal ["> 2.0", "~> 1.3"], ["> 2", "~> 1.3"]
assert_requirement_hash_equal "= 1.0", "= 1.0.0"
assert_requirement_hash_equal "= 1.1", "= 1.1.0"
assert_requirement_hash_equal "= 1", "= 1.0.0"
assert_requirement_hash_equal "1.0", "1.0.0"
assert_requirement_hash_equal "1.1", "1.1.0"
assert_requirement_hash_equal "1", "1.0.0"
end
# Assert that two requirements are equal. Handles Gem::Requirements,
# strings, arrays, numbers, and versions.
@ -416,6 +437,13 @@ class TestGemRequirement < Gem::TestCase
"#{requirement} is satisfied by #{version}"
end
# Assert that two requirement hashes are equal. Handles Gem::Requirements,
# strings, arrays, numbers, and versions.
def assert_requirement_hash_equal(expected, actual)
assert_equal req(expected).hash, req(actual).hash
end
# Refute the assumption that two requirements are equal.
def refute_requirement_equal(unexpected, actual)
@ -428,4 +456,10 @@ class TestGemRequirement < Gem::TestCase
refute req(requirement).satisfied_by?(v(version)),
"#{requirement} is not satisfied by #{version}"
end
# Refute the assumption that two requirements hashes are equal.
def refute_requirement_hash_equal(unexpected, actual)
refute_equal req(unexpected).hash, req(actual).hash
end
end