Merge RubyGems-3.4.11 and Bundler-2.4.11

This commit is contained in:
Hiroshi SHIBATA 2023-07-19 14:12:03 +09:00 committed by nagachika
parent 5d568e1898
commit dd91a17560
41 changed files with 18561 additions and 227 deletions

View file

@ -89,7 +89,7 @@ module Bundler
class << self class << self
def configure def configure
@configured ||= configure_gem_home_and_path @configure ||= configure_gem_home_and_path
end end
def ui def ui
@ -581,7 +581,7 @@ EOF
@bin_path = nil @bin_path = nil
@bundler_major_version = nil @bundler_major_version = nil
@bundle_path = nil @bundle_path = nil
@configured = nil @configure = nil
@configured_bundle_path = nil @configured_bundle_path = nil
@definition = nil @definition = nil
@load = nil @load = nil

View file

@ -668,9 +668,17 @@ module Bundler
def check_missing_lockfile_specs def check_missing_lockfile_specs
all_locked_specs = @locked_specs.map(&:name) << "bundler" all_locked_specs = @locked_specs.map(&:name) << "bundler"
@locked_specs.any? do |s| missing = @locked_specs.select do |s|
s.dependencies.any? {|dep| !all_locked_specs.include?(dep.name) } s.dependencies.any? {|dep| !all_locked_specs.include?(dep.name) }
end end
if missing.any?
@locked_specs.delete(missing)
true
else
false
end
end end
def converge_paths def converge_paths

View file

@ -93,7 +93,7 @@ module Bundler
locked_version = package.locked_version locked_version = package.locked_version
result = specs.sort do |a, b| result = specs.sort do |a, b|
unless locked_version && (package.prerelease_specified? || pre?) unless package.prerelease_specified? || pre?
a_pre = a.prerelease? a_pre = a.prerelease?
b_pre = b.prerelease? b_pre = b.prerelease?

View file

@ -122,7 +122,7 @@ module Bundler
end end
def to_s def to_s
@__to_s ||= if platform == Gem::Platform::RUBY @to_s ||= if platform == Gem::Platform::RUBY
"#{name} (#{version})" "#{name} (#{version})"
else else
"#{name} (#{version}-#{platform})" "#{name} (#{version}-#{platform})"

View file

@ -35,9 +35,7 @@ module Bundler
end end
def delete(specs) def delete(specs)
specs.each do |spec| @base.delete(specs)
@base.delete(spec)
end
end end
def get_package(name) def get_package(name)

View file

@ -107,7 +107,7 @@ module Bundler
ruby_engine_version = RUBY_ENGINE == "ruby" ? ruby_version : RUBY_ENGINE_VERSION.dup ruby_engine_version = RUBY_ENGINE == "ruby" ? ruby_version : RUBY_ENGINE_VERSION.dup
patchlevel = RUBY_PATCHLEVEL.to_s patchlevel = RUBY_PATCHLEVEL.to_s
@ruby_version ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version) @system ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version)
end end
private private

View file

@ -66,7 +66,9 @@ module Gem
alias_method :rg_extension_dir, :extension_dir alias_method :rg_extension_dir, :extension_dir
def extension_dir def extension_dir
@bundler_extension_dir ||= if source.respond_to?(:extension_dir_name) # following instance variable is already used in original method
# and that is the reason to prefix it with bundler_ and add rubocop exception
@bundler_extension_dir ||= if source.respond_to?(:extension_dir_name) # rubocop:disable Naming/MemoizedInstanceVariableName
unique_extension_dir = [source.extension_dir_name, File.basename(full_gem_path)].uniq.join("-") unique_extension_dir = [source.extension_dir_name, File.basename(full_gem_path)].uniq.join("-")
File.expand_path(File.join(extensions_dir, unique_extension_dir)) File.expand_path(File.join(extensions_dir, unique_extension_dir))
else else
@ -203,9 +205,9 @@ module Gem
protected protected
def _requirements_sorted? def _requirements_sorted?
return @_are_requirements_sorted if defined?(@_are_requirements_sorted) return @_requirements_sorted if defined?(@_requirements_sorted)
strings = as_list strings = as_list
@_are_requirements_sorted = strings == strings.sort @_requirements_sorted = strings == strings.sort
end end
def _with_sorted_requirements def _with_sorted_requirements

View file

