Skip to content

Commit

Permalink
Merge RubyGems/Bundler master from 8459ebd6ad65ce3397233416dc64083ae7…
Browse files Browse the repository at this point in the history
…572bb9
  • Loading branch information
hsbt committed Jul 14, 2021
1 parent 29f6f79 commit 896bbb9
Show file tree
Hide file tree
Showing 45 changed files with 535 additions and 446 deletions.
9 changes: 4 additions & 5 deletions lib/bundler.rb
Expand Up @@ -236,8 +236,9 @@ def user_home
end

if warning
user_home = tmp_home_path(warning)
Bundler.ui.warn "#{warning}\nBundler will use `#{user_home}' as your home directory temporarily.\n"
Bundler.ui.warn "#{warning}\n"
user_home = tmp_home_path
Bundler.ui.warn "Bundler will use `#{user_home}' as your home directory temporarily.\n"
user_home
else
Pathname.new(home)
Expand Down Expand Up @@ -684,15 +685,13 @@ def configure_gem_home
Bundler.rubygems.clear_paths
end

def tmp_home_path(warning)
def tmp_home_path
Kernel.send(:require, "tmpdir")
SharedHelpers.filesystem_access(Dir.tmpdir) do
path = Bundler.tmp
at_exit { Bundler.rm_rf(path) }
path
end
rescue RuntimeError => e
raise e.exception("#{warning}\nBundler also failed to create a temporary home directory':\n#{e}")
end

# @param env [Hash]
Expand Down
59 changes: 27 additions & 32 deletions lib/bundler/definition.rb
Expand Up @@ -138,7 +138,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
@unlock[:gems] ||= @dependencies.map(&:name)
else
eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
@unlock[:gems] = @locked_specs.for(eager_unlock, [], false, false, false).map(&:name)
@unlock[:gems] = @locked_specs.for(eager_unlock, false, false, false).map(&:name)
end

@dependency_changes = converge_dependencies
Expand Down Expand Up @@ -190,25 +190,15 @@ def resolve_remotely!
#
# @return [Bundler::SpecSet]
def specs
@specs ||= begin
begin
specs = resolve.materialize(requested_dependencies)
rescue GemNotFound => e # Handle yanked gem
gem_name, gem_version = extract_gem_info(e)
locked_gem = @locked_specs[gem_name].last
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
"removed in order to install."
end
unless specs["bundler"].any?
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
specs["bundler"] = bundler
end

specs
end
@specs ||= add_bundler_to(resolve.materialize(requested_dependencies))
rescue GemNotFound => e # Handle yanked gem
gem_name, gem_version = extract_gem_info(e)
locked_gem = @locked_specs[gem_name].last
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
"removed in order to install."
end

def new_specs
Expand Down Expand Up @@ -240,17 +230,11 @@ def missing_specs?
end

def requested_specs
@requested_specs ||= begin
groups = requested_groups
groups.map!(&:to_sym)
specs_for(groups)
end
specs_for(requested_groups)
end

def requested_dependencies
groups = requested_groups
groups.map!(&:to_sym)
dependencies_for(groups)
dependencies_for(requested_groups)
end

def current_dependencies
Expand All @@ -260,11 +244,13 @@ def current_dependencies
end

def specs_for(groups)
groups = requested_groups if groups.empty?
deps = dependencies_for(groups)
SpecSet.new(specs.for(expand_dependencies(deps)))
add_bundler_to(resolve.materialize(expand_dependencies(deps)))
end

def dependencies_for(groups)
groups.map!(&:to_sym)
current_dependencies.reject do |d|
(d.groups & groups).empty?
end
Expand Down Expand Up @@ -514,6 +500,15 @@ def unlocking?

private

def add_bundler_to(specs)
unless specs["bundler"].any?
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
specs["bundler"] = bundler
end

specs
end

def precompute_source_requirements_for_indirect_dependencies?
sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
end
Expand Down Expand Up @@ -742,7 +737,7 @@ def converge_locked_specs
# if we won't need the source (according to the lockfile),
# don't error if the path/git source isn't available
next if @locked_specs.
for(requested_dependencies, [], false, true, false).
for(requested_dependencies, false, true, false).
none? {|locked_spec| locked_spec.source == s.source }

raise
Expand All @@ -761,8 +756,8 @@ def converge_locked_specs
end

resolve = SpecSet.new(converged)
@locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), @unlock[:gems], true, true)
resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), [], false, false, false).reject{|s| @unlock[:gems].include?(s.name) })
@locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), true, true)
resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false, false).reject{|s| @unlock[:gems].include?(s.name) })
diff = nil

# Now, we unlock any sources that do not have anymore gems pinned to it
Expand Down
36 changes: 16 additions & 20 deletions lib/bundler/dsl.rb
Expand Up @@ -102,28 +102,26 @@ def gem(name, *args)
# if there's already a dependency with this name we try to prefer one
if current = @dependencies.find {|d| d.name == dep.name }
deleted_dep = @dependencies.delete(current) if current.type == :development
return if deleted_dep

if current.requirement != dep.requirement
unless deleted_dep
return if dep.type == :development
return if dep.type == :development

