Merge RubyGems-3.3.21 and Bundler-2.3.21

This commit is contained in:
Hiroshi SHIBATA 2022-08-25 10:50:40 +09:00 committed by nagachika
parent 522b75f1b6
commit a9bf13a4df
73 changed files with 811 additions and 173 deletions

View file

@ -53,13 +53,12 @@ module Bundler
autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__) autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__)
autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__) autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__)
autoload :Graph, File.expand_path("bundler/graph", __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 :Index, File.expand_path("bundler/index", __dir__)
autoload :Injector, File.expand_path("bundler/injector", __dir__) autoload :Injector, File.expand_path("bundler/injector", __dir__)
autoload :Installer, File.expand_path("bundler/installer", __dir__) autoload :Installer, File.expand_path("bundler/installer", __dir__)
autoload :LazySpecification, File.expand_path("bundler/lazy_specification", __dir__) autoload :LazySpecification, File.expand_path("bundler/lazy_specification", __dir__)
autoload :LockfileParser, File.expand_path("bundler/lockfile_parser", __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 :ProcessLock, File.expand_path("bundler/process_lock", __dir__)
autoload :RemoteSpecification, File.expand_path("bundler/remote_specification", __dir__) autoload :RemoteSpecification, File.expand_path("bundler/remote_specification", __dir__)
autoload :Resolver, File.expand_path("bundler/resolver", __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) FileUtils.remove_entry_secure(path) if path && File.exist?(path)
rescue ArgumentError rescue ArgumentError
message = <<EOF 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. 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 EOF
File.world_writable?(path) ? Bundler.ui.warn(message) : raise File.world_writable?(path) ? Bundler.ui.warn(message) : raise
raise PathError, "Please fix the world-writable issue with your #{path} directory" raise PathError, "Please fix the world-writable issue with your #{path} directory"

View file

@ -9,7 +9,7 @@ module Bundler
def run def run
platforms, ruby_version = Bundler.ui.silence do 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 gemfile_ruby_version = Bundler.definition.ruby_version && Bundler.definition.ruby_version.single_version_string
[Bundler.definition.platforms.map {|p| "* #{p}" }, [Bundler.definition.platforms.map {|p| "* #{p}" },
locked_ruby_version || gemfile_ruby_version] locked_ruby_version || gemfile_ruby_version]

View file

@ -145,8 +145,6 @@ module Bundler
@dependency_changes = converge_dependencies @dependency_changes = converge_dependencies
@local_changes = converge_locals @local_changes = converge_locals
@reresolve = nil
@requires = compute_requires @requires = compute_requires
end end
@ -218,6 +216,7 @@ module Bundler
true true
rescue BundlerError => e rescue BundlerError => e
@resolve = nil @resolve = nil
@resolver = nil
@specs = nil @specs = nil
@gem_version_promoter = nil @gem_version_promoter = nil
@ -288,7 +287,7 @@ module Bundler
end end
else else
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}") Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
@reresolve = reresolve resolver.start(expanded_dependencies)
end end
end end
@ -482,11 +481,18 @@ module Bundler
private private
def reresolve def resolver
last_resolve = converge_locked_specs @resolver ||= begin
remove_ruby_from_platforms_if_necessary!(dependencies) last_resolve = converge_locked_specs
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true) Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
Resolver.resolve(expanded_dependencies, 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 end
def filter_specs(specs, deps) def filter_specs(specs, deps)
@ -514,15 +520,13 @@ module Bundler
raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}" raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
end end
if @reresolve.nil? loop do
incomplete_specs = specs.incomplete_specs 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")
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)
@unlock[:gems].concat(incomplete_specs.map(&:name)) specs = resolve.materialize(dependencies)
@resolve = reresolve
specs = resolve.materialize(dependencies)
end
end end
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last 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 # commonly happen if the Gemfile has changed since the lockfile was last
# generated # generated
def converge_locked_specs 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 diff = nil
@ -788,7 +794,7 @@ module Bundler
end end
end end
SpecSet.new(filter_specs(converged, deps).reject {|s| @unlock[:gems].include?(s.name) }) filter_specs(converged, deps)
end end
def metadata_dependencies def metadata_dependencies
@ -877,10 +883,8 @@ module Bundler
def additional_base_requirements_for_resolve def additional_base_requirements_for_resolve
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources) return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
converge_specs(@originally_locked_specs).map do |locked_spec| converge_specs(@originally_locked_specs).map do |locked_spec|
name = locked_spec.name Dependency.new(locked_spec.name, ">= #{locked_spec.version}")
dep = Dependency.new(name, ">= #{locked_spec.version}") end.uniq
DepProxy.get_proxy(dep, locked_spec.platform)
end
end end
def remove_ruby_from_platforms_if_necessary!(dependencies) def remove_ruby_from_platforms_if_necessary!(dependencies)
@ -888,10 +892,11 @@ module Bundler
Bundler.local_platform == Gem::Platform::RUBY || Bundler.local_platform == Gem::Platform::RUBY ||
!platforms.include?(Gem::Platform::RUBY) || !platforms.include?(Gem::Platform::RUBY) ||
(@new_platform && platforms.last == 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) remove_platform(Gem::Platform::RUBY)
add_current_platform add_current_platform
resolver.platforms = @platforms
end end
def source_map def source_map

View file

@ -3,7 +3,7 @@
module Bundler module Bundler
# used for Creating Specifications from the Gemcutter Endpoint # used for Creating Specifications from the Gemcutter Endpoint
class EndpointSpecification < Gem::Specification class EndpointSpecification < Gem::Specification
include MatchPlatform include MatchRemoteMetadata
attr_reader :name, :version, :platform, :checksum attr_reader :name, :version, :platform, :checksum
attr_accessor :source, :remote, :dependencies attr_accessor :source, :remote, :dependencies
@ -22,17 +22,6 @@ module Bundler
parse_metadata(metadata) parse_metadata(metadata)
end 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 def fetch_platform
@platform @platform
end end