@ -7,8 +7,6 @@ module Bundler
class Rubygems < Source class Rubygems < Source
autoload :Remote, File.expand_path("rubygems/remote", __dir__) autoload :Remote, File.expand_path("rubygems/remote", __dir__)
# Use the API when installing less than X gems
API_REQUEST_LIMIT = 500
# Ask for X gems per API request # Ask for X gems per API request
API_REQUEST_SIZE = 50 API_REQUEST_SIZE = 50
@ -401,12 +399,11 @@ module Bundler
# gather lists from non-api sites # gather lists from non-api sites
fetch_names(index_fetchers, nil, idx, false) fetch_names(index_fetchers, nil, idx, false)
# because ensuring we have all the gems we need involves downloading # legacy multi-remote sources need special logic to figure out
# the gemspecs of those gems, if the non-api sites contain more than # dependency names and that logic can be very costly if one remote
# about 500 gems, we treat all sites as non-api for speed. # uses the dependency API but others don't. So use full indexes
allow_api = idx.size < API_REQUEST_LIMIT && dependency_names.size < API_REQUEST_LIMIT # consistently in that particular case.
Bundler.ui.debug "Need to query more than #{API_REQUEST_LIMIT} gems." \ allow_api = !multiple_remotes?
" Downloading full index instead..." unless allow_api
fetch_names(api_fetchers, allow_api && dependency_names, idx, false) fetch_names(api_fetchers, allow_api && dependency_names, idx, false)
end end

View file

@ -63,8 +63,8 @@ module Bundler
@sorted = nil @sorted = nil
end end
def delete(spec) def delete(specs)
@specs.delete(spec) specs.each {|spec| @specs.delete(spec) }
@lookup = nil @lookup = nil
@sorted = nil @sorted = nil
end end

View file

@ -2,4 +2,9 @@
require "mkmf" require "mkmf"
# Makes all symbols private by default to avoid unintended conflict
# with other gems. To explicitly export symbols you can use RUBY_FUNC_EXPORTED
# selectively, or entirely remove this flag.
append_cflags("-fvisibility=hidden")
create_makefile(<%= config[:makefile_path].inspect %>) create_makefile(<%= config[:makefile_path].inspect %>)

View file

