Merge RubyGems-3.3.15 and Bundler-2.3.15

This commit is contained in:
Hiroshi SHIBATA 2022-07-13 14:37:17 +09:00 committed by nagachika
parent d7862a5de4
commit b9f6a09bd2
40 changed files with 385 additions and 100 deletions

View file

@ -97,6 +97,17 @@ module Bundler
@bundle_path ||= Pathname.new(configured_bundle_path.path).expand_path(root) @bundle_path ||= Pathname.new(configured_bundle_path.path).expand_path(root)
end end
def create_bundle_path
SharedHelpers.filesystem_access(bundle_path.to_s) do |p|
mkdir_p(p)
end unless bundle_path.exist?
@bundle_path = bundle_path.realpath
rescue Errno::EEXIST
raise PathError, "Could not install to path `#{bundle_path}` " \
"because a file already exists at that path. Either remove or rename the file so the directory can be created."
end
def configured_bundle_path def configured_bundle_path
@configured_bundle_path ||= settings.path.tap(&:validate!) @configured_bundle_path ||= settings.path.tap(&:validate!)
end end

View file

@ -124,19 +124,17 @@ module Bundler
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \ 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})" \ "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
"#{update_prompt}" "#{update_prompt}"
elsif current.source != dep.source
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"
else else
Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \ 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" \ "You should probably keep only one of them.\n" \
"Remove any duplicate entries and specify the gem only once.\n" \ "Remove any duplicate entries and specify the gem only once.\n" \
"While it's not a problem now, it could cause errors if you change the version of one of them later." "While it's not a problem now, it could cause errors if you change the version of one of them later."
end end
if current.source != dep.source
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 end
end end

View file

@ -79,10 +79,6 @@ module Bundler
case @permission_type case @permission_type
when :create when :create
"executable permissions for all parent directories and write permissions for `#{parent_folder}`" "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
when :delete
permissions = "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
permissions += ", and the same thing for all subdirectories inside #{@path}" if File.directory?(@path)
permissions
else else
"#{@permission_type} permissions for that path" "#{@permission_type} permissions for that path"
end end
@ -172,4 +168,16 @@ module Bundler
status_code(32) status_code(32)
end end
class DirectoryRemovalError < BundlerError
def initialize(orig_exception, msg)
full_message = "#{msg}.\n" \
"The underlying error was #{orig_exception.class}: #{orig_exception.message}, with backtrace:\n" \
" #{orig_exception.backtrace.join("\n ")}\n\n" \
"Bundler Error Backtrace:"
super(full_message)
end
status_code(36)
end
end end

View file

@ -65,8 +65,7 @@ module Bundler
--- ERROR REPORT TEMPLATE ------------------------------------------------------- --- ERROR REPORT TEMPLATE -------------------------------------------------------
``` ```
#{e.class}: #{e.message} #{exception_message(e)}
#{e.backtrace && e.backtrace.join("\n ").chomp}
``` ```
#{Bundler::Env.report} #{Bundler::Env.report}
@ -85,6 +84,21 @@ module Bundler
EOS EOS
end end
def exception_message(error)
message = serialized_exception_for(error)
cause = error.cause
return message unless cause
message + serialized_exception_for(cause)
end
def serialized_exception_for(e)
<<-EOS.gsub(/^ {8}/, "")
#{e.class}: #{e.message}
#{e.backtrace && e.backtrace.join("\n ").chomp}
EOS
end
def issues_url(exception) def issues_url(exception)
message = exception.message.lines.first.tr(":", " ").chomp message = exception.message.lines.first.tr(":", " ").chomp
message = message.split("-").first if exception.is_a?(Errno) message = message.split("-").first if exception.is_a?(Errno)

View file

@ -72,6 +72,10 @@ module Bundler
deps.each {|dep| Bundler.ui.confirm "#{SharedHelpers.pretty_dependency(dep, false)} was removed." } deps.each {|dep| Bundler.ui.confirm "#{SharedHelpers.pretty_dependency(dep, false)} was removed." }
end end
# Invalidate the cached Bundler.definition.
# This prevents e.g. `bundle remove ...` from using outdated information.
Bundler.reset_paths!
end end
private private

