Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge rubygems/rubygems HEAD #7961

Merged
merged 1 commit into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 31 additions & 6 deletions lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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?
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/lockfile_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
18 changes: 16 additions & 2 deletions lib/bundler/resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
30 changes: 15 additions & 15 deletions lib/bundler/source/metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
1 change: 0 additions & 1 deletion lib/bundler/source/rubygems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 13 additions & 10 deletions spec/bundler/commands/lock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 3 additions & 5 deletions spec/bundler/commands/update_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}")

Expand Down Expand Up @@ -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

Expand Down
13 changes: 5 additions & 8 deletions spec/bundler/install/gemfile/specific_platform_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
1 change: 1 addition & 0 deletions spec/bundler/runtime/setup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions spec/bundler/support/activate.rb
Original file line number Diff line number Diff line change
@@ -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)
6 changes: 2 additions & 4 deletions spec/bundler/support/builders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 1 addition & 6 deletions spec/bundler/support/bundle.rb
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions spec/bundler/support/rubygems_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion tool/bundler/dev_gems.rb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down