View file

@ -88,6 +88,10 @@ module Bundler
end end
end end
def reset
@sort_versions = {}
end
# @return [bool] Convenience method for testing value of level variable. # @return [bool] Convenience method for testing value of level variable.
def major? def major?
level == :major level == :major

View file

@ -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

View file

@ -54,7 +54,7 @@ def gemfile(install = false, options = {}, &gemfile)
Bundler.ui = install ? ui : Bundler::UI::Silent.new Bundler.ui = install ? ui : Bundler::UI::Silent.new
if install || definition.missing_specs? 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 = Bundler::Installer.install(Bundler.root, definition, :system => true)
installer.post_install_messages.each do |name, message| installer.post_install_messages.each do |name, message|
Bundler.ui.info "Post-install message from #{name}:\n#{message}" Bundler.ui.info "Post-install message from #{name}:\n#{message}"

View file

@ -238,19 +238,14 @@ module Bundler
end end
def ensure_specs_are_compatible! def ensure_specs_are_compatible!
system_ruby = Bundler::RubyVersion.system
rubygems_version = Bundler.rubygems.version
@definition.specs.each do |spec| @definition.specs.each do |spec|
if required_ruby_version = spec.required_ruby_version unless spec.matches_current_ruby?
unless required_ruby_version.satisfied_by?(system_ruby.gem_version) raise InstallError, "#{spec.full_name} requires ruby version #{spec.required_ruby_version}, " \
raise InstallError, "#{spec.full_name} requires ruby version #{required_ruby_version}, " \ "which is incompatible with the current version, #{Gem.ruby_version}"
"which is incompatible with the current version, #{system_ruby}"
end
end end
next unless required_rubygems_version = spec.required_rubygems_version unless spec.matches_current_rubygems?
unless required_rubygems_version.satisfied_by?(rubygems_version) raise InstallError, "#{spec.full_name} requires rubygems version #{spec.required_rubygems_version}, " \
raise InstallError, "#{spec.full_name} requires rubygems version #{required_rubygems_version}, " \ "which is incompatible with the current version, #{Gem.rubygems_version}"
"which is incompatible with the current version, #{rubygems_version}"
end end
end end
end end

View file

@ -1,7 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative "match_platform"
module Bundler module Bundler
class LazySpecification class LazySpecification
include MatchPlatform include MatchPlatform
@ -97,8 +95,8 @@ module Bundler
@specification = begin @specification = begin
search = candidates.reverse.find do |spec| search = candidates.reverse.find do |spec|
spec.is_a?(StubSpecification) || spec.is_a?(StubSpecification) ||
(spec.required_ruby_version.satisfied_by?(Gem.ruby_version) && (spec.matches_current_ruby? &&
spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)) spec.matches_current_rubygems?)
end end
if search.nil? && Bundler.frozen_bundle? if search.nil? && Bundler.frozen_bundle?
search = candidates.last search = candidates.last

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory

View file

@ -1,13 +1,22 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options \fBbundle\-config\fR \- Set bundler configuration options
. .
.SH "SYNOPSIS" .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" .SH "DESCRIPTION"
This command allows you to interact with Bundler\'s configuration system\. This command allows you to interact with Bundler\'s configuration system\.

View file

@ -3,7 +3,10 @@ bundle-config(1) -- Set bundler configuration options
## SYNOPSIS ## 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 ## DESCRIPTION

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems \fBbundle\-doctor\fR \- Checks the bundle for common problems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle \fBbundle\-exec\fR \- Execute a command in the context of the bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem \fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle \fBbundle\-info\fR \- Show information for the given gem in your bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory \fBbundle\-init\fR \- Generates a Gemfile into the current working directory

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile \fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle \fBbundle\-list\fR \- List all the gems in the bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing \fBbundle\-lock\fR \- Creates / Updates a lockfile without installing

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle \fBbundle\-open\fR \- Opens the source directory for a gem in your bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available \fBbundle\-outdated\fR \- List installed gems with newer versions available

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information \fBbundle\-platform\fR \- Displays platform compatibility information

View file

@ -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

View file

@ -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)

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition \fBbundle\-pristine\fR \- Restores installed gems to their pristine condition

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile \fBbundle\-remove\fR \- Removes gems from the Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions \fBbundle\-update\fR \- Update your gems to the latest available versions

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.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" .SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile \fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE" "1" "July 2022" "" "" .TH "BUNDLE" "1" "August 2022" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\fR \- Ruby Dependency Management \fBbundle\fR \- Ruby Dependency Management
@ -120,6 +120,10 @@ Display warnings about common problems
\fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR \fBbundle remove(1)\fR \fIbundle\-remove\.1\.html\fR
Removes gems from the Gemfile Removes gems from the Gemfile
. .
.TP
\fBbundle plugin(1)\fR \fIbundle\-plugin\.1\.html\fR
Manage Bundler plugins
.
.SH "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\. 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\.
. .

View file

@ -97,6 +97,9 @@ We divide `bundle` subcommands into primary commands and utilities:
* [`bundle remove(1)`](bundle-remove.1.html): * [`bundle remove(1)`](bundle-remove.1.html):
Removes gems from the Gemfile Removes gems from the Gemfile
* [`bundle plugin(1)`](bundle-plugin.1.html):
Manage Bundler plugins
## PLUGINS ## PLUGINS
When running a command that isn't listed in PRIMARY COMMANDS or UTILITIES, When running a command that isn't listed in PRIMARY COMMANDS or UTILITIES,

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "GEMFILE" "5" "July 2022" "" "" .TH "GEMFILE" "5" "August 2022" "" ""
. .
.SH "NAME" .SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs

View file