View file

@ -38,12 +38,7 @@ def gemfile(install = false, options = {}, &gemfile)
raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty? raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
begin begin
old_root = Bundler.method(:root) Bundler.instance_variable_set(:@bundle_path, Pathname.new(Gem.dir))
bundler_module = class << Bundler; self; end
bundler_module.send(:remove_method, :root)
def Bundler.root
Bundler::SharedHelpers.pwd.expand_path
end
old_gemfile = ENV["BUNDLE_GEMFILE"] old_gemfile = ENV["BUNDLE_GEMFILE"]
Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile" Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile"
@ -71,11 +66,6 @@ def gemfile(install = false, options = {}, &gemfile)
runtime.setup.require runtime.setup.require
end end
ensure ensure
if bundler_module
bundler_module.send(:remove_method, :root)
bundler_module.send(:define_method, :root, old_root)
end
if old_gemfile if old_gemfile
ENV["BUNDLE_GEMFILE"] = old_gemfile ENV["BUNDLE_GEMFILE"] = old_gemfile
else else

View file

@ -66,7 +66,7 @@ module Bundler
# require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more # require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more
# information. # information.
def run(options) def run(options)
create_bundle_path Bundler.create_bundle_path
ProcessLock.lock do ProcessLock.lock do
if Bundler.frozen_bundle? if Bundler.frozen_bundle?
@ -262,15 +262,6 @@ module Bundler
end end
end end
def create_bundle_path
SharedHelpers.filesystem_access(Bundler.bundle_path.to_s) do |p|
Bundler.mkdir_p(p)
end unless Bundler.bundle_path.exist?
rescue Errno::EEXIST
raise PathError, "Could not install to path `#{Bundler.bundle_path}` " \
"because a file already exists at that path. Either remove or rename the file so the directory can be created."
end
# returns whether or not a re-resolve was needed # returns whether or not a re-resolve was needed
def resolve_if_needed(options) def resolve_if_needed(options)
if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file? if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?

View file

@ -12,7 +12,7 @@ module Bundler
yield yield
f.flock(File::LOCK_UN) f.flock(File::LOCK_UN)
end end
rescue Errno::EACCES, Errno::ENOLCK, Errno::ENOTSUP rescue Errno::EACCES, Errno::ENOLCK, Errno::ENOTSUP, Errno::EPERM, Errno::EROFS
# In the case the user does not have access to # In the case the user does not have access to
# create the lock file or is using NFS where # create the lock file or is using NFS where
# locks are not available we skip locking. # locks are not available we skip locking.

View file

