summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2022-07-13 14:37:17 +0900
committernagachika <nagachika@ruby-lang.org>2022-09-03 15:54:07 +0900
commitb9f6a09bd2127ea51612bd27bef5830831b48d4f (patch)
tree2ea33c0d2c14e86b1b0ad7449d85ec068d954aea
parentd7862a5de43f7412ab41cdae6709c8a30b988621 (diff)
Merge RubyGems-3.3.15 and Bundler-2.3.15
-rw-r--r--lib/bundler.rb11
-rw-r--r--lib/bundler/dsl.rb12
-rw-r--r--lib/bundler/errors.rb16
-rw-r--r--lib/bundler/friendly_errors.rb18
-rw-r--r--lib/bundler/injector.rb4
-rw-r--r--lib/bundler/inline.rb12
-rw-r--r--lib/bundler/installer.rb11
-rw-r--r--lib/bundler/process_lock.rb2
-rw-r--r--lib/bundler/resolver.rb15
-rw-r--r--lib/bundler/rubygems_gem_installer.rb11
-rw-r--r--lib/bundler/settings.rb2
-rw-r--r--lib/bundler/source/rubygems.rb2
-rw-r--r--lib/bundler/stub_specification.rb8
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/rubygems.rb2
-rw-r--r--lib/rubygems/command_manager.rb7
-rw-r--r--lib/rubygems/commands/update_command.rb9
-rw-r--r--lib/rubygems/specification.rb14
-rw-r--r--spec/bundler/commands/clean_spec.rb2
-rw-r--r--spec/bundler/commands/config_spec.rb28
-rw-r--r--spec/bundler/commands/install_spec.rb41
-rw-r--r--spec/bundler/commands/remove_spec.rb30
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb26
-rw-r--r--spec/bundler/install/gems/flex_spec.rb67
-rw-r--r--spec/bundler/install/gems/resolving_spec.rb21
-rw-r--r--spec/bundler/install/gems/standalone_spec.rb9
-rw-r--r--spec/bundler/install/process_lock_spec.rb22
-rw-r--r--spec/bundler/runtime/setup_spec.rb11
-rw-r--r--spec/bundler/spec_helper.rb4
-rw-r--r--spec/bundler/support/builders.rb5
-rw-r--r--spec/bundler/support/path.rb8
-rw-r--r--spec/bundler/support/sudo.rb4
-rw-r--r--test/rubygems/data/null-type.gemspec.rzbin504 -> 433 bytes
-rw-r--r--test/rubygems/test_gem_command_manager.rb8
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb31
-rw-r--r--test/rubygems/test_gem_specification.rb2
-rw-r--r--tool/bundler/dev_gems.rb.lock2
-rw-r--r--tool/bundler/rubocop_gems.rb.lock2
-rw-r--r--tool/bundler/standard_gems.rb.lock2
-rw-r--r--tool/bundler/test_gems.rb.lock2
40 files changed, 385 insertions, 100 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 0be01d1808..c99114ae64 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -97,6 +97,17 @@ module Bundler
@bundle_path ||= Pathname.new(configured_bundle_path.path).expand_path(root)
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
@configured_bundle_path ||= settings.path.tap(&:validate!)
end
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 8983ef3e2b..1ae19a46e9 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -124,19 +124,17 @@ module Bundler
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
"#{update_prompt}"
+ 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
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" \
"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."
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
diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb
index 9ad7460e58..0bc1a860df 100644
--- a/lib/bundler/errors.rb
+++ b/lib/bundler/errors.rb
@@ -79,10 +79,6 @@ module Bundler
case @permission_type
when :create
"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
"#{@permission_type} permissions for that path"
end
@@ -172,4 +168,16 @@ module Bundler
status_code(32)
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
diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb
index cc615db60c..ff6cdc4123 100644
--- a/lib/bundler/friendly_errors.rb
+++ b/lib/bundler/friendly_errors.rb
@@ -65,8 +65,7 @@ module Bundler
--- ERROR REPORT TEMPLATE -------------------------------------------------------
```
- #{e.class}: #{e.message}
- #{e.backtrace && e.backtrace.join("\n ").chomp}
+ #{exception_message(e)}
```
#{Bundler::Env.report}
@@ -85,6 +84,21 @@ module Bundler
EOS
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)
message = exception.message.lines.first.tr(":", " ").chomp
message = message.split("-").first if exception.is_a?(Errno)
diff --git a/lib/bundler/injector.rb b/lib/bundler/injector.rb
index 42f837a919..f6550abe88 100644
--- a/lib/bundler/injector.rb
+++ b/lib/bundler/injector.rb
@@ -72,6 +72,10 @@ module Bundler
deps.each {|dep| Bundler.ui.confirm "#{SharedHelpers.pretty_dependency(dep, false)} was removed." }
end
+
+ # Invalidate the cached Bundler.definition.
+ # This prevents e.g. `bundle remove ...` from using outdated information.
+ Bundler.reset_paths!
end
private
diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb
index a718418fce..8ef580f1f0 100644
--- a/lib/bundler/inline.rb
+++ b/lib/bundler/inline.rb
@@ -38,12 +38,7 @@ def gemfile(install = false, options = {}, &gemfile)
raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
begin
- old_root = Bundler.method(:root)
- bundler_module = class << Bundler; self; end
- bundler_module.send(:remove_method, :root)
- def Bundler.root
- Bundler::SharedHelpers.pwd.expand_path
- end
+ Bundler.instance_variable_set(:@bundle_path, Pathname.new(Gem.dir))
old_gemfile = ENV["BUNDLE_GEMFILE"]
Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile"
@@ -71,11 +66,6 @@ def gemfile(install = false, options = {}, &gemfile)
runtime.setup.require
end
ensure
- if bundler_module
- bundler_module.send(:remove_method, :root)
- bundler_module.send(:define_method, :root, old_root)
- end
-
if old_gemfile
ENV["BUNDLE_GEMFILE"] = old_gemfile
else
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index 915a04c0dc..f195d36600 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -66,7 +66,7 @@ module Bundler
# require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more
# information.
def run(options)
- create_bundle_path
+ Bundler.create_bundle_path
ProcessLock.lock do
if Bundler.frozen_bundle?
@@ -262,15 +262,6 @@ module Bundler
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
def resolve_if_needed(options)
if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
diff --git a/lib/bundler/process_lock.rb b/lib/bundler/process_lock.rb
index a5cc614e20..0297f80e2c 100644
--- a/lib/bundler/process_lock.rb
+++ b/lib/bundler/process_lock.rb
@@ -12,7 +12,7 @@ module Bundler
yield
f.flock(File::LOCK_UN)
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
# create the lock file or is using NFS where
# locks are not available we skip locking.
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 2285114c57..d749694952 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -19,13 +19,15 @@ module Bundler
# 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)
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)
- SpecSet.new(SpecSet.new(result).for(requirements.reject {|dep| dep.name.end_with?("\0") }))
+ SpecSet.new(SpecSet.new(result).for(regular_requirements))
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
+ @metadata_requirements = metadata_requirements
@base = base
@resolver = Molinillo::Resolver.new(self, self)
@search_for = {}
@@ -344,8 +346,6 @@ module Bundler
trees.sort_by! {|t| t.reverse.map(&:name) }
end
- metadata_requirements = {}
-
o << trees.map do |tree|
t = "".dup
depth = 2
@@ -354,7 +354,6 @@ module Bundler
base_tree_name = base_tree.name
if base_tree_name.end_with?("\0")
- metadata_requirements[base_tree_name] = base_tree
t = nil
else
tree.each do |req|
@@ -393,10 +392,10 @@ module Bundler
end
end
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
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)
elsif !conflict.existing
o << "\n"
diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb
index 452583617b..87b9772c27 100644
--- a/lib/bundler/rubygems_gem_installer.rb
+++ b/lib/bundler/rubygems_gem_installer.rb
@@ -93,14 +93,9 @@ module Bundler
private
def strict_rm_rf(dir)
- # FileUtils.rm_rf should probably rise in case of permission issues like
- # `rm -rf` does. However, it fails to delete the folder silently due to
- # https://github.com/ruby/fileutils/issues/57. It should probably be fixed
- # 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)
+ Bundler.rm_rf dir
+ rescue Errno::ENOTEMPTY => e
+ raise DirectoryRemovalError.new(e.cause, "Could not delete previous installation of `#{dir}`")
end
def validate_bundler_checksum(checksum)
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index 8f263cd012..398c66055a 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -487,7 +487,7 @@ module Bundler
/ix.freeze
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
"BUNDLE_#{key}"
end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index b37bfbccb9..5dceacbae4 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -499,7 +499,7 @@ module Bundler
end
def rubygems_dir
- Bundler.rubygems.gem_dir
+ Bundler.bundle_path
end
def default_cache_path_for(dir)
diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb
index fa071901e5..88a4257fa4 100644
--- a/lib/bundler/stub_specification.rb
+++ b/lib/bundler/stub_specification.rb
@@ -64,9 +64,11 @@ module Bundler
end
def full_gem_path
- # deleted gems can have their stubs return nil, so in that case grab the
- # expired path from the full spec
- stub.full_gem_path || method_missing(:full_gem_path)
+ stub.full_gem_path
+ end
+
+ def full_gem_path=(path)
+ stub.full_gem_path = path
end
def full_require_paths
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index 492cd1d751..9e8fa48a1d 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
- VERSION = "2.3.14".freeze
+ VERSION = "2.3.15".freeze
def self.bundler_major_version
@bundler_major_version ||= VERSION.split(".").first.to_i
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 0b83b1f0ed..8c2c465ad4 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
- VERSION = "3.3.14".freeze
+ VERSION = "3.3.15".freeze
end
# Must be first since it unloads the prelude from 1.9.2
diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb
index 03cdd6a4bb..e421f89884 100644
--- a/lib/rubygems/command_manager.rb
+++ b/lib/rubygems/command_manager.rb
@@ -148,7 +148,12 @@ class Gem::CommandManager
def run(args, build_args=nil)
process_args(args, build_args)
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
terminate_interaction(1)
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index 42d6f6046b..54b1251010 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -173,10 +173,11 @@ command to remove old versions.
highest_remote_gem.first
end
- def install_rubygems(version) # :nodoc:
+ def install_rubygems(spec) # :nodoc:
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
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
return if installed_gems.empty?
- version = installed_gems.first.version
-
- install_rubygems version
+ install_rubygems installed_gems.first
end
def update_rubygems_arguments # :nodoc:
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index 9b533caf54..33eb0a2bff 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -1270,7 +1270,14 @@ class Gem::Specification < Gem::BasicSpecification
def self._load(str)
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.instance_variable_set :@specification_version, array[1]
@@ -1289,11 +1296,6 @@ class Gem::Specification < Gem::BasicSpecification
raise TypeError, "invalid Gem::Specification format #{array.inspect}"
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 version
spec.instance_variable_set :@name, array[2]
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
index 576872b0f6..db81c10e9d 100644
--- a/spec/bundler/commands/clean_spec.rb
+++ b/spec/bundler/commands/clean_spec.rb
@@ -208,7 +208,7 @@ RSpec.describe "bundle clean" do
G
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 "install"
diff --git a/spec/bundler/commands/config_spec.rb b/spec/bundler/commands/config_spec.rb
index fb7aa3cc67..6148b1c7ce 100644
--- a/spec/bundler/commands/config_spec.rb
+++ b/spec/bundler/commands/config_spec.rb
@@ -435,6 +435,34 @@ E
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
it "list" do
bundle "config list", :env => { "BUNDLE_FOO" => "bar" }
diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb
index f189a70b10..4a48187db0 100644
--- a/spec/bundler/commands/install_spec.rb
+++ b/spec/bundler/commands/install_spec.rb
@@ -755,12 +755,8 @@ RSpec.describe "bundle install with gem sources" do
end
expect(err).not_to include("ERROR REPORT TEMPLATE")
-
- expect(err).to include(
- "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}."
- )
+ expect(err).to include("Could not delete previous installation of `#{foo_path}`.")
+ expect(err).to include("The underlying error was Errno::EACCES")
end
end
@@ -973,4 +969,37 @@ RSpec.describe "bundle install with gem sources" do
expect(last_command).to be_success
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
diff --git a/spec/bundler/commands/remove_spec.rb b/spec/bundler/commands/remove_spec.rb
index 95d6e75e9f..ceba6c5ede 100644
--- a/spec/bundler/commands/remove_spec.rb
+++ b/spec/bundler/commands/remove_spec.rb
@@ -13,6 +13,36 @@ RSpec.describe "bundle remove" do
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
it "removes gems from .bundle" do
gemfile <<-G
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index 62cad6800f..89c812e5d5 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -1255,6 +1255,32 @@ RSpec.describe "bundle install with gems on multiple sources" do
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
build_repo2 do
build_gem "example", "0.1.0"
diff --git a/spec/bundler/install/gems/flex_spec.rb b/spec/bundler/install/gems/flex_spec.rb
index f9b374cf01..28ffaff3d5 100644
--- a/spec/bundler/install/gems/flex_spec.rb
+++ b/spec/bundler/install/gems/flex_spec.rb
@@ -156,7 +156,7 @@ RSpec.describe "bundle flex_install" do
end
end
- describe "when Gemfile conflicts with lockfile" do
+ describe "when running bundle install and Gemfile conflicts with lockfile" do
before(:each) do
build_repo2
install_gemfile <<-G
@@ -190,7 +190,7 @@ RSpec.describe "bundle flex_install" do
expect(err).to match(/could not find gem 'rack-obama/i)
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"
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 (= 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.
E
@@ -214,6 +214,67 @@ RSpec.describe "bundle flex_install" do
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
before :each do
install_gemfile <<-G
diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb
index 469ecd412f..f23d137bc1 100644
--- a/spec/bundler/install/gems/resolving_spec.rb
+++ b/spec/bundler/install/gems/resolving_spec.rb
@@ -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.")
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
build_repo4 do
build_gem "rack", "9001.0.0" do |s|
diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb
index 5cbb484c68..0bbd829148 100644
--- a/spec/bundler/install/gems/standalone_spec.rb
+++ b/spec/bundler/install/gems/standalone_spec.rb
@@ -147,9 +147,16 @@ RSpec.shared_examples "bundle install --standalone" do
bundle "lock", :dir => cwd, :artifice => "compact_index"
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 :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
diff --git a/spec/bundler/install/process_lock_spec.rb b/spec/bundler/install/process_lock_spec.rb
index dac0d34bc4..1f8c62f26e 100644
--- a/spec/bundler/install/process_lock_spec.rb
+++ b/spec/bundler/install/process_lock_spec.rb
@@ -31,5 +31,27 @@ RSpec.describe "process lock spec" do
expect(processed).to eq true
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
diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb
index 35873dcaa9..91f8aaf78a 100644
--- a/spec/bundler/runtime/setup_spec.rb
+++ b/spec/bundler/runtime/setup_spec.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require "tmpdir"
-require "tempfile"
RSpec.describe "Bundler.setup" do
describe "with no arguments" do
@@ -800,7 +799,7 @@ end
run <<~RUBY
puts ENV['MANPATH']
require "open3"
- puts Open3.capture2e("man", "ls")[0]
+ puts Open3.capture2e({ "LC_ALL" => "C" }, "man", "ls")[0]
RUBY
lines = out.split("\n")
@@ -861,19 +860,17 @@ end
context "with bundler is located in symlinked GEM_HOME" do
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}" }
before do
- skip "symlink destination exists" if Gem.win_platform?
-
- FileUtils.ln_sf(gem_home, symlinked_gem_home)
+ File.symlink(gem_home, symlinked_gem_home)
gems_dir = File.join(gem_home, "gems")
specifications_dir = File.join(gem_home, "specifications")
Dir.mkdir(gems_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).
sub("Bundler::VERSION", %("#{Bundler::VERSION}")).
diff --git a/spec/bundler/spec_helper.rb b/spec/bundler/spec_helper.rb
index dce2939e83..23db133b67 100644
--- a/spec/bundler/spec_helper.rb
+++ b/spec/bundler/spec_helper.rb
@@ -113,6 +113,10 @@ RSpec.configure do |config|
end
end
+ config.before :each, :sudo => true do
+ Spec::Sudo.write_safe_config
+ end
+
config.after :suite do
FileUtils.rm_r Spec::Path.pristine_system_gem_path
end
diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb
index aca31638ac..91f0106d7d 100644
--- a/spec/bundler/support/builders.rb
+++ b/spec/bundler/support/builders.rb
@@ -484,7 +484,7 @@ module Spec
end
@spec.authors = ["no one"]
- @spec.files = @files.keys
+ @spec.files += @files.keys
case options[:gemspec]
when false
@@ -589,7 +589,8 @@ module Spec
class GemBuilder < LibBuilder
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
FileUtils.mkdir_p(lib_path.join(destination))
diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb
index 41b36997b2..a39e46c78a 100644
--- a/spec/bundler/support/path.rb
+++ b/spec/bundler/support/path.rb
@@ -258,6 +258,10 @@ module Spec
end
end
+ def git_root
+ ruby_core? ? source_root : source_root.parent
+ end
+
private
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"
end
- def git_root
- ruby_core? ? source_root : source_root.parent
- end
-
def ruby_core_tarball?
!git_root.join(".git").directory?
end
diff --git a/spec/bundler/support/sudo.rb b/spec/bundler/support/sudo.rb
index 04e9443945..7b9b392754 100644
--- a/spec/bundler/support/sudo.rb
+++ b/spec/bundler/support/sudo.rb
@@ -6,6 +6,10 @@ module Spec
@which_sudo ||= Bundler.which("sudo")
end
+ def self.write_safe_config
+ File.write(Spec::Path.tmp("gitconfig"), "[safe]\n\tdirectory = #{Spec::Path.git_root}")
+ end
+
def sudo(cmd)
raise "sudo not present" unless Sudo.present?
sys_exec("sudo #{cmd}")
diff --git a/test/rubygems/data/null-type.gemspec.rz b/test/rubygems/data/null-type.gemspec.rz
index 2134fcde29..58fc1ed8a0 100644
--- a/test/rubygems/data/null-type.gemspec.rz
+++ b/test/rubygems/data/null-type.gemspec.rz
Binary files differ
diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb
index bee635d67e..00197d10f7 100644
--- a/test/rubygems/test_gem_command_manager.rb
+++ b/test/rubygems/test_gem_command_manager.rb
@@ -80,7 +80,13 @@ class TestGemCommandManager < Gem::TestCase
message << "\nDid you mean? \"push\""
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
def test_run_interrupt
diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb
index c765e9a8df..b5e9f004d1 100644
--- a/test/rubygems/test_gem_commands_update_command.rb
+++ b/test/rubygems/test_gem_commands_update_command.rb
@@ -191,6 +191,37 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
assert_empty out
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
spec_fetcher do |fetcher|
fetcher.download 'rubygems-update', 8 do |s|
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb
index 8b0477c4dd..ccb81caf37 100644
--- a/test/rubygems/test_gem_specification.rb
+++ b/test/rubygems/test_gem_specification.rb
@@ -1072,7 +1072,7 @@ dependencies: []
data = Marshal.load Gem::Util.inflate(Gem.read_binary(path))
- assert_nil data.signing_key
+ assert_instance_of Gem::Specification, data
end
def test_initialize
diff --git a/tool/bundler/dev_gems.rb.lock b/tool/bundler/dev_gems.rb.lock
index c467b988f6..fc48d3e05f 100644
--- a/tool/bundler/dev_gems.rb.lock
+++ b/tool/bundler/dev_gems.rb.lock
@@ -72,4 +72,4 @@ DEPENDENCIES
webrick (~> 1.6)
BUNDLED WITH
- 2.3.14
+ 2.3.15
diff --git a/tool/bundler/rubocop_gems.rb.lock b/tool/bundler/rubocop_gems.rb.lock
index 0e2e34793f..4027570ebb 100644
--- a/tool/bundler/rubocop_gems.rb.lock
+++ b/tool/bundler/rubocop_gems.rb.lock
@@ -60,4 +60,4 @@ DEPENDENCIES
test-unit
BUNDLED WITH
- 2.3.14
+ 2.3.15
diff --git a/tool/bundler/standard_gems.rb.lock b/tool/bundler/standard_gems.rb.lock
index fa8daf69de..b939fa05d6 100644
--- a/tool/bundler/standard_gems.rb.lock
+++ b/tool/bundler/standard_gems.rb.lock
@@ -66,4 +66,4 @@ DEPENDENCIES
test-unit
BUNDLED WITH
- 2.3.14
+ 2.3.15
diff --git a/tool/bundler/test_gems.rb.lock b/tool/bundler/test_gems.rb.lock
index 05f88ccd98..dab017efc8 100644
--- a/tool/bundler/test_gems.rb.lock
+++ b/tool/bundler/test_gems.rb.lock
@@ -41,4 +41,4 @@ DEPENDENCIES
webrick (= 1.7.0)
BUNDLED WITH
- 2.3.14
+ 2.3.15