@ -2,7 +2,7 @@
VALUE rb_m<%= config[:constant_array].join %>; VALUE rb_m<%= config[:constant_array].join %>;
void RUBY_FUNC_EXPORTED void
Init_<%= config[:underscored_name] %>(void) Init_<%= config[:underscored_name] %>(void)
{ {
rb_m<%= config[:constant_array].join %> = rb_define_module(<%= config[:constant_name].inspect %>); rb_m<%= config[:constant_array].join %> = rb_define_module(<%= config[:constant_name].inspect %>);

View file

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

View file

@ -8,7 +8,7 @@
require "rbconfig" require "rbconfig"
module Gem module Gem
VERSION = "3.4.10" VERSION = "3.4.11"
end end
# Must be first since it unloads the prelude from 1.9.2 # Must be first since it unloads the prelude from 1.9.2

View file

@ -83,7 +83,7 @@ class Gem::CommandManager
# Return the authoritative instance of the command manager. # Return the authoritative instance of the command manager.
def self.instance def self.instance
@command_manager ||= new @instance ||= new
end end
## ##
@ -98,7 +98,7 @@ class Gem::CommandManager
# Reset the authoritative instance of the command manager. # Reset the authoritative instance of the command manager.
def self.reset def self.reset
@command_manager = nil @instance = nil
end end
## ##

View file

@ -388,7 +388,7 @@ class Gem::Installer
# we'll be installing into. # we'll be installing into.
def installed_specs def installed_specs
@specs ||= begin @installed_specs ||= begin
specs = [] specs = []
Gem::Util.glob_files_in_dir("*.gemspec", File.join(gem_home, "specifications")).each do |path| Gem::Util.glob_files_in_dir("*.gemspec", File.join(gem_home, "specifications")).each do |path|

View file

@ -107,7 +107,7 @@ class Gem::RequestSet
@requests = [] @requests = []
@sets = [] @sets = []
@soft_missing = false @soft_missing = false
@sorted = nil @sorted_requests = nil
@specs = nil @specs = nil
@vendor_set = nil @vendor_set = nil
@source_set = nil @source_set = nil
@ -424,7 +424,7 @@ class Gem::RequestSet
end end
def sorted_requests def sorted_requests
@sorted ||= strongly_connected_components.flatten @sorted_requests ||= strongly_connected_components.flatten
end end
def specs def specs

View file

@ -2233,7 +2233,7 @@ class Gem::Specification < Gem::BasicSpecification
# The platform this gem runs on. See Gem::Platform for details. # The platform this gem runs on. See Gem::Platform for details.
def platform def platform
@new_platform ||= Gem::Platform::RUBY @new_platform ||= Gem::Platform::RUBY # rubocop:disable Naming/MemoizedInstanceVariableName
end end
def pretty_print(q) # :nodoc: def pretty_print(q) # :nodoc:
@ -2712,6 +2712,8 @@ class Gem::Specification < Gem::BasicSpecification
end end
@installed_by_version ||= nil @installed_by_version ||= nil
nil
end end
def flatten_require_paths # :nodoc: def flatten_require_paths # :nodoc:

View file

@ -183,7 +183,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
## ##
# The full Gem::Specification for this gem, loaded from evalling its gemspec # The full Gem::Specification for this gem, loaded from evalling its gemspec
def to_spec def spec
@spec ||= if @data @spec ||= if @data
loaded = Gem.loaded_specs[name] loaded = Gem.loaded_specs[name]
loaded if loaded && loaded.version == version loaded if loaded && loaded.version == version
@ -191,6 +191,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
@spec ||= Gem::Specification.load(loaded_from) @spec ||= Gem::Specification.load(loaded_from)
end end
alias_method :to_spec, :spec
## ##
# Is this StubSpecification valid? i.e. have we found a stub line, OR does # Is this StubSpecification valid? i.e. have we found a stub line, OR does

View file

@ -1,175 +1,162 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe Bundler::GemVersionPromoter do RSpec.describe Bundler::GemVersionPromoter do
context "conservative resolver" do let(:gvp) { described_class.new }
def versions(result)
result.flatten.map(&:version).map(&:to_s)
end
# Rightmost (highest array index) in result is most preferred.
# Leftmost (lowest array index) in result is least preferred.
# `build_candidates` has all versions of gem in index.
# `build_spec` is the version currently in the .lock file.
#
# In default (not strict) mode, all versions in the index will
# be returned, allowing Bundler the best chance to resolve all
# dependencies, but sometimes resulting in upgrades that some
# would not consider conservative.
describe "#sort_versions" do
def build_candidates(versions) def build_candidates(versions)
versions.map do |v| versions.map do |v|
Bundler::Resolver::Candidate.new(v) Bundler::Resolver::Candidate.new(v)
end end
end end
def build_spec_set(name, v) def build_package(name, version, locked = [])
Bundler::SpecSet.new(build_spec(name, v)) Bundler::Resolver::Package.new(name, [], :locked_specs => Bundler::SpecSet.new(build_spec(name, version)), :unlock => locked)
end end
def build_package(name, platforms, locked_specs, unlock) def sorted_versions(candidates:, current:, name: "foo", locked: [])
Bundler::Resolver::Package.new(name, platforms, :locked_specs => locked_specs, :unlock => unlock) gvp.sort_versions(
build_package(name, current, locked),
build_candidates(candidates)
).flatten.map(&:version).map(&:to_s)
end end
# Rightmost (highest array index) in result is most preferred. it "numerically sorts versions" do
# Leftmost (lowest array index) in result is least preferred. versions = sorted_versions(:candidates => %w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0], :current => "1.7.8")
# `build_candidates` has all versions of gem in index. expect(versions).to eq %w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0]
# `build_spec` is the version currently in the .lock file. end
#
# In default (not strict) mode, all versions in the index will
# be returned, allowing Bundler the best chance to resolve all
# dependencies, but sometimes resulting in upgrades that some
# would not consider conservative.
context "filter specs (strict) level patch" do
let(:gvp) do
Bundler::GemVersionPromoter.new.tap do |gvp|
gvp.level = :patch
gvp.strict = true
end
end
it "when keeping build_spec, keep current, next release" do context "with no options" do
res = gvp.sort_versions( it "defaults to level=:major, strict=false, pre=false" do
build_package("foo", [], build_spec_set("foo", "1.7.8"), []), versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
build_candidates(%w[1.7.8 1.7.9 1.8.0]) expect(versions).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0]
)
expect(versions(res)).to eq %w[1.7.8 1.7.9]
end
it "when unlocking prefer next release first" do
res = gvp.sort_versions(
build_package("foo", [], build_spec_set("foo", "1.7.8"), []),
build_candidates(%w[1.7.8 1.7.9 1.8.0])
)
expect(versions(res)).to eq %w[1.7.8 1.7.9]
end
it "when unlocking keep current when already at latest release" do
res = gvp.sort_versions(
build_package("foo", [], build_spec_set("foo", "1.7.9"), []),
build_candidates(%w[1.7.9 1.8.0 2.0.0])
)
expect(versions(res)).to eq %w[1.7.9]
end end
end end
context "filter specs (strict) level minor" do context "when strict" do
let(:gvp) do before { gvp.strict = true }
Bundler::GemVersionPromoter.new.tap do |gvp|
gvp.level = :minor context "when level is major" do
gvp.strict = true before { gvp.level = :major }
it "keeps downgrades" do
versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
expect(versions).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0]
end end
end end
it "when unlocking favor next releases, remove minor and major increases" do context "when level is minor" do
res = gvp.sort_versions( before { gvp.level = :minor }
build_package("foo", [], build_spec_set("foo", "0.2.0"), []),
build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]) it "removes downgrades and major upgrades" do
) versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
expect(versions(res)).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0] expect(versions).to eq %w[0.3.0 0.3.1 0.9.0]
end
end end
it "when keep locked, keep current, then favor next release, remove minor and major increases" do context "when level is patch" do
res = gvp.sort_versions( before { gvp.level = :patch }
build_package("foo", [], build_spec_set("foo", "0.2.0"), ["bar"]),
build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]) it "removes downgrades and major and minor upgrades" do
) versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
expect(versions(res)).to eq %w[0.3.0 0.3.1 0.9.0 0.2.0] expect(versions).to eq %w[0.3.0 0.3.1]
end
end end
end end
context "sort specs (not strict) level patch" do context "when not strict" do
let(:gvp) do before { gvp.strict = false }
Bundler::GemVersionPromoter.new.tap do |gvp|
gvp.level = :patch context "when level is major" do
gvp.strict = false before { gvp.level = :major }
it "orders by version" do
versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
expect(versions).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0]
end end
end end
it "when not unlocking, same order but make sure build_spec version is most preferred to stay put" do context "when level is minor" do
res = gvp.sort_versions( before { gvp.level = :minor }
build_package("foo", [], build_spec_set("foo", "1.7.7"), ["bar"]),
build_candidates(%w[1.5.4 1.6.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 2.0.0 2.0.1]) it "favors downgrades, then upgrades by major descending, minor ascending, patch ascending" do
) versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
expect(versions(res)).to eq %w[1.5.4 1.6.5 1.7.6 2.0.0 2.0.1 1.8.0 1.8.1 1.7.8 1.7.9 1.7.7] expect(versions).to eq %w[0.2.0 2.0.1 2.1.0 1.0.0 0.3.0 0.3.1 0.9.0]
end
end end
it "when unlocking favor next release, then current over minor increase" do context "when level is patch" do
res = gvp.sort_versions( before { gvp.level = :patch }
build_package("foo", [], build_spec_set("foo", "1.7.8"), []),
build_candidates(%w[1.7.7 1.7.8 1.7.9 1.8.0])
)
expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9]
end
it "when unlocking do proper integer comparison, not string" do it "favors downgrades, then upgrades by major descending, minor descending, patch ascending" do
res = gvp.sort_versions( versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.1 2.1.0], :current => "0.3.0")
build_package("foo", [], build_spec_set("foo", "1.7.8"), []), expect(versions).to eq %w[0.2.0 2.1.0 2.0.1 1.0.0 0.9.0 0.3.0 0.3.1]
build_candidates(%w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0]) end
)
expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9 1.7.15]
end
it "leave current when unlocking but already at latest release" do
res = gvp.sort_versions(
build_package("foo", [], build_spec_set("foo", "1.7.9"), []),
build_candidates(%w[1.7.9 1.8.0 2.0.0])
)
expect(versions(res)).to eq %w[2.0.0 1.8.0 1.7.9]
end end
end end
context "sort specs (not strict) level minor" do context "when pre" do
let(:gvp) do before { gvp.pre = true }
Bundler::GemVersionPromoter.new.tap do |gvp|
gvp.level = :minor
gvp.strict = false
end
end
it "when unlocking favor next release, then minor increase over current" do it "sorts regardless of prerelease status" do
res = gvp.sort_versions( versions = sorted_versions(:candidates => %w[1.7.7.pre 1.8.0 1.8.1.pre 1.8.1 2.0.0.pre 2.0.0], :current => "1.8.0")
build_package("foo", [], build_spec_set("foo", "0.2.0"), []), expect(versions).to eq %w[1.7.7.pre 1.8.0 1.8.1.pre 1.8.1 2.0.0.pre 2.0.0]
build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1])
)
expect(versions(res)).to eq %w[2.0.0 2.0.1 1.0.0 0.2.0 0.3.0 0.3.1 0.9.0]
end end
end end
context "level error handling" do context "when not pre" do
subject { Bundler::GemVersionPromoter.new } before { gvp.pre = false }
it "should raise if not major, minor or patch is passed" do it "deprioritizes prerelease gems" do
expect { subject.level = :minjor }.to raise_error ArgumentError versions = sorted_versions(:candidates => %w[1.7.7.pre 1.8.0 1.8.1.pre 1.8.1 2.0.0.pre 2.0.0], :current => "1.8.0")
expect(versions).to eq %w[1.7.7.pre 1.8.1.pre 2.0.0.pre 1.8.0 1.8.1 2.0.0]
end end
end
it "should raise if invalid classes passed" do context "when locking and not major" do
[123, nil].each do |value| before { gvp.level = :minor }
expect { subject.level = value }.to raise_error ArgumentError
end it "keeps the current version last" do
versions = sorted_versions(:candidates => %w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.1.0 2.0.1], :current => "0.3.0", :locked => ["bar"])
expect(versions.last).to eq("0.3.0")
end end
end
end
it "should accept major, minor patch symbols" do describe "#level=" do
[:major, :minor, :patch].each do |value| subject { described_class.new }
subject.level = value
expect(subject.level).to eq value it "should raise if not major, minor or patch is passed" do
end expect { subject.level = :minjor }.to raise_error ArgumentError
end
it "should raise if invalid classes passed" do
[123, nil].each do |value|
expect { subject.level = value }.to raise_error ArgumentError
end end
end
it "should accept major, minor patch strings" do it "should accept major, minor patch symbols" do
%w[major minor patch].each do |value| [:major, :minor, :patch].each do |value|
subject.level = value subject.level = value
expect(subject.level).to eq value.to_sym expect(subject.level).to eq value
end end
end
it "should accept major, minor patch strings" do
%w[major minor patch].each do |value|
subject.level = value
expect(subject.level).to eq value.to_sym
end end
end end
end end