@ -19,13 +19,15 @@ module Bundler
# collection of gemspecs is returned. Otherwise, nil is returned. # collection of gemspecs is returned. Otherwise, nil is returned.
def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil) def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
base = SpecSet.new(base) unless base.is_a?(SpecSet) base = SpecSet.new(base) unless base.is_a?(SpecSet)
resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms) metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") }
resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements)
result = resolver.start(requirements) result = resolver.start(requirements)
SpecSet.new(SpecSet.new(result).for(requirements.reject {|dep| dep.name.end_with?("\0") })) SpecSet.new(SpecSet.new(result).for(regular_requirements))
end end
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms) def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements)
@source_requirements = source_requirements @source_requirements = source_requirements
@metadata_requirements = metadata_requirements
@base = base @base = base
@resolver = Molinillo::Resolver.new(self, self) @resolver = Molinillo::Resolver.new(self, self)
@search_for = {} @search_for = {}
@ -344,8 +346,6 @@ module Bundler
trees.sort_by! {|t| t.reverse.map(&:name) } trees.sort_by! {|t| t.reverse.map(&:name) }
end end
metadata_requirements = {}
o << trees.map do |tree| o << trees.map do |tree|
t = "".dup t = "".dup
depth = 2 depth = 2
@ -354,7 +354,6 @@ module Bundler
base_tree_name = base_tree.name base_tree_name = base_tree.name
if base_tree_name.end_with?("\0") if base_tree_name.end_with?("\0")
metadata_requirements[base_tree_name] = base_tree
t = nil t = nil
else else
tree.each do |req| tree.each do |req|
@ -393,10 +392,10 @@ module Bundler
end end
end end
elsif name.end_with?("\0") elsif name.end_with?("\0")
o << %(\n Current #{name} version:\n #{SharedHelpers.pretty_dependency(metadata_requirements[name])}\n\n) o << %(\n Current #{name} version:\n #{SharedHelpers.pretty_dependency(@metadata_requirements.find {|req| req.name == name })}\n\n)
elsif conflict.locked_requirement elsif conflict.locked_requirement
o << "\n" o << "\n"
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n) o << %(Deleting your #{name_for_locking_dependency_source} file and running `bundle install` will rebuild your snapshot from scratch, using only\n)
o << %(the gems in your Gemfile, which may resolve the conflict.\n) o << %(the gems in your Gemfile, which may resolve the conflict.\n)
elsif !conflict.existing elsif !conflict.existing
o << "\n" o << "\n"

View file

@ -93,14 +93,9 @@ module Bundler
private private
def strict_rm_rf(dir) def strict_rm_rf(dir)
# FileUtils.rm_rf should probably rise in case of permission issues like Bundler.rm_rf dir
# `rm -rf` does. However, it fails to delete the folder silently due to rescue Errno::ENOTEMPTY => e
# https://github.com/ruby/fileutils/issues/57. It should probably be fixed raise DirectoryRemovalError.new(e.cause, "Could not delete previous installation of `#{dir}`")
# inside `fileutils` but for now I`m checking whether the folder was
# removed after it completes, and raising otherwise.
FileUtils.rm_rf dir
raise PermissionError.new(dir, :delete) if File.directory?(dir)
end end
def validate_bundler_checksum(checksum) def validate_bundler_checksum(checksum)

View file

@ -487,7 +487,7 @@ module Bundler
/ix.freeze /ix.freeze
def self.key_for(key) def self.key_for(key)
key = normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http")
key = key.to_s.gsub(".", "__").gsub("-", "___").upcase key = key.to_s.gsub(".", "__").gsub("-", "___").upcase
"BUNDLE_#{key}" "BUNDLE_#{key}"
end end

View file

@ -499,7 +499,7 @@ module Bundler
end end
def rubygems_dir def rubygems_dir
Bundler.rubygems.gem_dir Bundler.bundle_path
end end
def default_cache_path_for(dir) def default_cache_path_for(dir)

View file

@ -64,9 +64,11 @@ module Bundler
end end
def full_gem_path def full_gem_path
# deleted gems can have their stubs return nil, so in that case grab the stub.full_gem_path
# expired path from the full spec end
stub.full_gem_path || method_missing(:full_gem_path)
def full_gem_path=(path)
stub.full_gem_path = path
end end
def full_require_paths def full_require_paths

View file

@ -1,7 +1,7 @@
# frozen_string_literal: false # frozen_string_literal: false
module Bundler module Bundler
VERSION = "2.3.14".freeze VERSION = "2.3.15".freeze
def self.bundler_major_version def self.bundler_major_version
@bundler_major_version ||= VERSION.split(".").first.to_i @bundler_major_version ||= VERSION.split(".").first.to_i

View file

@ -8,7 +8,7 @@
require 'rbconfig' require 'rbconfig'
module Gem module Gem
VERSION = "3.3.14".freeze VERSION = "3.3.15".freeze
end end
# Must be first since it unloads the prelude from 1.9.2 # Must be first since it unloads the prelude from 1.9.2

View file

@ -148,7 +148,12 @@ class Gem::CommandManager
def run(args, build_args=nil) def run(args, build_args=nil)
process_args(args, build_args) process_args(args, build_args)
rescue StandardError, Timeout::Error => ex rescue StandardError, Timeout::Error => ex
alert_error clean_text("While executing gem ... (#{ex.class})\n #{ex}") if ex.respond_to?(:detailed_message)
msg = ex.detailed_message(highlight: false).sub(/\A(.*?)(?: \(.+?\))/) { $1 }
else
msg = ex.message
end
alert_error clean_text("While executing gem ... (#{ex.class})\n #{msg}")
ui.backtrace ex ui.backtrace ex
terminate_interaction(1) terminate_interaction(1)

View file

@ -173,10 +173,11 @@ command to remove old versions.
highest_remote_gem.first highest_remote_gem.first
end end
def install_rubygems(version) # :nodoc: def install_rubygems(spec) # :nodoc:
args = update_rubygems_arguments args = update_rubygems_arguments
version = spec.version
update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}" update_dir = File.join spec.base_dir, 'gems', "rubygems-update-#{version}"
Dir.chdir update_dir do Dir.chdir update_dir do
say "Installing RubyGems #{version}" unless options[:silent] say "Installing RubyGems #{version}" unless options[:silent]
@ -290,9 +291,7 @@ command to remove old versions.
installed_gems = update_gem('rubygems-update', version) if installed_gems.empty? || installed_gems.first.version != version installed_gems = update_gem('rubygems-update', version) if installed_gems.empty? || installed_gems.first.version != version
return if installed_gems.empty? return if installed_gems.empty?
version = installed_gems.first.version install_rubygems installed_gems.first
install_rubygems version
end end
def update_rubygems_arguments # :nodoc: def update_rubygems_arguments # :nodoc:

