summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2022-08-25 10:50:40 +0900
committernagachika <nagachika@ruby-lang.org>2022-09-03 15:54:07 +0900
commita9bf13a4dfaed27e485a8a3f3fd9abcd9fd163b2 (patch)
treeaa84a270ff50bb09847124eee77f13287fa6ad8e /lib
parent522b75f1b666051f86a3c8961fd4255e560c5020 (diff)
Merge RubyGems-3.3.21 and Bundler-2.3.21
Diffstat (limited to 'lib')
-rw-r--r--lib/bundler.rb7
-rw-r--r--lib/bundler/cli/platform.rb2
-rw-r--r--lib/bundler/definition.rb49
-rw-r--r--lib/bundler/endpoint_specification.rb13
-rw-r--r--lib/bundler/gem_version_promoter.rb4
-rw-r--r--lib/bundler/incomplete_specification.rb12
-rw-r--r--lib/bundler/inline.rb2
-rw-r--r--lib/bundler/installer.rb17
-rw-r--r--lib/bundler/lazy_specification.rb6
-rw-r--r--lib/bundler/man/bundle-add.12
-rw-r--r--lib/bundler/man/bundle-binstubs.12
-rw-r--r--lib/bundler/man/bundle-cache.12
-rw-r--r--lib/bundler/man/bundle-check.12
-rw-r--r--lib/bundler/man/bundle-clean.12
-rw-r--r--lib/bundler/man/bundle-config.113
-rw-r--r--lib/bundler/man/bundle-config.1.ronn5
-rw-r--r--lib/bundler/man/bundle-doctor.12
-rw-r--r--lib/bundler/man/bundle-exec.12
-rw-r--r--lib/bundler/man/bundle-gem.12
-rw-r--r--lib/bundler/man/bundle-info.12
-rw-r--r--lib/bundler/man/bundle-init.12
-rw-r--r--lib/bundler/man/bundle-inject.12
-rw-r--r--lib/bundler/man/bundle-install.12
-rw-r--r--lib/bundler/man/bundle-list.12
-rw-r--r--lib/bundler/man/bundle-lock.12
-rw-r--r--lib/bundler/man/bundle-open.12
-rw-r--r--lib/bundler/man/bundle-outdated.12
-rw-r--r--lib/bundler/man/bundle-platform.12
-rw-r--r--lib/bundler/man/bundle-plugin.181
-rw-r--r--lib/bundler/man/bundle-plugin.1.ronn59
-rw-r--r--lib/bundler/man/bundle-pristine.12
-rw-r--r--lib/bundler/man/bundle-remove.12
-rw-r--r--lib/bundler/man/bundle-show.12
-rw-r--r--lib/bundler/man/bundle-update.12
-rw-r--r--lib/bundler/man/bundle-viz.12
-rw-r--r--lib/bundler/man/bundle.16
-rw-r--r--lib/bundler/man/bundle.1.ronn3
-rw-r--r--lib/bundler/man/gemfile.52
-rw-r--r--lib/bundler/man/index.txt1
-rw-r--r--lib/bundler/match_metadata.rb13
-rw-r--r--lib/bundler/match_remote_metadata.rb26
-rw-r--r--lib/bundler/plugin.rb2
-rw-r--r--lib/bundler/remote_specification.rb8
-rw-r--r--lib/bundler/resolver.rb56
-rw-r--r--lib/bundler/resolver/spec_group.rb19
-rw-r--r--lib/bundler/rubygems_ext.rb28
-rw-r--r--lib/bundler/spec_set.rb28
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/rubygems.rb2
-rw-r--r--lib/rubygems/platform.rb21
50 files changed, 389 insertions, 142 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 7df22ab3a5..24785ef5eb 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -53,13 +53,12 @@ module Bundler
autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__)
autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__)
autoload :Graph, File.expand_path("bundler/graph", __dir__)
- autoload :IncompleteSpecification, File.expand_path("bundler/incomplete_specification", __dir__)
autoload :Index, File.expand_path("bundler/index", __dir__)
autoload :Injector, File.expand_path("bundler/injector", __dir__)
autoload :Installer, File.expand_path("bundler/installer", __dir__)
autoload :LazySpecification, File.expand_path("bundler/lazy_specification", __dir__)
autoload :LockfileParser, File.expand_path("bundler/lockfile_parser", __dir__)
- autoload :MatchPlatform, File.expand_path("bundler/match_platform", __dir__)
+ autoload :MatchRemoteMetadata, File.expand_path("bundler/match_remote_metadata", __dir__)
autoload :ProcessLock, File.expand_path("bundler/process_lock", __dir__)
autoload :RemoteSpecification, File.expand_path("bundler/remote_specification", __dir__)
autoload :Resolver, File.expand_path("bundler/resolver", __dir__)
@@ -332,9 +331,9 @@ module Bundler
FileUtils.remove_entry_secure(path) if path && File.exist?(path)
rescue ArgumentError
message = <<EOF
-It is a security vulnerability to allow your home directory to be world-writable, and bundler can not continue.
+It is a security vulnerability to allow your home directory to be world-writable, and bundler cannot continue.
You should probably consider fixing this issue by running `chmod o-w ~` on *nix.
-Please refer to https://ruby-doc.org/stdlib-2.1.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure for details.
+Please refer to https://ruby-doc.org/stdlib-3.1.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure for details.
EOF
File.world_writable?(path) ? Bundler.ui.warn(message) : raise
raise PathError, "Please fix the world-writable issue with your #{path} directory"
diff --git a/lib/bundler/cli/platform.rb b/lib/bundler/cli/platform.rb
index 16d4e0145a..73da8cf80e 100644
--- a/lib/bundler/cli/platform.rb
+++ b/lib/bundler/cli/platform.rb
@@ -9,7 +9,7 @@ module Bundler
def run
platforms, ruby_version = Bundler.ui.silence do
- locked_ruby_version = Bundler.locked_gems && Bundler.locked_gems.ruby_version.gsub(/p\d+\Z/, "")
+ locked_ruby_version = Bundler.locked_gems && Bundler.locked_gems.ruby_version&.gsub(/p\d+\Z/, "")
gemfile_ruby_version = Bundler.definition.ruby_version && Bundler.definition.ruby_version.single_version_string
[Bundler.definition.platforms.map {|p| "* #{p}" },
locked_ruby_version || gemfile_ruby_version]
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 21c06e55ba..66efd82b53 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -145,8 +145,6 @@ module Bundler
@dependency_changes = converge_dependencies
@local_changes = converge_locals
- @reresolve = nil
-
@requires = compute_requires
end
@@ -218,6 +216,7 @@ module Bundler
true
rescue BundlerError => e
@resolve = nil
+ @resolver = nil
@specs = nil
@gem_version_promoter = nil
@@ -288,7 +287,7 @@ module Bundler
end
else
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
- @reresolve = reresolve
+ resolver.start(expanded_dependencies)
end
end
@@ -482,11 +481,18 @@ module Bundler
private
- def reresolve
- last_resolve = converge_locked_specs
- remove_ruby_from_platforms_if_necessary!(dependencies)
- expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true)
- Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
+ def resolver
+ @resolver ||= begin
+ last_resolve = converge_locked_specs
+ Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
+ end
+ end
+
+ def expanded_dependencies
+ @expanded_dependencies ||= begin
+ remove_ruby_from_platforms_if_necessary!(dependencies)
+ expand_dependencies(dependencies + metadata_dependencies, true)
+ end
end
def filter_specs(specs, deps)
@@ -514,15 +520,13 @@ module Bundler
raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
end
- if @reresolve.nil?
+ loop do
incomplete_specs = specs.incomplete_specs
+ break if incomplete_specs.empty?
- if incomplete_specs.any?
- Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
- @unlock[:gems].concat(incomplete_specs.map(&:name))
- @resolve = reresolve
- specs = resolve.materialize(dependencies)
- end
+ Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
+ @resolve = resolver.start(expanded_dependencies, :exclude_specs => incomplete_specs)
+ specs = resolve.materialize(dependencies)
end
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
@@ -715,7 +719,9 @@ module Bundler
# commonly happen if the Gemfile has changed since the lockfile was last
# generated
def converge_locked_specs
- resolve = converge_specs(@locked_specs)
+ converged = converge_specs(@locked_specs)
+
+ resolve = SpecSet.new(converged.reject {|s| @unlock[:gems].include?(s.name) })
diff = nil
@@ -788,7 +794,7 @@ module Bundler
end
end
- SpecSet.new(filter_specs(converged, deps).reject {|s| @unlock[:gems].include?(s.name) })
+ filter_specs(converged, deps)
end
def metadata_dependencies
@@ -877,10 +883,8 @@ module Bundler
def additional_base_requirements_for_resolve
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
converge_specs(@originally_locked_specs).map do |locked_spec|
- name = locked_spec.name
- dep = Dependency.new(name, ">= #{locked_spec.version}")
- DepProxy.get_proxy(dep, locked_spec.platform)
- end
+ Dependency.new(locked_spec.name, ">= #{locked_spec.version}")
+ end.uniq
end
def remove_ruby_from_platforms_if_necessary!(dependencies)
@@ -888,10 +892,11 @@ module Bundler
Bundler.local_platform == Gem::Platform::RUBY ||
!platforms.include?(Gem::Platform::RUBY) ||
(@new_platform && platforms.last == Gem::Platform::RUBY) ||
- !@originally_locked_specs.incomplete_ruby_specs?(dependencies)
+ !@originally_locked_specs.incomplete_ruby_specs?(expand_dependencies(dependencies))
remove_platform(Gem::Platform::RUBY)
add_current_platform
+ resolver.platforms = @platforms
end
def source_map
diff --git a/lib/bundler/endpoint_specification.rb b/lib/bundler/endpoint_specification.rb
index e9aa366b41..ea197328ba 100644
--- a/lib/bundler/endpoint_specification.rb
+++ b/lib/bundler/endpoint_specification.rb
@@ -3,7 +3,7 @@
module Bundler
# used for Creating Specifications from the Gemcutter Endpoint
class EndpointSpecification < Gem::Specification
- include MatchPlatform
+ include MatchRemoteMetadata
attr_reader :name, :version, :platform, :checksum
attr_accessor :source, :remote, :dependencies
@@ -22,17 +22,6 @@ module Bundler
parse_metadata(metadata)
end
- def required_ruby_version
- @required_ruby_version ||= _remote_specification.required_ruby_version
- end
-
- # A fallback is included because the original version of the specification
- # API didn't include that field, so some marshalled specs in the index have it
- # set to +nil+.
- def required_rubygems_version
- @required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default
- end
-
def fetch_platform
@platform
end
diff --git a/lib/bundler/gem_version_promoter.rb b/lib/bundler/gem_version_promoter.rb
index 3cce3f2139..ddf7446dd2 100644
--- a/lib/bundler/gem_version_promoter.rb
+++ b/lib/bundler/gem_version_promoter.rb
@@ -88,6 +88,10 @@ module Bundler
end
end
+ def reset
+ @sort_versions = {}
+ end
+
# @return [bool] Convenience method for testing value of level variable.
def major?
level == :major
diff --git a/lib/bundler/incomplete_specification.rb b/lib/bundler/incomplete_specification.rb
deleted file mode 100644
index 6d0b9b901c..0000000000
--- a/lib/bundler/incomplete_specification.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class IncompleteSpecification
- attr_reader :name, :platform
-
- def initialize(name, platform)
- @name = name
- @platform = platform
- end
- end
-end
diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb
index 8ef580f1f0..25e055fbe4 100644
--- a/lib/bundler/inline.rb
+++ b/lib/bundler/inline.rb
@@ -54,7 +54,7 @@ def gemfile(install = false, options = {}, &gemfile)
Bundler.ui = install ? ui : Bundler::UI::Silent.new
if install || definition.missing_specs?
- Bundler.settings.temporary(:inline => true) do
+ Bundler.settings.temporary(:inline => true, :no_install => false) do
installer = Bundler::Installer.install(Bundler.root, definition, :system => true)
installer.post_install_messages.each do |name, message|
Bundler.ui.info "Post-install message from #{name}:\n#{message}"
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index b7b0e36dfd..1b17de5d4e 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -238,19 +238,14 @@ module Bundler
end
def ensure_specs_are_compatible!
- system_ruby = Bundler::RubyVersion.system
- rubygems_version = Bundler.rubygems.version
@definition.specs.each do |spec|
- if required_ruby_version = spec.required_ruby_version
- unless required_ruby_version.satisfied_by?(system_ruby.gem_version)
- raise InstallError, "#{spec.full_name} requires ruby version #{required_ruby_version}, " \
- "which is incompatible with the current version, #{system_ruby}"
- end
+ unless spec.matches_current_ruby?
+ raise InstallError, "#{spec.full_name} requires ruby version #{spec.required_ruby_version}, " \
+ "which is incompatible with the current version, #{Gem.ruby_version}"
end
- next unless required_rubygems_version = spec.required_rubygems_version
- unless required_rubygems_version.satisfied_by?(rubygems_version)
- raise InstallError, "#{spec.full_name} requires rubygems version #{required_rubygems_version}, " \
- "which is incompatible with the current version, #{rubygems_version}"
+ unless spec.matches_current_rubygems?
+ raise InstallError, "#{spec.full_name} requires rubygems version #{spec.required_rubygems_version}, " \
+ "which is incompatible with the current version, #{Gem.rubygems_version}"
end
end
end
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index 5b40bec5a8..ec141cfa27 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require_relative "match_platform"
-
module Bundler
class LazySpecification
include MatchPlatform
@@ -97,8 +95,8 @@ module Bundler
@specification = begin
search = candidates.reverse.find do |spec|
spec.is_a?(StubSpecification) ||
- (spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
- spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version))
+ (spec.matches_current_ruby? &&
+ spec.matches_current_rubygems?)
end
if search.nil? && Bundler.frozen_bundle?
search = candidates.last
diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1
index 20430a78a0..f6e5004b5b 100644
--- a/lib/bundler/man/bundle-add.1
+++ b/lib/bundler/man/bundle-add.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-ADD" "1" "July 2022" "" ""
+.TH "BUNDLE\-ADD" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1
index 9c57c7c9c5..d1204104b1 100644
--- a/lib/bundler/man/bundle-binstubs.1
+++ b/lib/bundler/man/bundle-binstubs.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-BINSTUBS" "1" "July 2022" "" ""
+.TH "BUNDLE\-BINSTUBS" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1
index fdaaa3b92a..1393caec65 100644
--- a/lib/bundler/man/bundle-cache.1
+++ b/lib/bundler/man/bundle-cache.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CACHE" "1" "July 2022" "" ""
+.TH "BUNDLE\-CACHE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1
index 5be7886274..71ddb5cee3 100644
--- a/lib/bundler/man/bundle-check.1
+++ b/lib/bundler/man/bundle-check.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CHECK" "1" "July 2022" "" ""
+.TH "BUNDLE\-CHECK" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1
index 2bb95ed2de..e5dc4ccf92 100644
--- a/lib/bundler/man/bundle-clean.1
+++ b/lib/bundler/man/bundle-clean.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CLEAN" "1" "July 2022" "" ""
+.TH "BUNDLE\-CLEAN" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1
index 9f7887ca91..ffc91ed492 100644
--- a/lib/bundler/man/bundle-config.1
+++ b/lib/bundler/man/bundle-config.1
@@ -1,13 +1,22 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CONFIG" "1" "July 2022" "" ""
+.TH "BUNDLE\-CONFIG" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options
.
.SH "SYNOPSIS"
-\fBbundle config\fR [list|get|set|unset] [\fIname\fR [\fIvalue\fR]]
+\fBbundle config\fR list
+.
+.br
+\fBbundle config\fR [get] NAME
+.
+.br
+\fBbundle config\fR [set] NAME VALUE
+.
+.br
+\fBbundle config\fR unset NAME
.
.SH "DESCRIPTION"
This command allows you to interact with Bundler\'s configuration system\.
diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn
index 905c85fcd9..6f9edc9c39 100644
--- a/lib/bundler/man/bundle-config.1.ronn
+++ b/lib/bundler/man/bundle-config.1.ronn
@@ -3,7 +3,10 @@ bundle-config(1) -- Set bundler configuration options
## SYNOPSIS
-`bundle config` [list|get|set|unset] [<name> [<value>]]
+`bundle config` list<br>
+`bundle config` [get] NAME<br>
+`bundle config` [set] NAME VALUE<br>
+`bundle config` unset NAME
## DESCRIPTION
diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1
index 6aad9858db..3f18aaf569 100644
--- a/lib/bundler/man/bundle-doctor.1
+++ b/lib/bundler/man/bundle-doctor.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-DOCTOR" "1" "July 2022" "" ""
+.TH "BUNDLE\-DOCTOR" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems
diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1
index 210dd178e8..7f6a892f6c 100644
--- a/lib/bundler/man/bundle-exec.1
+++ b/lib/bundler/man/bundle-exec.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-EXEC" "1" "July 2022" "" ""
+.TH "BUNDLE\-EXEC" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1
index 0fb6f7d0ab..63d611bdd2 100644
--- a/lib/bundler/man/bundle-gem.1
+++ b/lib/bundler/man/bundle-gem.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-GEM" "1" "July 2022" "" ""
+.TH "BUNDLE\-GEM" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1
index d3bad843b8..ae9bc48539 100644
--- a/lib/bundler/man/bundle-info.1
+++ b/lib/bundler/man/bundle-info.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INFO" "1" "July 2022" "" ""
+.TH "BUNDLE\-INFO" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle
diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1
index 0b3abfeefc..0b06ce8997 100644
--- a/lib/bundler/man/bundle-init.1
+++ b/lib/bundler/man/bundle-init.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INIT" "1" "July 2022" "" ""
+.TH "BUNDLE\-INIT" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1
index 53f2eaae0a..4ad37ec3eb 100644
--- a/lib/bundler/man/bundle-inject.1
+++ b/lib/bundler/man/bundle-inject.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INJECT" "1" "July 2022" "" ""
+.TH "BUNDLE\-INJECT" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile
diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1
index 8e94fe2437..f219a062b1 100644
--- a/lib/bundler/man/bundle-install.1
+++ b/lib/bundler/man/bundle-install.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INSTALL" "1" "July 2022" "" ""
+.TH "BUNDLE\-INSTALL" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1
index 3a9cc9a237..6e89f810a1 100644
--- a/lib/bundler/man/bundle-list.1
+++ b/lib/bundler/man/bundle-list.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-LIST" "1" "July 2022" "" ""
+.TH "BUNDLE\-LIST" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle
diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1
index ac03c5478e..f5f0ce2bdb 100644
--- a/lib/bundler/man/bundle-lock.1
+++ b/lib/bundler/man/bundle-lock.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-LOCK" "1" "July 2022" "" ""
+.TH "BUNDLE\-LOCK" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1
index be6c5af248..7bda0afd33 100644
--- a/lib/bundler/man/bundle-open.1
+++ b/lib/bundler/man/bundle-open.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-OPEN" "1" "July 2022" "" ""
+.TH "BUNDLE\-OPEN" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1
index fc3d5e8caf..a2b8e2bf92 100644
--- a/lib/bundler/man/bundle-outdated.1
+++ b/lib/bundler/man/bundle-outdated.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-OUTDATED" "1" "July 2022" "" ""
+.TH "BUNDLE\-OUTDATED" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available
diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1
index f5a90c59e9..7fda4ef046 100644
--- a/lib/bundler/man/bundle-platform.1
+++ b/lib/bundler/man/bundle-platform.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PLATFORM" "1" "July 2022" "" ""
+.TH "BUNDLE\-PLATFORM" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information
diff --git a/lib/bundler/man/bundle-plugin.1 b/lib/bundler/man/bundle-plugin.1
new file mode 100644
index 0000000000..7210806327
--- /dev/null
+++ b/lib/bundler/man/bundle-plugin.1
@@ -0,0 +1,81 @@
+.\" generated with Ronn/v0.7.3
+.\" http://github.com/rtomayko/ronn/tree/0.7.3
+.
+.TH "BUNDLE\-PLUGIN" "1" "August 2022" "" ""
+.
+.SH "NAME"
+\fBbundle\-plugin\fR \- Manage Bundler plugins
+.
+.SH "SYNOPSIS"
+\fBbundle plugin\fR install PLUGINS [\-\-source=\fISOURCE\fR] [\-\-version=\fIversion\fR] [\-\-git|\-\-local_git=\fIgit\-url\fR] [\-\-branch=\fIbranch\fR|\-\-ref=\fIrev\fR]
+.
+.br
+\fBbundle plugin\fR uninstall PLUGINS
+.
+.br
+\fBbundle plugin\fR list
+.
+.br
+\fBbundle plugin\fR help [COMMAND]
+.
+.SH "DESCRIPTION"
+You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler\.
+.
+.SH "SUB\-COMMANDS"
+.
+.SS "install"
+Install the given plugin(s)\.
+.
+.IP "\(bu" 4
+\fBbundle plugin install bundler\-graph\fR: Install bundler\-graph gem from RubyGems\.org\. The global source, specified in source in Gemfile is ignored\.
+.
+.IP "\(bu" 4
+\fBbundle plugin install bundler\-graph \-\-source https://example\.com\fR: Install bundler\-graph gem from example\.com\. The global source, specified in source in Gemfile is not considered\.
+.
+.IP "\(bu" 4
+\fBbundle plugin install bundler\-graph \-\-version 0\.2\.1\fR: You can specify the version of the gem via \fB\-\-version\fR\.
+.
+.IP "\(bu" 4
+\fBbundle plugin install bundler\-graph \-\-git https://github\.com/rubygems/bundler\-graph\fR: Install bundler\-graph gem from Git repository\. \fB\-\-git\fR can be replaced with \fB\-\-local\-git\fR\. You cannot use both \fB\-\-git\fR and \fB\-\-local\-git\fR\. You can use standard Git URLs like:
+.
+.IP "\(bu" 4
+\fBssh://[user@]host\.xz[:port]/path/to/repo\.git\fR
+.
+.IP "\(bu" 4
+\fBhttp[s]://host\.xz[:port]/path/to/repo\.git\fR
+.
+.IP "\(bu" 4
+\fB/path/to/repo\fR
+.
+.IP "\(bu" 4
+\fBfile:///path/to/repo\fR
+.
+.IP "" 0
+.
+.IP
+When you specify \fB\-\-git\fR/\fB\-\-local\-git\fR, you can use \fB\-\-branch\fR or \fB\-\-ref\fR to specify any branch, tag, or commit hash (revision) to use\. When you specify both, only the latter is used\.
+.
+.IP "" 0
+.
+.SS "uninstall"
+Uninstall the plugin(s) specified in PLUGINS\.
+.
+.SS "list"
+List the installed plugins and available commands\.
+.
+.P
+No options\.
+.
+.SS "help"
+Describe subcommands or one specific subcommand\.
+.
+.P
+No options\.
+.
+.SH "SEE ALSO"
+.
+.IP "\(bu" 4
+How to write a Bundler plugin \fIhttps://bundler\.io/guides/bundler_plugins\.html\fR
+.
+.IP "" 0
+
diff --git a/lib/bundler/man/bundle-plugin.1.ronn b/lib/bundler/man/bundle-plugin.1.ronn
new file mode 100644
index 0000000000..4f234eeba7
--- /dev/null
+++ b/lib/bundler/man/bundle-plugin.1.ronn
@@ -0,0 +1,59 @@
+bundle-plugin(1) -- Manage Bundler plugins
+==========================================
+
+## SYNOPSIS
+
+`bundle plugin` install PLUGINS [--source=<SOURCE>] [--version=<version>]
+ [--git|--local_git=<git-url>] [--branch=<branch>|--ref=<rev>]<br>
+`bundle plugin` uninstall PLUGINS<br>
+`bundle plugin` list<br>
+`bundle plugin` help [COMMAND]
+
+## DESCRIPTION
+
+You can install, uninstall, and list plugin(s) with this command to extend functionalities of Bundler.
+
+## SUB-COMMANDS
+
+### install
+
+Install the given plugin(s).
+
+* `bundle plugin install bundler-graph`:
+ Install bundler-graph gem from RubyGems.org. The global source, specified in source in Gemfile is ignored.
+
+* `bundle plugin install bundler-graph --source https://example.com`:
+ Install bundler-graph gem from example.com. The global source, specified in source in Gemfile is not considered.
+
+* `bundle plugin install bundler-graph --version 0.2.1`:
+ You can specify the version of the gem via `--version`.
+
+* `bundle plugin install bundler-graph --git https://github.com/rubygems/bundler-graph`:
+ Install bundler-graph gem from Git repository. `--git` can be replaced with `--local-git`. You cannot use both `--git` and `--local-git`. You can use standard Git URLs like:
+
+ * `ssh://[user@]host.xz[:port]/path/to/repo.git`
+ * `http[s]://host.xz[:port]/path/to/repo.git`
+ * `/path/to/repo`
+ * `file:///path/to/repo`
+
+ When you specify `--git`/`--local-git`, you can use `--branch` or `--ref` to specify any branch, tag, or commit hash (revision) to use. When you specify both, only the latter is used.
+
+### uninstall
+
+Uninstall the plugin(s) specified in PLUGINS.
+
+### list
+
+List the installed plugins and available commands.
+
+No options.
+
+### help
+
+Describe subcommands or one specific subcommand.
+
+No options.
+
+## SEE ALSO
+
+* [How to write a Bundler plugin](https://bundler.io/guides/bundler_plugins.html)
diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1
index 44e5a83a01..d635d24e2d 100644
--- a/lib/bundler/man/bundle-pristine.1
+++ b/lib/bundler/man/bundle-pristine.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PRISTINE" "1" "July 2022" "" ""
+.TH "BUNDLE\-PRISTINE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1
index 29ec246018..4952e8094e 100644
--- a/lib/bundler/man/bundle-remove.1
+++ b/lib/bundler/man/bundle-remove.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-REMOVE" "1" "July 2022" "" ""
+.TH "BUNDLE\-REMOVE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile
diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1
index 227b1c8a1e..72ef3283cc 100644
--- a/lib/bundler/man/bundle-show.1
+++ b/lib/bundler/man/bundle-show.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-SHOW" "1" "July 2022" "" ""
+.TH "BUNDLE\-SHOW" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1
index 7d0988bfa5..06ceef85db 100644
--- a/lib/bundler/man/bundle-update.1
+++ b/lib/bundler/man/bundle-update.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-UPDATE" "1" "July 2022" "" ""
+.TH "BUNDLE\-UPDATE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions
diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1
index f6f51cde0e..cf63dd8f9e 100644
--- a/lib/bundler/man/bundle-viz.1
+++ b/lib/bundler/man/bundle-viz.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-VIZ" "1" "July 2022" "" ""
+.TH "BUNDLE\-VIZ" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1
index f683e78cc6..22e102e053 100644
--- a/lib/bundler/man/bundle.1
+++ b/lib/bundler/man/bundle.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE" "1" "July 2022" "" ""
+.TH "BUNDLE" "1" "August 2022" "" ""
.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management
@@ -120,6 +120,10 @@ Display warnings about common problems
\fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR
Removes gems from the Gemfile
.
+.TP
+\fBbundle plugin(1)\fR \fIbundle\-plugin\.1\.html\fR
+Manage Bundler plugins
+.
.SH "PLUGINS"
When running a command that isn\'t listed in PRIMARY COMMANDS or UTILITIES, Bundler will try to find an executable on your path named \fBbundler\-<command>\fR and execute it, passing down any extra arguments to it\.
.
diff --git a/lib/bundler/man/bundle.1.ronn b/lib/bundler/man/bundle.1.ronn
index 8f0159eee5..94106b183c 100644
--- a/lib/bundler/man/bundle.1.ronn
+++ b/lib/bundler/man/bundle.1.ronn
@@ -97,6 +97,9 @@ We divide `bundle` subcommands into primary commands and utilities:
* [`bundle remove(1)`](bundle-remove.1.html):
Removes gems from the Gemfile
+* [`bundle plugin(1)`](bundle-plugin.1.html):
+ Manage Bundler plugins
+
## PLUGINS
When running a command that isn't listed in PRIMARY COMMANDS or UTILITIES,
diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5
index 63a16ca3ff..3d3994153b 100644
--- a/lib/bundler/man/gemfile.5
+++ b/lib/bundler/man/gemfile.5
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "GEMFILE" "5" "July 2022" "" ""
+.TH "GEMFILE" "5" "August 2022" "" ""
.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
diff --git a/lib/bundler/man/index.txt b/lib/bundler/man/index.txt
index ef2956b2f9..b895aa537d 100644
--- a/lib/bundler/man/index.txt
+++ b/lib/bundler/man/index.txt
@@ -18,6 +18,7 @@ bundle-lock(1) bundle-lock.1
bundle-open(1) bundle-open.1
bundle-outdated(1) bundle-outdated.1
bundle-platform(1) bundle-platform.1
+bundle-plugin(1) bundle-plugin.1
bundle-pristine(1) bundle-pristine.1
bundle-remove(1) bundle-remove.1
bundle-show(1) bundle-show.1
diff --git a/lib/bundler/match_metadata.rb b/lib/bundler/match_metadata.rb
new file mode 100644
index 0000000000..499036ca93
--- /dev/null
+++ b/lib/bundler/match_metadata.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Bundler
+ module MatchMetadata
+ def matches_current_ruby?
+ @required_ruby_version.satisfied_by?(Gem.ruby_version)
+ end
+
+ def matches_current_rubygems?
+ @required_rubygems_version.satisfied_by?(Gem.rubygems_version)
+ end
+ end
+end
diff --git a/lib/bundler/match_remote_metadata.rb b/lib/bundler/match_remote_metadata.rb
new file mode 100644
index 0000000000..e1b2f4d0e2
--- /dev/null
+++ b/lib/bundler/match_remote_metadata.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Bundler
+ module FetchMetadata
+ def matches_current_ruby?
+ @required_ruby_version ||= _remote_specification.required_ruby_version
+
+ super
+ end
+
+ def matches_current_rubygems?
+ # A fallback is included because the original version of the specification
+ # API didn't include that field, so some marshalled specs in the index have it
+ # set to +nil+.
+ @required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default
+
+ super
+ end
+ end
+
+ module MatchRemoteMetadata
+ include MatchMetadata
+
+ prepend FetchMetadata
+ end
+end
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
index 158c69e1a1..26458bd596 100644
--- a/lib/bundler/plugin.rb
+++ b/lib/bundler/plugin.rb
@@ -36,6 +36,8 @@ module Bundler
# @param [Hash] options various parameters as described in description.
# Refer to cli/plugin for available options
def install(names, options)
+ raise InvalidOption, "You cannot specify `--branch` and `--ref` at the same time." if options["branch"] && options["ref"]
+
specs = Installer.new.install(names, options)
save_plugins names, specs
diff --git a/lib/bundler/remote_specification.rb b/lib/bundler/remote_specification.rb
index b5d7e3a6c9..601957746f 100644
--- a/lib/bundler/remote_specification.rb
+++ b/lib/bundler/remote_specification.rb
@@ -6,6 +6,7 @@ module Bundler
# be seeded with what we're given from the source's abbreviated index - the
# full specification will only be fetched when necessary.
class RemoteSpecification
+ include MatchRemoteMetadata
include MatchPlatform
include Comparable
@@ -28,13 +29,6 @@ module Bundler
@platform = _remote_specification.platform
end
- # A fallback is included because the original version of the specification
- # API didn't include that field, so some marshalled specs in the index have it
- # set to +nil+.
- def required_rubygems_version
- @required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default
- end
-
def full_name
if @original_platform == Gem::Platform::RUBY
"#{@name}-#{@version}"
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index ca1bdbda7b..e382319112 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -7,6 +7,8 @@ module Bundler
include GemHelpers
+ attr_writer :platforms
+
# Figures out the best possible configuration of gems that satisfies
# the list of passed dependencies and any child dependencies without
# causing any gem activation errors.
@@ -19,41 +21,48 @@ 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)
- 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(regular_requirements, false, platforms))
+ resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
+ resolver.start(requirements)
end
- def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements)
+ def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
@source_requirements = source_requirements
- @metadata_requirements = metadata_requirements
@base = base
@resolver = Molinillo::Resolver.new(self, self)
+ @results_for = {}
@search_for = {}
- @base_dg = Molinillo::DependencyGraph.new
- base.each do |ls|
- dep = Dependency.new(ls.name, ls.version)
- @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
- end
- additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
- @platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } }
+ @additional_base_requirements = additional_base_requirements
+ @platforms = platforms
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
@gem_version_promoter = gem_version_promoter
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
end
- def start(requirements)
+ def start(requirements, exclude_specs: [])
+ @metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") }
+
+ exclude_specs.each do |spec|
+ remove_from_candidates(spec)
+ end
+
+ @base_dg = Molinillo::DependencyGraph.new
+ @base.each do |ls|
+ dep = Dependency.new(ls.name, ls.version)
+ @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
+ end
+ @additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
+
@gem_version_promoter.prerelease_specified = @prerelease_specified = {}
requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
verify_gemfile_dependencies_are_found!(requirements)
- dg = @resolver.resolve(requirements, @base_dg)
- dg.
+ result = @resolver.resolve(requirements, @base_dg).
map(&:payload).
reject {|sg| sg.name.end_with?("\0") }.
map(&:to_specs).
flatten
+
+ SpecSet.new(SpecSet.new(result).for(regular_requirements, false, @platforms))
rescue Molinillo::VersionConflict => e
message = version_conflict_message(e)
raise VersionConflict.new(e.conflicts.keys.uniq, message)
@@ -177,7 +186,7 @@ module Bundler
end
def results_for(dependency)
- index_for(dependency).search(dependency)
+ @results_for[dependency] ||= index_for(dependency).search(dependency)
end
def name_for(dependency)
@@ -228,6 +237,19 @@ module Bundler
private
+ def remove_from_candidates(spec)
+ @base.delete(spec)
+ @gem_version_promoter.reset
+
+ @results_for.keys.each do |dep|
+ next unless dep.name == spec.name
+
+ @results_for[dep].reject {|s| s.name == spec.name && s.version == spec.version }
+ end
+
+ @search_for = {}
+ end
+
# returns an integer \in (-\infty, 0]
# a number closer to 0 means the dependency is less constraining
#
diff --git a/lib/bundler/resolver/spec_group.rb b/lib/bundler/resolver/spec_group.rb
index 4de5b91aa6..4e5b0082d3 100644
--- a/lib/bundler/resolver/spec_group.rb
+++ b/lib/bundler/resolver/spec_group.rb
@@ -97,14 +97,17 @@ module Bundler
def metadata_dependencies(platform)
spec = @specs[platform].first
return [] if spec.is_a?(LazySpecification)
- dependencies = []
- unless spec.required_ruby_version.none?
- dependencies << DepProxy.get_proxy(Dependency.new("Ruby\0", spec.required_ruby_version), platform)
- end
- unless spec.required_rubygems_version.none?
- dependencies << DepProxy.get_proxy(Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
- end
- dependencies
+
+ [
+ metadata_dependency("Ruby", spec.required_ruby_version, platform),
+ metadata_dependency("RubyGems", spec.required_rubygems_version, platform),
+ ].compact
+ end
+
+ def metadata_dependency(name, requirement, platform)
+ return if requirement.nil? || requirement.none?
+
+ DepProxy.get_proxy(Dependency.new("#{name}\0", requirement), platform)
end
end
end
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
index 938c58e64d..d976170f12 100644
--- a/lib/bundler/rubygems_ext.rb
+++ b/lib/bundler/rubygems_ext.rb
@@ -15,6 +15,7 @@ require "rubygems/specification"
# `Gem::Source` from the redefined `Gem::Specification#source`.
require "rubygems/source"
+require_relative "match_metadata"
require_relative "match_platform"
# Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler
@@ -28,6 +29,7 @@ end
module Gem
class Specification
+ include ::Bundler::MatchMetadata
include ::Bundler::MatchPlatform
attr_accessor :remote, :location, :relative_loaded_from
@@ -235,6 +237,32 @@ module Gem
MINGW = Gem::Platform.new("x86-mingw32")
X64_MINGW = [Gem::Platform.new("x64-mingw32"),
Gem::Platform.new("x64-mingw-ucrt")].freeze
+
+ if Gem::Platform.new("x86_64-linux-musl") === Gem::Platform.new("x86_64-linux")
+ remove_method :===
+
+ def ===(other)
+ return nil unless Gem::Platform === other
+
+ # universal-mingw32 matches x64-mingw-ucrt
+ return true if (@cpu == "universal" || other.cpu == "universal") &&
+ @os.start_with?("mingw") && other.os.start_with?("mingw")
+
+ # cpu
+ ([nil,"universal"].include?(@cpu) || [nil, "universal"].include?(other.cpu) || @cpu == other.cpu ||
+ (@cpu == "arm" && other.cpu.start_with?("arm"))) &&
+
+ # os
+ @os == other.os &&
+
+ # version
+ (
+ (@os != "linux" && (@version.nil? || other.version.nil?)) ||
+ (@os == "linux" && ((@version.nil? && ["gnu", "musl"].include?(other.version)) || (@version == "gnu" && other.version.nil?))) ||
+ @version == other.version
+ )
+ end
+ end
end
Platform.singleton_class.module_eval do
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 14733269d6..4965ca9e60 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -7,8 +7,11 @@ module Bundler
include Enumerable
include TSort
- def initialize(specs)
+ attr_reader :incomplete_specs
+
+ def initialize(specs, incomplete_specs = [])
@specs = specs
+ @incomplete_specs = incomplete_specs
end
def for(dependencies, check = false, platforms = [nil])
@@ -19,7 +22,10 @@ module Bundler
loop do
break unless dep = deps.shift
- key = [dep[0].name, dep[1]]
+ name = dep[0].name
+ platform = dep[1]
+
+ key = [name, platform]
next if handled.key?(key)
handled[key] = true
@@ -33,7 +39,7 @@ module Bundler
deps << [d, dep[1]]
end
elsif check
- specs << IncompleteSpecification.new(*key)
+ @incomplete_specs += lookup[name]
end
end
@@ -51,6 +57,12 @@ module Bundler
@sorted = nil
end
+ def delete(spec)
+ @specs.delete(spec)
+ @lookup = nil
+ @sorted = nil
+ end
+
def sort!
self
end
@@ -66,7 +78,7 @@ module Bundler
def materialize(deps)
materialized = self.for(deps, true)
- SpecSet.new(materialized)
+ SpecSet.new(materialized, incomplete_specs)
end
# Materialize for all the specs in the spec set, regardless of what platform they're for
@@ -83,17 +95,15 @@ module Bundler
end
def incomplete_ruby_specs?(deps)
- self.class.new(self.for(deps, true, [Gem::Platform::RUBY])).incomplete_specs.any?
+ self.for(deps, true, [Gem::Platform::RUBY])
+
+ @incomplete_specs.any?
end
def missing_specs
@specs.select {|s| s.is_a?(LazySpecification) }
end
- def incomplete_specs
- @specs.select {|s| s.is_a?(IncompleteSpecification) }
- end
-
def merge(set)
arr = sorted.dup
set.each do |set_spec|
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index f15165f86d..a37c989aa8 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
- VERSION = "2.3.20".freeze
+ VERSION = "2.3.21".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 616428475f..afe9a73b9c 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -8,7 +8,7 @@
require "rbconfig"
module Gem
- VERSION = "3.3.20".freeze
+ VERSION = "3.3.21".freeze
end
# Must be first since it unloads the prelude from 1.9.2
diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb
index ed3571dbff..8c5e7993ca 100644
--- a/lib/rubygems/platform.rb
+++ b/lib/rubygems/platform.rb
@@ -25,7 +25,7 @@ class Gem::Platform
platforms.any? do |local_platform|
platform.nil? ||
local_platform == platform ||
- (local_platform != Gem::Platform::RUBY && local_platform =~ platform)
+ (local_platform != Gem::Platform::RUBY && platform =~ local_platform)
end
end
private_class_method :match_platforms?
@@ -70,7 +70,7 @@ class Gem::Platform
when String then
arch = arch.split "-"
- if arch.length > 2 && arch.last !~ (/\d/) # reassemble x86-linux-gnu
+ if arch.length > 2 && arch.last !~ /\d+(\.\d+)?$/ # reassemble x86-linux-{libc}
extra = arch.pop
arch.last << "-#{extra}"
end
@@ -102,7 +102,7 @@ class Gem::Platform
when /^dalvik(\d+)?$/ then [ "dalvik", $1 ]
when /^dotnet$/ then [ "dotnet", nil ]
when /^dotnet([\d.]*)/ then [ "dotnet", $1 ]
- when /linux-?((?!gnu)\w+)?/ then [ "linux", $1 ]
+ when /linux-?(\w+)?/ then [ "linux", $1 ]
when /mingw32/ then [ "mingw32", nil ]
when /mingw-?(\w+)?/ then [ "mingw", $1 ]
when /(mswin\d+)(\_(\d+))?/ then
@@ -151,10 +151,17 @@ class Gem::Platform
##
# Does +other+ match this platform? Two platforms match if they have the
# same CPU, or either has a CPU of 'universal', they have the same OS, and
- # they have the same version, or either has no version.
+ # they have the same version, or either one has no version
#
# Additionally, the platform will match if the local CPU is 'arm' and the
# other CPU starts with "arm" (for generic ARM family support).
+ #
+ # Of note, this method is not commutative. Indeed the OS 'linux' has a
+ # special case: the version is the libc name, yet while "no version" stands
+ # as a wildcard for a binary gem platform (as for other OSes), for the
+ # runtime platform "no version" stands for 'gnu'. To be able to disinguish
+ # these, the method receiver is the gem platform, while the argument is
+ # the runtime platform.
def ===(other)
return nil unless Gem::Platform === other
@@ -171,7 +178,11 @@ class Gem::Platform
@os == other.os &&
# version
- (@version.nil? || other.version.nil? || @version == other.version)
+ (
+ (@os != "linux" && (@version.nil? || other.version.nil?)) ||
+ (@os == "linux" && ((@version.nil? && ["gnu", "musl"].include?(other.version)) || (@version == "gnu" && other.version.nil?))) ||
+ @version == other.version
+ )
end
##