update_prompt = ""
update_prompt = ""

if File.basename(@gemfile) == Injector::INJECTED_GEMS
if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
update_prompt = ". Gem already added"
else
update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
if File.basename(@gemfile) == Injector::INJECTED_GEMS
if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
update_prompt = ". Gem already added"
else
update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"

update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
end
update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
end

raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
"#{update_prompt}"
end

raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
"#{update_prompt}"
else
Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
"You should probably keep only one of them.\n" \
Expand All @@ -132,12 +130,10 @@ def gem(name, *args)
end

if current.source != dep.source
unless deleted_dep
return if dep.type == :development
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
"#{current.source || "an unspecified source"} and #{dep.source}\n"
end
return if dep.type == :development
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
"#{current.source || "an unspecified source"} and #{dep.source}\n"
end
end

Expand Down
6 changes: 1 addition & 5 deletions lib/bundler/index.rb
Expand Up @@ -195,11 +195,7 @@ def search_by_dependency(dependency, base = nil)
if base # allow all platforms when searching from a lockfile
dependency.matches_spec?(spec)
else
if Gem::Platform.respond_to? :match_spec?
dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
else
dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
end
dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/installer/standalone.rb
Expand Up @@ -3,7 +3,7 @@
module Bundler
class Standalone
def initialize(groups, definition)
@specs = groups.empty? ? definition.requested_specs : definition.specs_for(groups.map(&:to_sym))
@specs = definition.specs_for(groups)
end

def generate
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/plugin/installer.rb
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.add_global_rubygems_remote(rubygems_source) if rubygems_source
Array(rubygems_source).each {|remote| source_list.add_global_rubygems_remote(remote) } if rubygems_source

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

Expand Down
28 changes: 22 additions & 6 deletions lib/bundler/rubygems_ext.rb
Expand Up @@ -176,20 +176,36 @@ def hash
end
end

require "rubygems/platform"

class Platform
JAVA = Gem::Platform.new("java") unless defined?(JAVA)
MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64)
MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW)
X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW)
end

undef_method :hash if method_defined? :hash
def hash
@cpu.hash ^ @os.hash ^ @version.hash
end
Platform.singleton_class.module_eval do
unless Platform.singleton_methods.include?(:match_spec?)
def match_spec?(spec)
match_gem?(spec.platform, spec.name)
end

undef_method :eql? if method_defined? :eql?
alias_method :eql?, :==
def match_gem?(platform, gem_name)
match_platforms?(platform, Gem.platforms)
end

private

def match_platforms?(platform, platforms)
platforms.any? do |local_platform|
platform.nil? ||
local_platform == platform ||
(local_platform != Gem::Platform::RUBY && local_platform =~ platform)
end
end
end
end

require "rubygems/util"
Expand Down
4 changes: 1 addition & 3 deletions lib/bundler/runtime.rb
Expand Up @@ -12,12 +12,10 @@ def initialize(root, definition)
def setup(*groups)
@definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?

groups.map!(&:to_sym)

# Has to happen first
clean_load_path

specs = groups.any? ? @definition.specs_for(groups) : requested_specs
specs = @definition.specs_for(groups)

SharedHelpers.set_bundle_environment
Bundler.rubygems.replace_entrypoints(specs)
Expand Down
8 changes: 2 additions & 6 deletions lib/bundler/settings.rb
Expand Up @@ -428,12 +428,8 @@ def printable_value(value, key)
def global_config_file
if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
Pathname.new(ENV["BUNDLE_CONFIG"])
else
begin
Bundler.user_bundle_path("config")
rescue PermissionError, GenericSystemCallError
nil
end
elsif Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty?
Pathname.new(Bundler.rubygems.user_home).join(".bundle/config")
end
end

Expand Down
9 changes: 4 additions & 5 deletions lib/bundler/spec_set.rb
Expand Up @@ -11,15 +11,14 @@ def initialize(specs)
@specs = specs
end

def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
def for(dependencies, check = false, match_current_platform = false, raise_on_missing = true)
handled = []
deps = dependencies.dup
specs = []
skip += ["bundler"]

loop do
break unless dep = deps.shift
next if handled.include?(dep) || skip.include?(dep.name)
next if handled.any?{|d| d.name == dep.name && (match_current_platform || d.__platform == dep.__platform) } || dep.name == "bundler"

handled << dep

Expand Down Expand Up @@ -73,7 +72,7 @@ def to_hash
end

def materialize(deps, missing_specs = nil)
materialized = self.for(deps, [], false, true, !missing_specs)
materialized = self.for(deps, false, true, !missing_specs)

materialized.group_by(&:source).each do |source, specs|
next unless specs.any?{|s| s.is_a?(LazySpecification) }
Expand Down Expand Up @@ -195,7 +194,7 @@ def tsort_each_node
def spec_for_dependency(dep, match_current_platform)
specs_for_platforms = lookup[dep.name]
if match_current_platform
GemHelpers.select_best_platform_match(specs_for_platforms, Bundler.local_platform)
GemHelpers.select_best_platform_match(specs_for_platforms.select{|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform)
else
GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform)
end
Expand Down

0 comments on commit 896bbb9

Please sign in to comment.