View file

@ -1270,7 +1270,14 @@ class Gem::Specification < Gem::BasicSpecification
def self._load(str) def self._load(str)
Gem.load_yaml Gem.load_yaml
array = Marshal.load str array = begin
Marshal.load str
rescue ArgumentError => e
raise unless e.message.include?("YAML")
Object.const_set "YAML", Psych
Marshal.load str
end
spec = Gem::Specification.new spec = Gem::Specification.new
spec.instance_variable_set :@specification_version, array[1] spec.instance_variable_set :@specification_version, array[1]
@ -1289,11 +1296,6 @@ class Gem::Specification < Gem::BasicSpecification
raise TypeError, "invalid Gem::Specification format #{array.inspect}" raise TypeError, "invalid Gem::Specification format #{array.inspect}"
end end
# Cleanup any Psych::PrivateType. They only show up for an old bug
# where nil => null, so just convert them to nil based on the type.
array.map! {|e| e.kind_of?(Psych::PrivateType) ? nil : e }
spec.instance_variable_set :@rubygems_version, array[0] spec.instance_variable_set :@rubygems_version, array[0]
# spec version # spec version
spec.instance_variable_set :@name, array[2] spec.instance_variable_set :@name, array[2]

View file

@ -208,7 +208,7 @@ RSpec.describe "bundle clean" do
G G
FileUtils.mkdir_p(bundled_app("real-path")) FileUtils.mkdir_p(bundled_app("real-path"))
FileUtils.ln_sf(bundled_app("real-path"), bundled_app("symlink-path")) File.symlink(bundled_app("real-path"), bundled_app("symlink-path"))
bundle "config set path #{bundled_app("symlink-path")}" bundle "config set path #{bundled_app("symlink-path")}"
bundle "install" bundle "install"

View file

@ -435,6 +435,34 @@ E
end end
end end
describe "commented out settings with urls" do
before do
bundle "config set #mirror.https://rails-assets.org http://localhost:9292"
end
it "does not make bundler crash and ignores the configuration" do
bundle "config list --parseable"
expect(out).to eq("#mirror.https://rails-assets.org/=http://localhost:9292")
expect(err).to be_empty
ruby(<<~RUBY)
require "#{entrypoint}"
print Bundler.settings.mirror_for("https://rails-assets.org")
RUBY
expect(out).to eq("https://rails-assets.org/")
expect(err).to be_empty
bundle "config set mirror.all http://localhost:9293"
ruby(<<~RUBY)
require "#{entrypoint}"
print Bundler.settings.mirror_for("https://rails-assets.org")
RUBY
expect(out).to eq("http://localhost:9293/")
expect(err).to be_empty
end
end
describe "subcommands" do describe "subcommands" do
it "list" do it "list" do
bundle "config list", :env => { "BUNDLE_FOO" => "bar" } bundle "config list", :env => { "BUNDLE_FOO" => "bar" }

