Skip to content

Commit

Permalink
Merge RubyGems-3.3.0 and Bundler-2.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
hsbt committed Dec 21, 2021
1 parent ad450c9 commit 69dc2ea
Show file tree
Hide file tree
Showing 26 changed files with 278 additions and 174 deletions.
8 changes: 8 additions & 0 deletions lib/bundler.rb
Expand Up @@ -66,6 +66,7 @@ module Bundler
autoload :RubyDsl, File.expand_path("bundler/ruby_dsl", __dir__)
autoload :RubyVersion, File.expand_path("bundler/ruby_version", __dir__)
autoload :Runtime, File.expand_path("bundler/runtime", __dir__)
autoload :SelfManager, File.expand_path("bundler/self_manager", __dir__)
autoload :Settings, File.expand_path("bundler/settings", __dir__)
autoload :SharedHelpers, File.expand_path("bundler/shared_helpers", __dir__)
autoload :Source, File.expand_path("bundler/source", __dir__)
Expand Down Expand Up @@ -643,6 +644,13 @@ def configure_gem_home_and_path(path = bundle_path)
Bundler.rubygems.clear_paths
end

def self_manager
@self_manager ||= begin
require_relative "bundler/self_manager"
Bundler::SelfManager.new
end
end

private

def eval_yaml_gemspec(path, contents)
Expand Down
2 changes: 2 additions & 0 deletions lib/bundler/cli.rb
Expand Up @@ -61,6 +61,8 @@ def initialize(*args)
Bundler.reset_settings_and_root!
end

Bundler.self_manager.restart_with_locked_bundler_if_needed

Bundler.settings.set_command_option_if_given :retry, options[:retry]

current_cmd = args.last[:current_command].name
Expand Down
2 changes: 2 additions & 0 deletions lib/bundler/cli/install.rb
Expand Up @@ -12,6 +12,8 @@ def run

warn_if_root

Bundler.self_manager.install_locked_bundler_and_restart_with_it_if_needed

Bundler::SharedHelpers.set_env "RB_USER_INSTALL", "1" if Bundler::FREEBSD

# Disable color in deployment mode
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/definition.rb
Expand Up @@ -294,7 +294,7 @@ def lock(file, preserve_unknown_sections = false)

if updating_major = locked_major < current_major
Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
"after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
"after which you will be unable to return to Bundler #{locked_major}."
end
end

Expand Down
3 changes: 0 additions & 3 deletions lib/bundler/fetcher.rb
Expand Up @@ -122,7 +122,6 @@ def specs_with_retry(gem_names, source)

# return the specs in the bundler format as an index
def specs(gem_names, source)
old = Bundler.rubygems.sources
index = Bundler::Index.new

if Bundler::Fetcher.disable_endpoint
Expand Down Expand Up @@ -153,8 +152,6 @@ def specs(gem_names, source)
rescue CertificateFailureError
Bundler.ui.info "" if gem_names && use_api # newline after dots
raise
ensure
Bundler.rubygems.sources = old
end

def use_api
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/installer.rb
Expand Up @@ -239,7 +239,7 @@ def load_plugins

def ensure_specs_are_compatible!
system_ruby = Bundler::RubyVersion.system
rubygems_version = Gem::Version.create(Gem::VERSION)
rubygems_version = Bundler.rubygems.version
@definition.specs.each do |spec|
if required_ruby_version = spec.required_ruby_version
unless required_ruby_version.satisfied_by?(system_ruby.gem_version)
Expand Down
23 changes: 10 additions & 13 deletions lib/bundler/lockfile_parser.rb
Expand Up @@ -46,6 +46,16 @@ def self.sections_to_ignore(base_version = nil)
attributes
end

def self.bundled_with
lockfile = Bundler.default_lockfile
return unless lockfile.file?

lockfile_contents = Bundler.read_file(lockfile)
return unless lockfile_contents.include?(BUNDLED)

lockfile_contents.split(BUNDLED).last.strip
end

def initialize(lockfile)
@platforms = []
@sources = []
Expand Down Expand Up @@ -77,25 +87,12 @@ def initialize(lockfile)
end
end
@specs = @specs.values.sort_by(&:identifier)
warn_for_outdated_bundler_version
rescue ArgumentError => e
Bundler.ui.debug(e)
raise LockfileError, "Your lockfile is unreadable. Run `rm #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` " \
"and then `bundle install` to generate a new lockfile."
end