View file

@ -400,19 +400,19 @@ RSpec.describe "Bundler::RubyVersion and its subclasses" do
let(:bundler_system_ruby_version) { subject } let(:bundler_system_ruby_version) { subject }
around do |example| around do |example|
if Bundler::RubyVersion.instance_variable_defined?("@ruby_version") if Bundler::RubyVersion.instance_variable_defined?("@system")
begin begin
old_ruby_version = Bundler::RubyVersion.instance_variable_get("@ruby_version") old_ruby_version = Bundler::RubyVersion.instance_variable_get("@system")
Bundler::RubyVersion.remove_instance_variable("@ruby_version") Bundler::RubyVersion.remove_instance_variable("@system")
example.run example.run
ensure ensure
Bundler::RubyVersion.instance_variable_set("@ruby_version", old_ruby_version) Bundler::RubyVersion.instance_variable_set("@system", old_ruby_version)
end end
else else
begin begin
example.run example.run
ensure ensure
Bundler::RubyVersion.remove_instance_variable("@ruby_version") Bundler::RubyVersion.remove_instance_variable("@system")
end end
end end
end end

View file

@ -1008,6 +1008,29 @@ RSpec.describe "bundle lock" do
So, because Gemfile depends on rails >= 7.0.2.3, So, because Gemfile depends on rails >= 7.0.2.3,
version solving has failed. version solving has failed.
ERR ERR
lockfile lockfile.gsub(/PLATFORMS\n #{lockfile_platforms}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
bundle "lock", :raise_on_error => false
expect(err).to eq <<~ERR.strip
Could not find compatible versions
Because rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1
and rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3,
rails >= 7.0.2.3, < 7.0.4 requires activemodel = 7.0.2.3 OR = 7.0.3.1.
And because every version of activemodel depends on activesupport = 6.0.4,
rails >= 7.0.2.3, < 7.0.4 requires activesupport = 6.0.4.
Because rails >= 7.0.3.1, < 7.0.4 depends on activesupport = 7.0.3.1
and rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3,
rails >= 7.0.2.3, < 7.0.4 requires activesupport = 7.0.2.3 OR = 7.0.3.1.
Thus, rails >= 7.0.2.3, < 7.0.4 cannot be used.
And because rails >= 7.0.4 depends on activemodel = 7.0.4,
rails >= 7.0.2.3 requires activemodel = 7.0.4.
So, because activemodel = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally
and Gemfile depends on rails >= 7.0.2.3,
version solving has failed.
ERR
end end
it "does not accidentally resolves to prereleases" do it "does not accidentally resolves to prereleases" do

View file

@ -406,7 +406,7 @@ The checksum of /versions does not match the checksum provided by the server! So
expect(out).to include("Fetching source index from http://localgemserver.test/extra") expect(out).to include("Fetching source index from http://localgemserver.test/extra")
end end
it "does not fetch every spec if the index of gems is large when doing back deps" do it "does not fetch every spec when doing back deps" do
build_repo2 do build_repo2 do
build_gem "back_deps" do |s| build_gem "back_deps" do |s|
s.add_dependency "foo" s.add_dependency "foo"
@ -416,9 +416,7 @@ The checksum of /versions does not match the checksum provided by the server! So
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")] FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end end
api_request_limit = low_api_request_limit_for(gem_repo2) install_gemfile <<-G, :artifice => "compact_index_extra_missing", :env => env_for_missing_prerelease_default_gem_activation
install_gemfile <<-G, :artifice => "compact_index_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
source "#{source_uri}" source "#{source_uri}"
source "#{source_uri}/extra" do source "#{source_uri}/extra" do
gem "back_deps" gem "back_deps"
@ -428,7 +426,7 @@ The checksum of /versions does not match the checksum provided by the server! So
expect(the_bundle).to include_gems "back_deps 1.0" expect(the_bundle).to include_gems "back_deps 1.0"
end end
it "does not fetch every spec if the index of gems is large when doing back deps & everything is the compact index" do it "does not fetch every spec when doing back deps & everything is the compact index" do
build_repo4 do build_repo4 do
build_gem "back_deps" do |s| build_gem "back_deps" do |s|
s.add_dependency "foo" s.add_dependency "foo"
@ -438,9 +436,7 @@ The checksum of /versions does not match the checksum provided by the server! So
FileUtils.rm_rf Dir[gem_repo4("gems/foo-*.gem")] FileUtils.rm_rf Dir[gem_repo4("gems/foo-*.gem")]
end end
api_request_limit = low_api_request_limit_for(gem_repo4) install_gemfile <<-G, :artifice => "compact_index_extra_api_missing", :env => env_for_missing_prerelease_default_gem_activation
install_gemfile <<-G, :artifice => "compact_index_extra_api_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
source "#{source_uri}" source "#{source_uri}"
source "#{source_uri}/extra" do source "#{source_uri}/extra" do
gem "back_deps" gem "back_deps"

View file

@ -359,7 +359,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(out).to include("Fetching source index from http://localgemserver.test/extra") expect(out).to include("Fetching source index from http://localgemserver.test/extra")
end end
it "does not fetch every spec if the index of gems is large when doing back deps", :bundler => "< 3" do it "does not fetch every spec when doing back deps", :bundler => "< 3" do
build_repo2 do build_repo2 do
build_gem "back_deps" do |s| build_gem "back_deps" do |s|
s.add_dependency "foo" s.add_dependency "foo"
@ -369,9 +369,7 @@ RSpec.describe "gemcutter's dependency API" do
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")] FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end end
api_request_limit = low_api_request_limit_for(gem_repo2) install_gemfile <<-G, :artifice => "endpoint_extra_missing", :env => env_for_missing_prerelease_default_gem_activation
install_gemfile <<-G, :artifice => "endpoint_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
source "#{source_uri}" source "#{source_uri}"
source "#{source_uri}/extra" source "#{source_uri}/extra"
gem "back_deps" gem "back_deps"
@ -380,7 +378,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "back_deps 1.0" expect(the_bundle).to include_gems "back_deps 1.0"
end end
it "does not fetch every spec if the index of gems is large when doing back deps using blocks" do it "does not fetch every spec when doing back deps using blocks" do
build_repo2 do build_repo2 do
build_gem "back_deps" do |s| build_gem "back_deps" do |s|
s.add_dependency "foo" s.add_dependency "foo"
@ -390,9 +388,7 @@ RSpec.describe "gemcutter's dependency API" do
FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")] FileUtils.rm_rf Dir[gem_repo2("gems/foo-*.gem")]
end end
api_request_limit = low_api_request_limit_for(gem_repo2) install_gemfile <<-G, :artifice => "endpoint_extra_missing", :env => env_for_missing_prerelease_default_gem_activation
install_gemfile <<-G, :artifice => "endpoint_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
source "#{source_uri}" source "#{source_uri}"
source "#{source_uri}/extra" do source "#{source_uri}/extra" do
gem "back_deps" gem "back_deps"

View file

@ -1,16 +0,0 @@
# frozen_string_literal: true
if ENV["BUNDLER_SPEC_API_REQUEST_LIMIT"]
require_relative "path"
require "bundler/source"
require "bundler/source/rubygems"
module Bundler
class Source
class Rubygems < Source
remove_const :API_REQUEST_LIMIT
API_REQUEST_LIMIT = ENV["BUNDLER_SPEC_API_REQUEST_LIMIT"].to_i
end
end
end
end

File diff suppressed because it is too large Load diff

View file

@ -17,18 +17,6 @@ module Spec
Gem::Platform.new(platform) Gem::Platform.new(platform)
end end
# Returns a number smaller than the size of the index. Useful for specs that
# need the API request limit to be reached for some reason.
def low_api_request_limit_for(gem_repo)
all_gems = Dir[gem_repo.join("gems/*.gem")]
all_gem_names = all_gems.map do |file|
File.basename(file, ".gem").match(/\A(?<gem_name>[^-]+)-.*\z/)[:gem_name]
end.uniq
(all_gem_names - ["bundler"]).size
end
def build_repo1 def build_repo1
rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first

View file

@ -71,10 +71,6 @@ module Spec
@spec_dir ||= source_root.join(ruby_core? ? "spec/bundler" : "spec") @spec_dir ||= source_root.join(ruby_core? ? "spec/bundler" : "spec")
end end
def api_request_limit_hack_file
spec_dir.join("support/api_request_limit_hax.rb")
end
def man_dir def man_dir
@man_dir ||= lib_dir.join("bundler/man") @man_dir ||= lib_dir.join("bundler/man")
end end

View file

@ -1179,6 +1179,20 @@ Also, a list:
RUBY_PLATFORM.match("mswin") RUBY_PLATFORM.match("mswin")
end end
##
# Is this test being run on a version of Ruby built with mingw?
def self.mingw_windows?
RUBY_PLATFORM.match("mingw")
end
##
# Is this test being run on a version of Ruby built with mingw?
def mingw_windows?
RUBY_PLATFORM.match("mingw")
end
## ##
# Is this test being run on a ruby/ruby repository? # Is this test being run on a ruby/ruby repository?
# #

View file

@ -14,7 +14,7 @@ require "rubygems/request"
# The tested hosts are explained in detail here: https://github.com/rubygems/rubygems/commit/5e16a5428f973667cabfa07e94ff939e7a83ebd9 # The tested hosts are explained in detail here: https://github.com/rubygems/rubygems/commit/5e16a5428f973667cabfa07e94ff939e7a83ebd9
# #
class TestBundledCA < Gem::TestCase class TestGemBundledCA < Gem::TestCase
def bundled_certificate_store def bundled_certificate_store
store = OpenSSL::X509::Store.new store = OpenSSL::X509::Store.new

View file

@ -3,7 +3,7 @@ require_relative "helper"
require "rubygems" require "rubygems"
require "shellwords" require "shellwords"
class TestConfig < Gem::TestCase class TestGemConfig < Gem::TestCase
def test_datadir def test_datadir
util_make_gems util_make_gems
spec = Gem::Specification.find_by_name("a") spec = Gem::Specification.find_by_name("a")

View file

@ -2,7 +2,7 @@
require_relative "helper" require_relative "helper"
require "rubygems/deprecate" require "rubygems/deprecate"
class TestDeprecate < Gem::TestCase class TestGemDeprecate < Gem::TestCase
def setup def setup
super super

View file

@ -3,7 +3,7 @@
require_relative "helper" require_relative "helper"
require "rubygems" require "rubygems"
class TestExit < Gem::TestCase class TestGemExit < Gem::TestCase
def test_exit def test_exit
system(*ruby_with_rubygems_in_load_path, "-e", "raise Gem::SystemExitException.new(2)") system(*ruby_with_rubygems_in_load_path, "-e", "raise Gem::SystemExitException.new(2)")
assert_equal 2, $?.exitstatus assert_equal 2, $?.exitstatus

View file

@ -145,6 +145,7 @@ class TestGemExtCargoBuilder < Gem::TestCase
system(@rust_envs, "cargo", "-V", out: IO::NULL, err: [:child, :out]) system(@rust_envs, "cargo", "-V", out: IO::NULL, err: [:child, :out])
pend "cargo not present" unless $?.success? pend "cargo not present" unless $?.success?
pend "ruby.h is not provided by ruby repo" if ruby_repo? pend "ruby.h is not provided by ruby repo" if ruby_repo?
pend "rust toolchain of mingw is broken" if mingw_windows?
end end
def assert_ffi_handle(bundle, name) def assert_ffi_handle(bundle, name)

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative "helper" require_relative "helper"
class TestKernel < Gem::TestCase class TestGemKernel < Gem::TestCase
def setup def setup
super super

View file

@ -3,13 +3,36 @@
require_relative "helper" require_relative "helper"
require "open3" require "open3"
class TestProjectSanity < Gem::TestCase class TestGemProjectSanity < Gem::TestCase
def setup
end
def teardown
end
def test_manifest_is_up_to_date def test_manifest_is_up_to_date
pend unless File.exist?(File.expand_path("../../Rakefile", __dir__)) pend unless File.exist?("#{root}/Rakefile")
_, status = Open3.capture2e("rake check_manifest") _, status = Open3.capture2e("rake check_manifest")
assert status.success?, "Expected Manifest.txt to be up to date, but it's not. Run `rake update_manifest` to sync it." unless status.success?
original_contents = File.read("#{root}/Manifest.txt")
# Update the manifest to see if it fixes the problem
Open3.capture2e("rake update_manifest")
out, status = Open3.capture2e("rake check_manifest")
# If `rake update_manifest` fixed the problem, that was the original
# issue, otherwise it was an unknown error, so print the error output
if status.success?
File.write("#{root}/Manifest.txt", original_contents)
raise "Expected Manifest.txt to be up to date, but it's not. Run `rake update_manifest` to sync it."
else
raise "There was an error running `rake check_manifest`: #{out}"
end
end
end end
def test_require_rubygems_package def test_require_rubygems_package
@ -17,4 +40,10 @@ class TestProjectSanity < Gem::TestCase
assert status.success?, err assert status.success?, err
end end
private
def root
File.expand_path("../..", __dir__)
end
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative "helper" require_relative "helper"
class TestRemoteFetchError < Gem::TestCase class TestGemRemoteFetchError < Gem::TestCase
def test_password_redacted def test_password_redacted
error = Gem::RemoteFetcher::FetchError.new("There was an error fetching", "https://user:secret@gemsource.org") error = Gem::RemoteFetcher::FetchError.new("There was an error fetching", "https://user:secret@gemsource.org")
refute_match %r{secret}, error.to_s refute_match %r{secret}, error.to_s

View file

@ -167,7 +167,7 @@ end
# #
# Example: # Example:
# #
# HTTPResponseFactory.create( # Gem::HTTPResponseFactory.create(
# body: "", # body: "",
# code: 301, # code: 301,
# msg: "Moved Permanently", # msg: "Moved Permanently",
@ -175,7 +175,7 @@ end
# ) # )
# #
class HTTPResponseFactory class Gem::HTTPResponseFactory
def self.create(body:, code:, msg:, headers: {}) def self.create(body:, code:, msg:, headers: {})
response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg) response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
response.instance_variable_set(:@body, body) response.instance_variable_set(:@body, body)
@ -372,7 +372,7 @@ end
# #
# This class was added to flush out problems in Rubinius' IO implementation. # This class was added to flush out problems in Rubinius' IO implementation.
class TempIO < Tempfile class Gem::TempIO < Tempfile
## ##
# Creates a new TempIO that will be initialized to contain +string+. # Creates a new TempIO that will be initialized to contain +string+.
@ -391,3 +391,8 @@ class TempIO < Tempfile
Gem.read_binary path Gem.read_binary path
end end
end end
class Gem::TestCase
TempIO = Gem::TempIO
HTTPResponseFactory = Gem::HTTPResponseFactory
end

View file

@ -54,4 +54,4 @@ DEPENDENCIES
webrick (~> 1.6) webrick (~> 1.6)
BUNDLED WITH BUNDLED WITH
2.4.10 2.4.11

View file

@ -70,4 +70,4 @@ DEPENDENCIES
test-unit test-unit
BUNDLED WITH BUNDLED WITH
2.4.10 2.4.11

View file

@ -78,4 +78,4 @@ DEPENDENCIES
test-unit test-unit
BUNDLED WITH BUNDLED WITH
2.4.10 2.4.11

View file

@ -42,4 +42,4 @@ DEPENDENCIES
webrick (= 1.7.0) webrick (= 1.7.0)
BUNDLED WITH BUNDLED WITH
2.4.10 2.4.11