View file

@ -755,12 +755,8 @@ RSpec.describe "bundle install with gem sources" do
end end
expect(err).not_to include("ERROR REPORT TEMPLATE") expect(err).not_to include("ERROR REPORT TEMPLATE")
expect(err).to include("Could not delete previous installation of `#{foo_path}`.")
expect(err).to include( expect(err).to include("The underlying error was Errno::EACCES")
"There was an error while trying to delete `#{foo_path}`. " \
"It is likely that you need to grant executable permissions for all parent directories " \
"and write permissions for `#{gems_path}`, and the same thing for all subdirectories inside #{foo_path}."
)
end end
end end
@ -973,4 +969,37 @@ RSpec.describe "bundle install with gem sources" do
expect(last_command).to be_success expect(last_command).to be_success
end end
end end
context "with a symlinked configured as bundle path and a gem with symlinks" do
before do
symlinked_bundled_app = tmp("bundled_app-symlink")
File.symlink(bundled_app, symlinked_bundled_app)
bundle "config path #{File.join(symlinked_bundled_app, ".vendor")}"
binman_path = tmp("binman")
FileUtils.mkdir_p binman_path
readme_path = File.join(binman_path, "README.markdown")
FileUtils.touch(readme_path)
man_path = File.join(binman_path, "man", "man0")
FileUtils.mkdir_p man_path
File.symlink("../../README.markdown", File.join(man_path, "README.markdown"))
build_repo4 do
build_gem "binman", :path => gem_repo4("gems"), :lib_path => binman_path, :no_default => true do |s|
s.files = ["README.markdown", "man/man0/README.markdown"]
end
end
end
it "installs fine" do
install_gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "binman"
G
end
end
end end

View file

@ -13,6 +13,36 @@ RSpec.describe "bundle remove" do
end end
end end
context "after 'bundle install' is run" do
describe "running 'bundle remove GEM_NAME'" do
it "removes it from the lockfile" do
rack_dep = <<~L
DEPENDENCIES
rack
L
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "install"
expect(lockfile).to include(rack_dep)
bundle "remove rack"
expect(gemfile).to eq <<~G
source "#{file_uri_for(gem_repo1)}"
G
expect(lockfile).to_not include(rack_dep)
end
end
end
context "when --install flag is specified", :bundler => "< 3" do context "when --install flag is specified", :bundler => "< 3" do
it "removes gems from .bundle" do it "removes gems from .bundle" do
gemfile <<-G gemfile <<-G

View file

@ -1255,6 +1255,32 @@ RSpec.describe "bundle install with gems on multiple sources" do
end end
end end
context "when Gemfile overrides a gemspec development dependency to change the default source" do
before do
build_repo4 do
build_gem "bar"
end
build_lib("gemspec_test", :path => tmp.join("gemspec_test")) do |s|
s.add_development_dependency "bar"
end
install_gemfile <<-G, :artifice => "compact_index"
source "https://gem.repo1"
source "https://gem.repo4" do
gem "bar"
end
gemspec :path => "#{tmp.join("gemspec_test")}"
G
end
it "does not print warnings" do
expect(err).to be_empty
end
end
it "doesn't update version when a gem uses a source block but a higher version from another source is already installed locally" do it "doesn't update version when a gem uses a source block but a higher version from another source is already installed locally" do
build_repo2 do build_repo2 do
build_gem "example", "0.1.0" build_gem "example", "0.1.0"

View file