def warn_for_outdated_bundler_version
return unless bundler_version
return if bundler_version.segments.last == "dev"
prerelease_text = bundler_version.prerelease? ? " --pre" : ""
current_version = Gem::Version.create(Bundler::VERSION)
return unless current_version < bundler_version
Bundler.ui.warn "Warning: the running version of Bundler (#{current_version}) is older " \
"than the version that created the lockfile (#{bundler_version}). We suggest you to " \
"upgrade to the version that created the lockfile by running `gem install " \
"bundler:#{bundler_version}#{prerelease_text}`.\n"
end

private

TYPES = {
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/plugin/installer.rb
Expand Up @@ -21,7 +21,7 @@ def install(names, options)
elsif options[:local_git]
install_local_git(names, version, options)
else
sources = options[:source] || Bundler.rubygems.sources
sources = options[:source] || Gem.sources
install_rubygems(names, version, sources)
end
end
Expand Down
33 changes: 10 additions & 23 deletions lib/bundler/rubygems_integration.rb
Expand Up @@ -12,25 +12,21 @@ class RubygemsIntegration
EXT_LOCK = Monitor.new
end

def self.version
@version ||= Gem::Version.new(Gem::VERSION)
end

def self.provides?(req_str)
Gem::Requirement.new(req_str).satisfied_by?(version)
end

def initialize
@replaced_methods = {}
backport_ext_builder_monitor
end

def version
self.class.version
@version ||= Gem.rubygems_version
end

def provides?(req_str)
self.class.provides?(req_str)
Gem::Requirement.new(req_str).satisfied_by?(version)
end

def supports_bundler_trampolining?
provides?(">= 3.3.0.a")
end

def build_args
Expand Down Expand Up @@ -142,19 +138,6 @@ def correct_for_windows_path(path)
end
end

def sources=(val)
# Gem.configuration creates a new Gem::ConfigFile, which by default will read ~/.gemrc
# If that file exists, its settings (including sources) will overwrite the values we
# are about to set here. In order to avoid that, we force memoizing the config file now.
configuration

Gem.sources = val
end

def sources
Gem.sources
end

def gem_dir
Gem.dir
end
Expand Down Expand Up @@ -588,6 +571,10 @@ module Ext
end
end

def find_bundler(version)
find_name("bundler").find {|s| s.version.to_s == version }
end

def find_name(name)
Gem::Specification.stubs_for(name).map(&:to_spec)
end
Expand Down
73 changes: 73 additions & 0 deletions lib/bundler/self_manager.rb
@@ -0,0 +1,73 @@
# frozen_string_literal: true

module Bundler
#
# This class handles installing and switching to the version of bundler needed
# by an application.
#
class SelfManager
def restart_with_locked_bundler_if_needed
return unless needs_switching? && installed?

restart_with_locked_bundler
end

def install_locked_bundler_and_restart_with_it_if_needed
return unless needs_switching?

Bundler.ui.info \
"Bundler #{current_version} is running, but your lockfile was generated with #{lockfile_version}. " \
"Installing Bundler #{lockfile_version} and restarting using that version."

install_and_restart_with_locked_bundler
end

private

def install_and_restart_with_locked_bundler
bundler_dep = Gem::Dependency.new("bundler", lockfile_version)

Gem.install(bundler_dep)
rescue StandardError => e
Bundler.ui.trace e
Bundler.ui.warn "There was an error installing the locked bundler version (#{lockfile_version}), rerun with the `--verbose` flag for more details. Going on using bundler #{current_version}."
else
restart_with_locked_bundler
end

def restart_with_locked_bundler
configured_gem_home = ENV["GEM_HOME"]
configured_gem_path = ENV["GEM_PATH"]

Bundler.with_original_env do
Kernel.exec(
{ "GEM_HOME" => configured_gem_home, "GEM_PATH" => configured_gem_path, "BUNDLER_VERSION" => lockfile_version },
$PROGRAM_NAME, *ARGV
)
end
end

def needs_switching?
ENV["BUNDLER_VERSION"].nil? &&
Bundler.rubygems.supports_bundler_trampolining? &&
SharedHelpers.in_bundle? &&
lockfile_version &&
!lockfile_version.end_with?(".dev") &&
lockfile_version != current_version
end

def installed?
Bundler.configure

Bundler.rubygems.find_bundler(lockfile_version)
end

def current_version
@current_version ||= Bundler::VERSION
end

def lockfile_version
@lockfile_version ||= Bundler::LockfileParser.bundled_with
end
end
end
2 changes: 1 addition & 1 deletion lib/bundler/source/metadata.rb
Expand Up @@ -25,7 +25,7 @@ def specs
s.loaded_from = File.expand_path("..", __FILE__)
end

if local_spec = Bundler.rubygems.find_name("bundler").find {|s| s.version.to_s == VERSION }
if local_spec = Bundler.rubygems.find_bundler(VERSION)
idx << local_spec
end

Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/templates/Executable.bundler
Expand Up @@ -73,7 +73,7 @@ m = Module.new do

requirement = bundler_gem_version.approximate_recommendation

return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
return requirement unless Gem.rubygems_version < Gem::Version.new("2.7.0")

requirement += ".a" if bundler_gem_version.prerelease?

Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false

module Bundler
VERSION = "2.3.0.dev".freeze
VERSION = "2.3.0".freeze

def self.bundler_major_version
@bundler_major_version ||= VERSION.split(".").first.to_i
Expand Down
2 changes: 1 addition & 1 deletion lib/rubygems.rb
Expand Up @@ -8,7 +8,7 @@
require 'rbconfig'

module Gem
VERSION = "3.3.0.dev".freeze
VERSION = "3.3.0".freeze
end

# Must be first since it unloads the prelude from 1.9.2
Expand Down
2 changes: 1 addition & 1 deletion spec/bundler/bundler/plugin/installer_spec.rb
Expand Up @@ -7,7 +7,7 @@
it "uses Gem.sources when non of the source is provided" do
sources = double(:sources)
Bundler.settings # initialize it before we have to touch rubygems.ext_lock
allow(Bundler).to receive_message_chain("rubygems.sources") { sources }
allow(Gem).to receive(:sources) { sources }

allow(installer).to receive(:install_rubygems).
with("new-plugin", [">= 0"], sources).once
Expand Down
18 changes: 16 additions & 2 deletions spec/bundler/commands/binstubs_spec.rb
Expand Up @@ -186,11 +186,25 @@

before do
lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 55.0")

update_repo2 do
with_built_bundler("55.0") {|gem_path| FileUtils.mv(gem_path, gem_repo2("gems")) }
end
end

it "installs and runs the exact version of bundler", :rubygems => ">= 3.3.0.dev" do
sys_exec "bin/bundle install --verbose", :env => { "BUNDLER_SPEC_GEM_SOURCES" => file_uri_for(gem_repo2).to_s, "RUBYOPT" => "-r#{spec_dir}/support/hax.rb" }
expect(exitstatus).not_to eq(42)
expect(out).to include("Bundler 55.1 is running, but your lockfile was generated with 55.0. Installing Bundler 55.0 and restarting using that version.")
expect(out).to include("Using bundler 55.0")
expect(err).not_to include("Activating bundler (~> 55.0) failed:")
end

it "runs the available version of bundler when the version is older and the same major" do
sys_exec "bin/bundle install"
it "runs the available version of bundler", :rubygems => "< 3.3.0.dev" do
sys_exec "bin/bundle install --verbose"
expect(exitstatus).not_to eq(42)
expect(out).not_to include("Bundler 55.1 is running, but your lockfile was generated with 55.0. Installing Bundler 55.0 and restarting using that version.")
expect(out).to include("Using bundler 55.1")
expect(err).not_to include("Activating bundler (~> 55.0) failed:")
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/bundler/commands/check_spec.rb
Expand Up @@ -471,10 +471,10 @@ def lock_with(bundler_version = nil)
end

context "is newer" do
it "does not change the lock but warns" do
it "does not change the lock and does not warn" do
lockfile lock_with(Bundler::VERSION.succ)
bundle :check
expect(err).to include("the running version of Bundler (#{Bundler::VERSION}) is older than the version that created the lockfile (#{Bundler::VERSION.succ})")
expect(err).to be_empty
expect(lockfile).to eq lock_with(Bundler::VERSION.succ)
end
end
Expand Down

0 comments on commit 69dc2ea

Please sign in to comment.