@ -18,6 +18,7 @@ bundle-lock(1) bundle-lock.1
bundle-open(1) bundle-open.1 bundle-open(1) bundle-open.1
bundle-outdated(1) bundle-outdated.1 bundle-outdated(1) bundle-outdated.1
bundle-platform(1) bundle-platform.1 bundle-platform(1) bundle-platform.1
bundle-plugin(1) bundle-plugin.1
bundle-pristine(1) bundle-pristine.1 bundle-pristine(1) bundle-pristine.1
bundle-remove(1) bundle-remove.1 bundle-remove(1) bundle-remove.1
bundle-show(1) bundle-show.1 bundle-show(1) bundle-show.1

View file

@ -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

View file

@ -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

View file

@ -36,6 +36,8 @@ module Bundler
# @param [Hash] options various parameters as described in description. # @param [Hash] options various parameters as described in description.
# Refer to cli/plugin for available options # Refer to cli/plugin for available options
def install(names, 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) specs = Installer.new.install(names, options)
save_plugins names, specs save_plugins names, specs

View file

@ -6,6 +6,7 @@ module Bundler
# be seeded with what we're given from the source's abbreviated index - the # be seeded with what we're given from the source's abbreviated index - the
# full specification will only be fetched when necessary. # full specification will only be fetched when necessary.
class RemoteSpecification class RemoteSpecification
include MatchRemoteMetadata
include MatchPlatform include MatchPlatform
include Comparable include Comparable
@ -28,13 +29,6 @@ module Bundler
@platform = _remote_specification.platform @platform = _remote_specification.platform
end 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 def full_name
if @original_platform == Gem::Platform::RUBY if @original_platform == Gem::Platform::RUBY
"#{@name}-#{@version}" "#{@name}-#{@version}"

View file

@ -7,6 +7,8 @@ module Bundler
include GemHelpers include GemHelpers
attr_writer :platforms
# Figures out the best possible configuration of gems that satisfies # Figures out the best possible configuration of gems that satisfies
# the list of passed dependencies and any child dependencies without # the list of passed dependencies and any child dependencies without
# causing any gem activation errors. # causing any gem activation errors.
@ -19,41 +21,48 @@ module Bundler
# collection of gemspecs is returned. Otherwise, nil is returned. # 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) 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) 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)
resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements) resolver.start(requirements)
result = resolver.start(requirements)
SpecSet.new(SpecSet.new(result).for(regular_requirements, false, platforms))
end 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 @source_requirements = source_requirements
@metadata_requirements = metadata_requirements
@base = base @base = base
@resolver = Molinillo::Resolver.new(self, self) @resolver = Molinillo::Resolver.new(self, self)
@results_for = {}
@search_for = {} @search_for = {}
@base_dg = Molinillo::DependencyGraph.new @additional_base_requirements = additional_base_requirements
base.each do |ls| @platforms = platforms
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 } }
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY] @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
@gem_version_promoter = gem_version_promoter @gem_version_promoter = gem_version_promoter
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major? @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
end 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 = {} @gem_version_promoter.prerelease_specified = @prerelease_specified = {}
requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? } requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
verify_gemfile_dependencies_are_found!(requirements) verify_gemfile_dependencies_are_found!(requirements)
dg = @resolver.resolve(requirements, @base_dg) result = @resolver.resolve(requirements, @base_dg).
dg.
map(&:payload). map(&:payload).
reject {|sg| sg.name.end_with?("\0") }. reject {|sg| sg.name.end_with?("\0") }.
map(&:to_specs). map(&:to_specs).
flatten flatten
SpecSet.new(SpecSet.new(result).for(regular_requirements, false, @platforms))
rescue Molinillo::VersionConflict => e rescue Molinillo::VersionConflict => e
message = version_conflict_message(e) message = version_conflict_message(e)
raise VersionConflict.new(e.conflicts.keys.uniq, message) raise VersionConflict.new(e.conflicts.keys.uniq, message)
@ -177,7 +186,7 @@ module Bundler
end end
def results_for(dependency) def results_for(dependency)
index_for(dependency).search(dependency) @results_for[dependency] ||= index_for(dependency).search(dependency)
end end
def name_for(dependency) def name_for(dependency)
@ -228,6 +237,19 @@ module Bundler
private 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] # returns an integer \in (-\infty, 0]
# a number closer to 0 means the dependency is less constraining # a number closer to 0 means the dependency is less constraining
# #

View file

@ -97,14 +97,17 @@ module Bundler
def metadata_dependencies(platform) def metadata_dependencies(platform)
spec = @specs[platform].first spec = @specs[platform].first
return [] if spec.is_a?(LazySpecification) 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) metadata_dependency("Ruby", spec.required_ruby_version, platform),
end metadata_dependency("RubyGems", spec.required_rubygems_version, platform),
unless spec.required_rubygems_version.none? ].compact
dependencies << DepProxy.get_proxy(Dependency.new("RubyGems\0", spec.required_rubygems_version), platform) end
end
dependencies def metadata_dependency(name, requirement, platform)
return if requirement.nil? || requirement.none?
DepProxy.get_proxy(Dependency.new("#{name}\0", requirement), platform)
end end
end end
end end

View file

@ -15,6 +15,7 @@ require "rubygems/specification"
# `Gem::Source` from the redefined `Gem::Specification#source`. # `Gem::Source` from the redefined `Gem::Specification#source`.
require "rubygems/source" require "rubygems/source"
require_relative "match_metadata"
require_relative "match_platform" require_relative "match_platform"
# Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler # Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler
@ -28,6 +29,7 @@ end
module Gem module Gem
class Specification class Specification
include ::Bundler::MatchMetadata
include ::Bundler::MatchPlatform include ::Bundler::MatchPlatform
attr_accessor :remote, :location, :relative_loaded_from attr_accessor :remote, :location, :relative_loaded_from
@ -235,6 +237,32 @@ module Gem
MINGW = Gem::Platform.new("x86-mingw32") MINGW = Gem::Platform.new("x86-mingw32")
X64_MINGW = [Gem::Platform.new("x64-mingw32"), X64_MINGW = [Gem::Platform.new("x64-mingw32"),
Gem::Platform.new("x64-mingw-ucrt")].freeze 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 end
Platform.singleton_class.module_eval do Platform.singleton_class.module_eval do

View file

@ -7,8 +7,11 @@ module Bundler
include Enumerable include Enumerable
include TSort include TSort
def initialize(specs) attr_reader :incomplete_specs
def initialize(specs, incomplete_specs = [])
@specs = specs @specs = specs
@incomplete_specs = incomplete_specs
end end
def for(dependencies, check = false, platforms = [nil]) def for(dependencies, check = false, platforms = [nil])
@ -19,7 +22,10 @@ module Bundler
loop do loop do
break unless dep = deps.shift 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) next if handled.key?(key)
handled[key] = true handled[key] = true
@ -33,7 +39,7 @@ module Bundler
deps << [d, dep[1]] deps << [d, dep[1]]
end end
elsif check elsif check
specs << IncompleteSpecification.new(*key) @incomplete_specs += lookup[name]
end end
end end
@ -51,6 +57,12 @@ module Bundler
@sorted = nil @sorted = nil
end end
def delete(spec)
@specs.delete(spec)
@lookup = nil
@sorted = nil
end
def sort! def sort!
self self
end end
@ -66,7 +78,7 @@ module Bundler
def materialize(deps) def materialize(deps)
materialized = self.for(deps, true) materialized = self.for(deps, true)
SpecSet.new(materialized) SpecSet.new(materialized, incomplete_specs)
end end
# Materialize for all the specs in the spec set, regardless of what platform they're for # Materialize for all the specs in the spec set, regardless of what platform they're for
@ -83,17 +95,15 @@ module Bundler
end end
def incomplete_ruby_specs?(deps) 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 end
def missing_specs def missing_specs
@specs.select {|s| s.is_a?(LazySpecification) } @specs.select {|s| s.is_a?(LazySpecification) }
end end
def incomplete_specs
@specs.select {|s| s.is_a?(IncompleteSpecification) }
end
def merge(set) def merge(set)
arr = sorted.dup arr = sorted.dup
set.each do |set_spec| set.each do |set_spec|

View file

@ -1,7 +1,7 @@
# frozen_string_literal: false # frozen_string_literal: false
module Bundler module Bundler
VERSION = "2.3.20".freeze VERSION = "2.3.21".freeze
def self.bundler_major_version def self.bundler_major_version
@bundler_major_version ||= VERSION.split(".").first.to_i @bundler_major_version ||= VERSION.split(".").first.to_i

View file

@ -8,7 +8,7 @@
require "rbconfig" require "rbconfig"
module Gem module Gem
VERSION = "3.3.20".freeze VERSION = "3.3.21".freeze
end end
# Must be first since it unloads the prelude from 1.9.2 # Must be first since it unloads the prelude from 1.9.2

View file

@ -25,7 +25,7 @@ class Gem::Platform
platforms.any? do |local_platform| platforms.any? do |local_platform|
platform.nil? || platform.nil? ||
local_platform == platform || local_platform == platform ||
(local_platform != Gem::Platform::RUBY && local_platform =~ platform) (local_platform != Gem::Platform::RUBY && platform =~ local_platform)
end end
end end
private_class_method :match_platforms? private_class_method :match_platforms?
@ -70,7 +70,7 @@ class Gem::Platform
when String then when String then
arch = arch.split "-" 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 extra = arch.pop
arch.last << "-#{extra}" arch.last << "-#{extra}"
end end
@ -102,7 +102,7 @@ class Gem::Platform
when /^dalvik(\d+)?$/ then [ "dalvik", $1 ] when /^dalvik(\d+)?$/ then [ "dalvik", $1 ]
when /^dotnet$/ then [ "dotnet", nil ] when /^dotnet$/ then [ "dotnet", nil ]
when /^dotnet([\d.]*)/ then [ "dotnet", $1 ] 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 /mingw32/ then [ "mingw32", nil ]
when /mingw-?(\w+)?/ then [ "mingw", $1 ] when /mingw-?(\w+)?/ then [ "mingw", $1 ]
when /(mswin\d+)(\_(\d+))?/ then when /(mswin\d+)(\_(\d+))?/ then
@ -151,10 +151,17 @@ class Gem::Platform
## ##
# Does +other+ match this platform? Two platforms match if they have the # 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 # 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 # Additionally, the platform will match if the local CPU is 'arm' and the
# other CPU starts with "arm" (for generic ARM family support). # 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) def ===(other)
return nil unless Gem::Platform === other return nil unless Gem::Platform === other
@ -171,7 +178,11 @@ class Gem::Platform
@os == other.os && @os == other.os &&
# version # 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 end
## ##

View file

@ -167,9 +167,9 @@ RSpec.describe Bundler do
allow(::Bundler::FileUtils).to receive(:remove_entry_secure).and_raise(ArgumentError) allow(::Bundler::FileUtils).to receive(:remove_entry_secure).and_raise(ArgumentError)
allow(File).to receive(:world_writable?).and_return(true) allow(File).to receive(:world_writable?).and_return(true)
message = <<EOF 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. 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 EOF
expect(bundler_ui).to receive(:warn).with(message) expect(bundler_ui).to receive(:warn).with(message)
expect { Bundler.send(:rm_rf, bundled_app) }.to raise_error(Bundler::PathError) expect { Bundler.send(:rm_rf, bundled_app) }.to raise_error(Bundler::PathError)

View file

@ -42,7 +42,7 @@ RSpec.describe "bundle init" do
context "when the dir is not writable by the current user" do context "when the dir is not writable by the current user" do
let(:subdir) { "child_dir" } let(:subdir) { "child_dir" }
it "notifies the user that it can not write to it" do it "notifies the user that it cannot write to it" do
FileUtils.mkdir bundled_app(subdir) FileUtils.mkdir bundled_app(subdir)
# chmod a-w it # chmod a-w it
mode = File.stat(bundled_app(subdir)).mode ^ 0o222 mode = File.stat(bundled_app(subdir)).mode ^ 0o222

View file

@ -234,6 +234,29 @@ G
expect(out).to eq("ruby 1.0.0") expect(out).to eq("ruby 1.0.0")
end end
it "handles when there is a lockfile with no requirement" do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
G
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo1)}/
specs:
PLATFORMS
ruby
DEPENDENCIES
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "platform --ruby"
expect(out).to eq("No ruby version specified")
end
it "handles when there is a requirement in the gemfile" do it "handles when there is a requirement in the gemfile" do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"

View file

@ -522,7 +522,7 @@ RSpec.describe "bundle remove" do
end end
end end
context "when gems can not be removed from other gemfile" do context "when gems cannot be removed from other gemfile" do
it "shows error" do it "shows error" do
create_file "Gemfile-other", <<-G create_file "Gemfile-other", <<-G
gem "rails"; gem "rack" gem "rails"; gem "rack"
@ -574,7 +574,7 @@ RSpec.describe "bundle remove" do
end end
context "when gem present in gemfiles but could not be removed from one from one of them" do context "when gem present in gemfiles but could not be removed from one from one of them" do
it "removes gem which can be removed and shows warning for file from which it can not be removed" do it "removes gem which can be removed and shows warning for file from which it cannot be removed" do
create_file "Gemfile-other", <<-G create_file "Gemfile-other", <<-G
gem "rack" gem "rack"
G G

View file

@ -301,6 +301,66 @@ RSpec.describe "bundle update" do
expect(lockfile).to eq(previous_lockfile) expect(lockfile).to eq(previous_lockfile)
end end
it "does not downgrade direct dependencies when run with --conservative" do
build_repo4 do
build_gem "oauth2", "2.0.6" do |s|
s.add_dependency "faraday", ">= 0.17.3", "< 3.0"
end
build_gem "oauth2", "1.4.10" do |s|
s.add_dependency "faraday", ">= 0.17.3", "< 3.0"
s.add_dependency "multi_json", "~> 1.3"
end
build_gem "faraday", "2.5.2"
build_gem "multi_json", "1.15.0"
build_gem "quickbooks-ruby", "1.0.19" do |s|
s.add_dependency "oauth2", "~> 1.4"
end
build_gem "quickbooks-ruby", "0.1.9" do |s|
s.add_dependency "oauth2"
end
end
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "oauth2"
gem "quickbooks-ruby"
G
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
faraday (2.5.2)
multi_json (1.15.0)
oauth2 (1.4.10)
faraday (>= 0.17.3, < 3.0)
multi_json (~> 1.3)
quickbooks-ruby (1.0.19)
oauth2 (~> 1.4)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
oauth2
quickbooks-ruby
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "update --conservative --verbose"
expect(out).not_to include("Installing quickbooks-ruby 0.1.9")
expect(out).to include("Installing quickbooks-ruby 1.0.19").and include("Installing oauth2 1.4.10")
end
it "does not downgrade indirect dependencies unnecessarily" do it "does not downgrade indirect dependencies unnecessarily" do
build_repo4 do build_repo4 do
build_gem "a" do |s| build_gem "a" do |s|

View file

@ -445,6 +445,47 @@ RSpec.describe "bundle install with specific platforms" do
L L
end end
it "does not remove ruby if gems for other platforms, and not present in the lockfile, exist in the Gemfile" do
build_repo4 do
build_gem "nokogiri", "1.13.8"
build_gem "nokogiri", "1.13.8" do |s|
s.platform = Gem::Platform.local
end
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "nokogiri"
gem "tzinfo", "~> 1.2", platform: :#{not_local_tag}
G
original_lockfile = <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
nokogiri (1.13.8)
nokogiri (1.13.8-#{Gem::Platform.local})
PLATFORMS
#{lockfile_platforms_for([specific_local_platform, "ruby"])}
DEPENDENCIES
nokogiri
tzinfo (~> 1.2)
BUNDLED WITH
#{Bundler::VERSION}
L
lockfile original_lockfile
bundle "lock --update"
expect(lockfile).to eq(original_lockfile)
end
it "can fallback to a source gem when platform gems are incompatible with current ruby version" do it "can fallback to a source gem when platform gems are incompatible with current ruby version" do
setup_multiplatform_gem_with_source_gem setup_multiplatform_gem_with_source_gem

View file

@ -443,6 +443,22 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "back_deps 1.0" expect(the_bundle).to include_gems "back_deps 1.0"
end end
it "does not fetch all marshaled specs" do
build_repo2 do
build_gem "foo", "1.0"
build_gem "foo", "2.0"
end
install_gemfile <<-G, :artifice => "endpoint", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, :verbose => true
source "#{source_uri}"
gem "foo"
G
expect(out).to include("foo-2.0.gemspec.rz")
expect(out).not_to include("foo-1.0.gemspec.rz")
end
it "does not refetch if the only unmet dependency is bundler" do it "does not refetch if the only unmet dependency is bundler" do
build_repo2 do build_repo2 do
build_gem "bundler_dep" do |s| build_gem "bundler_dep" do |s|

View file

@ -305,6 +305,77 @@ RSpec.describe "bundle install with install-time dependencies" do
end end
end end
context "in a transitive dependencies in a lockfile" do
before do
build_repo2 do
build_gem "rubocop", "1.28.2" do |s|
s.required_ruby_version = ">= #{current_ruby_minor}"
s.add_dependency "rubocop-ast", ">= 1.17.0", "< 2.0"
end
build_gem "rubocop", "1.35.0" do |s|
s.required_ruby_version = ">= #{next_ruby_minor}"
s.add_dependency "rubocop-ast", ">= 1.20.1", "< 2.0"
end
build_gem "rubocop-ast", "1.17.0" do |s|
s.required_ruby_version = ">= #{current_ruby_minor}"
end
build_gem "rubocop-ast", "1.21.0" do |s|
s.required_ruby_version = ">= #{next_ruby_minor}"
end
end
gemfile <<-G
source "http://localgemserver.test/"
gem 'rubocop'
G
lockfile <<~L
GEM
remote: http://localgemserver.test/
specs:
rubocop (1.35.0)
rubocop-ast (>= 1.20.1, < 2.0)
rubocop-ast (1.21.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
parallel_tests
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "automatically updates lockfile to use the older compatible versions" do
bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(lockfile).to eq <<~L
GEM
remote: http://localgemserver.test/
specs:
rubocop (1.28.2)
rubocop-ast (>= 1.17.0, < 2.0)
rubocop-ast (1.17.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rubocop
BUNDLED WITH
#{Bundler::VERSION}
L
end
end
it "gives a meaningful error on ruby version mismatches between dependencies" do it "gives a meaningful error on ruby version mismatches between dependencies" do
build_repo4 do build_repo4 do
build_gem "requires-old-ruby" do |s| build_gem "requires-old-ruby" do |s|

View file

@ -32,7 +32,8 @@ RSpec.describe "bundler plugin install" do
it "shows help when --help flag is given" do it "shows help when --help flag is given" do
bundle "plugin install --help" bundle "plugin install --help"
expect(out).to include("bundle plugin install PLUGINS # Install the plugin from the source") # The help message defined in ../../lib/bundler/man/bundle-plugin.1.ronn will be output.
expect(out).to include("You can install, uninstall, and list plugin(s)")
end end
context "plugin is already installed" do context "plugin is already installed" do
@ -84,6 +85,26 @@ RSpec.describe "bundler plugin install" do
expect(out).to include("Using foo 1.1") expect(out).to include("Using foo 1.1")
end end
it "installs when --branch specified" do
bundle "plugin install foo --branch main --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installed plugin foo")
end
it "installs when --ref specified" do
bundle "plugin install foo --ref v1.2.3 --source #{file_uri_for(gem_repo2)}"
expect(out).to include("Installed plugin foo")
end
it "raises error when both --branch and --ref options are specified" do
bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --branch main --ref v1.2.3", :raise_on_error => false
expect(out).not_to include("Installed plugin foo")
expect(err).to include("You cannot specify `--branch` and `--ref` at the same time.")
end
it "works with different load paths" do it "works with different load paths" do
build_repo2 do build_repo2 do
build_plugin "testing" do |s| build_plugin "testing" do |s|

View file

@ -82,6 +82,79 @@ RSpec.describe "Resolving platform craziness" do
should_resolve_as %w[foo-1.0.0-x64-mingw32] should_resolve_as %w[foo-1.0.0-x64-mingw32]
end end
describe "on a linux platform", :rubygems => ">= 3.1.0.pre.1" do
# Ruby's platform is *-linux => platform's libc is glibc, so not musl
# Ruby's platform is *-linux-musl => platform's libc is musl, so not glibc
# Gem's platform is *-linux => gem is glibc + maybe musl compatible
# Gem's platform is *-linux-musl => gem is musl compatible but not glibc
it "favors the platform version-specific gem on a version-specifying linux platform" do
@index = build_index do
gem "foo", "1.0.0"
gem "foo", "1.0.0", "x86_64-linux"
gem "foo", "1.0.0", "x86_64-linux-musl"
end
dep "foo"
platforms "x86_64-linux-musl"
should_resolve_as %w[foo-1.0.0-x86_64-linux-musl]
end
it "favors the version-less gem over the version-specific gem on a gnu linux platform" do
@index = build_index do
gem "foo", "1.0.0"
gem "foo", "1.0.0", "x86_64-linux"
gem "foo", "1.0.0", "x86_64-linux-musl"
end
dep "foo"
platforms "x86_64-linux"
should_resolve_as %w[foo-1.0.0-x86_64-linux]
end
it "ignores the platform version-specific gem on a gnu linux platform" do
@index = build_index do
gem "foo", "1.0.0", "x86_64-linux-musl"
end
dep "foo"
platforms "x86_64-linux"
should_not_resolve
end
it "falls back to the platform version-less gem on a linux platform with a version" do
@index = build_index do
gem "foo", "1.0.0"
gem "foo", "1.0.0", "x86_64-linux"
end
dep "foo"
platforms "x86_64-linux-musl"
should_resolve_as %w[foo-1.0.0-x86_64-linux]
end
it "falls back to the ruby platform gem on a gnu linux platform when only a version-specifying gem is available" do
@index = build_index do
gem "foo", "1.0.0"
gem "foo", "1.0.0", "x86_64-linux-musl"
end
dep "foo"
platforms "x86_64-linux"
should_resolve_as %w[foo-1.0.0]
end
it "falls back to the platform version-less gem on a version-specifying linux platform and no ruby platform gem is available" do
@index = build_index do
gem "foo", "1.0.0", "x86_64-linux"
end
dep "foo"
platforms "x86_64-linux-musl"
should_resolve_as %w[foo-1.0.0-x86_64-linux]
end
end
it "takes the latest ruby gem if the platform specific gem doesn't match the required_ruby_version" do it "takes the latest ruby gem if the platform specific gem doesn't match the required_ruby_version" do
@index = build_index do @index = build_index do
gem "foo", "1.0.0" gem "foo", "1.0.0"

View file

@ -355,6 +355,20 @@ RSpec.describe "bundler/inline#gemfile" do
expect(err).to be_empty expect(err).to be_empty
end end
it "still installs if the application has `bundle package` no_install config set" do
bundle "config set --local no_install true"
script <<-RUBY
gemfile do
source "#{file_uri_for(gem_repo1)}"
gem "rack"
end
RUBY
expect(last_command).to be_success
expect(system_gem_path("gems/rack-1.0.0")).to exist
end
it "preserves previous BUNDLE_GEMFILE value" do it "preserves previous BUNDLE_GEMFILE value" do
ENV["BUNDLE_GEMFILE"] = "" ENV["BUNDLE_GEMFILE"] = ""
script <<-RUBY script <<-RUBY

View file

@ -6,12 +6,7 @@ Artifice.deactivate
class CompactIndexApiMissing < CompactIndexAPI class CompactIndexApiMissing < CompactIndexAPI
get "/fetch/actual/gem/:id" do get "/fetch/actual/gem/:id" do
warn params[:id] halt 404
if params[:id] == "rack-1.0.gemspec.rz"
halt 404
else
File.binread("#{gem_repo2}/quick/Marshal.4.8/#{params[:id]}")
end
end end
end end

View file

@ -33,6 +33,10 @@ module Spec
Bundler::Resolver.resolve(deps, source_requirements, *args) Bundler::Resolver.resolve(deps, source_requirements, *args)
end end
def should_not_resolve
expect { resolve }.to raise_error(Bundler::GemNotFound)
end
def should_resolve_as(specs) def should_resolve_as(specs)
got = resolve got = resolve
got = got.map(&:full_name).sort got = got.map(&:full_name).sort

View file

@ -160,9 +160,9 @@ dependencies = [
[[package]] [[package]]
name = "rb-sys" name = "rb-sys"
version = "0.9.29" version = "0.9.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0317cb843cdeef14c5622917c55c0a170cee31348eb600c4a1683fb8c9e87e7a" checksum = "24b22a374fc2e92eb6f49d7efe4eb7663655c6e9455d9259ed3342cc1599da85"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"linkify", "linkify",
@ -171,9 +171,9 @@ dependencies = [
[[package]] [[package]]
name = "rb-sys-build" name = "rb-sys-build"
version = "0.9.29" version = "0.9.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4b8274327aecb7edcff86e290d9cbe7b572b7889c1cfc7476358f4831f78ce5" checksum = "3cd23b6dd929b7d50ccb35a6d3aa77dec364328ab9cb304dd32c629332491671"
dependencies = [ dependencies = [
"regex", "regex",
"shell-words", "shell-words",

View file

@ -7,4 +7,4 @@ edition = "2021"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
rb-sys = { version = "0.9.29", features = ["gem"] } rb-sys = { version = "0.9.30", features = ["gem"] }

View file

@ -153,9 +153,9 @@ dependencies = [
[[package]] [[package]]
name = "rb-sys" name = "rb-sys"
version = "0.9.29" version = "0.9.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0317cb843cdeef14c5622917c55c0a170cee31348eb600c4a1683fb8c9e87e7a" checksum = "24b22a374fc2e92eb6f49d7efe4eb7663655c6e9455d9259ed3342cc1599da85"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"linkify", "linkify",
@ -164,9 +164,9 @@ dependencies = [
[[package]] [[package]]
name = "rb-sys-build" name = "rb-sys-build"
version = "0.9.29" version = "0.9.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4b8274327aecb7edcff86e290d9cbe7b572b7889c1cfc7476358f4831f78ce5" checksum = "3cd23b6dd929b7d50ccb35a6d3aa77dec364328ab9cb304dd32c629332491671"
dependencies = [ dependencies = [
"regex", "regex",
"shell-words", "shell-words",

View file

@ -7,4 +7,4 @@ edition = "2021"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
rb-sys = { version = "0.9.29", features = ["gem"] } rb-sys = { version = "0.9.30", features = ["gem"] }

View file

@ -119,8 +119,8 @@ class TestGemPlatform < Gem::TestCase
"i586-linux" => ["x86", "linux", nil], "i586-linux" => ["x86", "linux", nil],
"i486-linux" => ["x86", "linux", nil], "i486-linux" => ["x86", "linux", nil],
"i386-linux" => ["x86", "linux", nil], "i386-linux" => ["x86", "linux", nil],
"i586-linux-gnu" => ["x86", "linux", nil], "i586-linux-gnu" => ["x86", "linux", "gnu"],
"i386-linux-gnu" => ["x86", "linux", nil], "i386-linux-gnu" => ["x86", "linux", "gnu"],
"i386-mingw32" => ["x86", "mingw32", nil], "i386-mingw32" => ["x86", "mingw32", nil],
"x64-mingw-ucrt" => ["x64", "mingw", "ucrt"], "x64-mingw-ucrt" => ["x64", "mingw", "ucrt"],
"i386-mswin32" => ["x86", "mswin32", nil], "i386-mswin32" => ["x86", "mswin32", nil],
@ -135,7 +135,9 @@ class TestGemPlatform < Gem::TestCase
"i386-solaris2.8" => ["x86", "solaris", "2.8"], "i386-solaris2.8" => ["x86", "solaris", "2.8"],
"mswin32" => ["x86", "mswin32", nil], "mswin32" => ["x86", "mswin32", nil],
"x86_64-linux" => ["x86_64", "linux", nil], "x86_64-linux" => ["x86_64", "linux", nil],
"x86_64-linux-gnu" => ["x86_64", "linux", "gnu"],
"x86_64-linux-musl" => ["x86_64", "linux", "musl"], "x86_64-linux-musl" => ["x86_64", "linux", "musl"],
"x86_64-linux-uclibc" => ["x86_64", "linux", "uclibc"],
"x86_64-openbsd3.9" => ["x86_64", "openbsd", "3.9"], "x86_64-openbsd3.9" => ["x86_64", "openbsd", "3.9"],
"x86_64-openbsd4.0" => ["x86_64", "openbsd", "4.0"], "x86_64-openbsd4.0" => ["x86_64", "openbsd", "4.0"],
"x86_64-openbsd" => ["x86_64", "openbsd", nil], "x86_64-openbsd" => ["x86_64", "openbsd", nil],
@ -144,6 +146,7 @@ class TestGemPlatform < Gem::TestCase
test_cases.each do |arch, expected| test_cases.each do |arch, expected|
platform = Gem::Platform.new arch platform = Gem::Platform.new arch
assert_equal expected, platform.to_a, arch.inspect assert_equal expected, platform.to_a, arch.inspect
assert_equal expected, Gem::Platform.new(platform.to_s).to_a, arch.inspect
end end
end end
@ -262,6 +265,42 @@ class TestGemPlatform < Gem::TestCase
assert((with_x86_arch === with_nil_arch), "x86 =~ nil") assert((with_x86_arch === with_nil_arch), "x86 =~ nil")
end end
def test_nil_version_is_treated_as_any_version
x86_darwin_8 = Gem::Platform.new "i686-darwin8.0"
x86_darwin_nil = Gem::Platform.new "i686-darwin"
assert((x86_darwin_8 === x86_darwin_nil), "8.0 =~ nil")
assert((x86_darwin_nil === x86_darwin_8), "nil =~ 8.0")
end
def test_nil_version_is_stricter_for_linux_os
x86_linux = Gem::Platform.new "i686-linux"
x86_linux_gnu = Gem::Platform.new "i686-linux-gnu"
x86_linux_musl = Gem::Platform.new "i686-linux-musl"
x86_linux_uclibc = Gem::Platform.new "i686-linux-uclibc"
# a naked linux runtime is implicit gnu, as it represents the common glibc-linked runtime
assert(x86_linux === x86_linux_gnu, "linux =~ linux-gnu")
assert(x86_linux_gnu === x86_linux, "linux-gnu =~ linux")
# musl and explicit gnu should differ
refute(x86_linux_gnu === x86_linux_musl, "linux-gnu =~ linux-musl")
refute(x86_linux_musl === x86_linux_gnu, "linux-musl =~ linux-gnu")
# explicit libc differ
refute(x86_linux_uclibc === x86_linux_musl, "linux-uclibc =~ linux-musl")
refute(x86_linux_musl === x86_linux_uclibc, "linux-musl =~ linux-uclibc")
# musl host runtime accepts libc-generic or statically linked gems...
assert(x86_linux === x86_linux_musl, "linux =~ linux-musl")
# ...but implicit gnu runtime generally does not accept musl-specific gems
refute(x86_linux_musl === x86_linux, "linux-musl =~ linux")
# other libc are not glibc compatible
refute(x86_linux === x86_linux_uclibc, "linux =~ linux-uclibc")
refute(x86_linux_uclibc === x86_linux, "linux-uclibc =~ linux")
end
def test_equals3_cpu_arm def test_equals3_cpu_arm
arm = Gem::Platform.new "arm-linux" arm = Gem::Platform.new "arm-linux"
armv5 = Gem::Platform.new "armv5-linux" armv5 = Gem::Platform.new "armv5-linux"

View file

@ -322,16 +322,15 @@ class TestGemResolver < Gem::TestCase
def test_picks_best_platform def test_picks_best_platform
is = Gem::Resolver::IndexSpecification is = Gem::Resolver::IndexSpecification
unknown = Gem::Platform.new "unknown" unknown = Gem::Platform.new "unknown"
a2_p1 = a3_p2 = nil
spec_fetcher do |fetcher| spec_fetcher do |fetcher|
fetcher.spec "a", 2 fetcher.spec "a", 2
a2_p1 = fetcher.spec "a", 2 do |s| fetcher.spec "a", 2 do |s|
s.platform = Gem::Platform.local s.platform = Gem::Platform.local
end end
a3_p2 = fetcher.spec "a", 3 do |s| fetcher.spec "a", 3 do |s|
s.platform = unknown s.platform = unknown
end end
end end
@ -357,6 +356,41 @@ class TestGemResolver < Gem::TestCase
assert_resolves_to [a2_p1.spec], res assert_resolves_to [a2_p1.spec], res
end end
def test_does_not_pick_musl_variants_on_non_musl_linux
util_set_arch "aarch64-linux" do
is = Gem::Resolver::IndexSpecification
linux_musl = Gem::Platform.new("aarch64-linux-musl")
spec_fetcher do |fetcher|
fetcher.spec "libv8-node", "15.14.0.1" do |s|
s.platform = Gem::Platform.local
end
fetcher.spec "libv8-node", "15.14.0.1" do |s|
s.platform = linux_musl
end
end
v15 = v("15.14.0.1")
source = Gem::Source.new @gem_repo
s = set
v15_linux = is.new s, "libv8-node", v15, source, Gem::Platform.local.to_s
v15_linux_musl = is.new s, "libv8-node", v15, source, linux_musl.to_s
s.add v15_linux
s.add v15_linux_musl
ad = make_dep "libv8-node", "= 15.14.0.1"
res = Gem::Resolver.new([ad], s)
assert_resolves_to [v15_linux.spec], res
end
end
def test_only_returns_spec_once def test_only_returns_spec_once
a1 = util_spec "a", "1", "c" => "= 1" a1 = util_spec "a", "1", "c" => "= 1"
b1 = util_spec "b", "1", "c" => "= 1" b1 = util_spec "b", "1", "c" => "= 1"

View file

@ -53,4 +53,4 @@ DEPENDENCIES
webrick (~> 1.6) webrick (~> 1.6)
BUNDLED WITH BUNDLED WITH
2.3.20 2.3.21

View file

@ -62,4 +62,4 @@ DEPENDENCIES
test-unit test-unit
BUNDLED WITH BUNDLED WITH
2.3.20 2.3.21

View file

@ -68,4 +68,4 @@ DEPENDENCIES
test-unit test-unit
BUNDLED WITH BUNDLED WITH
2.3.20 2.3.21

View file

@ -43,4 +43,4 @@ DEPENDENCIES
webrick (= 1.7.0) webrick (= 1.7.0)
BUNDLED WITH BUNDLED WITH
2.3.20 2.3.21