@ -156,7 +156,7 @@ RSpec.describe "bundle flex_install" do
end end
end end
describe "when Gemfile conflicts with lockfile" do describe "when running bundle install and Gemfile conflicts with lockfile" do
before(:each) do before(:each) do
build_repo2 build_repo2
install_gemfile <<-G install_gemfile <<-G
@ -190,7 +190,7 @@ RSpec.describe "bundle flex_install" do
expect(err).to match(/could not find gem 'rack-obama/i) expect(err).to match(/could not find gem 'rack-obama/i)
end end
it "suggests bundle update when the Gemfile requires different versions than the lock" do it "suggests deleting the Gemfile.lock file when the Gemfile requires different versions than the lock" do
bundle "config set force_ruby_platform true" bundle "config set force_ruby_platform true"
nice_error = <<-E.strip.gsub(/^ {8}/, "") nice_error = <<-E.strip.gsub(/^ {8}/, "")
@ -205,7 +205,7 @@ RSpec.describe "bundle flex_install" do
rack_middleware was resolved to 1.0, which depends on rack_middleware was resolved to 1.0, which depends on
rack (= 0.9.1) rack (= 0.9.1)
Running `bundle update` will rebuild your snapshot from scratch, using only Deleting your Gemfile.lock file and running `bundle install` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict. the gems in your Gemfile, which may resolve the conflict.
E E
@ -214,6 +214,67 @@ RSpec.describe "bundle flex_install" do
end end
end end
describe "when running bundle update and Gemfile conflicts with lockfile" do
before(:each) do
build_repo4 do
build_gem "jekyll-feed", "0.16.0"
build_gem "jekyll-feed", "0.15.1"
build_gem "github-pages", "226" do |s|
s.add_dependency "jekyll-feed", "0.15.1"
end
end
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "jekyll-feed", "~> 0.12"
G
puts lockfile
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
jekyll-feed (0.16.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
jekyll-feed
BUNDLED WITH
#{Bundler::VERSION}
L
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "github-pages", "~> 226"
gem "jekyll-feed", "~> 0.12"
G
end
it "suggests deleting the Gemfile.lock file when the Gemfile requires different versions than the lock" do
nice_error = <<-E.strip.gsub(/^ {8}/, "")
Bundler could not find compatible versions for gem "jekyll-feed":
In snapshot (Gemfile.lock):
jekyll-feed (>= 0.16.0)
In Gemfile:
jekyll-feed (~> 0.12)
github-pages (~> 226) was resolved to 226, which depends on
jekyll-feed (= 0.15.1)
Deleting your Gemfile.lock file and running `bundle install` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
E
bundle :update, :raise_on_error => false
expect(err).to end_with(nice_error)
end
end
describe "subtler cases" do describe "subtler cases" do
before :each do before :each do
install_gemfile <<-G install_gemfile <<-G

View file

@ -282,6 +282,27 @@ RSpec.describe "bundle install with install-time dependencies" do
expect(err).not_to include("That means the author of parallel_tests (3.8.0) has removed it.") expect(err).not_to include("That means the author of parallel_tests (3.8.0) has removed it.")
end end
it "gives a meaningful error on ruby version mismatches between dependencies" do
build_repo4 do
build_gem "requires-old-ruby" do |s|
s.required_ruby_version = "< #{RUBY_VERSION}"
end
end
build_lib("foo", :path => bundled_app) do |s|
s.required_ruby_version = ">= #{RUBY_VERSION}"
s.add_dependency "requires-old-ruby"
end
install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo4)}"
gemspec
G
expect(err).to include("Bundler found conflicting requirements for the Ruby\0 version:")
end
it "installs the older version under rate limiting conditions" do it "installs the older version under rate limiting conditions" do
build_repo4 do build_repo4 do
build_gem "rack", "9001.0.0" do |s| build_gem "rack", "9001.0.0" do |s|

View file

@ -147,9 +147,16 @@ RSpec.shared_examples "bundle install --standalone" do
bundle "lock", :dir => cwd, :artifice => "compact_index" bundle "lock", :dir => cwd, :artifice => "compact_index"
end end
it "works" do it "works and points to the vendored copies, not to the default copies" do
bundle "config set --local path #{bundled_app("bundle")}" bundle "config set --local path #{bundled_app("bundle")}"
bundle :install, :standalone => true, :dir => cwd, :artifice => "compact_index", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s } bundle :install, :standalone => true, :dir => cwd, :artifice => "compact_index", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }
load_path_lines = bundled_app("bundle/bundler/setup.rb").read.split("\n").select {|line| line.start_with?("$:.unshift") }
expect(load_path_lines).to eq [
'$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}/gems/bar-1.0.0/lib")',
'$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}/gems/foo-1.0.0/lib")',
]
end end
end end

