Sync RubyGems and Bundler with upstream
This commit is contained in:
parent
6e2240a2f9
commit
c082c6eb7c
Notes:
git
2021-07-07 15:32:14 +09:00
@ -37,7 +37,7 @@ module Bundler
|
|||||||
environment_preserver = EnvironmentPreserver.from_env
|
environment_preserver = EnvironmentPreserver.from_env
|
||||||
ORIGINAL_ENV = environment_preserver.restore
|
ORIGINAL_ENV = environment_preserver.restore
|
||||||
environment_preserver.replace_with_backup
|
environment_preserver.replace_with_backup
|
||||||
SUDO_MUTEX = Mutex.new
|
SUDO_MUTEX = Thread::Mutex.new
|
||||||
|
|
||||||
autoload :Definition, File.expand_path("bundler/definition", __dir__)
|
autoload :Definition, File.expand_path("bundler/definition", __dir__)
|
||||||
autoload :Dependency, File.expand_path("bundler/dependency", __dir__)
|
autoload :Dependency, File.expand_path("bundler/dependency", __dir__)
|
||||||
|
@ -100,8 +100,11 @@ module Bundler
|
|||||||
files_not_readable_or_writable = []
|
files_not_readable_or_writable = []
|
||||||
files_not_rw_and_owned_by_different_user = []
|
files_not_rw_and_owned_by_different_user = []
|
||||||
files_not_owned_by_current_user_but_still_rw = []
|
files_not_owned_by_current_user_but_still_rw = []
|
||||||
|
broken_symlinks = []
|
||||||
Find.find(Bundler.bundle_path.to_s).each do |f|
|
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
|
if File.stat(f).uid != Process.uid
|
||||||
files_not_rw_and_owned_by_different_user << f
|
files_not_rw_and_owned_by_different_user << f
|
||||||
else
|
else
|
||||||
@ -113,6 +116,13 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
ok = true
|
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?
|
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 " \
|
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 - ")}"
|
"user, but are still readable/writable. These files are:\n - #{files_not_owned_by_current_user_but_still_rw.join("\n - ")}"
|
||||||
|
@ -104,7 +104,7 @@ module Bundler
|
|||||||
private
|
private
|
||||||
|
|
||||||
def warn_if_root
|
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 " \
|
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 " \
|
"if it is needed, and installing your bundle as root will break this " \
|
||||||
"application for all non-root users on this machine.", :wrap => true
|
"application for all non-root users on this machine.", :wrap => true
|
||||||
|
@ -5,7 +5,7 @@ require "set"
|
|||||||
|
|
||||||
module Bundler
|
module Bundler
|
||||||
class CompactIndexClient
|
class CompactIndexClient
|
||||||
DEBUG_MUTEX = Mutex.new
|
DEBUG_MUTEX = Thread::Mutex.new
|
||||||
def self.debug
|
def self.debug
|
||||||
return unless ENV["DEBUG_COMPACT_INDEX"]
|
return unless ENV["DEBUG_COMPACT_INDEX"]
|
||||||
DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
|
DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
|
||||||
@ -25,7 +25,7 @@ module Bundler
|
|||||||
@endpoints = Set.new
|
@endpoints = Set.new
|
||||||
@info_checksums_by_name = {}
|
@info_checksums_by_name = {}
|
||||||
@parsed_checksums = false
|
@parsed_checksums = false
|
||||||
@mutex = Mutex.new
|
@mutex = Thread::Mutex.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def execution_mode=(block)
|
def execution_mode=(block)
|
||||||
|
@ -65,19 +65,19 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def mswin?
|
def mswin?
|
||||||
Bundler::WINDOWS
|
Gem.win_platform?
|
||||||
end
|
end
|
||||||
|
|
||||||
def mswin64?
|
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
|
end
|
||||||
|
|
||||||
def mingw?
|
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
|
end
|
||||||
|
|
||||||
def x64_mingw?
|
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
|
end
|
||||||
|
|
||||||
(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
|
(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
|
||||||
|
@ -61,10 +61,8 @@ module Bundler
|
|||||||
@unlocking_bundler = false
|
@unlocking_bundler = false
|
||||||
@unlocking = unlock
|
@unlocking = unlock
|
||||||
else
|
else
|
||||||
unlock = unlock.dup
|
|
||||||
@unlocking_bundler = unlock.delete(:bundler)
|
@unlocking_bundler = unlock.delete(:bundler)
|
||||||
unlock.delete_if {|_k, v| Array(v).empty? }
|
@unlocking = unlock.any? {|_k, v| !Array(v).empty? }
|
||||||
@unlocking = !unlock.empty?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@dependencies = dependencies
|
@dependencies = dependencies
|
||||||
@ -111,8 +109,8 @@ module Bundler
|
|||||||
@locked_platforms = []
|
@locked_platforms = []
|
||||||
end
|
end
|
||||||
|
|
||||||
@locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
||||||
@multisource_allowed = @locked_gem_sources.any?(&:multiple_remotes?) && Bundler.frozen_bundle?
|
@multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle?
|
||||||
|
|
||||||
if @multisource_allowed
|
if @multisource_allowed
|
||||||
unless sources.aggregate_global_source?
|
unless sources.aggregate_global_source?
|
||||||
@ -121,7 +119,7 @@ module Bundler
|
|||||||
Bundler::SharedHelpers.major_deprecation 2, msg
|
Bundler::SharedHelpers.major_deprecation 2, msg
|
||||||
end
|
end
|
||||||
|
|
||||||
@sources.merged_gem_lockfile_sections!
|
@sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
|
||||||
end
|
end
|
||||||
|
|
||||||
@unlock[:sources] ||= []
|
@unlock[:sources] ||= []
|
||||||
@ -506,9 +504,6 @@ module Bundler
|
|||||||
attr_reader :sources
|
attr_reader :sources
|
||||||
private :sources
|
private :sources
|
||||||
|
|
||||||
attr_reader :locked_gem_sources
|
|
||||||
private :locked_gem_sources
|
|
||||||
|
|
||||||
def nothing_changed?
|
def nothing_changed?
|
||||||
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
|
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
|
||||||
end
|
end
|
||||||
@ -636,35 +631,11 @@ module Bundler
|
|||||||
end
|
end
|
||||||
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
|
def converge_sources
|
||||||
changes = false
|
|
||||||
|
|
||||||
changes |= converge_rubygems_sources
|
|
||||||
|
|
||||||
# Replace the sources from the Gemfile with the sources from the Gemfile.lock,
|
# 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
|
# 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.
|
# 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|
|
sources.all_sources.each do |source|
|
||||||
# If the source is unlockable and the current command allows an unlock of
|
# If the source is unlockable and the current command allows an unlock of
|
||||||
@ -913,14 +884,13 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def additional_base_requirements_for_resolve
|
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) }
|
dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) }
|
||||||
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
|
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
|
||||||
name = locked_spec.name
|
name = locked_spec.name
|
||||||
dependency = dependencies_by_name[name]
|
dependency = dependencies_by_name[name]
|
||||||
next requirements unless dependency
|
|
||||||
next requirements if @locked_gems.dependencies[name] != 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}")
|
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
|
||||||
requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
|
requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
|
||||||
requirements
|
requirements
|
||||||
|
@ -24,9 +24,6 @@ module Bundler
|
|||||||
def initialize
|
def initialize
|
||||||
@source = nil
|
@source = nil
|
||||||
@sources = SourceList.new
|
@sources = SourceList.new
|
||||||
|
|
||||||
@global_rubygems_sources = []
|
|
||||||
|
|
||||||
@git_sources = {}
|
@git_sources = {}
|
||||||
@dependencies = []
|
@dependencies = []
|
||||||
@groups = []
|
@groups = []
|
||||||
@ -48,7 +45,6 @@ module Bundler
|
|||||||
@gemfiles << expanded_gemfile_path
|
@gemfiles << expanded_gemfile_path
|
||||||
contents ||= Bundler.read_file(@gemfile.to_s)
|
contents ||= Bundler.read_file(@gemfile.to_s)
|
||||||
instance_eval(contents.dup.tap{|x| x.untaint if RUBY_VERSION < "2.7" }, gemfile.to_s, 1)
|
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
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||||
message = "There was an error " \
|
message = "There was an error " \
|
||||||
"#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
|
"#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
|
||||||
@ -168,7 +164,7 @@ module Bundler
|
|||||||
elsif block_given?
|
elsif block_given?
|
||||||
with_source(@sources.add_rubygems_source("remotes" => source), &blk)
|
with_source(@sources.add_rubygems_source("remotes" => source), &blk)
|
||||||
else
|
else
|
||||||
@global_rubygems_sources << source
|
@sources.add_global_rubygems_remote(source)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -222,6 +218,7 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def to_definition(lockfile, unlock)
|
def to_definition(lockfile, unlock)
|
||||||
|
check_primary_source_safety
|
||||||
Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
|
Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -453,12 +450,7 @@ repo_name ||= user_name
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_rubygems_source_safety
|
def check_rubygems_source_safety
|
||||||
@sources.global_rubygems_source = @global_rubygems_sources.shift
|
return unless @sources.aggregate_global_source?
|
||||||
return if @global_rubygems_sources.empty?
|
|
||||||
|
|
||||||
@global_rubygems_sources.each do |source|
|
|
||||||
@sources.add_rubygems_remote(source)
|
|
||||||
end
|
|
||||||
|
|
||||||
if Bundler.feature_flag.bundler_3_mode?
|
if Bundler.feature_flag.bundler_3_mode?
|
||||||
msg = "This Gemfile contains multiple primary sources. " \
|
msg = "This Gemfile contains multiple primary sources. " \
|
||||||
|
@ -135,7 +135,7 @@ module Bundler
|
|||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
|
mode = Gem.win_platform? ? "wb:UTF-8" : "w"
|
||||||
require "erb"
|
require "erb"
|
||||||
content = if RUBY_VERSION >= "2.6"
|
content = if RUBY_VERSION >= "2.6"
|
||||||
ERB.new(template, :trim_mode => "-").result(binding)
|
ERB.new(template, :trim_mode => "-").result(binding)
|
||||||
@ -144,7 +144,7 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask)
|
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"
|
prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
|
||||||
File.write("#{binstub_path}.cmd", prefix + content, :mode => mode)
|
File.write("#{binstub_path}.cmd", prefix + content, :mode => mode)
|
||||||
end
|
end
|
||||||
@ -182,7 +182,7 @@ module Bundler
|
|||||||
executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
|
executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
|
||||||
executable_path = executable_path
|
executable_path = executable_path
|
||||||
|
|
||||||
mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
|
mode = Gem.win_platform? ? "wb:UTF-8" : "w"
|
||||||
require "erb"
|
require "erb"
|
||||||
content = if RUBY_VERSION >= "2.6"
|
content = if RUBY_VERSION >= "2.6"
|
||||||
ERB.new(template, :trim_mode => "-").result(binding)
|
ERB.new(template, :trim_mode => "-").result(binding)
|
||||||
@ -191,7 +191,7 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755)
|
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"
|
prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
|
||||||
File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode)
|
File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode)
|
||||||
end
|
end
|
||||||
|
@ -1,16 +1,5 @@
|
|||||||
# frozen_string_literal: true
|
# 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
|
module Bundler
|
||||||
class LockfileParser
|
class LockfileParser
|
||||||
attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version
|
attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version
|
||||||
@ -124,12 +113,7 @@ module Bundler
|
|||||||
@sources << @current_source
|
@sources << @current_source
|
||||||
when GIT
|
when GIT
|
||||||
@current_source = TYPES[@type].from_lock(@opts)
|
@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
|
@sources << @current_source
|
||||||
end
|
|
||||||
when GEM
|
when GEM
|
||||||
@opts["remotes"] = Array(@opts.delete("remote")).reverse
|
@opts["remotes"] = Array(@opts.delete("remote")).reverse
|
||||||
@current_source = TYPES[@type].from_lock(@opts)
|
@current_source = TYPES[@type].from_lock(@opts)
|
||||||
@ -212,9 +196,7 @@ module Bundler
|
|||||||
@current_spec = LazySpecification.new(name, version, platform)
|
@current_spec = LazySpecification.new(name, version, platform)
|
||||||
@current_spec.source = @current_source
|
@current_spec.source = @current_source
|
||||||
|
|
||||||
# Avoid introducing multiple copies of the same spec (caused by
|
@specs[@current_spec.identifier] = @current_spec
|
||||||
# duplicate GIT sections)
|
|
||||||
@specs[@current_spec.identifier] ||= @current_spec
|
|
||||||
elsif spaces.size == 6
|
elsif spaces.size == 6
|
||||||
version = version.split(",").map(&:strip) if version
|
version = version.split(",").map(&:strip) if version
|
||||||
dep = Gem::Dependency.new(name, version)
|
dep = Gem::Dependency.new(name, version)
|
||||||
|
@ -77,7 +77,7 @@ module Bundler
|
|||||||
source_list = SourceList.new
|
source_list = SourceList.new
|
||||||
|
|
||||||
source_list.add_git_source(git_source_options) if git_source_options
|
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 }
|
deps = names.map {|name| Dependency.new name, version }
|
||||||
|
|
||||||
|
@ -134,6 +134,8 @@ module Gem
|
|||||||
class Requirement
|
class Requirement
|
||||||
module OrderIndependentComparison
|
module OrderIndependentComparison
|
||||||
def ==(other)
|
def ==(other)
|
||||||
|
return unless Gem::Requirement === other
|
||||||
|
|
||||||
if _requirements_sorted? && other._requirements_sorted?
|
if _requirements_sorted? && other._requirements_sorted?
|
||||||
super
|
super
|
||||||
else
|
else
|
||||||
|
@ -252,19 +252,6 @@ module Bundler
|
|||||||
other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
|
other_remotes.map(&method(:remove_auth)) == @remotes.map(&method(:remove_auth))
|
||||||
end
|
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
|
def spec_names
|
||||||
if @allow_remote && dependency_api_available?
|
if @allow_remote && dependency_api_available?
|
||||||
remote_specs.spec_names
|
remote_specs.spec_names
|
||||||
|
@ -28,8 +28,9 @@ module Bundler
|
|||||||
@merged_gem_lockfile_sections
|
@merged_gem_lockfile_sections
|
||||||
end
|
end
|
||||||
|
|
||||||
def merged_gem_lockfile_sections!
|
def merged_gem_lockfile_sections!(replacement_source)
|
||||||
@merged_gem_lockfile_sections = true
|
@merged_gem_lockfile_sections = true
|
||||||
|
@global_rubygems_source = replacement_source
|
||||||
end
|
end
|
||||||
|
|
||||||
def aggregate_global_source?
|
def aggregate_global_source?
|
||||||
@ -53,18 +54,17 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_rubygems_source(options = {})
|
def add_rubygems_source(options = {})
|
||||||
add_source_to_list Source::Rubygems.new(options), @rubygems_sources
|
new_source = Source::Rubygems.new(options)
|
||||||
|
return @global_rubygems_source if @global_rubygems_source == new_source
|
||||||
|
|
||||||
|
add_source_to_list new_source, @rubygems_sources
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_plugin_source(source, options = {})
|
def add_plugin_source(source, options = {})
|
||||||
add_source_to_list Plugin.source(source).new(options), @plugin_sources
|
add_source_to_list Plugin.source(source).new(options), @plugin_sources
|
||||||
end
|
end
|
||||||
|
|
||||||
def global_rubygems_source=(uri)
|
def add_global_rubygems_remote(uri)
|
||||||
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri, "allow_local" => true)
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_rubygems_remote(uri)
|
|
||||||
global_rubygems_source.add_remote(uri)
|
global_rubygems_source.add_remote(uri)
|
||||||
global_rubygems_source
|
global_rubygems_source
|
||||||
end
|
end
|
||||||
@ -109,27 +109,26 @@ module Bundler
|
|||||||
if merged_gem_lockfile_sections?
|
if merged_gem_lockfile_sections?
|
||||||
[combine_rubygems_sources]
|
[combine_rubygems_sources]
|
||||||
else
|
else
|
||||||
rubygems_sources.sort_by(&:to_s).uniq
|
rubygems_sources.sort_by(&:to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true if there are changes
|
# Returns true if there are changes
|
||||||
def replace_sources!(replacement_sources)
|
def replace_sources!(replacement_sources)
|
||||||
return true if replacement_sources.empty?
|
return false if replacement_sources.empty?
|
||||||
|
|
||||||
[path_sources, git_sources, plugin_sources].each do |source_list|
|
@path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
|
||||||
source_list.map! do |source|
|
|
||||||
replacement_sources.find {|s| s == source } || source
|
different_sources?(lock_sources, replacement_sources)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
replacement_rubygems = merged_gem_lockfile_sections? &&
|
# Returns true if there are changes
|
||||||
replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
|
def expired_sources?(replacement_sources)
|
||||||
@global_rubygems_source = replacement_rubygems if replacement_rubygems
|
return false if replacement_sources.empty?
|
||||||
|
|
||||||
return true if !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
|
lock_sources = dup_with_replaced_sources(replacement_sources).lock_sources
|
||||||
|
|
||||||
false
|
different_sources?(lock_sources, replacement_sources)
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_only!
|
def local_only!
|
||||||
@ -146,6 +145,24 @@ module Bundler
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def dup_with_replaced_sources(replacement_sources)
|
||||||
|
new_source_list = dup
|
||||||
|
new_source_list.replace_sources!(replacement_sources)
|
||||||
|
new_source_list
|
||||||
|
end
|
||||||
|
|
||||||
|
def map_sources(replacement_sources)
|
||||||
|
[path_sources, git_sources, plugin_sources].map do |sources|
|
||||||
|
sources.map do |source|
|
||||||
|
replacement_sources.find {|s| s == source } || source
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def different_sources?(lock_sources, replacement_sources)
|
||||||
|
!equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
|
||||||
|
end
|
||||||
|
|
||||||
def rubygems_aggregate_class
|
def rubygems_aggregate_class
|
||||||
Source::Rubygems
|
Source::Rubygems
|
||||||
end
|
end
|
||||||
|
@ -27,7 +27,7 @@ class Bundler::ConnectionPool
|
|||||||
|
|
||||||
# @!visibility private
|
# @!visibility private
|
||||||
def initialize
|
def initialize
|
||||||
@mutex = Mutex.new
|
@mutex = Thread::Mutex.new
|
||||||
@last_time = Time.now.to_f
|
@last_time = Time.now.to_f
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ class Bundler::ConnectionPool::TimedStack
|
|||||||
@created = 0
|
@created = 0
|
||||||
@que = []
|
@que = []
|
||||||
@max = size
|
@max = size
|
||||||
@mutex = Mutex.new
|
@mutex = Thread::Mutex.new
|
||||||
@resource = ConditionVariable.new
|
@resource = Thread::ConditionVariable.new
|
||||||
@shutdown_block = nil
|
@shutdown_block = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ module Bundler
|
|||||||
# @param func [Proc] job to run in inside the worker pool
|
# @param func [Proc] job to run in inside the worker pool
|
||||||
def initialize(size, name, func)
|
def initialize(size, name, func)
|
||||||
@name = name
|
@name = name
|
||||||
@request_queue = Queue.new
|
@request_queue = Thread::Queue.new
|
||||||
@response_queue = Queue.new
|
@response_queue = Thread::Queue.new
|
||||||
@func = func
|
@func = func
|
||||||
@size = size
|
@size = size
|
||||||
@threads = nil
|
@threads = nil
|
||||||
|
@ -178,7 +178,7 @@ module Gem
|
|||||||
@configuration = nil
|
@configuration = nil
|
||||||
@gemdeps = nil
|
@gemdeps = nil
|
||||||
@loaded_specs = {}
|
@loaded_specs = {}
|
||||||
LOADED_SPECS_MUTEX = Mutex.new
|
LOADED_SPECS_MUTEX = Thread::Mutex.new
|
||||||
@path_to_default_spec_map = {}
|
@path_to_default_spec_map = {}
|
||||||
@platforms = []
|
@platforms = []
|
||||||
@ruby = nil
|
@ruby = nil
|
||||||
|
@ -11,10 +11,10 @@ module CoreExtensions
|
|||||||
IPV4_DELAY_SECONDS = 0.1
|
IPV4_DELAY_SECONDS = 0.1
|
||||||
|
|
||||||
def initialize(host, serv, *rest)
|
def initialize(host, serv, *rest)
|
||||||
mutex = Mutex.new
|
mutex = Thread::Mutex.new
|
||||||
addrs = []
|
addrs = []
|
||||||
threads = []
|
threads = []
|
||||||
cond_var = ConditionVariable.new
|
cond_var = Thread::ConditionVariable.new
|
||||||
|
|
||||||
Addrinfo.foreach(host, serv, nil, :STREAM) do |addr|
|
Addrinfo.foreach(host, serv, nil, :STREAM) do |addr|
|
||||||
Thread.report_on_exception = false if defined? Thread.report_on_exception = ()
|
Thread.report_on_exception = false if defined? Thread.report_on_exception = ()
|
||||||
|
@ -1,23 +1,70 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
##
|
##
|
||||||
# Provides a single method +deprecate+ to be used to declare when
|
# Provides 3 methods for declaring when something is going away.
|
||||||
# something is going away.
|
#
|
||||||
|
# +deprecate(name, repl, year, month)+:
|
||||||
|
# Indicate something may be removed on/after a certain date.
|
||||||
|
#
|
||||||
|
# +rubygems_deprecate(name, replacement=:none)+:
|
||||||
|
# Indicate something will be removed in the next major RubyGems version,
|
||||||
|
# and (optionally) a replacement for it.
|
||||||
|
#
|
||||||
|
# +rubygems_deprecate_command+:
|
||||||
|
# Indicate a RubyGems command (in +lib/rubygems/commands/*.rb+) will be
|
||||||
|
# removed in the next RubyGems version.
|
||||||
|
#
|
||||||
|
# Also provides +skip_during+ for temporarily turning off deprecation warnings.
|
||||||
|
# This is intended to be used in the test suite, so deprecation warnings
|
||||||
|
# don't cause test failures if you need to make sure stderr is otherwise empty.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Example usage of +deprecate+ and +rubygems_deprecate+:
|
||||||
#
|
#
|
||||||
# class Legacy
|
# class Legacy
|
||||||
# def self.klass_method
|
# def self.some_class_method
|
||||||
# # ...
|
# # ...
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# def instance_method
|
# def some_instance_method
|
||||||
|
# # ...
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def some_old_method
|
||||||
# # ...
|
# # ...
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# extend Gem::Deprecate
|
# extend Gem::Deprecate
|
||||||
# deprecate :instance_method, "X.z", 2011, 4
|
# deprecate :some_instance_method, "X.z", 2011, 4
|
||||||
|
# rubygems_deprecate :some_old_method, "Modern#some_new_method"
|
||||||
#
|
#
|
||||||
# class << self
|
# class << self
|
||||||
# extend Gem::Deprecate
|
# extend Gem::Deprecate
|
||||||
# deprecate :klass_method, :none, 2011, 4
|
# deprecate :some_class_method, :none, 2011, 4
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Example usage of +rubygems_deprecate_command+:
|
||||||
|
#
|
||||||
|
# class Gem::Commands::QueryCommand < Gem::Command
|
||||||
|
# extend Gem::Deprecate
|
||||||
|
# rubygems_deprecate_command
|
||||||
|
#
|
||||||
|
# # ...
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Example usage of +skip_during+:
|
||||||
|
#
|
||||||
|
# class TestSomething < Gem::Testcase
|
||||||
|
# def test_some_thing_with_deprecations
|
||||||
|
# Gem::Deprecate.skip_during do
|
||||||
|
# actual_stdout, actual_stderr = capture_output do
|
||||||
|
# Gem.something_deprecated
|
||||||
|
# end
|
||||||
|
# assert_empty actual_stdout
|
||||||
|
# assert_equal(expected, actual_stderr)
|
||||||
|
# end
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
@ -51,6 +51,13 @@ module Gem::GemcutterUtilities
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# The OTP code from the command options or from the user's configuration.
|
||||||
|
|
||||||
|
def otp
|
||||||
|
options[:otp] || ENV["GEM_HOST_OTP_CODE"]
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# The host to connect to either from the RUBYGEMS_HOST environment variable
|
# The host to connect to either from the RUBYGEMS_HOST environment variable
|
||||||
# or from the user's configuration
|
# or from the user's configuration
|
||||||
@ -126,7 +133,7 @@ module Gem::GemcutterUtilities
|
|||||||
response = rubygems_api_request(:put, "api/v1/api_key",
|
response = rubygems_api_request(:put, "api/v1/api_key",
|
||||||
sign_in_host, scope: scope) do |request|
|
sign_in_host, scope: scope) do |request|
|
||||||
request.basic_auth email, password
|
request.basic_auth email, password
|
||||||
request["OTP"] = options[:otp] if options[:otp]
|
request["OTP"] = otp if otp
|
||||||
request.body = URI.encode_www_form({:api_key => api_key }.merge(update_scope_params))
|
request.body = URI.encode_www_form({:api_key => api_key }.merge(update_scope_params))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -159,7 +166,7 @@ module Gem::GemcutterUtilities
|
|||||||
response = rubygems_api_request(:post, "api/v1/api_key",
|
response = rubygems_api_request(:post, "api/v1/api_key",
|
||||||
sign_in_host, scope: scope) do |request|
|
sign_in_host, scope: scope) do |request|
|
||||||
request.basic_auth email, password
|
request.basic_auth email, password
|
||||||
request["OTP"] = options[:otp] if options[:otp]
|
request["OTP"] = otp if otp
|
||||||
request.body = URI.encode_www_form({ name: key_name }.merge(scope_params))
|
request.body = URI.encode_www_form({ name: key_name }.merge(scope_params))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -224,7 +231,7 @@ module Gem::GemcutterUtilities
|
|||||||
request_method = Net::HTTP.const_get method.to_s.capitalize
|
request_method = Net::HTTP.const_get method.to_s.capitalize
|
||||||
|
|
||||||
Gem::RemoteFetcher.fetcher.request(uri, request_method) do |req|
|
Gem::RemoteFetcher.fetcher.request(uri, request_method) do |req|
|
||||||
req["OTP"] = options[:otp] if options[:otp]
|
req["OTP"] = otp if otp
|
||||||
block.call(req)
|
block.call(req)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -68,7 +68,7 @@ class Gem::Installer
|
|||||||
|
|
||||||
@path_warning = false
|
@path_warning = false
|
||||||
|
|
||||||
@install_lock = Mutex.new
|
@install_lock = Thread::Mutex.new
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
##
|
##
|
||||||
|
@ -4,7 +4,7 @@ require 'rubygems/request'
|
|||||||
require 'rubygems/request/connection_pools'
|
require 'rubygems/request/connection_pools'
|
||||||
require 'rubygems/s3_uri_signer'
|
require 'rubygems/s3_uri_signer'
|
||||||
require 'rubygems/uri_formatter'
|
require 'rubygems/uri_formatter'
|
||||||
require 'rubygems/uri_parsing'
|
require 'rubygems/uri_parser'
|
||||||
require 'rubygems/user_interaction'
|
require 'rubygems/user_interaction'
|
||||||
require 'resolv'
|
require 'resolv'
|
||||||
|
|
||||||
@ -14,15 +14,12 @@ require 'resolv'
|
|||||||
|
|
||||||
class Gem::RemoteFetcher
|
class Gem::RemoteFetcher
|
||||||
include Gem::UserInteraction
|
include Gem::UserInteraction
|
||||||
include Gem::UriParsing
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# A FetchError exception wraps up the various possible IO and HTTP failures
|
# A FetchError exception wraps up the various possible IO and HTTP failures
|
||||||
# that could happen while downloading from the internet.
|
# that could happen while downloading from the internet.
|
||||||
|
|
||||||
class FetchError < Gem::Exception
|
class FetchError < Gem::Exception
|
||||||
include Gem::UriParsing
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# The URI which was being accessed when the exception happened.
|
# The URI which was being accessed when the exception happened.
|
||||||
|
|
||||||
@ -31,7 +28,7 @@ class Gem::RemoteFetcher
|
|||||||
def initialize(message, uri)
|
def initialize(message, uri)
|
||||||
super message
|
super message
|
||||||
|
|
||||||
uri = parse_uri(uri)
|
uri = Gem::UriParser.parse_uri(uri)
|
||||||
|
|
||||||
@original_uri = uri.dup
|
@original_uri = uri.dup
|
||||||
|
|
||||||
@ -88,7 +85,7 @@ class Gem::RemoteFetcher
|
|||||||
|
|
||||||
@proxy = proxy
|
@proxy = proxy
|
||||||
@pools = {}
|
@pools = {}
|
||||||
@pool_lock = Mutex.new
|
@pool_lock = Thread::Mutex.new
|
||||||
@cert_files = Gem::Request.get_cert_files
|
@cert_files = Gem::Request.get_cert_files
|
||||||
|
|
||||||
@headers = headers
|
@headers = headers
|
||||||
@ -133,7 +130,7 @@ class Gem::RemoteFetcher
|
|||||||
require "fileutils"
|
require "fileutils"
|
||||||
FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir
|
FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir
|
||||||
|
|
||||||
source_uri = parse_uri(source_uri)
|
source_uri = Gem::UriParser.parse_uri(source_uri)
|
||||||
|
|
||||||
scheme = source_uri.scheme
|
scheme = source_uri.scheme
|
||||||
|
|
||||||
@ -228,7 +225,7 @@ class Gem::RemoteFetcher
|
|||||||
unless location = response['Location']
|
unless location = response['Location']
|
||||||
raise FetchError.new("redirecting but no redirect location was given", uri)
|
raise FetchError.new("redirecting but no redirect location was given", uri)
|
||||||
end
|
end
|
||||||
location = parse_uri location
|
location = Gem::UriParser.parse_uri location
|
||||||
|
|
||||||
if https?(uri) && !https?(location)
|
if https?(uri) && !https?(location)
|
||||||
raise FetchError.new("redirecting to non-https resource: #{location}", uri)
|
raise FetchError.new("redirecting to non-https resource: #{location}", uri)
|
||||||
@ -246,7 +243,7 @@ class Gem::RemoteFetcher
|
|||||||
# Downloads +uri+ and returns it as a String.
|
# Downloads +uri+ and returns it as a String.
|
||||||
|
|
||||||
def fetch_path(uri, mtime = nil, head = false)
|
def fetch_path(uri, mtime = nil, head = false)
|
||||||
uri = parse_uri uri
|
uri = Gem::UriParser.parse_uri uri
|
||||||
|
|
||||||
unless uri.scheme
|
unless uri.scheme
|
||||||
raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}"
|
raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}"
|
||||||
|
@ -11,7 +11,7 @@ class Gem::Request::ConnectionPools # :nodoc:
|
|||||||
@proxy_uri = proxy_uri
|
@proxy_uri = proxy_uri
|
||||||
@cert_files = cert_files
|
@cert_files = cert_files
|
||||||
@pools = {}
|
@pools = {}
|
||||||
@pool_mutex = Mutex.new
|
@pool_mutex = Thread::Mutex.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def pool_for(uri)
|
def pool_for(uri)
|
||||||
|
@ -12,7 +12,7 @@ class Gem::Request::HTTPPool # :nodoc:
|
|||||||
@http_args = http_args
|
@http_args = http_args
|
||||||
@cert_files = cert_files
|
@cert_files = cert_files
|
||||||
@proxy_uri = proxy_uri
|
@proxy_uri = proxy_uri
|
||||||
@queue = SizedQueue.new 1
|
@queue = Thread::SizedQueue.new 1
|
||||||
@queue << nil
|
@queue << nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ class Gem::RequestSet
|
|||||||
@prerelease = options[:prerelease]
|
@prerelease = options[:prerelease]
|
||||||
|
|
||||||
requests = []
|
requests = []
|
||||||
download_queue = Queue.new
|
download_queue = Thread::Queue.new
|
||||||
|
|
||||||
# Create a thread-safe list of gems to download
|
# Create a thread-safe list of gems to download
|
||||||
sorted_requests.each do |req|
|
sorted_requests.each do |req|
|
||||||
|
@ -105,7 +105,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|||||||
# rubocop:disable Style/MutableConstant
|
# rubocop:disable Style/MutableConstant
|
||||||
LOAD_CACHE = {} # :nodoc:
|
LOAD_CACHE = {} # :nodoc:
|
||||||
# rubocop:enable Style/MutableConstant
|
# rubocop:enable Style/MutableConstant
|
||||||
LOAD_CACHE_MUTEX = Mutex.new
|
LOAD_CACHE_MUTEX = Thread::Mutex.new
|
||||||
|
|
||||||
private_constant :LOAD_CACHE if defined? private_constant
|
private_constant :LOAD_CACHE if defined? private_constant
|
||||||
|
|
||||||
|
@ -5,10 +5,18 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
class Gem::UriParser
|
class Gem::UriParser
|
||||||
|
def self.parse_uri(source_uri)
|
||||||
|
return source_uri unless source_uri.is_a?(String)
|
||||||
|
|
||||||
|
new.parse(source_uri)
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Parses the #uri, raising if it's invalid
|
# Parses the #uri, raising if it's invalid
|
||||||
|
|
||||||
def parse!(uri)
|
def parse!(uri)
|
||||||
|
require "uri"
|
||||||
|
|
||||||
raise URI::InvalidURIError unless uri
|
raise URI::InvalidURIError unless uri
|
||||||
|
|
||||||
# Always escape URI's to deal with potential spaces and such
|
# Always escape URI's to deal with potential spaces and such
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "rubygems/uri_parser"
|
|
||||||
|
|
||||||
module Gem::UriParsing
|
|
||||||
|
|
||||||
def parse_uri(source_uri)
|
|
||||||
return source_uri unless source_uri.is_a?(String)
|
|
||||||
|
|
||||||
uri_parser.parse(source_uri)
|
|
||||||
end
|
|
||||||
|
|
||||||
private :parse_uri
|
|
||||||
|
|
||||||
def uri_parser
|
|
||||||
require "uri"
|
|
||||||
|
|
||||||
Gem::UriParser.new
|
|
||||||
end
|
|
||||||
|
|
||||||
private :uri_parser
|
|
||||||
|
|
||||||
end
|
|
@ -543,7 +543,7 @@ class Gem::StreamUI
|
|||||||
# A progress reporter that behaves nicely with threaded downloading.
|
# A progress reporter that behaves nicely with threaded downloading.
|
||||||
|
|
||||||
class ThreadedDownloadReporter
|
class ThreadedDownloadReporter
|
||||||
MUTEX = Mutex.new
|
MUTEX = Thread::Mutex.new
|
||||||
|
|
||||||
##
|
##
|
||||||
# The current file name being displayed
|
# The current file name being displayed
|
||||||
|
@ -2,16 +2,6 @@
|
|||||||
|
|
||||||
require "bundler/cli"
|
require "bundler/cli"
|
||||||
|
|
||||||
using Module.new {
|
|
||||||
# Some `man` (e.g., on macOS) always highlights the output even to
|
|
||||||
# non-tty.
|
|
||||||
refine Spec::Helpers do
|
|
||||||
def out
|
|
||||||
super.gsub(/.[\b]/, "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
} if RUBY_VERSION >= "2.4"
|
|
||||||
|
|
||||||
RSpec.describe "bundle executable" do
|
RSpec.describe "bundle executable" do
|
||||||
it "returns non-zero exit status when passed unrecognized options" do
|
it "returns non-zero exit status when passed unrecognized options" do
|
||||||
bundle "--invalid_argument", :raise_on_error => false
|
bundle "--invalid_argument", :raise_on_error => false
|
||||||
@ -42,49 +32,57 @@ RSpec.describe "bundle executable" do
|
|||||||
it "aliases e to exec" do
|
it "aliases e to exec" do
|
||||||
bundle "e --help"
|
bundle "e --help"
|
||||||
|
|
||||||
expect(out).to include("bundle-exec")
|
expect(out_with_macos_man_workaround).to include("bundle-exec")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "aliases ex to exec" do
|
it "aliases ex to exec" do
|
||||||
bundle "ex --help"
|
bundle "ex --help"
|
||||||
|
|
||||||
expect(out).to include("bundle-exec")
|
expect(out_with_macos_man_workaround).to include("bundle-exec")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "aliases exe to exec" do
|
it "aliases exe to exec" do
|
||||||
bundle "exe --help"
|
bundle "exe --help"
|
||||||
|
|
||||||
expect(out).to include("bundle-exec")
|
expect(out_with_macos_man_workaround).to include("bundle-exec")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "aliases c to check" do
|
it "aliases c to check" do
|
||||||
bundle "c --help"
|
bundle "c --help"
|
||||||
|
|
||||||
expect(out).to include("bundle-check")
|
expect(out_with_macos_man_workaround).to include("bundle-check")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "aliases i to install" do
|
it "aliases i to install" do
|
||||||
bundle "i --help"
|
bundle "i --help"
|
||||||
|
|
||||||
expect(out).to include("bundle-install")
|
expect(out_with_macos_man_workaround).to include("bundle-install")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "aliases ls to list" do
|
it "aliases ls to list" do
|
||||||
bundle "ls --help"
|
bundle "ls --help"
|
||||||
|
|
||||||
expect(out).to include("bundle-list")
|
expect(out_with_macos_man_workaround).to include("bundle-list")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "aliases package to cache" do
|
it "aliases package to cache" do
|
||||||
bundle "package --help"
|
bundle "package --help"
|
||||||
|
|
||||||
expect(out).to include("bundle-cache")
|
expect(out_with_macos_man_workaround).to include("bundle-cache")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "aliases pack to cache" do
|
it "aliases pack to cache" do
|
||||||
bundle "pack --help"
|
bundle "pack --help"
|
||||||
|
|
||||||
expect(out).to include("bundle-cache")
|
expect(out_with_macos_man_workaround).to include("bundle-cache")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Some `man` (e.g., on macOS) always highlights the output even to
|
||||||
|
# non-tty.
|
||||||
|
def out_with_macos_man_workaround
|
||||||
|
out.gsub(/.[\b]/, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ RSpec.describe Bundler::Definition do
|
|||||||
context "eager unlock" do
|
context "eager unlock" do
|
||||||
let(:source_list) do
|
let(:source_list) do
|
||||||
Bundler::SourceList.new.tap do |source_list|
|
Bundler::SourceList.new.tap do |source_list|
|
||||||
source_list.global_rubygems_source = file_uri_for(gem_repo4)
|
source_list.add_global_rubygems_remote(file_uri_for(gem_repo4))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -115,15 +115,15 @@ RSpec.describe Bundler::SourceList do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#add_rubygems_remote", :bundler => "< 3" do
|
describe "#add_global_rubygems_remote" do
|
||||||
let!(:returned_source) { source_list.add_rubygems_remote("https://rubygems.org/") }
|
let!(:returned_source) { source_list.add_global_rubygems_remote("https://rubygems.org/") }
|
||||||
|
|
||||||
it "returns the aggregate rubygems source" do
|
it "returns the aggregate rubygems source" do
|
||||||
expect(returned_source).to be_instance_of(Bundler::Source::Rubygems)
|
expect(returned_source).to be_instance_of(Bundler::Source::Rubygems)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "adds the provided remote to the beginning of the aggregate source" do
|
it "adds the provided remote to the beginning of the aggregate source" do
|
||||||
source_list.add_rubygems_remote("https://othersource.org")
|
source_list.add_global_rubygems_remote("https://othersource.org")
|
||||||
expect(returned_source.remotes).to eq [
|
expect(returned_source.remotes).to eq [
|
||||||
Bundler::URI("https://othersource.org/"),
|
Bundler::URI("https://othersource.org/"),
|
||||||
Bundler::URI("https://rubygems.org/"),
|
Bundler::URI("https://rubygems.org/"),
|
||||||
@ -212,22 +212,22 @@ RSpec.describe Bundler::SourceList do
|
|||||||
|
|
||||||
describe "#path_sources" do
|
describe "#path_sources" do
|
||||||
it "returns an empty array when no path sources have been added" do
|
it "returns an empty array when no path sources have been added" do
|
||||||
source_list.add_rubygems_remote("https://rubygems.org")
|
source_list.add_global_rubygems_remote("https://rubygems.org")
|
||||||
source_list.add_git_source("uri" => "git://host/path.git")
|
source_list.add_git_source("uri" => "git://host/path.git")
|
||||||
expect(source_list.path_sources).to be_empty
|
expect(source_list.path_sources).to be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns path sources in the reverse order that they were added" do
|
it "returns path sources in the reverse order that they were added" do
|
||||||
source_list.add_git_source("uri" => "git://third-git.org/path.git")
|
source_list.add_git_source("uri" => "git://third-git.org/path.git")
|
||||||
source_list.add_rubygems_remote("https://fifth-rubygems.org")
|
source_list.add_global_rubygems_remote("https://fifth-rubygems.org")
|
||||||
source_list.add_path_source("path" => "/third/path/to/gem")
|
source_list.add_path_source("path" => "/third/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://fourth-rubygems.org")
|
source_list.add_global_rubygems_remote("https://fourth-rubygems.org")
|
||||||
source_list.add_path_source("path" => "/second/path/to/gem")
|
source_list.add_path_source("path" => "/second/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://third-rubygems.org")
|
source_list.add_global_rubygems_remote("https://third-rubygems.org")
|
||||||
source_list.add_git_source("uri" => "git://second-git.org/path.git")
|
source_list.add_git_source("uri" => "git://second-git.org/path.git")
|
||||||
source_list.add_rubygems_remote("https://second-rubygems.org")
|
source_list.add_global_rubygems_remote("https://second-rubygems.org")
|
||||||
source_list.add_path_source("path" => "/first/path/to/gem")
|
source_list.add_path_source("path" => "/first/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://first-rubygems.org")
|
source_list.add_global_rubygems_remote("https://first-rubygems.org")
|
||||||
source_list.add_git_source("uri" => "git://first-git.org/path.git")
|
source_list.add_git_source("uri" => "git://first-git.org/path.git")
|
||||||
|
|
||||||
expect(source_list.path_sources).to eq [
|
expect(source_list.path_sources).to eq [
|
||||||
@ -240,7 +240,7 @@ RSpec.describe Bundler::SourceList do
|
|||||||
|
|
||||||
describe "#git_sources" do
|
describe "#git_sources" do
|
||||||
it "returns an empty array when no git sources have been added" do
|
it "returns an empty array when no git sources have been added" do
|
||||||
source_list.add_rubygems_remote("https://rubygems.org")
|
source_list.add_global_rubygems_remote("https://rubygems.org")
|
||||||
source_list.add_path_source("path" => "/path/to/gem")
|
source_list.add_path_source("path" => "/path/to/gem")
|
||||||
|
|
||||||
expect(source_list.git_sources).to be_empty
|
expect(source_list.git_sources).to be_empty
|
||||||
@ -248,15 +248,15 @@ RSpec.describe Bundler::SourceList do
|
|||||||
|
|
||||||
it "returns git sources in the reverse order that they were added" do
|
it "returns git sources in the reverse order that they were added" do
|
||||||
source_list.add_git_source("uri" => "git://third-git.org/path.git")
|
source_list.add_git_source("uri" => "git://third-git.org/path.git")
|
||||||
source_list.add_rubygems_remote("https://fifth-rubygems.org")
|
source_list.add_global_rubygems_remote("https://fifth-rubygems.org")
|
||||||
source_list.add_path_source("path" => "/third/path/to/gem")
|
source_list.add_path_source("path" => "/third/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://fourth-rubygems.org")
|
source_list.add_global_rubygems_remote("https://fourth-rubygems.org")
|
||||||
source_list.add_path_source("path" => "/second/path/to/gem")
|
source_list.add_path_source("path" => "/second/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://third-rubygems.org")
|
source_list.add_global_rubygems_remote("https://third-rubygems.org")
|
||||||
source_list.add_git_source("uri" => "git://second-git.org/path.git")
|
source_list.add_git_source("uri" => "git://second-git.org/path.git")
|
||||||
source_list.add_rubygems_remote("https://second-rubygems.org")
|
source_list.add_global_rubygems_remote("https://second-rubygems.org")
|
||||||
source_list.add_path_source("path" => "/first/path/to/gem")
|
source_list.add_path_source("path" => "/first/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://first-rubygems.org")
|
source_list.add_global_rubygems_remote("https://first-rubygems.org")
|
||||||
source_list.add_git_source("uri" => "git://first-git.org/path.git")
|
source_list.add_git_source("uri" => "git://first-git.org/path.git")
|
||||||
|
|
||||||
expect(source_list.git_sources).to eq [
|
expect(source_list.git_sources).to eq [
|
||||||
@ -269,7 +269,7 @@ RSpec.describe Bundler::SourceList do
|
|||||||
|
|
||||||
describe "#plugin_sources" do
|
describe "#plugin_sources" do
|
||||||
it "returns an empty array when no plugin sources have been added" do
|
it "returns an empty array when no plugin sources have been added" do
|
||||||
source_list.add_rubygems_remote("https://rubygems.org")
|
source_list.add_global_rubygems_remote("https://rubygems.org")
|
||||||
source_list.add_path_source("path" => "/path/to/gem")
|
source_list.add_path_source("path" => "/path/to/gem")
|
||||||
|
|
||||||
expect(source_list.plugin_sources).to be_empty
|
expect(source_list.plugin_sources).to be_empty
|
||||||
@ -279,13 +279,13 @@ RSpec.describe Bundler::SourceList do
|
|||||||
source_list.add_plugin_source("new_source", "uri" => "https://third-git.org/path.git")
|
source_list.add_plugin_source("new_source", "uri" => "https://third-git.org/path.git")
|
||||||
source_list.add_git_source("https://new-git.org")
|
source_list.add_git_source("https://new-git.org")
|
||||||
source_list.add_path_source("path" => "/third/path/to/gem")
|
source_list.add_path_source("path" => "/third/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://fourth-rubygems.org")
|
source_list.add_global_rubygems_remote("https://fourth-rubygems.org")
|
||||||
source_list.add_path_source("path" => "/second/path/to/gem")
|
source_list.add_path_source("path" => "/second/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://third-rubygems.org")
|
source_list.add_global_rubygems_remote("https://third-rubygems.org")
|
||||||
source_list.add_plugin_source("new_source", "uri" => "git://second-git.org/path.git")
|
source_list.add_plugin_source("new_source", "uri" => "git://second-git.org/path.git")
|
||||||
source_list.add_rubygems_remote("https://second-rubygems.org")
|
source_list.add_global_rubygems_remote("https://second-rubygems.org")
|
||||||
source_list.add_path_source("path" => "/first/path/to/gem")
|
source_list.add_path_source("path" => "/first/path/to/gem")
|
||||||
source_list.add_rubygems_remote("https://first-rubygems.org")
|
source_list.add_global_rubygems_remote("https://first-rubygems.org")
|
||||||
source_list.add_plugin_source("new_source", "uri" => "git://first-git.org/path.git")
|
source_list.add_plugin_source("new_source", "uri" => "git://first-git.org/path.git")
|
||||||
|
|
||||||
expect(source_list.plugin_sources).to eq [
|
expect(source_list.plugin_sources).to eq [
|
||||||
@ -339,7 +339,7 @@ RSpec.describe Bundler::SourceList do
|
|||||||
describe "#get" do
|
describe "#get" do
|
||||||
context "when it includes an equal source" do
|
context "when it includes an equal source" do
|
||||||
let(:rubygems_source) { Bundler::Source::Rubygems.new("remotes" => ["https://rubygems.org"]) }
|
let(:rubygems_source) { Bundler::Source::Rubygems.new("remotes" => ["https://rubygems.org"]) }
|
||||||
before { @equal_source = source_list.add_rubygems_remote("https://rubygems.org") }
|
before { @equal_source = source_list.add_global_rubygems_remote("https://rubygems.org") }
|
||||||
|
|
||||||
it "returns the equal source" do
|
it "returns the equal source" do
|
||||||
expect(source_list.get(rubygems_source)).to be @equal_source
|
expect(source_list.get(rubygems_source)).to be @equal_source
|
||||||
|
@ -32,6 +32,8 @@ RSpec.describe "bundle doctor" do
|
|||||||
unwritable_file = double("file")
|
unwritable_file = double("file")
|
||||||
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
||||||
allow(Find).to receive(:find).with(Bundler.bundle_path.to_s) { [unwritable_file] }
|
allow(Find).to receive(:find).with(Bundler.bundle_path.to_s) { [unwritable_file] }
|
||||||
|
allow(File).to receive(:exist?).and_call_original
|
||||||
|
allow(File).to receive(:exist?).with(unwritable_file).and_return(true)
|
||||||
allow(File).to receive(:stat).with(unwritable_file) { stat }
|
allow(File).to receive(:stat).with(unwritable_file) { stat }
|
||||||
allow(stat).to receive(:uid) { Process.uid }
|
allow(stat).to receive(:uid) { Process.uid }
|
||||||
allow(File).to receive(:writable?).with(unwritable_file) { true }
|
allow(File).to receive(:writable?).with(unwritable_file) { true }
|
||||||
@ -47,7 +49,6 @@ RSpec.describe "bundle doctor" do
|
|||||||
doctor = Bundler::CLI::Doctor.new({})
|
doctor = Bundler::CLI::Doctor.new({})
|
||||||
expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
|
expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
|
||||||
expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/lib/libSystem.dylib"]
|
expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/lib/libSystem.dylib"]
|
||||||
allow(File).to receive(:exist?).and_call_original
|
|
||||||
allow(File).to receive(:exist?).with("/usr/lib/libSystem.dylib").and_return(true)
|
allow(File).to receive(:exist?).with("/usr/lib/libSystem.dylib").and_return(true)
|
||||||
expect { doctor.run }.not_to(raise_error, @stdout.string)
|
expect { doctor.run }.not_to(raise_error, @stdout.string)
|
||||||
expect(@stdout.string).to be_empty
|
expect(@stdout.string).to be_empty
|
||||||
@ -57,7 +58,6 @@ RSpec.describe "bundle doctor" do
|
|||||||
doctor = Bundler::CLI::Doctor.new({})
|
doctor = Bundler::CLI::Doctor.new({})
|
||||||
expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
|
expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"]
|
||||||
expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib"]
|
expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib"]
|
||||||
allow(File).to receive(:exist?).and_call_original
|
|
||||||
allow(File).to receive(:exist?).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_return(false)
|
allow(File).to receive(:exist?).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_return(false)
|
||||||
expect { doctor.run }.to raise_error(Bundler::ProductionError, strip_whitespace(<<-E).strip), @stdout.string
|
expect { doctor.run }.to raise_error(Bundler::ProductionError, strip_whitespace(<<-E).strip), @stdout.string
|
||||||
The following gems are missing OS dependencies:
|
The following gems are missing OS dependencies:
|
||||||
@ -67,12 +67,32 @@ RSpec.describe "bundle doctor" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when home contains broken symlinks" do
|
||||||
|
before(:each) do
|
||||||
|
@broken_symlink = double("file")
|
||||||
|
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
||||||
|
allow(Find).to receive(:find).with(Bundler.bundle_path.to_s) { [@broken_symlink] }
|
||||||
|
allow(File).to receive(:exist?).and_call_original
|
||||||
|
allow(File).to receive(:exist?).with(@broken_symlink) { false }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "exits with an error if home contains files that are not readable/writable" do
|
||||||
|
expect { Bundler::CLI::Doctor.new({}).run }.not_to raise_error
|
||||||
|
expect(@stdout.string).to include(
|
||||||
|
"Broken links exist in the Bundler home. Please report them to the offending gem's upstream repo. These files are:\n - #{@unwritable_file}"
|
||||||
|
)
|
||||||
|
expect(@stdout.string).not_to include("No issues")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when home contains files that are not readable/writable" do
|
context "when home contains files that are not readable/writable" do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@stat = double("stat")
|
@stat = double("stat")
|
||||||
@unwritable_file = double("file")
|
@unwritable_file = double("file")
|
||||||
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
|
||||||
allow(Find).to receive(:find).with(Bundler.bundle_path.to_s) { [@unwritable_file] }
|
allow(Find).to receive(:find).with(Bundler.bundle_path.to_s) { [@unwritable_file] }
|
||||||
|
allow(File).to receive(:exist?).and_call_original
|
||||||
|
allow(File).to receive(:exist?).with(@unwritable_file) { true }
|
||||||
allow(File).to receive(:stat).with(@unwritable_file) { @stat }
|
allow(File).to receive(:stat).with(@unwritable_file) { @stat }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -241,6 +241,94 @@ RSpec.describe "bundle update" do
|
|||||||
expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
|
expect(the_bundle).to include_gems("slim 3.0.9", "slim-rails 3.1.3", "slim_lint 0.16.1")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not go to an older version, even if the version upgrade that could cause another gem to downgrade is activated first" do
|
||||||
|
build_repo4 do
|
||||||
|
# countries is processed before country_select by the resolver due to having less spec groups (groups of versions with the same dependencies) (2 vs 3)
|
||||||
|
|
||||||
|
build_gem "countries", "2.1.4"
|
||||||
|
build_gem "countries", "3.1.0"
|
||||||
|
|
||||||
|
build_gem "countries", "4.0.0" do |s|
|
||||||
|
s.add_dependency "sixarm_ruby_unaccent", "~> 1.1"
|
||||||
|
end
|
||||||
|
|
||||||
|
build_gem "country_select", "1.2.0"
|
||||||
|
|
||||||
|
build_gem "country_select", "2.1.4" do |s|
|
||||||
|
s.add_dependency "countries", "~> 2.0"
|
||||||
|
end
|
||||||
|
build_gem "country_select", "3.1.1" do |s|
|
||||||
|
s.add_dependency "countries", "~> 2.0"
|
||||||
|
end
|
||||||
|
|
||||||
|
build_gem "country_select", "5.1.0" do |s|
|
||||||
|
s.add_dependency "countries", "~> 3.0"
|
||||||
|
end
|
||||||
|
|
||||||
|
build_gem "sixarm_ruby_unaccent", "1.1.0"
|
||||||
|
end
|
||||||
|
|
||||||
|
gemfile <<~G
|
||||||
|
source "#{file_uri_for(gem_repo4)}"
|
||||||
|
|
||||||
|
gem "country_select"
|
||||||
|
gem "countries"
|
||||||
|
G
|
||||||
|
|
||||||
|
lockfile <<~L
|
||||||
|
GEM
|
||||||
|
remote: #{file_uri_for(gem_repo4)}/
|
||||||
|
specs:
|
||||||
|
countries (3.1.0)
|
||||||
|
country_select (5.1.0)
|
||||||
|
countries (~> 3.0)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
#{specific_local_platform}
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
countries
|
||||||
|
country_select
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
#{Bundler::VERSION}
|
||||||
|
L
|
||||||
|
|
||||||
|
previous_lockfile = lockfile
|
||||||
|
|
||||||
|
bundle "lock --update"
|
||||||
|
|
||||||
|
expect(lockfile).to eq(previous_lockfile)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not downgrade indirect dependencies unnecessarily" do
|
||||||
|
build_repo4 do
|
||||||
|
build_gem "a" do |s|
|
||||||
|
s.add_dependency "b"
|
||||||
|
s.add_dependency "c"
|
||||||
|
end
|
||||||
|
build_gem "b"
|
||||||
|
build_gem "c"
|
||||||
|
build_gem "c", "2.0"
|
||||||
|
end
|
||||||
|
|
||||||
|
install_gemfile <<-G, :verbose => true
|
||||||
|
source "#{file_uri_for(gem_repo4)}"
|
||||||
|
gem "a"
|
||||||
|
G
|
||||||
|
|
||||||
|
expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
|
||||||
|
|
||||||
|
update_repo4 do
|
||||||
|
build_gem "b", "2.0" do |s|
|
||||||
|
s.add_dependency "c", "< 2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
bundle "update", :all => true, :verbose => true
|
||||||
|
expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
|
||||||
|
end
|
||||||
|
|
||||||
it "should still downgrade if forced by the Gemfile" do
|
it "should still downgrade if forced by the Gemfile" do
|
||||||
build_repo4 do
|
build_repo4 do
|
||||||
build_gem "a"
|
build_gem "a"
|
||||||
|
@ -26,6 +26,38 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "eval-ed Gemfile points to an internal gemspec and uses a scoped source that duplicates the main Gemfile global source" do
|
||||||
|
before do
|
||||||
|
build_repo2 do
|
||||||
|
build_gem "rails", "6.1.3.2"
|
||||||
|
|
||||||
|
build_gem "zip-zip", "0.3"
|
||||||
|
end
|
||||||
|
|
||||||
|
create_file bundled_app("gems/Gemfile"), <<-G
|
||||||
|
gemspec :path => "\#{__dir__}/gunks"
|
||||||
|
|
||||||
|
source "#{file_uri_for(gem_repo2)}" do
|
||||||
|
gem "zip-zip"
|
||||||
|
end
|
||||||
|
G
|
||||||
|
end
|
||||||
|
|
||||||
|
it "installs and finds gems correctly" do
|
||||||
|
install_gemfile <<-G
|
||||||
|
source "#{file_uri_for(gem_repo2)}"
|
||||||
|
|
||||||
|
gem "rails"
|
||||||
|
|
||||||
|
eval_gemfile File.join(__dir__, "gems/Gemfile")
|
||||||
|
G
|
||||||
|
expect(out).to include("Resolving dependencies")
|
||||||
|
expect(out).to include("Bundle complete")
|
||||||
|
|
||||||
|
expect(the_bundle).to include_gem "rails 6.1.3.2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "eval-ed Gemfile has relative-path gems" do
|
context "eval-ed Gemfile has relative-path gems" do
|
||||||
before do
|
before do
|
||||||
build_lib("a", :path => bundled_app("gems/a"))
|
build_lib("a", :path => bundled_app("gems/a"))
|
||||||
|
@ -1355,4 +1355,74 @@ RSpec.describe "bundle install with gems on multiple sources" do
|
|||||||
expect(the_bundle).not_to be_locked
|
expect(the_bundle).not_to be_locked
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when upgrading a lockfile suffering from dependency confusion" do
|
||||||
|
before do
|
||||||
|
build_repo4 do
|
||||||
|
build_gem "mime-types", "3.0.0"
|
||||||
|
end
|
||||||
|
|
||||||
|
build_repo2 do
|
||||||
|
build_gem "capybara", "2.5.0" do |s|
|
||||||
|
s.add_dependency "mime-types", ">= 1.16"
|
||||||
|
end
|
||||||
|
|
||||||
|
build_gem "mime-types", "3.3.1"
|
||||||
|
end
|
||||||
|
|
||||||
|
gemfile <<~G
|
||||||
|
source "https://gem.repo2"
|
||||||
|
|
||||||
|
gem "capybara", "~> 2.5.0"
|
||||||
|
|
||||||
|
source "https://gem.repo4" do
|
||||||
|
gem "mime-types", "~> 3.0"
|
||||||
|
end
|
||||||
|
G
|
||||||
|
|
||||||
|
lockfile <<-L
|
||||||
|
GEM
|
||||||
|
remote: https://gem.repo2/
|
||||||
|
remote: https://gem.repo4/
|
||||||
|
specs:
|
||||||
|
capybara (2.5.0)
|
||||||
|
mime-types (>= 1.16)
|
||||||
|
mime-types (3.3.1)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
#{specific_local_platform}
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
capybara (~> 2.5.0)
|
||||||
|
mime-types (~> 3.0)!
|
||||||
|
L
|
||||||
|
end
|
||||||
|
|
||||||
|
it "upgrades the lockfile correctly" do
|
||||||
|
bundle "lock --update", :artifice => "compact_index"
|
||||||
|
|
||||||
|
expect(lockfile).to eq <<~L
|
||||||
|
GEM
|
||||||
|
remote: https://gem.repo2/
|
||||||
|
specs:
|
||||||
|
capybara (2.5.0)
|
||||||
|
mime-types (>= 1.16)
|
||||||
|
|
||||||
|
GEM
|
||||||
|
remote: https://gem.repo4/
|
||||||
|
specs:
|
||||||
|
mime-types (3.0.0)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
#{specific_local_platform}
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
capybara (~> 2.5.0)
|
||||||
|
mime-types (~> 3.0)!
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
#{Bundler::VERSION}
|
||||||
|
L
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -399,7 +399,7 @@ The checksum of /versions does not match the checksum provided by the server! So
|
|||||||
|
|
||||||
api_request_limit = low_api_request_limit_for(gem_repo2)
|
api_request_limit = low_api_request_limit_for(gem_repo2)
|
||||||
|
|
||||||
install_gemfile <<-G, :artifice => "compact_index_extra_missing", :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
|
install_gemfile <<-G, :artifice => "compact_index_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
|
||||||
source "#{source_uri}"
|
source "#{source_uri}"
|
||||||
source "#{source_uri}/extra" do
|
source "#{source_uri}/extra" do
|
||||||
gem "back_deps"
|
gem "back_deps"
|
||||||
@ -421,7 +421,7 @@ The checksum of /versions does not match the checksum provided by the server! So
|
|||||||
|
|
||||||
api_request_limit = low_api_request_limit_for(gem_repo4)
|
api_request_limit = low_api_request_limit_for(gem_repo4)
|
||||||
|
|
||||||
install_gemfile <<-G, :artifice => "compact_index_extra_api_missing", :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
|
install_gemfile <<-G, :artifice => "compact_index_extra_api_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
|
||||||
source "#{source_uri}"
|
source "#{source_uri}"
|
||||||
source "#{source_uri}/extra" do
|
source "#{source_uri}/extra" do
|
||||||
gem "back_deps"
|
gem "back_deps"
|
||||||
|
@ -371,7 +371,7 @@ RSpec.describe "gemcutter's dependency API" do
|
|||||||
|
|
||||||
api_request_limit = low_api_request_limit_for(gem_repo2)
|
api_request_limit = low_api_request_limit_for(gem_repo2)
|
||||||
|
|
||||||
install_gemfile <<-G, :artifice => "endpoint_extra_missing", :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
|
install_gemfile <<-G, :artifice => "endpoint_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
|
||||||
source "#{source_uri}"
|
source "#{source_uri}"
|
||||||
source "#{source_uri}/extra"
|
source "#{source_uri}/extra"
|
||||||
gem "back_deps"
|
gem "back_deps"
|
||||||
@ -392,7 +392,7 @@ RSpec.describe "gemcutter's dependency API" do
|
|||||||
|
|
||||||
api_request_limit = low_api_request_limit_for(gem_repo2)
|
api_request_limit = low_api_request_limit_for(gem_repo2)
|
||||||
|
|
||||||
install_gemfile <<-G, :artifice => "endpoint_extra_missing", :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
|
install_gemfile <<-G, :artifice => "endpoint_extra_missing", :requires => [api_request_limit_hack_file], :env => { "BUNDLER_SPEC_API_REQUEST_LIMIT" => api_request_limit.to_s }.merge(env_for_missing_prerelease_default_gem_activation)
|
||||||
source "#{source_uri}"
|
source "#{source_uri}"
|
||||||
source "#{source_uri}/extra" do
|
source "#{source_uri}/extra" do
|
||||||
gem "back_deps"
|
gem "back_deps"
|
||||||
|
@ -181,8 +181,11 @@ RSpec.describe "global gem caching" do
|
|||||||
bundle :install, :artifice => "compact_index_no_gem", :dir => bundled_app2
|
bundle :install, :artifice => "compact_index_no_gem", :dir => bundled_app2
|
||||||
|
|
||||||
# activesupport is installed and both are in the global cache
|
# activesupport is installed and both are in the global cache
|
||||||
|
simulate_bundler_version_when_missing_prerelease_default_gem_activation do
|
||||||
expect(the_bundle).not_to include_gems "rack 1.0.0", :dir => bundled_app2
|
expect(the_bundle).not_to include_gems "rack 1.0.0", :dir => bundled_app2
|
||||||
expect(the_bundle).to include_gems "activesupport 2.3.5", :dir => bundled_app2
|
expect(the_bundle).to include_gems "activesupport 2.3.5", :dir => bundled_app2
|
||||||
|
end
|
||||||
|
|
||||||
expect(source_global_cache("rack-1.0.0.gem")).to exist
|
expect(source_global_cache("rack-1.0.0.gem")).to exist
|
||||||
expect(source_global_cache("activesupport-2.3.5.gem")).to exist
|
expect(source_global_cache("activesupport-2.3.5.gem")).to exist
|
||||||
end
|
end
|
||||||
|
@ -1178,83 +1178,6 @@ RSpec.describe "the lockfile format" do
|
|||||||
G
|
G
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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.
|
|
||||||
it "fixes corrupted lockfiles" do
|
|
||||||
build_git "omg", :path => lib_path("omg")
|
|
||||||
revision = revision_for(lib_path("omg"))
|
|
||||||
|
|
||||||
gemfile <<-G
|
|
||||||
source "#{file_uri_for(gem_repo2)}/"
|
|
||||||
gem "omg", :git => "#{lib_path("omg")}", :branch => 'master'
|
|
||||||
G
|
|
||||||
|
|
||||||
bundle "config set --local path vendor"
|
|
||||||
bundle :install
|
|
||||||
expect(the_bundle).to include_gems "omg 1.0"
|
|
||||||
|
|
||||||
# Create a Gemfile.lock that has duplicate GIT sections
|
|
||||||
lockfile <<-L
|
|
||||||
GIT
|
|
||||||
remote: #{lib_path("omg")}
|
|
||||||
revision: #{revision}
|
|
||||||
branch: master
|
|
||||||
specs:
|
|
||||||
omg (1.0)
|
|
||||||
|
|
||||||
GIT
|
|
||||||
remote: #{lib_path("omg")}
|
|
||||||
revision: #{revision}
|
|
||||||
branch: master
|
|
||||||
specs:
|
|
||||||
omg (1.0)
|
|
||||||
|
|
||||||
GEM
|
|
||||||
remote: #{file_uri_for(gem_repo2)}/
|
|
||||||
specs:
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
#{lockfile_platforms}
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
omg!
|
|
||||||
|
|
||||||
BUNDLED WITH
|
|
||||||
#{Bundler::VERSION}
|
|
||||||
L
|
|
||||||
|
|
||||||
FileUtils.rm_rf(bundled_app("vendor"))
|
|
||||||
bundle "install"
|
|
||||||
expect(the_bundle).to include_gems "omg 1.0"
|
|
||||||
|
|
||||||
# Confirm that duplicate specs do not appear
|
|
||||||
lockfile_should_be(<<-L)
|
|
||||||
GIT
|
|
||||||
remote: #{lib_path("omg")}
|
|
||||||
revision: #{revision}
|
|
||||||
branch: master
|
|
||||||
specs:
|
|
||||||
omg (1.0)
|
|
||||||
|
|
||||||
GEM
|
|
||||||
remote: #{file_uri_for(gem_repo2)}/
|
|
||||||
specs:
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
#{lockfile_platforms}
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
omg!
|
|
||||||
|
|
||||||
BUNDLED WITH
|
|
||||||
#{Bundler::VERSION}
|
|
||||||
L
|
|
||||||
end
|
|
||||||
|
|
||||||
it "raises a helpful error message when the lockfile is missing deps" do
|
it "raises a helpful error message when the lockfile is missing deps" do
|
||||||
lockfile <<-L
|
lockfile <<-L
|
||||||
GEM
|
GEM
|
||||||
@ -1326,9 +1249,12 @@ RSpec.describe "the lockfile format" do
|
|||||||
|
|
||||||
expect { bundle "update", :all => true }.to change { File.mtime(bundled_app_lock) }
|
expect { bundle "update", :all => true }.to change { File.mtime(bundled_app_lock) }
|
||||||
expect(File.read(bundled_app_lock)).to match("\r\n")
|
expect(File.read(bundled_app_lock)).to match("\r\n")
|
||||||
|
|
||||||
|
simulate_bundler_version_when_missing_prerelease_default_gem_activation do
|
||||||
expect(the_bundle).to include_gems "rack 1.2"
|
expect(the_bundle).to include_gems "rack 1.2"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when nothing changes" do
|
context "when nothing changes" do
|
||||||
it "preserves Gemfile.lock \\n line endings" do
|
it "preserves Gemfile.lock \\n line endings" do
|
||||||
|
@ -211,133 +211,6 @@ RSpec.describe "real world edgecases", :realworld => true do
|
|||||||
expect(err).to be_empty
|
expect(err).to be_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
it "checks out git repos when the lockfile is corrupted" do
|
|
||||||
gemfile <<-G
|
|
||||||
source "https://rubygems.org"
|
|
||||||
git_source(:github) {|repo| "https://github.com/\#{repo}.git" }
|
|
||||||
|
|
||||||
gem 'activerecord', :github => 'carlhuda/rails-bundler-test', :branch => 'master'
|
|
||||||
gem 'activesupport', :github => 'carlhuda/rails-bundler-test', :branch => 'master'
|
|
||||||
gem 'actionpack', :github => 'carlhuda/rails-bundler-test', :branch => 'master'
|
|
||||||
G
|
|
||||||
|
|
||||||
lockfile <<-L
|
|
||||||
GIT
|
|
||||||
remote: https://github.com/carlhuda/rails-bundler-test.git
|
|
||||||
revision: 369e28a87419565f1940815219ea9200474589d4
|
|
||||||
branch: master
|
|
||||||
specs:
|
|
||||||
actionpack (3.2.2)
|
|
||||||
activemodel (= 3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
builder (~> 3.0.0)
|
|
||||||
erubis (~> 2.7.0)
|
|
||||||
journey (~> 1.0.1)
|
|
||||||
rack (~> 1.4.0)
|
|
||||||
rack-cache (~> 1.2)
|
|
||||||
rack-test (~> 0.6.1)
|
|
||||||
sprockets (~> 2.1.2)
|
|
||||||
activemodel (3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
builder (~> 3.0.0)
|
|
||||||
activerecord (3.2.2)
|
|
||||||
activemodel (= 3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
arel (~> 3.0.2)
|
|
||||||
tzinfo (~> 0.3.29)
|
|
||||||
activesupport (3.2.2)
|
|
||||||
i18n (~> 0.6)
|
|
||||||
multi_json (~> 1.0)
|
|
||||||
|
|
||||||
GIT
|
|
||||||
remote: https://github.com/carlhuda/rails-bundler-test.git
|
|
||||||
revision: 369e28a87419565f1940815219ea9200474589d4
|
|
||||||
branch: master
|
|
||||||
specs:
|
|
||||||
actionpack (3.2.2)
|
|
||||||
activemodel (= 3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
builder (~> 3.0.0)
|
|
||||||
erubis (~> 2.7.0)
|
|
||||||
journey (~> 1.0.1)
|
|
||||||
rack (~> 1.4.0)
|
|
||||||
rack-cache (~> 1.2)
|
|
||||||
rack-test (~> 0.6.1)
|
|
||||||
sprockets (~> 2.1.2)
|
|
||||||
activemodel (3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
builder (~> 3.0.0)
|
|
||||||
activerecord (3.2.2)
|
|
||||||
activemodel (= 3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
arel (~> 3.0.2)
|
|
||||||
tzinfo (~> 0.3.29)
|
|
||||||
activesupport (3.2.2)
|
|
||||||
i18n (~> 0.6)
|
|
||||||
multi_json (~> 1.0)
|
|
||||||
|
|
||||||
GIT
|
|
||||||
remote: https://github.com/carlhuda/rails-bundler-test.git
|
|
||||||
revision: 369e28a87419565f1940815219ea9200474589d4
|
|
||||||
branch: master
|
|
||||||
specs:
|
|
||||||
actionpack (3.2.2)
|
|
||||||
activemodel (= 3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
builder (~> 3.0.0)
|
|
||||||
erubis (~> 2.7.0)
|
|
||||||
journey (~> 1.0.1)
|
|
||||||
rack (~> 1.4.0)
|
|
||||||
rack-cache (~> 1.2)
|
|
||||||
rack-test (~> 0.6.1)
|
|
||||||
sprockets (~> 2.1.2)
|
|
||||||
activemodel (3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
builder (~> 3.0.0)
|
|
||||||
activerecord (3.2.2)
|
|
||||||
activemodel (= 3.2.2)
|
|
||||||
activesupport (= 3.2.2)
|
|
||||||
arel (~> 3.0.2)
|
|
||||||
tzinfo (~> 0.3.29)
|
|
||||||
activesupport (3.2.2)
|
|
||||||
i18n (~> 0.6)
|
|
||||||
multi_json (~> 1.0)
|
|
||||||
|
|
||||||
GEM
|
|
||||||
remote: https://rubygems.org/
|
|
||||||
specs:
|
|
||||||
arel (3.0.2)
|
|
||||||
builder (3.0.0)
|
|
||||||
erubis (2.7.0)
|
|
||||||
hike (1.2.1)
|
|
||||||
i18n (0.6.0)
|
|
||||||
journey (1.0.3)
|
|
||||||
multi_json (1.1.0)
|
|
||||||
rack (1.4.1)
|
|
||||||
rack-cache (1.2)
|
|
||||||
rack (>= 0.4)
|
|
||||||
rack-test (0.6.1)
|
|
||||||
rack (>= 1.0)
|
|
||||||
sprockets (2.1.2)
|
|
||||||
hike (~> 1.2)
|
|
||||||
rack (~> 1.0)
|
|
||||||
tilt (~> 1.1, != 1.3.0)
|
|
||||||
tilt (1.3.3)
|
|
||||||
tzinfo (0.3.32)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
ruby
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
actionpack!
|
|
||||||
activerecord!
|
|
||||||
activesupport!
|
|
||||||
L
|
|
||||||
|
|
||||||
bundle :lock
|
|
||||||
expect(err).to be_empty
|
|
||||||
end
|
|
||||||
|
|
||||||
it "outputs a helpful error message when gems have invalid gemspecs" do
|
it "outputs a helpful error message when gems have invalid gemspecs" do
|
||||||
install_gemfile <<-G, :standalone => true, :raise_on_error => false
|
install_gemfile <<-G, :standalone => true, :raise_on_error => false
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
@ -349,7 +222,7 @@ RSpec.describe "real world edgecases", :realworld => true do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't hang on big gemfile" do
|
it "doesn't hang on big gemfile" do
|
||||||
skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3"
|
skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM =~ /darwin/
|
||||||
|
|
||||||
gemfile <<~G
|
gemfile <<~G
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
@ -461,7 +334,7 @@ RSpec.describe "real world edgecases", :realworld => true do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't hang on tricky gemfile" do
|
it "doesn't hang on tricky gemfile" do
|
||||||
skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3"
|
skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM =~ /darwin/
|
||||||
|
|
||||||
gemfile <<~G
|
gemfile <<~G
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
@ -487,7 +360,7 @@ RSpec.describe "real world edgecases", :realworld => true do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't hang on nix gemfile" do
|
it "doesn't hang on nix gemfile" do
|
||||||
skip "Only for ruby 3.0.1" if RUBY_VERSION != "3.0.1"
|
skip "Only for ruby 3.0.1" if RUBY_VERSION != "3.0.1" || RUBY_PLATFORM =~ /darwin/
|
||||||
|
|
||||||
gemfile <<~G
|
gemfile <<~G
|
||||||
source "https://rubygems.org" do
|
source "https://rubygems.org" do
|
||||||
|
@ -4,17 +4,19 @@ require "spec_helper"
|
|||||||
|
|
||||||
RSpec.describe "bundle install with complex dependencies", :realworld => true do
|
RSpec.describe "bundle install with complex dependencies", :realworld => true do
|
||||||
it "resolves quickly" do
|
it "resolves quickly" do
|
||||||
start_time = Time.now
|
gemfile <<-G
|
||||||
|
|
||||||
install_gemfile <<-G
|
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem "actionmailer"
|
gem "actionmailer"
|
||||||
gem "mongoid", ">= 0.10.2"
|
gem "mongoid", ">= 0.10.2"
|
||||||
G
|
G
|
||||||
|
|
||||||
|
start_time = Time.now
|
||||||
|
|
||||||
|
bundle "lock"
|
||||||
|
|
||||||
duration = Time.now - start_time
|
duration = Time.now - start_time
|
||||||
|
|
||||||
expect(duration.to_f).to be < 120 # seconds
|
expect(duration.to_f).to be < 12 # seconds
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -13,7 +13,7 @@ require "bundler"
|
|||||||
require "rspec/core"
|
require "rspec/core"
|
||||||
require "rspec/expectations"
|
require "rspec/expectations"
|
||||||
require "rspec/mocks"
|
require "rspec/mocks"
|
||||||
require "diff/lcs"
|
require "rspec/support/differ"
|
||||||
|
|
||||||
require_relative "support/builders"
|
require_relative "support/builders"
|
||||||
require_relative "support/build_metadata"
|
require_relative "support/build_metadata"
|
||||||
|
16
spec/bundler/support/api_request_limit_hax.rb
Normal file
16
spec/bundler/support/api_request_limit_hax.rb
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
if ENV["BUNDLER_SPEC_API_REQUEST_LIMIT"]
|
||||||
|
require_relative "path"
|
||||||
|
require "bundler/source"
|
||||||
|
require "bundler/source/rubygems"
|
||||||
|
|
||||||
|
module Bundler
|
||||||
|
class Source
|
||||||
|
class Rubygems < Source
|
||||||
|
remove_const :API_REQUEST_LIMIT
|
||||||
|
API_REQUEST_LIMIT = ENV["BUNDLER_SPEC_API_REQUEST_LIMIT"].to_i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -7,7 +7,7 @@ Artifice.deactivate
|
|||||||
class CompactIndexRateLimited < CompactIndexAPI
|
class CompactIndexRateLimited < CompactIndexAPI
|
||||||
class RequestCounter
|
class RequestCounter
|
||||||
def self.queue
|
def self.queue
|
||||||
@queue ||= Queue.new
|
@queue ||= Thread::Queue.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.size
|
def self.size
|
||||||
|
@ -8,7 +8,7 @@ require "artifice"
|
|||||||
require "sinatra/base"
|
require "sinatra/base"
|
||||||
|
|
||||||
ALL_REQUESTS = [] # rubocop:disable Style/MutableConstant
|
ALL_REQUESTS = [] # rubocop:disable Style/MutableConstant
|
||||||
ALL_REQUESTS_MUTEX = Mutex.new
|
ALL_REQUESTS_MUTEX = Thread::Mutex.new
|
||||||
|
|
||||||
at_exit do
|
at_exit do
|
||||||
if expected = ENV["BUNDLER_SPEC_ALL_REQUESTS"]
|
if expected = ENV["BUNDLER_SPEC_ALL_REQUESTS"]
|
||||||
|
@ -35,28 +35,3 @@ module Gem
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if ENV["BUNDLER_SPEC_WINDOWS"] == "true"
|
|
||||||
require_relative "path"
|
|
||||||
require "bundler/constants"
|
|
||||||
|
|
||||||
module Bundler
|
|
||||||
remove_const :WINDOWS if defined?(WINDOWS)
|
|
||||||
WINDOWS = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if ENV["BUNDLER_SPEC_API_REQUEST_LIMIT"]
|
|
||||||
require_relative "path"
|
|
||||||
require "bundler/source"
|
|
||||||
require "bundler/source/rubygems"
|
|
||||||
|
|
||||||
module Bundler
|
|
||||||
class Source
|
|
||||||
class Rubygems < Source
|
|
||||||
remove_const :API_REQUEST_LIMIT
|
|
||||||
API_REQUEST_LIMIT = ENV["BUNDLER_SPEC_API_REQUEST_LIMIT"].to_i
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
@ -457,15 +457,11 @@ module Spec
|
|||||||
end
|
end
|
||||||
|
|
||||||
def simulate_windows(platform = mswin)
|
def simulate_windows(platform = mswin)
|
||||||
old = ENV["BUNDLER_SPEC_WINDOWS"]
|
|
||||||
ENV["BUNDLER_SPEC_WINDOWS"] = "true"
|
|
||||||
simulate_platform platform do
|
simulate_platform platform do
|
||||||
simulate_bundler_version_when_missing_prerelease_default_gem_activation do
|
simulate_bundler_version_when_missing_prerelease_default_gem_activation do
|
||||||
yield
|
yield
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
ensure
|
|
||||||
ENV["BUNDLER_SPEC_WINDOWS"] = old
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def simulate_bundler_version_when_missing_prerelease_default_gem_activation
|
def simulate_bundler_version_when_missing_prerelease_default_gem_activation
|
||||||
|
@ -118,14 +118,14 @@ module Spec
|
|||||||
opts[:raise_on_error] = false
|
opts[:raise_on_error] = false
|
||||||
@errors = names.map do |full_name|
|
@errors = names.map do |full_name|
|
||||||
name, version, platform = full_name.split(/\s+/)
|
name, version, platform = full_name.split(/\s+/)
|
||||||
require_path = name == "bundler" ? "#{lib_dir}/bundler" : name.tr("-", "/")
|
require_path = name.tr("-", "/")
|
||||||
version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name)
|
version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name)
|
||||||
source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
|
source_const = "#{Spec::Builders.constantize(name)}_SOURCE"
|
||||||
ruby <<~R, opts
|
ruby <<~R, opts
|
||||||
require '#{lib_dir}/bundler'
|
require 'bundler'
|
||||||
Bundler.setup(#{groups})
|
Bundler.setup(#{groups})
|
||||||
|
|
||||||
require '#{require_path}.rb'
|
require '#{require_path}'
|
||||||
actual_version, actual_platform = #{version_const}.split(/\s+/, 2)
|
actual_version, actual_platform = #{version_const}.split(/\s+/, 2)
|
||||||
unless Gem::Version.new(actual_version) == Gem::Version.new('#{version}')
|
unless Gem::Version.new(actual_version) == Gem::Version.new('#{version}')
|
||||||
puts actual_version
|
puts actual_version
|
||||||
@ -170,7 +170,7 @@ module Spec
|
|||||||
name, version = name.split(/\s+/, 2)
|
name, version = name.split(/\s+/, 2)
|
||||||
ruby <<-R, opts
|
ruby <<-R, opts
|
||||||
begin
|
begin
|
||||||
require '#{lib_dir}/bundler'
|
require 'bundler'
|
||||||
Bundler.setup(#{groups})
|
Bundler.setup(#{groups})
|
||||||
rescue Bundler::GemNotFound, Bundler::GitError
|
rescue Bundler::GemNotFound, Bundler::GitError
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -71,6 +71,10 @@ module Spec
|
|||||||
@spec_dir ||= source_root.join(ruby_core? ? "spec/bundler" : "spec")
|
@spec_dir ||= source_root.join(ruby_core? ? "spec/bundler" : "spec")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def api_request_limit_hack_file
|
||||||
|
spec_dir.join("support/api_request_limit_hax.rb")
|
||||||
|
end
|
||||||
|
|
||||||
def man_dir
|
def man_dir
|
||||||
@man_dir ||= lib_dir.join("bundler/man")
|
@man_dir ||= lib_dir.join("bundler/man")
|
||||||
end
|
end
|
||||||
|
@ -1595,7 +1595,7 @@ class Object
|
|||||||
metaclass.send :undef_method, name
|
metaclass.send :undef_method, name
|
||||||
metaclass.send :alias_method, name, new_name
|
metaclass.send :alias_method, name, new_name
|
||||||
metaclass.send :undef_method, new_name
|
metaclass.send :undef_method, new_name
|
||||||
end
|
end unless method_defined?(:stub) # lib/resolv/test_dns.rb also has the same method definition
|
||||||
end
|
end
|
||||||
|
|
||||||
require_relative 'utilities'
|
require_relative 'utilities'
|
||||||
|
@ -14,6 +14,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|||||||
Gem.configuration.disable_default_gem_server = nil
|
Gem.configuration.disable_default_gem_server = nil
|
||||||
|
|
||||||
ENV['RUBYGEMS_HOST'] = nil
|
ENV['RUBYGEMS_HOST'] = nil
|
||||||
|
ENV['GEM_HOST_OTP_CODE'] = nil
|
||||||
Gem.configuration.rubygems_api_key = nil
|
Gem.configuration.rubygems_api_key = nil
|
||||||
|
|
||||||
@cmd = Gem::Command.new '', 'summary'
|
@cmd = Gem::Command.new '', 'summary'
|
||||||
@ -22,6 +23,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|||||||
|
|
||||||
def teardown
|
def teardown
|
||||||
ENV['RUBYGEMS_HOST'] = nil
|
ENV['RUBYGEMS_HOST'] = nil
|
||||||
|
ENV['GEM_HOST_OTP_CODE'] = nil
|
||||||
Gem.configuration.rubygems_api_key = nil
|
Gem.configuration.rubygems_api_key = nil
|
||||||
|
|
||||||
credential_teardown
|
credential_teardown
|
||||||
@ -186,6 +188,16 @@ class TestGemGemcutterUtilities < Gem::TestCase
|
|||||||
assert_match %r{Access Denied.}, @sign_in_ui.output
|
assert_match %r{Access Denied.}, @sign_in_ui.output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_signin_with_env_otp_code
|
||||||
|
ENV['GEM_HOST_OTP_CODE'] = '111111'
|
||||||
|
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
|
||||||
|
|
||||||
|
util_sign_in [api_key, 200, 'OK']
|
||||||
|
|
||||||
|
assert_match 'Signed in with API key:', @sign_in_ui.output
|
||||||
|
assert_equal '111111', @fetcher.last_request['OTP']
|
||||||
|
end
|
||||||
|
|
||||||
def test_sign_in_with_correct_otp_code
|
def test_sign_in_with_correct_otp_code
|
||||||
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
|
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
|
||||||
response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
|
response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user