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

Sync RubyGems and Bundler with upstream #4634

Merged
merged 1 commit into from
Jul 7, 2021
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/bundler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module Bundler
environment_preserver = EnvironmentPreserver.from_env
ORIGINAL_ENV = environment_preserver.restore
environment_preserver.replace_with_backup
SUDO_MUTEX = Mutex.new
SUDO_MUTEX = Thread::Mutex.new

autoload :Definition, File.expand_path("bundler/definition", __dir__)
autoload :Dependency, File.expand_path("bundler/dependency", __dir__)
Expand Down
12 changes: 11 additions & 1 deletion lib/bundler/cli/doctor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,11 @@ def check_home_permissions
files_not_readable_or_writable = []
files_not_rw_and_owned_by_different_user = []
files_not_owned_by_current_user_but_still_rw = []
broken_symlinks = []
Find.find(Bundler.bundle_path.to_s).each do |f|
if !File.writable?(f) || !File.readable?(f)
if !File.exist?(f)
broken_symlinks << f
elsif !File.writable?(f) || !File.readable?(f)
if File.stat(f).uid != Process.uid
files_not_rw_and_owned_by_different_user << f
else
Expand All @@ -113,6 +116,13 @@ def check_home_permissions
end

ok = true

if broken_symlinks.any?
Bundler.ui.warn "Broken links exist in the Bundler home. Please report them to the offending gem's upstream repo. These files are:\n - #{broken_symlinks.join("\n - ")}"

ok = false
end

if files_not_owned_by_current_user_but_still_rw.any?
Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \
"user, but are still readable/writable. These files are:\n - #{files_not_owned_by_current_user_but_still_rw.join("\n - ")}"
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/cli/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def run
private

def warn_if_root
return if Bundler.settings[:silence_root_warning] || Bundler::WINDOWS || !Process.uid.zero?
return if Bundler.settings[:silence_root_warning] || Gem.win_platform? || !Process.uid.zero?
Bundler.ui.warn "Don't run Bundler as root. Bundler can ask for sudo " \
"if it is needed, and installing your bundle as root will break this " \
"application for all non-root users on this machine.", :wrap => true
Expand Down
4 changes: 2 additions & 2 deletions lib/bundler/compact_index_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

module Bundler
class CompactIndexClient
DEBUG_MUTEX = Mutex.new
DEBUG_MUTEX = Thread::Mutex.new
def self.debug
return unless ENV["DEBUG_COMPACT_INDEX"]
DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
Expand All @@ -25,7 +25,7 @@ def initialize(directory, fetcher)
@endpoints = Set.new
@info_checksums_by_name = {}
@parsed_checksums = false
@mutex = Mutex.new
@mutex = Thread::Mutex.new
end

def execution_mode=(block)
Expand Down
8 changes: 4 additions & 4 deletions lib/bundler/current_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,19 @@ def truffleruby?
end

def mswin?
Bundler::WINDOWS
Gem.win_platform?
end

def mswin64?
Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
end

def mingw?
Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
end

def x64_mingw?
Bundler::WINDOWS && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64"
end

(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
Expand Down
44 changes: 7 additions & 37 deletions lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,8 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
@unlocking_bundler = false
@unlocking = unlock
else
unlock = unlock.dup
@unlocking_bundler = unlock.delete(:bundler)
unlock.delete_if {|_k, v| Array(v).empty? }
@unlocking = !unlock.empty?
@unlocking = unlock.any? {|_k, v| !Array(v).empty? }
end

@dependencies = dependencies
Expand Down Expand Up @@ -111,8 +109,8 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
@locked_platforms = []
end

@locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
@multisource_allowed = @locked_gem_sources.any?(&:multiple_remotes?) && Bundler.frozen_bundle?
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
@multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle?

if @multisource_allowed
unless sources.aggregate_global_source?
Expand All @@ -121,7 +119,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
Bundler::SharedHelpers.major_deprecation 2, msg
end

@sources.merged_gem_lockfile_sections!
@sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
end

@unlock[:sources] ||= []
Expand Down Expand Up @@ -506,9 +504,6 @@ def most_specific_locked_platform
attr_reader :sources
private :sources

attr_reader :locked_gem_sources
private :locked_gem_sources

def nothing_changed?
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
end
Expand Down Expand Up @@ -636,35 +631,11 @@ def converge_path_sources_to_gemspec_sources
end
end

def converge_rubygems_sources
return false unless multisource_allowed?

return false if locked_gem_sources.empty?

# Get the RubyGems remotes from the Gemfile
actual_remotes = sources.rubygems_remotes
return false if actual_remotes.empty?

changes = false

# If there is a RubyGems source in both
locked_gem_sources.each do |locked_gem_source|
# Merge the remotes from the Gemfile into the Gemfile.lock
changes |= locked_gem_source.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
end

changes
end

def converge_sources
changes = false

changes |= converge_rubygems_sources

# Replace the sources from the Gemfile with the sources from the Gemfile.lock,
# if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
# source in the Gemfile.lock, use the one from the Gemfile.
changes |= sources.replace_sources!(@locked_sources)
changes = sources.replace_sources!(@locked_sources)

sources.all_sources.each do |source|
# If the source is unlockable and the current command allows an unlock of
Expand Down Expand Up @@ -913,14 +884,13 @@ def compute_requires
end

def additional_base_requirements_for_resolve
return [] unless @locked_gems
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
name = locked_spec.name
dependency = dependencies_by_name[name]
next requirements unless dependency
next requirements if @locked_gems.dependencies[name] != dependency
next requirements if dependency.source.is_a?(Source::Path)
next requirements if dependency && dependency.source.is_a?(Source::Path)
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
requirements
Expand Down
14 changes: 3 additions & 11 deletions lib/bundler/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ def self.evaluate(gemfile, lockfile, unlock)
def initialize
@source = nil
@sources = SourceList.new

@global_rubygems_sources = []

@git_sources = {}
@dependencies = []
@groups = []
Expand All @@ -48,7 +45,6 @@ def eval_gemfile(gemfile, contents = nil)
@gemfiles << expanded_gemfile_path
contents ||= Bundler.read_file(@gemfile.to_s)
instance_eval(contents.dup.tap{|x| x.untaint if RUBY_VERSION < "2.7" }, gemfile.to_s, 1)
check_primary_source_safety
rescue Exception => e # rubocop:disable Lint/RescueException
message = "There was an error " \
"#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
Expand Down Expand Up @@ -168,7 +164,7 @@ def source(source, *args, &blk)
elsif block_given?
with_source(@sources.add_rubygems_source("remotes" => source), &blk)
else
@global_rubygems_sources << source
@sources.add_global_rubygems_remote(source)
end
end

Expand Down Expand Up @@ -222,6 +218,7 @@ def github(repo, options = {})
end

def to_definition(lockfile, unlock)
check_primary_source_safety
Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
end

Expand Down Expand Up @@ -453,12 +450,7 @@ def check_path_source_safety
end

def check_rubygems_source_safety
@sources.global_rubygems_source = @global_rubygems_sources.shift
return if @global_rubygems_sources.empty?

@global_rubygems_sources.each do |source|
@sources.add_rubygems_remote(source)
end
return unless @sources.aggregate_global_source?

if Bundler.feature_flag.bundler_3_mode?
msg = "This Gemfile contains multiple primary sources. " \
Expand Down
8 changes: 4 additions & 4 deletions lib/bundler/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def generate_bundler_executable_stubs(spec, options = {})
next
end

mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
mode = Gem.win_platform? ? "wb:UTF-8" : "w"
require "erb"
content = if RUBY_VERSION >= "2.6"
ERB.new(template, :trim_mode => "-").result(binding)
Expand All @@ -144,7 +144,7 @@ def generate_bundler_executable_stubs(spec, options = {})
end

File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask)
if Bundler::WINDOWS || options[:all_platforms]
if Gem.win_platform? || options[:all_platforms]
prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
File.write("#{binstub_path}.cmd", prefix + content, :mode => mode)
end
Expand Down Expand Up @@ -182,7 +182,7 @@ def generate_standalone_bundler_executable_stubs(spec, options = {})
executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
executable_path = executable_path

mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
mode = Gem.win_platform? ? "wb:UTF-8" : "w"
require "erb"
content = if RUBY_VERSION >= "2.6"
ERB.new(template, :trim_mode => "-").result(binding)
Expand All @@ -191,7 +191,7 @@ def generate_standalone_bundler_executable_stubs(spec, options = {})
end

File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755)
if Bundler::WINDOWS || options[:all_platforms]
if Gem.win_platform? || options[:all_platforms]
prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode)
end
Expand Down
22 changes: 2 additions & 20 deletions lib/bundler/lockfile_parser.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
# frozen_string_literal: true

#--
# Some versions of the Bundler 1.1 RC series introduced corrupted
# lockfiles. There were two major problems:
#
# * multiple copies of the same GIT section appeared in the lockfile
# * when this happened, those sections got multiple copies of gems
# in those sections.
#
# As a result, Bundler 1.1 contains code that fixes the earlier
# corruption. We will remove this fix-up code in Bundler 1.2.

module Bundler
class LockfileParser
attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version
Expand Down Expand Up @@ -124,12 +113,7 @@ def parse_source(line)
@sources << @current_source
when GIT
@current_source = TYPES[@type].from_lock(@opts)
# Strip out duplicate GIT sections
if @sources.include?(@current_source)
@current_source = @sources.find {|s| s == @current_source }
else
@sources << @current_source
end
@sources << @current_source
when GEM
@opts["remotes"] = Array(@opts.delete("remote")).reverse
@current_source = TYPES[@type].from_lock(@opts)
Expand Down Expand Up @@ -212,9 +196,7 @@ def parse_spec(line)
@current_spec = LazySpecification.new(name, version, platform)
@current_spec.source = @current_source

# Avoid introducing multiple copies of the same spec (caused by
# duplicate GIT sections)
@specs[@current_spec.identifier] ||= @current_spec
@specs[@current_spec.identifier] = @current_spec
elsif spaces.size == 6
version = version.split(",").map(&:strip) if version
dep = Gem::Dependency.new(name, version)
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/plugin/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def install_all_sources(names, version, git_source_options, rubygems_source)
source_list = SourceList.new

source_list.add_git_source(git_source_options) if git_source_options
source_list.global_rubygems_source = rubygems_source if rubygems_source
source_list.add_global_rubygems_remote(rubygems_source) if rubygems_source

deps = names.map {|name| Dependency.new name, version }

Expand Down
2 changes: 2 additions & 0 deletions lib/bundler/rubygems_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ def to_lock
class Requirement
module OrderIndependentComparison
def ==(other)
return unless Gem::Requirement === other

if _requirements_sorted? && other._requirements_sorted?
super
else
Expand Down
13 changes: 0 additions & 13 deletions lib/bundler/source/rubygems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,19 +252,6 @@ def equivalent_remotes?(other_remotes)
other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
end

def replace_remotes(other_remotes, allow_equivalent = false)
return false if other_remotes == @remotes

equivalent = allow_equivalent && equivalent_remotes?(other_remotes)

@remotes = []
other_remotes.reverse_each do |r|
add_remote r.to_s
end

!equivalent
end

def spec_names
if @allow_remote && dependency_api_available?
remote_specs.spec_names
Expand Down
Loading