View file

@ -31,5 +31,27 @@ RSpec.describe "process lock spec" do
expect(processed).to eq true expect(processed).to eq true
end end
end end
context "when creating a lock raises Errno::EPERM" do
before { allow(File).to receive(:open).and_raise(Errno::EPERM) }
it "skips creating the lock file and yields" do
processed = false
Bundler::ProcessLock.lock(default_bundle_path) { processed = true }
expect(processed).to eq true
end
end
context "when creating a lock raises Errno::EROFS" do
before { allow(File).to receive(:open).and_raise(Errno::EROFS) }
it "skips creating the lock file and yields" do
processed = false
Bundler::ProcessLock.lock(default_bundle_path) { processed = true }
expect(processed).to eq true
end
end
end end
end end

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
require "tmpdir" require "tmpdir"
require "tempfile"
RSpec.describe "Bundler.setup" do RSpec.describe "Bundler.setup" do
describe "with no arguments" do describe "with no arguments" do
@ -800,7 +799,7 @@ end
run <<~RUBY run <<~RUBY
puts ENV['MANPATH'] puts ENV['MANPATH']
require "open3" require "open3"
puts Open3.capture2e("man", "ls")[0] puts Open3.capture2e({ "LC_ALL" => "C" }, "man", "ls")[0]
RUBY RUBY
lines = out.split("\n") lines = out.split("\n")
@ -861,19 +860,17 @@ end
context "with bundler is located in symlinked GEM_HOME" do context "with bundler is located in symlinked GEM_HOME" do
let(:gem_home) { Dir.mktmpdir } let(:gem_home) { Dir.mktmpdir }
let(:symlinked_gem_home) { Tempfile.new("gem_home").path } let(:symlinked_gem_home) { tmp("gem_home-symlink").to_s }
let(:full_name) { "bundler-#{Bundler::VERSION}" } let(:full_name) { "bundler-#{Bundler::VERSION}" }
before do before do
skip "symlink destination exists" if Gem.win_platform? File.symlink(gem_home, symlinked_gem_home)
FileUtils.ln_sf(gem_home, symlinked_gem_home)
gems_dir = File.join(gem_home, "gems") gems_dir = File.join(gem_home, "gems")
specifications_dir = File.join(gem_home, "specifications") specifications_dir = File.join(gem_home, "specifications")
Dir.mkdir(gems_dir) Dir.mkdir(gems_dir)
Dir.mkdir(specifications_dir) Dir.mkdir(specifications_dir)
FileUtils.ln_s(source_root, File.join(gems_dir, full_name)) File.symlink(source_root, File.join(gems_dir, full_name))
gemspec_content = File.binread(gemspec). gemspec_content = File.binread(gemspec).
sub("Bundler::VERSION", %("#{Bundler::VERSION}")). sub("Bundler::VERSION", %("#{Bundler::VERSION}")).

View file

@ -113,6 +113,10 @@ RSpec.configure do |config|
end end
end end
config.before :each, :sudo => true do
Spec::Sudo.write_safe_config
end
config.after :suite do config.after :suite do
FileUtils.rm_r Spec::Path.pristine_system_gem_path FileUtils.rm_r Spec::Path.pristine_system_gem_path
end end

View file

@ -484,7 +484,7 @@ module Spec
end end
@spec.authors = ["no one"] @spec.authors = ["no one"]
@spec.files = @files.keys @spec.files += @files.keys
case options[:gemspec] case options[:gemspec]
when false when false
@ -589,7 +589,8 @@ module Spec
class GemBuilder < LibBuilder class GemBuilder < LibBuilder
def _build(opts) def _build(opts)
lib_path = super(opts.merge(:path => @context.tmp(".tmp/#{@spec.full_name}"), :no_default => opts[:no_default])) lib_path = opts[:lib_path] || @context.tmp(".tmp/#{@spec.full_name}")
lib_path = super(opts.merge(:path => lib_path, :no_default => opts[:no_default]))
destination = opts[:path] || _default_path destination = opts[:path] || _default_path
FileUtils.mkdir_p(lib_path.join(destination)) FileUtils.mkdir_p(lib_path.join(destination))

View file

@ -258,6 +258,10 @@ module Spec
end end
end end
def git_root
ruby_core? ? source_root : source_root.parent
end
private private
def git_ls_files(glob) def git_ls_files(glob)
@ -278,10 +282,6 @@ module Spec
ruby_core? ? "man/bundle* man/gemfile*" : "lib/bundler/man/bundle*.1 lib/bundler/man/gemfile*.5" ruby_core? ? "man/bundle* man/gemfile*" : "lib/bundler/man/bundle*.1 lib/bundler/man/gemfile*.5"
end end
def git_root
ruby_core? ? source_root : source_root.parent
end
def ruby_core_tarball? def ruby_core_tarball?
!git_root.join(".git").directory? !git_root.join(".git").directory?
end end

View file

@ -6,6 +6,10 @@ module Spec
@which_sudo ||= Bundler.which("sudo") @which_sudo ||= Bundler.which("sudo")
end end
def self.write_safe_config
File.write(Spec::Path.tmp("gitconfig"), "[safe]\n\tdirectory = #{Spec::Path.git_root}")
end
def sudo(cmd) def sudo(cmd)
raise "sudo not present" unless Sudo.present? raise "sudo not present" unless Sudo.present?
sys_exec("sudo #{cmd}") sys_exec("sudo #{cmd}")

View file

@ -80,7 +80,13 @@ class TestGemCommandManager < Gem::TestCase
message << "\nDid you mean? \"push\"" message << "\nDid you mean? \"push\""
end end
assert_equal message, e.message if e.respond_to?(:detailed_message)
actual_message = e.detailed_message(highlight: false).sub(/\A(.*?)(?: \(.+?\))/) { $1 }
else
actual_message = e.message
end
assert_equal message, actual_message
end end
def test_run_interrupt def test_run_interrupt

View file

@ -191,6 +191,37 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
assert_empty out assert_empty out
end end
def test_execute_system_update_installed_in_non_default_gem_path
rubygems_update_spec = quick_gem "rubygems-update", 9 do |s|
write_file File.join(@tempdir, 'setup.rb')
s.files += %w[setup.rb]
end
util_setup_spec_fetcher rubygems_update_spec
rubygems_update_package = Gem::Package.build rubygems_update_spec
gemhome2 = "#{@gemhome}2"
Gem::Installer.at(rubygems_update_package, :install_dir => gemhome2).install
Gem.use_paths @gemhome, [gemhome2, @gemhome]
@cmd.options[:args] = []
@cmd.options[:system] = true
use_ui @ui do
@cmd.execute
end
out = @ui.output.split "\n"
assert_equal "Installing RubyGems 9", out.shift
assert_equal "RubyGems system software updated", out.shift
assert_empty out
end
def test_execute_system_specific def test_execute_system_specific
spec_fetcher do |fetcher| spec_fetcher do |fetcher|
fetcher.download 'rubygems-update', 8 do |s| fetcher.download 'rubygems-update', 8 do |s|

View file

@ -1072,7 +1072,7 @@ dependencies: []
data = Marshal.load Gem::Util.inflate(Gem.read_binary(path)) data = Marshal.load Gem::Util.inflate(Gem.read_binary(path))
assert_nil data.signing_key assert_instance_of Gem::Specification, data
end end
def test_initialize def test_initialize

View file

@ -72,4 +72,4 @@ DEPENDENCIES
webrick (~> 1.6) webrick (~> 1.6)
BUNDLED WITH BUNDLED WITH
2.3.14 2.3.15

View file

@ -60,4 +60,4 @@ DEPENDENCIES
test-unit test-unit
BUNDLED WITH BUNDLED WITH
2.3.14 2.3.15

View file

@ -66,4 +66,4 @@ DEPENDENCIES
test-unit test-unit
BUNDLED WITH BUNDLED WITH
2.3.14 2.3.15

View file

@ -41,4 +41,4 @@ DEPENDENCIES
webrick (= 1.7.0) webrick (= 1.7.0)
BUNDLED WITH BUNDLED WITH
2.3.14 2.3.15