mirror of
https://github.com/ruby/ruby.git
synced 2025-09-20 19:14:00 +02:00
Merge RubyGems-3.3.15 and Bundler-2.3.15
This commit is contained in:
parent
d7862a5de4
commit
b9f6a09bd2
40 changed files with 385 additions and 100 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -499,7 +499,7 @@ module Bundler
|
|||
end
|
||||
|
||||
def rubygems_dir
|
||||
Bundler.rubygems.gem_dir
|
||||
Bundler.bundle_path
|
||||
end
|
||||
|
||||
def default_cache_path_for(dir)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}")).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}")
|
||||
|
|
Binary file not shown.
|
@ -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
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -72,4 +72,4 @@ DEPENDENCIES
|
|||
webrick (~> 1.6)
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.14
|
||||
2.3.15
|
||||
|
|
|
@ -60,4 +60,4 @@ DEPENDENCIES
|
|||
test-unit
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.14
|
||||
2.3.15
|
||||
|
|
|
@ -66,4 +66,4 @@ DEPENDENCIES
|
|||
test-unit
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.14
|
||||
2.3.15
|
||||
|
|
|
@ -41,4 +41,4 @@ DEPENDENCIES
|
|||
webrick (= 1.7.0)
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.14
|
||||
2.3.15
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue