From 1edbaa850f6907c9b4bbaa083ef13a578f251da1 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 20 Jun 2023 12:04:04 +0900 Subject: [PATCH] Merge rubygems/rubygems HEAD Pick from https://github.com/rubygems/rubygems/commit/880dd95996c93adc1e032399816931b243c5fe17 --- lib/bundler/definition.rb | 37 ++++++++++++++++--- lib/bundler/lockfile_generator.rb | 2 +- lib/bundler/resolver.rb | 18 ++++++++- lib/bundler/source/metadata.rb | 30 +++++++-------- lib/bundler/source/rubygems.rb | 1 - spec/bundler/commands/lock_spec.rb | 23 +++++++----- spec/bundler/commands/update_spec.rb | 8 ++-- .../install/gemfile/specific_platform_spec.rb | 13 +++---- spec/bundler/runtime/setup_spec.rb | 1 + spec/bundler/support/activate.rb | 9 +++++ spec/bundler/support/builders.rb | 6 +-- spec/bundler/support/bundle.rb | 7 +--- spec/bundler/support/rubygems_ext.rb | 1 + tool/bundler/dev_gems.rb.lock | 2 +- 14 files changed, 99 insertions(+), 59 deletions(-) create mode 100644 spec/bundler/support/activate.rb diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 268f4249287c27..070543575d3576 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -76,8 +76,11 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti @lockfile = lockfile @lockfile_contents = String.new + @locked_bundler_version = nil - @locked_ruby_version = nil + @resolved_bundler_version = nil + + @locked_ruby_version = nil @new_platform = nil @removed_platform = nil @@ -318,7 +321,7 @@ def lock(file, preserve_unknown_sections = false) if @locked_bundler_version locked_major = @locked_bundler_version.segments.first - current_major = Bundler.gem_version.segments.first + current_major = bundler_version_to_lock.segments.first updating_major = locked_major < current_major end @@ -358,6 +361,10 @@ def locked_ruby_version_object end end + def bundler_version_to_lock + @resolved_bundler_version || Bundler.gem_version + end + def to_lock require_relative "lockfile_generator" LockfileGenerator.generate(self) @@ -471,7 +478,7 @@ def most_specific_locked_platform private :sources def nothing_changed? - !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@missing_lockfile_dep + !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@missing_lockfile_dep && !@unlocking_bundler end def no_resolve_needed? @@ -489,7 +496,14 @@ def resolver end def expanded_dependencies - dependencies + metadata_dependencies + dependencies_with_bundler + metadata_dependencies + end + + def dependencies_with_bundler + return dependencies unless @unlocking_bundler + return dependencies if dependencies.map(&:name).include?("bundler") + + [Dependency.new("bundler", @unlocking_bundler)] + dependencies end def resolution_packages @@ -555,6 +569,8 @@ def materialize(dependencies) def start_resolution result = resolver.start + @resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version + SpecSet.new(SpecSet.new(result).for(dependencies, false, @platforms)) end @@ -613,6 +629,7 @@ def change_reason [@path_changes, "the gemspecs for path gems changed"], [@local_changes, "the gemspecs for git local gems changed"], [@missing_lockfile_dep, "your lock file is missing \"#{@missing_lockfile_dep}\""], + [@unlocking_bundler, "an update to the version of Bundler itself was requested"], ].select(&:first).map(&:last).join(", ") end @@ -868,8 +885,16 @@ def source_requirements metadata_dependencies.each do |dep| source_requirements[dep.name] = sources.metadata_source end - source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source - source_requirements["bundler"] = sources.metadata_source # needs to come last to override + + default_bundler_source = source_requirements["bundler"] || sources.default_source + + if @unlocking_bundler + default_bundler_source.add_dependency_names("bundler") + else + source_requirements[:default_bundler] = default_bundler_source + source_requirements["bundler"] = sources.metadata_source # needs to come last to override + end + verify_changed_sources! source_requirements end diff --git a/lib/bundler/lockfile_generator.rb b/lib/bundler/lockfile_generator.rb index a7ee026f679ab7..f7ba51b3e69275 100644 --- a/lib/bundler/lockfile_generator.rb +++ b/lib/bundler/lockfile_generator.rb @@ -71,7 +71,7 @@ def add_locked_ruby_version end def add_bundled_with - add_section("BUNDLED WITH", Bundler::VERSION) + add_section("BUNDLED WITH", definition.bundler_version_to_lock.to_s) end def add_section(name, value) diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index c8cc88a3eecb73..2ad35bc931a136 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -160,7 +160,7 @@ def no_versions_incompatibility_for(package, unsatisfied_term) constraint_string = constraint.constraint_string requirements = constraint_string.split(" OR ").map {|req| Gem::Requirement.new(req.split(",")) } - if name == "bundler" + if name == "bundler" && bundler_pinned_to_current_version? custom_explanation = "the current Bundler version (#{Bundler::VERSION}) does not satisfy #{constraint}" extended_explanation = bundler_not_found_message(requirements) else @@ -230,6 +230,12 @@ def incompatibilities_for(package, version) def all_versions_for(package) name = package.name results = (@base[name] + filter_prereleases(@all_specs[name], package)).uniq {|spec| [spec.version.hash, spec.platform] } + + if name == "bundler" && !bundler_pinned_to_current_version? + bundler_spec = Gem.loaded_specs["bundler"] + results << bundler_spec if bundler_spec + end + locked_requirement = base_requirements[name] results = filter_matching_specs(results, locked_requirement) if locked_requirement @@ -254,6 +260,14 @@ def source_for(name) @source_requirements[name] || @source_requirements[:default] end + def default_bundler_source + @source_requirements[:default_bundler] + end + + def bundler_pinned_to_current_version? + !default_bundler_source.nil? + end + def name_for_explicit_dependency_source Bundler.default_gemfile.basename.to_s rescue StandardError @@ -398,7 +412,7 @@ def to_dependency_hash(dependencies, packages) end def bundler_not_found_message(conflict_dependencies) - candidate_specs = filter_matching_specs(source_for(:default_bundler).specs.search("bundler"), conflict_dependencies) + candidate_specs = filter_matching_specs(default_bundler_source.specs.search("bundler"), conflict_dependencies) if candidate_specs.any? target_version = candidate_specs.last.version diff --git a/lib/bundler/source/metadata.rb b/lib/bundler/source/metadata.rb index 593da6d1a7b904..524db9c204ae2d 100644 --- a/lib/bundler/source/metadata.rb +++ b/lib/bundler/source/metadata.rb @@ -10,22 +10,22 @@ def specs s.required_rubygems_version = Gem::Requirement.default end - idx << Gem::Specification.new do |s| - s.name = "bundler" - s.version = VERSION - s.license = "MIT" - s.platform = Gem::Platform::RUBY - s.authors = ["bundler team"] - s.bindir = "exe" - s.homepage = "https://bundler.io" - s.summary = "The best way to manage your application's dependencies" - s.executables = %w[bundle] - # can't point to the actual gemspec or else the require paths will be wrong - s.loaded_from = __dir__ - end - - if local_spec = Bundler.rubygems.find_bundler(VERSION) + if local_spec = Gem.loaded_specs["bundler"] idx << local_spec + else + idx << Gem::Specification.new do |s| + s.name = "bundler" + s.version = VERSION + s.license = "MIT" + s.platform = Gem::Platform::RUBY + s.authors = ["bundler team"] + s.bindir = "exe" + s.homepage = "https://bundler.io" + s.summary = "The best way to manage your application's dependencies" + s.executables = %w[bundle] + # can't point to the actual gemspec or else the require paths will be wrong + s.loaded_from = __dir__ + end end idx.each {|s| s.source = self } diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index af82ca6b6c067f..af55ba0f2c8caf 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -381,7 +381,6 @@ def cached_specs idx = @allow_local ? installed_specs.dup : Index.new Dir["#{cache_path}/*.gem"].each do |gemfile| - next if /^bundler\-[\d\.]+?\.gem/.match?(gemfile) s ||= Bundler.rubygems.spec_from_gem(gemfile) s.source = self idx << s diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index 85b3d4a07505e2..491fa30949861d 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -297,24 +297,27 @@ def read_lockfile(file = "Gemfile.lock") end end - it "updates the bundler version in the lockfile without re-resolving", :rubygems => ">= 3.3.0.dev" do + it "updates the bundler version in the lockfile to the latest bundler version" do build_repo4 do - build_gem "rack", "1.0" + build_gem "bundler", "55" end - install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "rack" + system_gems "bundler-55", :gem_repo => gem_repo4 + + install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + source "https://gems.repo4" G lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2') - FileUtils.rm_r gem_repo4 + bundle "lock --update --bundler --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + expect(lockfile).to end_with("BUNDLED WITH\n 55\n") - bundle "lock --update --bundler" - expect(the_bundle).to include_gem "rack 1.0" + update_repo4 do + build_gem "bundler", "99" + end - allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) - expect(the_bundle.locked_gems.bundler_version).to eq v(Bundler::VERSION) + bundle "lock --update --bundler --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + expect(lockfile).to end_with("BUNDLED WITH\n 99\n") end it "supports adding new platforms" do diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index df69de44d244d9..4a720a9120c843 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -1239,7 +1239,7 @@ end RSpec.describe "bundle update --bundler" do - it "updates the bundler version in the lockfile without re-resolving" do + it "updates the bundler version in the lockfile" do build_repo4 do build_gem "rack", "1.0" end @@ -1250,8 +1250,6 @@ G lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2') - FileUtils.rm_r gem_repo4 - bundle :update, :bundler => true, :artifice => "compact_index", :verbose => true expect(out).to include("Using bundler #{Bundler::VERSION}") @@ -1473,8 +1471,8 @@ 2.1.4 L - bundle "update --bundler=2.3.9", :env => { "BUNDLE_FROZEN" => "true" } - expect(err).to include("Cannot write a changed lockfile while frozen") + bundle "update --bundler=2.3.9", :env => { "BUNDLE_FROZEN" => "true" }, :raise_on_error => false + expect(err).to include("An update to the version of bundler itself was requested, but the lockfile can't be updated because frozen mode is set") end end diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 6974af3270830a..cab53a663a9fc1 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -115,8 +115,6 @@ s.platform = "arm64-darwin" s.required_ruby_version = "< #{Gem.ruby_version}" end - - build_gem "bundler", "2.1.4" end gemfile <<~G @@ -137,22 +135,21 @@ DEPENDENCIES nokogiri - RUBY VERSION - 2.5.3p105 - BUNDLED WITH - 2.1.4 + #{Bundler::VERSION} L simulate_platform "arm64-darwin-22", &example end it "still installs the generic RUBY variant if necessary" do - bundle "update --bundler", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + expect(out).to include("Installing nokogiri 1.3.10") end it "still installs the generic RUBY variant if necessary, even in frozen mode" do - bundle "update --bundler", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLE_FROZEN" => "true" } + bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLE_FROZEN" => "true" } + expect(out).to include("Installing nokogiri 1.3.10") end end diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index 9bfcbdaed82ee1..0321e168ca8afa 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -144,6 +144,7 @@ def clean_load_path(lp) ruby <<-RUBY require 'bundler' + gem "bundler", "#{Bundler::VERSION}" if #{ruby_core?} Bundler.setup puts $LOAD_PATH RUBY diff --git a/spec/bundler/support/activate.rb b/spec/bundler/support/activate.rb new file mode 100644 index 00000000000000..e19a6d0ed1e866 --- /dev/null +++ b/spec/bundler/support/activate.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require "rubygems" +Gem.instance_variable_set(:@ruby, ENV["RUBY"]) if ENV["RUBY"] + +require_relative "path" +bundler_gemspec = Spec::Path.loaded_gemspec +bundler_gemspec.instance_variable_set(:@full_gem_path, Spec::Path.source_root) +bundler_gemspec.activate if bundler_gemspec.respond_to?(:activate) diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb index 7c164701532c71..7b91aaef57de79 100644 --- a/spec/bundler/support/builders.rb +++ b/spec/bundler/support/builders.rb @@ -208,10 +208,8 @@ def update_repo4(&blk) update_repo(gem_repo4, &blk) end - def update_repo2 - update_repo gem_repo2 do - yield if block_given? - end + def update_repo2(&blk) + update_repo(gem_repo2, &blk) end def build_security_repo diff --git a/spec/bundler/support/bundle.rb b/spec/bundler/support/bundle.rb index 5f808531ff4ccf..5d6d6580405c0f 100644 --- a/spec/bundler/support/bundle.rb +++ b/spec/bundler/support/bundle.rb @@ -1,10 +1,5 @@ # frozen_string_literal: true -require "rubygems" -Gem.instance_variable_set(:@ruby, ENV["RUBY"]) if ENV["RUBY"] +require_relative "activate" -require_relative "path" -bundler_gemspec = Spec::Path.loaded_gemspec -bundler_gemspec.instance_variable_set(:@full_gem_path, Spec::Path.source_root) -bundler_gemspec.activate if bundler_gemspec.respond_to?(:activate) load File.expand_path("bundle", Spec::Path.bindir) diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb index 4553c0606eac8e..936c82d08cc16b 100644 --- a/spec/bundler/support/rubygems_ext.rb +++ b/spec/bundler/support/rubygems_ext.rb @@ -118,6 +118,7 @@ def gem_activate_and_possibly_install(gem_name) end def gem_activate(gem_name) + require_relative "activate" require "bundler" gem_requirement = Bundler::LockfileParser.new(File.read(dev_lockfile)).specs.find {|spec| spec.name == gem_name }.version gem gem_name, gem_requirement diff --git a/tool/bundler/dev_gems.rb.lock b/tool/bundler/dev_gems.rb.lock index 1bec91b5e0c793..7466ef05942345 100644 --- a/tool/bundler/dev_gems.rb.lock +++ b/tool/bundler/dev_gems.rb.lock @@ -11,7 +11,7 @@ GEM power_assert (2.0.3) rake (13.0.6) rb_sys (0.9.79) - rdiscount (2.2.7) + rdiscount (2.2.7.1) ronn (0.7.3) hpricot (>= 0.8.2) mustache (>= 0.7.0)