summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2021-03-24 04:52:19 +0900
committerGitHub <noreply@github.com>2021-03-24 04:52:19 +0900
commit2efda212b0d9ad5ec265271db25ad51d796fde44 (patch)
treeb2667694205da0fd71dfa8dafc2655f6d464896e
parentff2ea4daeb795ebb3d0afa8c57d86a4af9757e50 (diff)
Merge RubyGems-3.2.15 and Bundler-2.2.15 (#4311)
-rw-r--r--lib/bundler/installer/parallel_installer.rb37
-rw-r--r--lib/bundler/lazy_specification.rb7
-rw-r--r--lib/bundler/source/path.rb4
-rw-r--r--lib/bundler/source/path/installer.rb2
-rw-r--r--lib/bundler/source_list.rb2
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/rubygems.rb2
-rw-r--r--lib/rubygems/commands/update_command.rb24
-rw-r--r--lib/rubygems/security/trust_dir.rb1
-rw-r--r--spec/bundler/bundler/installer/parallel_installer_spec.rb33
-rw-r--r--spec/bundler/bundler/installer/spec_installation_spec.rb4
-rw-r--r--spec/bundler/install/gemfile/path_spec.rb3
-rw-r--r--spec/bundler/lock/lockfile_spec.rb24
-rw-r--r--spec/bundler/runtime/platform_spec.rb38
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb29
15 files changed, 194 insertions, 18 deletions
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index c3bf5843b7..5b6680e5e1 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -6,10 +6,11 @@ require_relative "gem_installer"
module Bundler
class ParallelInstaller
class SpecInstallation
- attr_accessor :spec, :name, :post_install_message, :state, :error
+ attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error
def initialize(spec)
@spec = spec
@name = spec.name
+ @full_name = spec.full_name
@state = :none
@post_install_message = ""
@error = nil
@@ -49,14 +50,11 @@ module Bundler
# Represents only the non-development dependencies, the ones that are
# itself and are in the total list.
def dependencies
- @dependencies ||= begin
- all_dependencies.reject {|dep| ignorable_dependency? dep }
- end
+ @dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep }
end
def missing_lockfile_dependencies(all_spec_names)
- deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
- deps.reject {|dep| all_spec_names.include? dep.name }
+ dependencies.reject {|dep| all_spec_names.include? dep.name }
end
# Represents all dependencies
@@ -65,7 +63,7 @@ module Bundler
end
def to_s
- "#<#{self.class} #{@spec.full_name} (#{state})>"
+ "#<#{self.class} #{full_name} (#{state})>"
end
end
@@ -99,12 +97,37 @@ module Bundler
install_serially
end
+ check_for_unmet_dependencies
+
handle_error if failed_specs.any?
@specs
ensure
worker_pool && worker_pool.stop
end
+ def check_for_unmet_dependencies
+ unmet_dependencies = @specs.map do |s|
+ [
+ s,
+ s.dependencies.reject {|dep| @specs.any? {|spec| dep.matches_spec?(spec.spec) } },
+ ]
+ end.reject {|a| a.last.empty? }
+ return if unmet_dependencies.empty?
+
+ warning = []
+ warning << "Your lockfile doesn't include a valid resolution."
+ warning << "You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies."
+ warning << "The unmet dependencies are:"
+
+ unmet_dependencies.each do |spec, unmet_spec_dependencies|
+ unmet_spec_dependencies.each do |unmet_spec_dependency|
+ warning << "* #{unmet_spec_dependency}, depended upon #{spec.full_name}, unsatisfied by #{@specs.find {|s| s.name == unmet_spec_dependency.name && !unmet_spec_dependency.matches_spec?(s.spec) }.full_name}"
+ end
+ end
+
+ Bundler.ui.warn(warning.join("\n"))
+ end
+
def check_for_corrupt_lockfile
missing_dependencies = @specs.map do |s|
[
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index 04ba2a2364..7cd7e4254d 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -73,7 +73,12 @@ module Bundler
same_platform_candidates = candidates.select do |spec|
MatchPlatform.platforms_match?(spec.platform, platform_object)
end
- search = same_platform_candidates.last || candidates.last
+ installable_candidates = same_platform_candidates.select do |spec|
+ !spec.is_a?(RemoteSpecification) &&
+ spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
+ spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
+ end
+ search = installable_candidates.last || same_platform_candidates.last
search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
search
end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 2c2e9023b3..01f89b204d 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -82,7 +82,9 @@ module Bundler
end
def install(spec, options = {})
- print_using_message "Using #{version_message(spec)} from #{self}"
+ using_message = "Using #{version_message(spec)} from #{self}"
+ using_message += " and installing its executables" unless spec.executables.empty?
+ print_using_message using_message
generate_bin(spec, :disable_extensions => true)
nil # no post-install message
end
diff --git a/lib/bundler/source/path/installer.rb b/lib/bundler/source/path/installer.rb
index 72bfbb4836..a70973bde7 100644
--- a/lib/bundler/source/path/installer.rb
+++ b/lib/bundler/source/path/installer.rb
@@ -35,7 +35,7 @@ module Bundler
run_hooks(:post_build)
end
- generate_bin unless spec.executables.nil? || spec.executables.empty?
+ generate_bin unless spec.executables.empty?
run_hooks(:post_install)
ensure
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index 51698af46e..6f5636f41e 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -88,7 +88,7 @@ module Bundler
def lock_sources
lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
if disable_multisource?
- lock_sources + rubygems_sources.sort_by(&:to_s)
+ lock_sources + rubygems_sources.sort_by(&:to_s).uniq
else
lock_sources << combine_rubygems_sources
end
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index 5e71e22df8..5b6473c465 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
- VERSION = "2.2.14".freeze
+ VERSION = "2.2.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 682360264a..61a2d465a2 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
- VERSION = "3.2.14".freeze
+ VERSION = "3.2.15".freeze
end
# Must be first since it unloads the prelude from 1.9.2
diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb
index fcc52c293e..8d168d1cbd 100644
--- a/lib/rubygems/commands/update_command.rb
+++ b/lib/rubygems/commands/update_command.rb
@@ -76,7 +76,7 @@ command to remove old versions.
def check_oldest_rubygems(version) # :nodoc:
if oldest_supported_version > version
- alert_error "rubygems #{version} is not supported. The oldest supported version is #{oldest_supported_version}"
+ alert_error "rubygems #{version} is not supported on #{RUBY_VERSION}. The oldest version supported by this ruby is #{oldest_supported_version}"
terminate_interaction 1
end
end
@@ -322,8 +322,26 @@ command to remove old versions.
private
+ #
+ # Oldest version we support downgrading to. This is the version that
+ # originally ships with the first patch version of each ruby, because we never
+ # test each ruby against older rubygems, so we can't really guarantee it
+ # works. Version list can be checked here: https://stdgems.org/rubygems
+ #
def oldest_supported_version
- # for Ruby 2.3
- @oldest_supported_version ||= Gem::Version.new("2.5.2")
+ @oldest_supported_version ||=
+ if Gem.ruby_version > Gem::Version.new("3.0.a")
+ Gem::Version.new("3.2.3")
+ elsif Gem.ruby_version > Gem::Version.new("2.7.a")
+ Gem::Version.new("3.1.2")
+ elsif Gem.ruby_version > Gem::Version.new("2.6.a")
+ Gem::Version.new("3.0.1")
+ elsif Gem.ruby_version > Gem::Version.new("2.5.a")
+ Gem::Version.new("2.7.3")
+ elsif Gem.ruby_version > Gem::Version.new("2.4.a")
+ Gem::Version.new("2.6.8")
+ else
+ Gem::Version.new("2.5.2")
+ end
end
end
diff --git a/lib/rubygems/security/trust_dir.rb b/lib/rubygems/security/trust_dir.rb
index 1d93ceabd1..456947274c 100644
--- a/lib/rubygems/security/trust_dir.rb
+++ b/lib/rubygems/security/trust_dir.rb
@@ -104,6 +104,7 @@ class Gem::Security::TrustDir
# permissions.
def verify
+ require 'fileutils'
if File.exist? @dir
raise Gem::Security::Exception,
"trust directory #{@dir} is not a directory" unless
diff --git a/spec/bundler/bundler/installer/parallel_installer_spec.rb b/spec/bundler/bundler/installer/parallel_installer_spec.rb
index ace5c1a23a..e680633862 100644
--- a/spec/bundler/bundler/installer/parallel_installer_spec.rb
+++ b/spec/bundler/bundler/installer/parallel_installer_spec.rb
@@ -44,4 +44,37 @@ The missing gems are:
end
end
end
+
+ context "when the spec set is not a valid resolution" do
+ let(:all_specs) do
+ [
+ build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
+ build_spec("diff-lcs", "1.4.4"),
+ ].flatten
+ end
+
+ it "prints a warning" do
+ expect(Bundler.ui).to receive(:warn).with(<<-W.strip)
+Your lockfile doesn't include a valid resolution.
+You can fix this by regenerating your lockfile or trying to manually editing the bad locked gems to a version that satisfies all dependencies.
+The unmet dependencies are:
+* diff-lcs (< 1.4), depended upon cucumber-4.1.0, unsatisfied by diff-lcs-1.4.4
+ W
+ subject.check_for_unmet_dependencies
+ end
+ end
+
+ context "when the spec set is a valid resolution" do
+ let(:all_specs) do
+ [
+ build_spec("cucumber", "4.1.0") {|s| s.runtime "diff-lcs", "< 1.4" },
+ build_spec("diff-lcs", "1.3"),
+ ].flatten
+ end
+
+ it "doesn't print a warning" do
+ expect(Bundler.ui).not_to receive(:warn)
+ subject.check_for_unmet_dependencies
+ end
+ end
end
diff --git a/spec/bundler/bundler/installer/spec_installation_spec.rb b/spec/bundler/bundler/installer/spec_installation_spec.rb
index a9cf09a372..e63ef26cb3 100644
--- a/spec/bundler/bundler/installer/spec_installation_spec.rb
+++ b/spec/bundler/bundler/installer/spec_installation_spec.rb
@@ -8,6 +8,10 @@ RSpec.describe Bundler::ParallelInstaller::SpecInstallation do
def a_spec.name
"I like tests"
end
+
+ def a_spec.full_name
+ "I really like tests"
+ end
a_spec
end
diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb
index 7322d11892..e78217d369 100644
--- a/spec/bundler/install/gemfile/path_spec.rb
+++ b/spec/bundler/install/gemfile/path_spec.rb
@@ -328,11 +328,12 @@ RSpec.describe "bundle install with explicit source paths" do
s.executables = "foobar"
end
- install_gemfile <<-G
+ install_gemfile <<-G, :verbose => true
path "#{lib_path("foo-1.0")}" do
gem 'foo'
end
G
+ expect(out).to include("Using foo 1.0 from source at `#{lib_path("foo-1.0")}` and installing its executables")
expect(the_bundle).to include_gems "foo 1.0"
bundle "exec foobar"
diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb
index 639ccb87ea..7ef85ecf13 100644
--- a/spec/bundler/lock/lockfile_spec.rb
+++ b/spec/bundler/lock/lockfile_spec.rb
@@ -641,6 +641,30 @@ RSpec.describe "the lockfile format" do
G
end
+ it "removes redundant sources" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo2)}/"
+
+ gem "rack", :source => "#{file_uri_for(gem_repo2)}/"
+ G
+
+ lockfile_should_be <<-G
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ rack (1.0.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
it "lists gems alphabetically" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}/"
diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb
index 154d967e12..bec42e0f70 100644
--- a/spec/bundler/runtime/platform_spec.rb
+++ b/spec/bundler/runtime/platform_spec.rb
@@ -108,6 +108,44 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(lockfile).to eq(good_lockfile)
end
+ it "will not try to install platform specific gems when they don't match the current ruby if locked only to ruby" do
+ build_repo4 do
+ build_gem "nokogiri", "1.11.1"
+
+ build_gem "nokogiri", "1.11.1" do |s|
+ s.platform = Bundler.local_platform
+ s.required_ruby_version = "< #{Gem.ruby_version}"
+ end
+ end
+
+ gemfile <<-G
+ source "https://gems.repo4"
+ gem "nokogiri"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: https://gems.repo4/
+ specs:
+ nokogiri (1.11.1)
+
+ PLATFORMS
+ ruby
+
+ DEPENDENCIES
+ nokogiri
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+
+ expect(out).to include("Fetching nokogiri 1.11.1")
+ expect(the_bundle).to include_gems "nokogiri 1.11.1"
+ expect(the_bundle).not_to include_gems "nokogiri 1.11.1 #{Bundler.local_platform}"
+ end
+
it "will use the java platform if both generic java and generic ruby platforms are locked", :jruby do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb
index 749e9bee20..a06b19c790 100644
--- a/test/rubygems/test_gem_commands_update_command.rb
+++ b/test/rubygems/test_gem_commands_update_command.rb
@@ -168,6 +168,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
@cmd.options[:args] = []
@cmd.options[:system] = "2.5.1"
+ oldest_version_mod = Module.new do
+ def oldest_supported_version
+ Gem::Version.new("2.5.2")
+ end
+ private :oldest_supported_version
+ end
+
+ @cmd.extend(oldest_version_mod)
+
assert_raises Gem::MockGemUi::TermError do
use_ui @ui do
@cmd.execute
@@ -175,7 +184,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
assert_empty @ui.output
- assert_equal "ERROR: rubygems 2.5.1 is not supported. The oldest supported version is 2.5.2\n", @ui.error
+ assert_equal "ERROR: rubygems 2.5.1 is not supported on #{RUBY_VERSION}. The oldest version supported by this ruby is 2.5.2\n", @ui.error
end
def test_execute_system_specific_older_than_3_2_removes_plugins_dir
@@ -185,6 +194,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
end
+ oldest_version_mod = Module.new do
+ def oldest_supported_version
+ Gem::Version.new("2.5.2")
+ end
+ private :oldest_supported_version
+ end
+
+ @cmd.extend(oldest_version_mod)
+
@cmd.options[:args] = []
@cmd.options[:system] = "3.1"
@@ -203,6 +221,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
end
+ oldest_version_mod = Module.new do
+ def oldest_supported_version
+ Gem::Version.new("2.5.2")
+ end
+ private :oldest_supported_version
+ end
+
+ @cmd.extend(oldest_version_mod)
+
@cmd.options[:args] = []
@cmd.options[:system] = "3.2.a"