summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2021-08-02 12:06:43 +0900
committernagachika <nagachika@ruby-lang.org>2021-08-19 15:46:40 +0900
commit679185d6c87e0f2e4f6a5da5ce50d02c80ab31b1 (patch)
tree293fa8c1f863aeb2f711310dc4941528fa829401 /lib
parentf1039afa4179f9d3a42f0d89b499e3c955b495d9 (diff)
Merge RubyGems 3.2.24 and Bundler 2.2.24
Diffstat (limited to 'lib')
-rw-r--r--lib/bundler/cli.rb1
-rw-r--r--lib/bundler/definition.rb59
-rw-r--r--lib/bundler/dsl.rb51
-rw-r--r--lib/bundler/installer/standalone.rb2
-rw-r--r--lib/bundler/plugin.rb2
-rw-r--r--lib/bundler/plugin/index.rb5
-rw-r--r--lib/bundler/runtime.rb4
-rw-r--r--lib/bundler/spec_set.rb7
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/rubygems.rb2
-rw-r--r--lib/rubygems/gemcutter_utilities.rb3
-rw-r--r--lib/rubygems/uninstaller.rb41
12 files changed, 105 insertions, 74 deletions
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 45d4e62481..177f362070 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -14,6 +14,7 @@ module Bundler
COMMAND_ALIASES = {
"check" => "c",
"install" => "i",
+ "plugin" => "",
"list" => "ls",
"exec" => ["e", "ex", "exe"],
"cache" => ["package", "pack"],
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index e043b5c713..94b8bc4057 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -133,7 +133,7 @@ module Bundler
@unlock[:gems] ||= @dependencies.map(&:name)
else
eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
- @unlock[:gems] = @locked_specs.for(eager_unlock, [], false, false, false).map(&:name)
+ @unlock[:gems] = @locked_specs.for(eager_unlock, false, false, false).map(&:name)
end
@dependency_changes = converge_dependencies
@@ -185,25 +185,15 @@ module Bundler
#
# @return [Bundler::SpecSet]
def specs
- @specs ||= begin
- begin
- specs = resolve.materialize(requested_dependencies)
- rescue GemNotFound => e # Handle yanked gem
- gem_name, gem_version = extract_gem_info(e)
- locked_gem = @locked_specs[gem_name].last
- raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
- raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
- "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
- "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
- "removed in order to install."
- end
- unless specs["bundler"].any?
- bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
- specs["bundler"] = bundler
- end
-
- specs
- end
+ @specs ||= add_bundler_to(resolve.materialize(requested_dependencies))
+ rescue GemNotFound => e # Handle yanked gem
+ gem_name, gem_version = extract_gem_info(e)
+ locked_gem = @locked_specs[gem_name].last
+ raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
+ raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
+ "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
+ "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
+ "removed in order to install."
end
def new_specs
@@ -235,17 +225,11 @@ module Bundler
end
def requested_specs
- @requested_specs ||= begin
- groups = requested_groups
- groups.map!(&:to_sym)
- specs_for(groups)
- end
+ specs_for(requested_groups)
end
def requested_dependencies
- groups = requested_groups
- groups.map!(&:to_sym)
- dependencies_for(groups)
+ dependencies_for(requested_groups)
end
def current_dependencies
@@ -255,11 +239,13 @@ module Bundler
end
def specs_for(groups)
+ groups = requested_groups if groups.empty?
deps = dependencies_for(groups)
- SpecSet.new(specs.for(expand_dependencies(deps)))
+ add_bundler_to(resolve.materialize(expand_dependencies(deps)))
end
def dependencies_for(groups)
+ groups.map!(&:to_sym)
current_dependencies.reject do |d|
(d.groups & groups).empty?
end
@@ -507,6 +493,15 @@ module Bundler
private
+ def add_bundler_to(specs)
+ unless specs["bundler"].any?
+ bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
+ specs["bundler"] = bundler
+ end
+
+ specs
+ end
+
def precompute_source_requirements_for_indirect_dependencies?
sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
end
@@ -735,7 +730,7 @@ module Bundler
# if we won't need the source (according to the lockfile),
# don't error if the path/git source isn't available
next if @locked_specs.
- for(requested_dependencies, [], false, true, false).
+ for(requested_dependencies, false, true, false).
none? {|locked_spec| locked_spec.source == s.source }
raise
@@ -754,8 +749,8 @@ module Bundler
end
resolve = SpecSet.new(converged)
- @locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), @unlock[:gems], true, true)
- resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), [], false, false, false).reject{|s| @unlock[:gems].include?(s.name) })
+ @locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), true, true)
+ resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false, false).reject{|s| @unlock[:gems].include?(s.name) })
diff = nil
# Now, we unlock any sources that do not have anymore gems pinned to it
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 1605210e55..ac955894a7 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -102,38 +102,39 @@ module Bundler
# if there's already a dependency with this name we try to prefer one
if current = @dependencies.find {|d| d.name == dep.name }
deleted_dep = @dependencies.delete(current) if current.type == :development
- return if deleted_dep
- if current.requirement != dep.requirement
- return if dep.type == :development
+ unless deleted_dep
+ if current.requirement != dep.requirement
+ return if dep.type == :development
- update_prompt = ""
+ update_prompt = ""
- if File.basename(@gemfile) == Injector::INJECTED_GEMS
- if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
- update_prompt = ". Gem already added"
- else
- update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
+ if File.basename(@gemfile) == Injector::INJECTED_GEMS
+ if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
+ update_prompt = ". Gem already added"
+ else
+ update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
- update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
+ update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
+ end
end
- end
- 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}"
- 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
+ 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}"
+ 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"
+ 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/installer/standalone.rb b/lib/bundler/installer/standalone.rb
index 2a3f5cfe35..f16135cb48 100644
--- a/lib/bundler/installer/standalone.rb
+++ b/lib/bundler/installer/standalone.rb
@@ -3,7 +3,7 @@
module Bundler
class Standalone
def initialize(groups, definition)
- @specs = groups.empty? ? definition.requested_specs : definition.specs_for(groups.map(&:to_sym))
+ @specs = definition.specs_for(groups)
end
def generate
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
index 023c25b33e..bfe4fd7286 100644
--- a/lib/bundler/plugin.rb
+++ b/lib/bundler/plugin.rb
@@ -309,6 +309,8 @@ module Bundler
#
# @param [String] name of the plugin
def load_plugin(name)
+ return unless name && !name.empty?
+
# Need to ensure before this that plugin root where the rest of gems
# are installed to be on load path to support plugin deps. Currently not
# done to avoid conflicts
diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb
index 819bc60588..29d33be718 100644
--- a/lib/bundler/plugin/index.rb
+++ b/lib/bundler/plugin/index.rb
@@ -74,7 +74,10 @@ module Bundler
def unregister_plugin(name)
@commands.delete_if {|_, v| v == name }
@sources.delete_if {|_, v| v == name }
- @hooks.each {|_, plugin_names| plugin_names.delete(name) }
+ @hooks.each do |hook, names|
+ names.delete(name)
+ @hooks.delete(hook) if names.empty?
+ end
@plugin_paths.delete(name)
@load_paths.delete(name)
save_index
diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb
index e259b590bf..287fa1cfe9 100644
--- a/lib/bundler/runtime.rb
+++ b/lib/bundler/runtime.rb
@@ -12,12 +12,10 @@ module Bundler
def setup(*groups)
@definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?
- groups.map!(&:to_sym)
-
# Has to happen first
clean_load_path
- specs = groups.any? ? @definition.specs_for(groups) : requested_specs
+ specs = @definition.specs_for(groups)
SharedHelpers.set_bundle_environment
Bundler.rubygems.replace_entrypoints(specs)
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 2ab0386955..1a8906c47e 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -11,15 +11,14 @@ module Bundler
@specs = specs
end
- def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
+ def for(dependencies, check = false, match_current_platform = false, raise_on_missing = true)
handled = []
deps = dependencies.dup
specs = []
- skip += ["bundler"]
loop do
break unless dep = deps.shift
- next if handled.include?(dep) || skip.include?(dep.name)
+ next if handled.any?{|d| d.name == dep.name && (match_current_platform || d.__platform == dep.__platform) } || dep.name == "bundler"
handled << dep
@@ -73,7 +72,7 @@ module Bundler
end
def materialize(deps, missing_specs = nil)
- materialized = self.for(deps, [], false, true, !missing_specs)
+ materialized = self.for(deps, false, true, !missing_specs)
materialized.group_by(&:source).each do |source, specs|
next unless specs.any?{|s| s.is_a?(LazySpecification) }
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index f6851e35d3..c4f92994ff 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
- VERSION = "2.2.23".freeze
+ VERSION = "2.2.24".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 f369b0eb2c..2216e59d17 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
- VERSION = "3.2.23".freeze
+ VERSION = "3.2.24".freeze
end
# Must be first since it unloads the prelude from 1.9.2
diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb
index 00e68916c4..f465881041 100644
--- a/lib/rubygems/gemcutter_utilities.rb
+++ b/lib/rubygems/gemcutter_utilities.rb
@@ -31,7 +31,8 @@ module Gem::GemcutterUtilities
def add_otp_option
add_option('--otp CODE',
- 'Digit code for multifactor authentication') do |value, options|
+ 'Digit code for multifactor authentication',
+ 'You can also use the environment variable GEM_HOST_OTP_CODE') do |value, options|
options[:otp] = value
end
end
diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb
index 51ac3494f3..93e414b1c9 100644
--- a/lib/rubygems/uninstaller.rb
+++ b/lib/rubygems/uninstaller.rb
@@ -70,6 +70,9 @@ class Gem::Uninstaller
# only add user directory if install_dir is not set
@user_install = false
@user_install = options[:user_install] unless options[:install_dir]
+
+ # Optimization: populated during #uninstall
+ @default_specs_matching_uninstall_params = []
end
##
@@ -98,10 +101,8 @@ class Gem::Uninstaller
default_specs, list = list.partition do |spec|
spec.default_gem?
end
-
- default_specs.each do |default_spec|
- say "Gem #{default_spec.full_name} cannot be uninstalled because it is a default gem"
- end
+ warn_cannot_uninstall_default_gems(default_specs - list)
+ @default_specs_matching_uninstall_params = default_specs
list, other_repo_specs = list.partition do |spec|
@gem_home == spec.base_dir or
@@ -270,7 +271,7 @@ class Gem::Uninstaller
end
safe_delete { FileUtils.rm_r gemspec }
- say "Successfully uninstalled #{spec.full_name}"
+ announce_deletion_of(spec)
Gem::Specification.reset
end
@@ -373,4 +374,34 @@ class Gem::Uninstaller
raise e
end
+
+ private
+
+ def announce_deletion_of(spec)
+ name = spec.full_name
+ say "Successfully uninstalled #{name}"
+ if default_spec_matches?(spec)
+ say(
+ "There was both a regular copy and a default copy of #{name}. The " \
+ "regular copy was successfully uninstalled, but the default copy " \
+ "was left around because default gems can't be removed."
+ )
+ end
+ end
+
+ # @return true if the specs of any default gems are `==` to the given `spec`.
+ def default_spec_matches?(spec)
+ !default_specs_that_match(spec).empty?
+ end
+
+ # @return [Array] specs of default gems that are `==` to the given `spec`.
+ def default_specs_that_match(spec)
+ @default_specs_matching_uninstall_params.select {|default_spec| spec == default_spec }
+ end
+
+ def warn_cannot_uninstall_default_gems(specs)
+ specs.each do |spec|
+ say "Gem #{spec.full_name} cannot be uninstalled because it is a default gem"
+ end
+ end
end