Merge RubyGems and Bundler master

This commit is contained in:
Hiroshi SHIBATA 2022-07-13 12:56:36 +09:00
parent e3a988a29c
commit 437a5ae9d6
Notes: git 2022-07-13 14:12:21 +09:00
49 changed files with 583 additions and 238 deletions

View File

@ -455,7 +455,7 @@ EOF
end end
def local_platform def local_platform
return Gem::Platform::RUBY if settings[:force_ruby_platform] || Gem.platforms == [Gem::Platform::RUBY] return Gem::Platform::RUBY if settings[:force_ruby_platform]
Gem::Platform.local Gem::Platform.local
end end

View File

@ -78,7 +78,7 @@ module Bundler
end end
def x64_mingw? def x64_mingw?
Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu == "x64" Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os.start_with?("mingw") && Bundler.local_platform.cpu == "x64"
end end
(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version| (KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|

View File

@ -235,6 +235,14 @@ module Bundler
@locked_deps.values @locked_deps.values
end end
def new_deps
@new_deps ||= @dependencies - locked_dependencies
end
def deleted_deps
@deleted_deps ||= locked_dependencies - @dependencies
end
def specs_for(groups) def specs_for(groups)
return specs if groups.empty? return specs if groups.empty?
deps = dependencies_for(groups) deps = dependencies_for(groups)
@ -259,8 +267,17 @@ module Bundler
Bundler.ui.debug "Frozen, using resolution from the lockfile" Bundler.ui.debug "Frozen, using resolution from the lockfile"
@locked_specs @locked_specs
elsif !unlocking? && nothing_changed? elsif !unlocking? && nothing_changed?
if deleted_deps.any?
Bundler.ui.debug("Some dependencies were deleted, using a subset of the resolution from the lockfile")
SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
else
Bundler.ui.debug("Found no changes, using resolution from the lockfile") Bundler.ui.debug("Found no changes, using resolution from the lockfile")
SpecSet.new(filter_specs(@locked_specs, @dependencies.select {|dep| @locked_specs[dep].any? })) if @locked_gems.may_include_redundant_platform_specific_gems?
SpecSet.new(filter_specs(@locked_specs, @dependencies))
else
@locked_specs
end
end
else else
last_resolve = converge_locked_specs last_resolve = converge_locked_specs
# Run a resolve against the locally available gems # Run a resolve against the locally available gems
@ -359,9 +376,6 @@ module Bundler
added.concat new_platforms.map {|p| "* platform: #{p}" } added.concat new_platforms.map {|p| "* platform: #{p}" }
deleted.concat deleted_platforms.map {|p| "* platform: #{p}" } deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
new_deps = @dependencies - locked_dependencies
deleted_deps = locked_dependencies - @dependencies
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any? added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any? deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
@ -806,7 +820,7 @@ module Bundler
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 name = locked_spec.name
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}") dep = Dependency.new(name, ">= #{locked_spec.version}")
DepProxy.get_proxy(dep, locked_spec.platform) DepProxy.get_proxy(dep, locked_spec.platform)
end end
end end

View File

@ -1,13 +1,16 @@
# frozen_string_literal: true # frozen_string_literal: true
require "rubygems/dependency" require "rubygems/dependency"
require_relative "force_platform"
require_relative "shared_helpers" require_relative "shared_helpers"
require_relative "rubygems_ext" require_relative "rubygems_ext"
module Bundler module Bundler
class Dependency < Gem::Dependency class Dependency < Gem::Dependency
include ForcePlatform
attr_reader :autorequire attr_reader :autorequire
attr_reader :groups, :platforms, :gemfile, :git, :github, :branch, :ref attr_reader :groups, :platforms, :gemfile, :git, :github, :branch, :ref, :force_ruby_platform
# rubocop:disable Naming/VariableNumber # rubocop:disable Naming/VariableNumber
PLATFORM_MAP = { PLATFORM_MAP = {
@ -109,6 +112,7 @@ module Bundler
@env = options["env"] @env = options["env"]
@should_include = options.fetch("should_include", true) @should_include = options.fetch("should_include", true)
@gemfile = options["gemfile"] @gemfile = options["gemfile"]
@force_ruby_platform = options.fetch("force_ruby_platform", default_force_ruby_platform)
@autorequire = Array(options["require"] || []) if options.key?("require") @autorequire = Array(options["require"] || []) if options.key?("require")
end end
@ -122,7 +126,7 @@ module Bundler
end end
def expanded_platforms def expanded_platforms
@expanded_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.uniq @expanded_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.flatten.uniq
end end
def should_include? def should_include?

View File

@ -16,7 +16,7 @@ module Bundler
VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze
VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
platform platforms type source install_if gemfile].freeze platform platforms type source install_if gemfile force_ruby_platform].freeze
GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}.freeze GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}.freeze

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
module Bundler
module ForcePlatform
private
# The `:force_ruby_platform` value used by dependencies for resolution, and
# by locked specifications for materialization is `false` by default, except
# for TruffleRuby. TruffleRuby generally needs to force the RUBY platform
# variant unless the name is explicitly allowlisted.
def default_force_ruby_platform
return false unless Bundler.current_ruby.truffleruby?
!Gem::Platform::REUSE_AS_BINARY_ON_TRUFFLERUBY.include?(name)
end
end
end

View File

@ -5,11 +5,13 @@ module Bundler
GENERIC_CACHE = { Gem::Platform::RUBY => Gem::Platform::RUBY } # rubocop:disable Style/MutableConstant GENERIC_CACHE = { Gem::Platform::RUBY => Gem::Platform::RUBY } # rubocop:disable Style/MutableConstant
GENERICS = [ GENERICS = [
[Gem::Platform.new("java"), Gem::Platform.new("java")], [Gem::Platform.new("java"), Gem::Platform.new("java")],
[Gem::Platform.new("universal-java"), Gem::Platform.new("java")],
[Gem::Platform.new("mswin32"), Gem::Platform.new("mswin32")], [Gem::Platform.new("mswin32"), Gem::Platform.new("mswin32")],
[Gem::Platform.new("mswin64"), Gem::Platform.new("mswin64")], [Gem::Platform.new("mswin64"), Gem::Platform.new("mswin64")],
[Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")], [Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
[Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")], [Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
[Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")], [Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
[Gem::Platform.new("x64-mingw-ucrt"), Gem::Platform.new("x64-mingw-ucrt")],
[Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")], [Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
].freeze ].freeze

View File

@ -192,11 +192,7 @@ module Bundler
specs += base if base specs += base if base
found = specs.select do |spec| found = specs.select do |spec|
next true if spec.source.is_a?(Source::Gemspec) next true if spec.source.is_a?(Source::Gemspec)
if base # allow all platforms when searching from a lockfile
dependency.matches_spec?(spec) dependency.matches_spec?(spec)
else
dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
end
end end
found found

View File

@ -1,12 +1,15 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative "force_platform"
require_relative "match_platform" require_relative "match_platform"
module Bundler module Bundler
class LazySpecification class LazySpecification
include ForcePlatform
include MatchPlatform include MatchPlatform
attr_reader :name, :version, :dependencies, :platform attr_reader :name, :version, :dependencies, :platform
attr_writer :force_ruby_platform
attr_accessor :source, :remote attr_accessor :source, :remote
def initialize(name, version, platform, source = nil) def initialize(name, version, platform, source = nil)
@ -16,6 +19,7 @@ module Bundler
@platform = platform || Gem::Platform::RUBY @platform = platform || Gem::Platform::RUBY
@source = source @source = source
@specification = nil @specification = nil
@force_ruby_platform = nil
end end
def full_name def full_name
@ -26,6 +30,12 @@ module Bundler
end end
end end
def force_ruby_platform
return @force_ruby_platform unless @force_ruby_platform.nil?
default_force_ruby_platform
end
def ==(other) def ==(other)
identifier == other.identifier identifier == other.identifier
end end
@ -84,7 +94,7 @@ module Bundler
else else
ruby_platform_materializes_to_ruby_platform? ? self : Dependency.new(name, version) ruby_platform_materializes_to_ruby_platform? ? self : Dependency.new(name, version)
end end
platform_object = Gem::Platform.new(platform) platform_object = ruby_platform_materializes_to_ruby_platform? ? Gem::Platform.new(platform) : Gem::Platform.local
candidates = source.specs.search(search_object) candidates = source.specs.search(search_object)
same_platform_candidates = candidates.select do |spec| same_platform_candidates = candidates.select do |spec|
MatchPlatform.platforms_match?(spec.platform, platform_object) MatchPlatform.platforms_match?(spec.platform, platform_object)
@ -152,7 +162,7 @@ module Bundler
# explicitly add a more specific platform. # explicitly add a more specific platform.
# #
def ruby_platform_materializes_to_ruby_platform? def ruby_platform_materializes_to_ruby_platform?
!Bundler.most_specific_locked_platform?(Gem::Platform::RUBY) || Bundler.settings[:force_ruby_platform] !Bundler.most_specific_locked_platform?(generic_local_platform) || force_ruby_platform || Bundler.settings[:force_ruby_platform]
end end
end end
end end

View File

@ -93,6 +93,10 @@ module Bundler
"and then `bundle install` to generate a new lockfile." "and then `bundle install` to generate a new lockfile."
end end
def may_include_redundant_platform_specific_gems?
bundler_version.nil? || bundler_version < Gem::Version.new("1.16.2")
end
private private
TYPES = { TYPES = {

View File

@ -331,6 +331,30 @@ gem "nokogiri", platforms: [:mri_18, :jruby]
.P .P
All operations involving groups (\fBbundle install\fR \fIbundle\-install\.1\.html\fR, \fBBundler\.setup\fR, \fBBundler\.require\fR) behave exactly the same as if any groups not matching the current platform were explicitly excluded\. All operations involving groups (\fBbundle install\fR \fIbundle\-install\.1\.html\fR, \fBBundler\.setup\fR, \fBBundler\.require\fR) behave exactly the same as if any groups not matching the current platform were explicitly excluded\.
. .
.SS "FORCE_RUBY_PLATFORM"
If you always want the pure ruby variant of a gem to be chosen over platform specific variants, you can use the \fBforce_ruby_platform\fR option:
.
.IP "" 4
.
.nf
gem "ffi", force_ruby_platform: true
.
.fi
.
.IP "" 0
.
.P
This can be handy (assuming the pure ruby variant works fine) when:
.
.IP "\(bu" 4
You\'re having issues with the platform specific variant\.
.
.IP "\(bu" 4
The platform specific variant does not yet support a newer ruby (and thus has a \fBrequired_ruby_version\fR upper bound), but you still want your Gemfile{\.lock} files to resolve under that ruby\.
.
.IP "" 0
.
.SS "SOURCE" .SS "SOURCE"
You can select an alternate Rubygems repository for a gem using the \':source\' option\. You can select an alternate Rubygems repository for a gem using the \':source\' option\.
. .
@ -688,7 +712,7 @@ The \fB\.gemspec\fR \fIhttp://guides\.rubygems\.org/specification\-reference/\fR
If you wish to use Bundler to help install dependencies for a gem while it is being developed, use the \fBgemspec\fR method to pull in the dependencies listed in the \fB\.gemspec\fR file\. If you wish to use Bundler to help install dependencies for a gem while it is being developed, use the \fBgemspec\fR method to pull in the dependencies listed in the \fB\.gemspec\fR file\.
. .
.P .P
The \fBgemspec\fR method adds any runtime dependencies as gem requirements in the default group\. It also adds development dependencies as gem requirements in the \fBdevelopment\fR group\. Finally, it adds a gem requirement on your project (\fB:path => \'\.\'\fR)\. In conjunction with \fBBundler\.setup\fR, this allows you to require project files in your test code as you would if the project were installed as a gem; you need not manipulate the load path manually or require project files via relative paths\. The \fBgemspec\fR method adds any runtime dependencies as gem requirements in the default group\. It also adds development dependencies as gem requirements in the \fBdevelopment\fR group\. Finally, it adds a gem requirement on your project (\fBpath: \'\.\'\fR)\. In conjunction with \fBBundler\.setup\fR, this allows you to require project files in your test code as you would if the project were installed as a gem; you need not manipulate the load path manually or require project files via relative paths\.
. .
.P .P
The \fBgemspec\fR method supports optional \fB:path\fR, \fB:glob\fR, \fB:name\fR, and \fB:development_group\fR options, which control where bundler looks for the \fB\.gemspec\fR, the glob it uses to look for the gemspec (defaults to: "{,\fI,\fR/*}\.gemspec"), what named \fB\.gemspec\fR it uses (if more than one is present), and which group development dependencies are included in\. The \fBgemspec\fR method supports optional \fB:path\fR, \fB:glob\fR, \fB:name\fR, and \fB:development_group\fR options, which control where bundler looks for the \fB\.gemspec\fR, the glob it uses to look for the gemspec (defaults to: "{,\fI,\fR/*}\.gemspec"), what named \fB\.gemspec\fR it uses (if more than one is present), and which group development dependencies are included in\.

View File

@ -231,6 +231,20 @@ All operations involving groups ([`bundle install`](bundle-install.1.html), `Bun
`Bundler.require`) behave exactly the same as if any groups not `Bundler.require`) behave exactly the same as if any groups not
matching the current platform were explicitly excluded. matching the current platform were explicitly excluded.
### FORCE_RUBY_PLATFORM
If you always want the pure ruby variant of a gem to be chosen over platform
specific variants, you can use the `force_ruby_platform` option:
gem "ffi", force_ruby_platform: true
This can be handy (assuming the pure ruby variant works fine) when:
* You're having issues with the platform specific variant.
* The platform specific variant does not yet support a newer ruby (and thus has
a `required_ruby_version` upper bound), but you still want your Gemfile{.lock}
files to resolve under that ruby.
### SOURCE ### SOURCE
You can select an alternate Rubygems repository for a gem using the ':source' You can select an alternate Rubygems repository for a gem using the ':source'
@ -495,8 +509,8 @@ the `.gemspec` file.
The `gemspec` method adds any runtime dependencies as gem requirements in the The `gemspec` method adds any runtime dependencies as gem requirements in the
default group. It also adds development dependencies as gem requirements in the default group. It also adds development dependencies as gem requirements in the
`development` group. Finally, it adds a gem requirement on your project (`:path `development` group. Finally, it adds a gem requirement on your project (`path:
=> '.'`). In conjunction with `Bundler.setup`, this allows you to require project '.'`). In conjunction with `Bundler.setup`, this allows you to require project
files in your test code as you would if the project were installed as a gem; you files in your test code as you would if the project were installed as a gem; you
need not manipulate the load path manually or require project files via relative need not manipulate the load path manually or require project files via relative
paths. paths.

View File

@ -15,7 +15,6 @@ module Bundler
return true if Gem::Platform::RUBY == gemspec_platform return true if Gem::Platform::RUBY == gemspec_platform
return true if local_platform == gemspec_platform return true if local_platform == gemspec_platform
gemspec_platform = Gem::Platform.new(gemspec_platform) gemspec_platform = Gem::Platform.new(gemspec_platform)
return true if GemHelpers.generic(gemspec_platform) === local_platform
return true if gemspec_platform === local_platform return true if gemspec_platform === local_platform
false false

View File

@ -143,9 +143,12 @@ module Bundler
end end
spec_group_ruby = SpecGroup.create_for(specs_by_platform, [Gem::Platform::RUBY], Gem::Platform::RUBY) spec_group_ruby = SpecGroup.create_for(specs_by_platform, [Gem::Platform::RUBY], Gem::Platform::RUBY)
groups << spec_group_ruby if spec_group_ruby if spec_group_ruby
spec_group_ruby.force_ruby_platform = dependency.force_ruby_platform
groups << spec_group_ruby
end
next groups if @resolving_only_for_ruby next groups if @resolving_only_for_ruby || dependency.force_ruby_platform
spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform) spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform)
groups << spec_group groups << spec_group
@ -284,7 +287,7 @@ module Bundler
if specs_matching_requirement.any? if specs_matching_requirement.any?
specs = specs_matching_requirement specs = specs_matching_requirement
matching_part = requirement_label matching_part = requirement_label
requirement_label = "#{requirement_label} #{requirement.__platform}" requirement_label = "#{requirement_label}' with platform '#{requirement.__platform}"
end end
message = String.new("Could not find gem '#{requirement_label}'#{extra_message} in #{source}#{cache_message}.\n") message = String.new("Could not find gem '#{requirement_label}'#{extra_message} in #{source}#{cache_message}.\n")

View File

@ -4,7 +4,7 @@ module Bundler
class Resolver class Resolver
class SpecGroup class SpecGroup
attr_accessor :name, :version, :source attr_accessor :name, :version, :source
attr_accessor :activated_platforms attr_accessor :activated_platforms, :force_ruby_platform
def self.create_for(specs, all_platforms, specific_platform) def self.create_for(specs, all_platforms, specific_platform)
specific_platform_specs = specs[specific_platform] specific_platform_specs = specs[specific_platform]
@ -35,6 +35,7 @@ module Bundler
specs.map do |s| specs.map do |s|
lazy_spec = LazySpecification.new(name, version, s.platform, source) lazy_spec = LazySpecification.new(name, version, s.platform, source)
lazy_spec.force_ruby_platform = force_ruby_platform
lazy_spec.dependencies.replace s.dependencies lazy_spec.dependencies.replace s.dependencies
lazy_spec lazy_spec
end end
@ -88,7 +89,7 @@ module Bundler
dependencies = [] dependencies = []
@specs[platform].first.dependencies.each do |dep| @specs[platform].first.dependencies.each do |dep|
next if dep.type == :development next if dep.type == :development
dependencies << DepProxy.get_proxy(dep, platform) dependencies << DepProxy.get_proxy(Dependency.new(dep.name, dep.requirement), platform)
end end
dependencies dependencies
end end
@ -98,10 +99,10 @@ module Bundler
return [] if spec.is_a?(LazySpecification) return [] if spec.is_a?(LazySpecification)
dependencies = [] dependencies = []
unless spec.required_ruby_version.none? unless spec.required_ruby_version.none?
dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform) dependencies << DepProxy.get_proxy(Dependency.new("Ruby\0", spec.required_ruby_version), platform)
end end
unless spec.required_rubygems_version.none? unless spec.required_rubygems_version.none?
dependencies << DepProxy.get_proxy(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform) dependencies << DepProxy.get_proxy(Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
end end
dependencies dependencies
end end

View File

@ -216,32 +216,15 @@ module Gem
require "rubygems/platform" require "rubygems/platform"
class Platform class Platform
JAVA = Gem::Platform.new("java") unless defined?(JAVA) JAVA = Gem::Platform.new("java")
MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN) MSWIN = Gem::Platform.new("mswin32")
MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64) MSWIN64 = Gem::Platform.new("mswin64")
MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW) MINGW = Gem::Platform.new("x86-mingw32")
X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW) X64_MINGW = [Gem::Platform.new("x64-mingw32"),
end Gem::Platform.new("x64-mingw-ucrt")].freeze
Platform.singleton_class.module_eval do if RUBY_ENGINE == "truffleruby" && !defined?(REUSE_AS_BINARY_ON_TRUFFLERUBY)
unless Platform.singleton_methods.include?(:match_spec?) REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 sorbet-static].freeze
def match_spec?(spec)
match_gem?(spec.platform, spec.name)
end
def match_gem?(platform, gem_name)
match_platforms?(platform, Gem.platforms)
end
private
def match_platforms?(platform, platforms)
platforms.any? do |local_platform|
platform.nil? ||
local_platform == platform ||
(local_platform != Gem::Platform::RUBY && local_platform =~ platform)
end
end
end end
end end

View File

@ -24,13 +24,13 @@ module Bundler
# use a hash here to ensure constant lookup time in the `any?` call above # use a hash here to ensure constant lookup time in the `any?` call above
handled[dep.name] << dep handled[dep.name] << dep
specs_for_dep = spec_for_dependency(dep, match_current_platform) specs_for_dep = specs_for_dependency(dep, match_current_platform)
if specs_for_dep.any? if specs_for_dep.any?
specs.concat(specs_for_dep) specs.concat(specs_for_dep)
specs_for_dep.first.dependencies.each do |d| specs_for_dep.first.dependencies.each do |d|
next if d.type == :development next if d.type == :development
d = DepProxy.get_proxy(d, dep.__platform) unless match_current_platform d = DepProxy.get_proxy(Dependency.new(d.name, d.requirement), dep.__platform) unless match_current_platform
deps << d deps << d
end end
elsif check elsif check
@ -173,12 +173,13 @@ module Bundler
@specs.sort_by(&:name).each {|s| yield s } @specs.sort_by(&:name).each {|s| yield s }
end end
def spec_for_dependency(dep, match_current_platform) def specs_for_dependency(dep, match_current_platform)
specs_for_platforms = lookup[dep.name] specs_for_name = lookup[dep.name]
if match_current_platform if match_current_platform
GemHelpers.select_best_platform_match(specs_for_platforms.select {|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform) GemHelpers.select_best_platform_match(specs_for_name, Bundler.local_platform)
else else
GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform) specs_for_name_and_platform = GemHelpers.select_best_platform_match(specs_for_name, dep.force_ruby_platform ? Gem::Platform::RUBY : dep.__platform)
specs_for_name_and_platform.any? ? specs_for_name_and_platform : specs_for_name
end end
end end

View File

@ -9,11 +9,6 @@ require_relative '../rubygems'
require_relative 'command_manager' require_relative 'command_manager'
require_relative 'deprecate' require_relative 'deprecate'
##
# Load additional plugins from $LOAD_PATH
Gem.load_env_plugins rescue nil
## ##
# Run an instance of the gem program. # Run an instance of the gem program.
# #
@ -37,6 +32,9 @@ class Gem::GemRunner
do_configuration args do_configuration args
Gem.load_env_plugins rescue nil
Gem.load_plugins
cmd = @command_manager_class.instance cmd = @command_manager_class.instance
cmd.command_names.each do |command_name| cmd.command_names.each do |command_name|
@ -75,5 +73,3 @@ class Gem::GemRunner
Gem::Command.extra_args = Gem.configuration[:gem] Gem::Command.extra_args = Gem.configuration[:gem]
end end
end end
Gem.load_plugins

View File

@ -340,7 +340,7 @@ class Gem::Installer
say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil? say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil?
Gem::Specification.reset Gem::Specification.add_spec(spec)
run_post_install_hooks run_post_install_hooks

View File

@ -159,6 +159,10 @@ class Gem::Platform
def ===(other) def ===(other)
return nil unless Gem::Platform === other return nil unless Gem::Platform === other
# universal-mingw32 matches x64-mingw-ucrt
return true if (@cpu == 'universal' or other.cpu == 'universal') and
@os.start_with?('mingw') and other.os.start_with?('mingw')
# cpu # cpu
([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or ([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or
(@cpu == 'arm' and other.cpu.start_with?("arm"))) and (@cpu == 'arm' and other.cpu.start_with?("arm"))) and

View File

@ -882,6 +882,21 @@ class Gem::Specification < Gem::BasicSpecification
end end
end end
##
# Adds +spec+ to the known specifications, keeping the collection
# properly sorted.
def self.add_spec(spec)
return if _all.include? spec
_all << spec
stubs << spec
(@@stubs_by_name[spec.name] ||= []) << spec
_resort!(@@stubs_by_name[spec.name])
_resort!(stubs)
end
## ##
# Returns all specifications. This method is discouraged from use. # Returns all specifications. This method is discouraged from use.
# You probably want to use one of the Enumerable methods instead. # You probably want to use one of the Enumerable methods instead.

View File

@ -136,7 +136,7 @@ RSpec.describe Bundler::Definition do
only_java (1.1-java) only_java (1.1-java)
PLATFORMS PLATFORMS
#{lockfile_platforms_for(["java"] + local_platforms)} #{lockfile_platforms_for(["java", specific_local_platform])}
DEPENDENCIES DEPENDENCIES
only_java only_java

View File

@ -217,7 +217,7 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile) lockfile = Bundler::LockfileParser.new(read_lockfile)
expect(lockfile.platforms).to match_array(local_platforms.unshift(java, mingw).uniq) expect(lockfile.platforms).to match_array([java, mingw, specific_local_platform].uniq)
end end
it "supports adding new platforms with force_ruby_platform = true" do it "supports adding new platforms with force_ruby_platform = true" do
@ -249,7 +249,7 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile) lockfile = Bundler::LockfileParser.new(read_lockfile)
expect(lockfile.platforms).to match_array(local_platforms.unshift("ruby").uniq) expect(lockfile.platforms).to match_array(["ruby", specific_local_platform].uniq)
end end
it "warns when adding an unknown platform" do it "warns when adding an unknown platform" do
@ -262,16 +262,16 @@ RSpec.describe "bundle lock" do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
lockfile = Bundler::LockfileParser.new(read_lockfile) lockfile = Bundler::LockfileParser.new(read_lockfile)
expect(lockfile.platforms).to match_array(local_platforms.unshift(java, mingw).uniq) expect(lockfile.platforms).to match_array([java, mingw, specific_local_platform].uniq)
bundle "lock --remove-platform java" bundle "lock --remove-platform java"
lockfile = Bundler::LockfileParser.new(read_lockfile) lockfile = Bundler::LockfileParser.new(read_lockfile)
expect(lockfile.platforms).to match_array(local_platforms.unshift(mingw).uniq) expect(lockfile.platforms).to match_array([mingw, specific_local_platform].uniq)
end end
it "errors when removing all platforms" do it "errors when removing all platforms" do
bundle "lock --remove-platform #{local_platforms.join(" ")}", :raise_on_error => false bundle "lock --remove-platform #{specific_local_platform}", :raise_on_error => false
expect(err).to include("Removing all platforms from the bundle is not allowed") expect(err).to include("Removing all platforms from the bundle is not allowed")
end end

View File

@ -821,7 +821,7 @@ RSpec.describe "bundle outdated" do
expect(out).to end_with("Bundle up to date!") expect(out).to end_with("Bundle up to date!")
end end
it "reports that updates are available if the JRuby platform is used", :jruby do it "reports that updates are available if the JRuby platform is used", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}" source "#{file_uri_for(gem_repo2)}"
gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby] gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby]

View File

@ -0,0 +1,118 @@
# frozen_string_literal: true
RSpec.describe "bundle install with force_ruby_platform DSL option", :jruby do
context "when no transitive deps" do
before do
build_repo4 do
# Build a gem with platform specific versions
build_gem("platform_specific") do |s|
s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 RUBY'"
end
build_gem("platform_specific") do |s|
s.platform = Bundler.local_platform
s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'"
end
# Build the exact same gem with a different name to compare using vs not using the option
build_gem("platform_specific_forced") do |s|
s.write "lib/platform_specific_forced.rb", "PLATFORM_SPECIFIC_FORCED = '1.0.0 RUBY'"
end
build_gem("platform_specific_forced") do |s|
s.platform = Bundler.local_platform
s.write "lib/platform_specific_forced.rb", "PLATFORM_SPECIFIC_FORCED = '1.0.0 #{Bundler.local_platform}'"
end
end
end
it "pulls the pure ruby variant of the given gem" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "platform_specific_forced", :force_ruby_platform => true
gem "platform_specific"
G
expect(the_bundle).to include_gems "platform_specific_forced 1.0.0 RUBY"
expect(the_bundle).to include_gems "platform_specific 1.0.0 #{Bundler.local_platform}"
end
it "still respects a global `force_ruby_platform` config" do
install_gemfile <<-G, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" }
source "#{file_uri_for(gem_repo4)}"
gem "platform_specific_forced", :force_ruby_platform => true
gem "platform_specific"
G
expect(the_bundle).to include_gems "platform_specific_forced 1.0.0 RUBY"
expect(the_bundle).to include_gems "platform_specific 1.0.0 RUBY"
end
end
context "when also a transitive dependency" do
before do
build_repo4 do
build_gem("depends_on_platform_specific") {|s| s.add_runtime_dependency "platform_specific" }
build_gem("platform_specific") do |s|
s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 RUBY'"
end
build_gem("platform_specific") do |s|
s.platform = Bundler.local_platform
s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'"
end
end
end
it "still pulls the ruby variant" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "depends_on_platform_specific"
gem "platform_specific", :force_ruby_platform => true
G
expect(the_bundle).to include_gems "platform_specific 1.0.0 RUBY"
end
end
context "with transitive dependencies with platform specific versions" do
before do
build_repo4 do
build_gem("depends_on_platform_specific") do |s|
s.add_runtime_dependency "platform_specific"
s.write "lib/depends_on_platform_specific.rb", "DEPENDS_ON_PLATFORM_SPECIFIC = '1.0.0 RUBY'"
end
build_gem("depends_on_platform_specific") do |s|
s.add_runtime_dependency "platform_specific"
s.platform = Bundler.local_platform
s.write "lib/depends_on_platform_specific.rb", "DEPENDS_ON_PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'"
end
build_gem("platform_specific") do |s|
s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 RUBY'"
end
build_gem("platform_specific") do |s|
s.platform = Bundler.local_platform
s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'"
end
end
end
it "ignores ruby variants for the transitive dependencies" do
install_gemfile <<-G, :env => { "DEBUG_RESOLVER" => "true" }
source "#{file_uri_for(gem_repo4)}"
gem "depends_on_platform_specific", :force_ruby_platform => true
G
expect(the_bundle).to include_gems "depends_on_platform_specific 1.0.0 RUBY"
expect(the_bundle).to include_gems "platform_specific 1.0.0 #{Bundler.local_platform}"
end
end
end

View File

@ -8,6 +8,26 @@ RSpec.describe "bundle install from an existing gemspec" do
end end
end end
let(:x64_mingw_archs) do
if RUBY_PLATFORM == "x64-mingw-ucrt"
if Gem.rubygems_version >= Gem::Version.new("3.2.28")
["x64-mingw-ucrt", "x64-mingw32"]
else
["x64-mingw32", "x64-unknown"]
end
else
["x64-mingw32"]
end
end
let(:x64_mingw_gems) do
x64_mingw_archs.map {|p| "platform_specific (1.0-#{p})" }.join("\n ")
end
let(:x64_mingw_platforms) do
x64_mingw_archs.join("\n ")
end
it "should install runtime and development dependencies" do it "should install runtime and development dependencies" do
build_lib("foo", :path => tmp.join("foo")) do |s| build_lib("foo", :path => tmp.join("foo")) do |s|
s.write("Gemfile", "source :rubygems\ngemspec") s.write("Gemfile", "source :rubygems\ngemspec")
@ -168,7 +188,7 @@ RSpec.describe "bundle install from an existing gemspec" do
expect(out.scan(message).size).to eq(1) expect(out.scan(message).size).to eq(1)
end end
it "should match a lockfile on non-ruby platforms with a transitive platform dependency", :jruby do it "should match a lockfile on non-ruby platforms with a transitive platform dependency", :jruby_only do
build_lib("foo", :path => tmp.join("foo")) do |s| build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "platform_specific" s.add_dependency "platform_specific"
end end
@ -328,12 +348,7 @@ RSpec.describe "bundle install from an existing gemspec" do
context "with a lockfile and some missing dependencies" do context "with a lockfile and some missing dependencies" do
let(:source_uri) { "http://localgemserver.test" } let(:source_uri) { "http://localgemserver.test" }
context "previously bundled for Ruby" do
let(:platform) { "ruby" }
before do before do
skip "not installing for some reason" if Gem.win_platform?
build_lib("foo", :path => tmp.join("foo")) do |s| build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "rack", "=1.0.0" s.add_dependency "rack", "=1.0.0"
end end
@ -366,7 +381,7 @@ RSpec.describe "bundle install from an existing gemspec" do
L L
end end
context "using JRuby with explicit platform", :jruby do context "using JRuby with explicit platform", :jruby_only do
before do before do
create_file( create_file(
tmp.join("foo", "foo-java.gemspec"), tmp.join("foo", "foo-java.gemspec"),
@ -385,26 +400,13 @@ RSpec.describe "bundle install from an existing gemspec" do
end end
end end
context "using JRuby", :jruby do it "should install", :jruby do
it "should install" do
results = bundle "install", :artifice => "endpoint" results = bundle "install", :artifice => "endpoint"
expect(results).to include("Installing rack 1.0.0") expect(results).to include("Installing rack 1.0.0")
expect(the_bundle).to include_gems "rack 1.0.0" expect(the_bundle).to include_gems "rack 1.0.0"
end end
end
context "using Windows" do context "bundled for multiple platforms" do
it "should install" do
simulate_windows do
results = bundle "install", :artifice => "endpoint"
expect(results).to include("Installing rack 1.0.0")
expect(the_bundle).to include_gems "rack 1.0.0"
end
end
end
end
context "bundled for ruby and jruby" do
let(:platform_specific_type) { :runtime } let(:platform_specific_type) { :runtime }
let(:dependency) { "platform_specific" } let(:dependency) { "platform_specific" }
before do before do
@ -434,6 +436,7 @@ RSpec.describe "bundle install from an existing gemspec" do
simulate_new_machine simulate_new_machine
simulate_platform("jruby") { bundle "install" } simulate_platform("jruby") { bundle "install" }
simulate_platform(x64_mingw) { bundle "install" }
end end
context "on ruby" do context "on ruby" do
@ -443,7 +446,7 @@ RSpec.describe "bundle install from an existing gemspec" do
end end
context "as a runtime dependency" do context "as a runtime dependency" do
it "keeps java dependencies in the lockfile" do it "keeps all platform dependencies in the lockfile" do
expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY"
expect(lockfile).to eq strip_whitespace(<<-L) expect(lockfile).to eq strip_whitespace(<<-L)
PATH PATH
@ -457,10 +460,12 @@ RSpec.describe "bundle install from an existing gemspec" do
specs: specs:
platform_specific (1.0) platform_specific (1.0)
platform_specific (1.0-java) platform_specific (1.0-java)
#{x64_mingw_gems}
PLATFORMS PLATFORMS
java java
ruby ruby
#{x64_mingw_platforms}
DEPENDENCIES DEPENDENCIES
foo! foo!
@ -474,7 +479,7 @@ RSpec.describe "bundle install from an existing gemspec" do
context "as a development dependency" do context "as a development dependency" do
let(:platform_specific_type) { :development } let(:platform_specific_type) { :development }
it "keeps java dependencies in the lockfile" do it "keeps all platform dependencies in the lockfile" do
expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY"
expect(lockfile).to eq strip_whitespace(<<-L) expect(lockfile).to eq strip_whitespace(<<-L)
PATH PATH
@ -487,10 +492,12 @@ RSpec.describe "bundle install from an existing gemspec" do
specs: specs:
platform_specific (1.0) platform_specific (1.0)
platform_specific (1.0-java) platform_specific (1.0-java)
#{x64_mingw_gems}
PLATFORMS PLATFORMS
java java
ruby ruby
#{x64_mingw_platforms}
DEPENDENCIES DEPENDENCIES
foo! foo!
@ -506,7 +513,7 @@ RSpec.describe "bundle install from an existing gemspec" do
let(:platform_specific_type) { :development } let(:platform_specific_type) { :development }
let(:dependency) { "indirect_platform_specific" } let(:dependency) { "indirect_platform_specific" }
it "keeps java dependencies in the lockfile" do it "keeps all platform dependencies in the lockfile" do
expect(the_bundle).to include_gems "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 RUBY" expect(the_bundle).to include_gems "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 RUBY"
expect(lockfile).to eq strip_whitespace(<<-L) expect(lockfile).to eq strip_whitespace(<<-L)
PATH PATH
@ -521,10 +528,12 @@ RSpec.describe "bundle install from an existing gemspec" do
platform_specific platform_specific
platform_specific (1.0) platform_specific (1.0)
platform_specific (1.0-java) platform_specific (1.0-java)
#{x64_mingw_gems}
PLATFORMS PLATFORMS
java java
ruby ruby
#{x64_mingw_platforms}
DEPENDENCIES DEPENDENCIES
foo! foo!
@ -608,7 +617,7 @@ RSpec.describe "bundle install from an existing gemspec" do
PLATFORMS PLATFORMS
ruby ruby
x64-mingw32 #{x64_mingw_platforms}
x86-mingw32 x86-mingw32
DEPENDENCIES DEPENDENCIES
@ -665,7 +674,7 @@ RSpec.describe "bundle install from an existing gemspec" do
railties (6.1.4) railties (6.1.4)
PLATFORMS PLATFORMS
#{lockfile_platforms_for(["java"] + local_platforms)} #{lockfile_platforms_for(["java", specific_local_platform])}
DEPENDENCIES DEPENDENCIES
activeadmin! activeadmin!

View File

@ -92,7 +92,7 @@ RSpec.describe "bundle install with git sources" do
expect(err).to include("The source contains the following gems matching 'foo':\n * foo-1.0") expect(err).to include("The source contains the following gems matching 'foo':\n * foo-1.0")
end end
it "complains with version and platform if pinned specs don't exist in the git repo", :jruby do it "complains with version and platform if pinned specs don't exist in the git repo", :jruby_only do
build_git "only_java" do |s| build_git "only_java" do |s|
s.platform = "java" s.platform = "java"
end end
@ -107,7 +107,7 @@ RSpec.describe "bundle install with git sources" do
expect(err).to include("The source contains the following gems matching 'only_java':\n * only_java-1.0-java") expect(err).to include("The source contains the following gems matching 'only_java':\n * only_java-1.0-java")
end end
it "complains with multiple versions and platforms if pinned specs don't exist in the git repo", :jruby do it "complains with multiple versions and platforms if pinned specs don't exist in the git repo", :jruby_only do
build_git "only_java", "1.0" do |s| build_git "only_java", "1.0" do |s|
s.platform = "java" s.platform = "java"
end end

View File

@ -50,7 +50,7 @@ RSpec.describe "bundle install across platforms" do
expect(the_bundle).to include_gems "platform_specific 1.0 JAVA" expect(the_bundle).to include_gems "platform_specific 1.0 JAVA"
end end
it "pulls the pure ruby version on jruby if the java platform is not present in the lockfile and bundler is run in frozen mode", :jruby do it "pulls the pure ruby version on jruby if the java platform is not present in the lockfile and bundler is run in frozen mode", :jruby_only do
lockfile <<-G lockfile <<-G
GEM GEM
remote: #{file_uri_for(gem_repo1)} remote: #{file_uri_for(gem_repo1)}
@ -216,28 +216,28 @@ RSpec.describe "bundle install across platforms" do
pry pry
BUNDLED WITH BUNDLED WITH
#{Bundler::VERSION} 1.16.1
L L
aggregate_failures do aggregate_failures do
lockfile bad_lockfile lockfile bad_lockfile
bundle :install bundle :install, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile expect(lockfile).to eq good_lockfile
lockfile bad_lockfile lockfile bad_lockfile
bundle :update, :all => true bundle :update, :all => true, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile expect(lockfile).to eq good_lockfile
lockfile bad_lockfile lockfile bad_lockfile
bundle "update ffi" bundle "update ffi", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile expect(lockfile).to eq good_lockfile
lockfile bad_lockfile lockfile bad_lockfile
bundle "update empyrean" bundle "update empyrean", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile expect(lockfile).to eq good_lockfile
lockfile bad_lockfile lockfile bad_lockfile
bundle :lock bundle :lock, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile expect(lockfile).to eq good_lockfile
end end
end end
@ -332,8 +332,6 @@ end
RSpec.describe "bundle install with platform conditionals" do RSpec.describe "bundle install with platform conditionals" do
it "installs gems tagged w/ the current platforms" do it "installs gems tagged w/ the current platforms" do
skip "platform issues" if Gem.win_platform?
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
@ -402,8 +400,6 @@ RSpec.describe "bundle install with platform conditionals" do
end end
it "installs gems tagged w/ the current platforms inline" do it "installs gems tagged w/ the current platforms inline" do
skip "platform issues" if Gem.win_platform?
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "nokogiri", :platforms => :#{local_tag} gem "nokogiri", :platforms => :#{local_tag}
@ -422,8 +418,6 @@ RSpec.describe "bundle install with platform conditionals" do
end end
it "installs gems tagged w/ the current platform inline" do it "installs gems tagged w/ the current platform inline" do
skip "platform issues" if Gem.win_platform?
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "nokogiri", :platform => :#{local_tag} gem "nokogiri", :platform => :#{local_tag}

View File

@ -250,10 +250,11 @@ RSpec.describe "bundle install with specific platforms" do
end end
end end
it "installs sorbet-static, which does not provide a pure ruby variant, just fine on truffleruby", :truffleruby do it "installs sorbet-static, which does not provide a pure ruby variant, just fine", :truffleruby do
skip "does not apply to Windows" if Gem.win_platform?
build_repo2 do build_repo2 do
build_gem("sorbet-static", "0.5.6403") {|s| s.platform = "x86_64-linux" } build_gem("sorbet-static", "0.5.6403") {|s| s.platform = Bundler.local_platform }
build_gem("sorbet-static", "0.5.6403") {|s| s.platform = "universal-darwin-20" }
end end
gemfile <<~G gemfile <<~G
@ -266,8 +267,7 @@ RSpec.describe "bundle install with specific platforms" do
GEM GEM
remote: #{file_uri_for(gem_repo2)}/ remote: #{file_uri_for(gem_repo2)}/
specs: specs:
sorbet-static (0.5.6403-universal-darwin-20) sorbet-static (0.5.6403-#{Bundler.local_platform})
sorbet-static (0.5.6403-x86_64-linux)
PLATFORMS PLATFORMS
ruby ruby
@ -283,19 +283,19 @@ RSpec.describe "bundle install with specific platforms" do
end end
it "does not resolve if the current platform does not match any of available platform specific variants for a top level dependency" do it "does not resolve if the current platform does not match any of available platform specific variants for a top level dependency" do
build_repo2 do build_repo4 do
build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "x86_64-linux" } build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "x86_64-linux" }
build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "universal-darwin-20" } build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "universal-darwin-20" }
end end
gemfile <<~G gemfile <<~G
source "#{file_uri_for(gem_repo2)}" source "#{file_uri_for(gem_repo4)}"
gem "sorbet-static", "0.5.6433" gem "sorbet-static", "0.5.6433"
G G
error_message = <<~ERROR.strip error_message = <<~ERROR.strip
Could not find gem 'sorbet-static (= 0.5.6433) arm64-darwin-21' in rubygems repository #{file_uri_for(gem_repo2)}/ or installed locally. Could not find gem 'sorbet-static (= 0.5.6433)' with platform 'arm64-darwin-21' in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
The source contains the following gems matching 'sorbet-static (= 0.5.6433)': The source contains the following gems matching 'sorbet-static (= 0.5.6433)':
* sorbet-static-0.5.6433-universal-darwin-20 * sorbet-static-0.5.6433-universal-darwin-20
@ -303,7 +303,7 @@ RSpec.describe "bundle install with specific platforms" do
ERROR ERROR
simulate_platform "arm64-darwin-21" do simulate_platform "arm64-darwin-21" do
bundle "install", :raise_on_error => false bundle "lock", :raise_on_error => false
end end
expect(err).to include(error_message).once expect(err).to include(error_message).once
@ -311,27 +311,27 @@ RSpec.describe "bundle install with specific platforms" do
# Make sure it doesn't print error twice in verbose mode # Make sure it doesn't print error twice in verbose mode
simulate_platform "arm64-darwin-21" do simulate_platform "arm64-darwin-21" do
bundle "install --verbose", :raise_on_error => false bundle "lock --verbose", :raise_on_error => false
end end
expect(err).to include(error_message).once expect(err).to include(error_message).once
end end
it "does not resolve if the current platform does not match any of available platform specific variants for a transitive dependency" do it "does not resolve if the current platform does not match any of available platform specific variants for a transitive dependency" do
build_repo2 do build_repo4 do
build_gem("sorbet", "0.5.6433") {|s| s.add_dependency "sorbet-static", "= 0.5.6433" } build_gem("sorbet", "0.5.6433") {|s| s.add_dependency "sorbet-static", "= 0.5.6433" }
build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "x86_64-linux" } build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "x86_64-linux" }
build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "universal-darwin-20" } build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "universal-darwin-20" }
end end
gemfile <<~G gemfile <<~G
source "#{file_uri_for(gem_repo2)}" source "#{file_uri_for(gem_repo4)}"
gem "sorbet", "0.5.6433" gem "sorbet", "0.5.6433"
G G
error_message = <<~ERROR.strip error_message = <<~ERROR.strip
Could not find gem 'sorbet-static (= 0.5.6433) arm64-darwin-21', which is required by gem 'sorbet (= 0.5.6433)', in rubygems repository #{file_uri_for(gem_repo2)}/ or installed locally. Could not find gem 'sorbet-static (= 0.5.6433)' with platform 'arm64-darwin-21', which is required by gem 'sorbet (= 0.5.6433)', in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
The source contains the following gems matching 'sorbet-static (= 0.5.6433)': The source contains the following gems matching 'sorbet-static (= 0.5.6433)':
* sorbet-static-0.5.6433-universal-darwin-20 * sorbet-static-0.5.6433-universal-darwin-20
@ -339,7 +339,7 @@ RSpec.describe "bundle install with specific platforms" do
ERROR ERROR
simulate_platform "arm64-darwin-21" do simulate_platform "arm64-darwin-21" do
bundle "install", :raise_on_error => false bundle "lock", :raise_on_error => false
end end
expect(err).to include(error_message).once expect(err).to include(error_message).once
@ -347,12 +347,33 @@ RSpec.describe "bundle install with specific platforms" do
# Make sure it doesn't print error twice in verbose mode # Make sure it doesn't print error twice in verbose mode
simulate_platform "arm64-darwin-21" do simulate_platform "arm64-darwin-21" do
bundle "install --verbose", :raise_on_error => false bundle "lock --verbose", :raise_on_error => false
end end
expect(err).to include(error_message).once expect(err).to include(error_message).once
end end
it "does not generate a lockfile if RUBY platform is forced and some gem has no RUBY variant available" do
build_repo4 do
build_gem("sorbet-static", "0.5.9889") {|s| s.platform = Gem::Platform.local }
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "sorbet-static", "0.5.9889"
G
bundle "lock", :raise_on_error => false, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" }
expect(err).to include <<~ERROR.rstrip
Could not find gem 'sorbet-static (= 0.5.9889)' with platform 'ruby' in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
The source contains the following gems matching 'sorbet-static (= 0.5.9889)':
* sorbet-static-0.5.9889-#{Gem::Platform.local}
ERROR
end
private private
def setup_multiplatform_gem def setup_multiplatform_gem

View File

@ -66,7 +66,7 @@ RSpec.describe "bundle install" do
end end
end end
context "with engine specified in symbol", :jruby do context "with engine specified in symbol", :jruby_only do
it "does not raise any error parsing Gemfile" do it "does not raise any error parsing Gemfile" do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"

View File

@ -187,11 +187,7 @@ RSpec.describe "bundle install with install-time dependencies" do
bundle :install, :env => { "DEBUG_RESOLVER_TREE" => "1", "DEBUG" => "1" } bundle :install, :env => { "DEBUG_RESOLVER_TREE" => "1", "DEBUG" => "1" }
activated_groups = if local_platforms.any? activated_groups = "net_b (1.0) (ruby), net_b (1.0) (#{specific_local_platform})"
"net_b (1.0) (ruby), net_b (1.0) (#{local_platforms.join(", ")})"
else
"net_b (1.0) (ruby)"
end
expect(out).to include(" net_b"). expect(out).to include(" net_b").
and include("BUNDLER: Starting resolution"). and include("BUNDLER: Starting resolution").

View File

@ -982,7 +982,7 @@ RSpec.describe "the lockfile format" do
rack (1.0.0) rack (1.0.0)
PLATFORMS PLATFORMS
#{lockfile_platforms_for(["java"] + local_platforms)} #{lockfile_platforms_for(["java", specific_local_platform])}
DEPENDENCIES DEPENDENCIES
rack rack

View File

@ -44,6 +44,10 @@ RSpec.describe "Bundler::GemHelpers#generic" do
expect(generic(pl("x64-mingw32"))).to eq(pl("x64-mingw32")) expect(generic(pl("x64-mingw32"))).to eq(pl("x64-mingw32"))
expect(generic(pl("x86_64-mingw32"))).to eq(pl("x64-mingw32")) expect(generic(pl("x86_64-mingw32"))).to eq(pl("x64-mingw32"))
end end
it "converts 64-bit mingw UCRT platform variants into x64-mingw-ucrt" do
expect(generic(pl("x64-mingw-ucrt"))).to eq(pl("x64-mingw-ucrt"))
end
end end
RSpec.describe "Gem::SourceIndex#refresh!" do RSpec.describe "Gem::SourceIndex#refresh!" do

View File

@ -2,10 +2,6 @@
RSpec.describe "bundle platform" do RSpec.describe "bundle platform" do
context "without flags" do context "without flags" do
let(:bundle_platform_platforms_string) do
local_platforms.reverse.map {|pl| "* #{pl}" }.join("\n")
end
it "returns all the output" do it "returns all the output" do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
@ -20,7 +16,7 @@ RSpec.describe "bundle platform" do
Your platform is: #{Gem::Platform.local} Your platform is: #{Gem::Platform.local}
Your app has gems that work on these platforms: Your app has gems that work on these platforms:
#{bundle_platform_platforms_string} * #{specific_local_platform}
Your Gemfile specifies a Ruby version requirement: Your Gemfile specifies a Ruby version requirement:
* ruby #{RUBY_VERSION} * ruby #{RUBY_VERSION}
@ -43,7 +39,7 @@ G
Your platform is: #{Gem::Platform.local} Your platform is: #{Gem::Platform.local}
Your app has gems that work on these platforms: Your app has gems that work on these platforms:
#{bundle_platform_platforms_string} * #{specific_local_platform}
Your Gemfile specifies a Ruby version requirement: Your Gemfile specifies a Ruby version requirement:
* ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} * ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}
@ -64,7 +60,7 @@ G
Your platform is: #{Gem::Platform.local} Your platform is: #{Gem::Platform.local}
Your app has gems that work on these platforms: Your app has gems that work on these platforms:
#{bundle_platform_platforms_string} * #{specific_local_platform}
Your Gemfile does not specify a Ruby version requirement. Your Gemfile does not specify a Ruby version requirement.
G G
@ -84,7 +80,7 @@ G
Your platform is: #{Gem::Platform.local} Your platform is: #{Gem::Platform.local}
Your app has gems that work on these platforms: Your app has gems that work on these platforms:
#{bundle_platform_platforms_string} * #{specific_local_platform}
Your Gemfile specifies a Ruby version requirement: Your Gemfile specifies a Ruby version requirement:
* ruby #{not_local_ruby_version} * ruby #{not_local_ruby_version}
@ -305,7 +301,7 @@ G
expect(bundled_app_lock).to exist expect(bundled_app_lock).to exist
end end
it "installs fine with any engine", :jruby do it "installs fine with any engine", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rack" gem "rack"
@ -351,7 +347,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "doesn't install when engine version doesn't match", :jruby do it "doesn't install when engine version doesn't match", :jruby_only do
install_gemfile <<-G, :raise_on_error => false install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rack" gem "rack"
@ -394,7 +390,7 @@ G
expect(out).to match(/\AResolving dependencies\.\.\.\.*\nThe Gemfile's dependencies are satisfied\z/) expect(out).to match(/\AResolving dependencies\.\.\.\.*\nThe Gemfile's dependencies are satisfied\z/)
end end
it "checks fine with any engine", :jruby do it "checks fine with any engine", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rack" gem "rack"
@ -445,7 +441,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "fails when engine version doesn't match", :jruby do it "fails when engine version doesn't match", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rack" gem "rack"
@ -511,7 +507,7 @@ G
expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0" expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
end end
it "updates fine with any engine", :jruby do it "updates fine with any engine", :jruby_only do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo2)}" source "#{file_uri_for(gem_repo2)}"
gem "activesupport" gem "activesupport"
@ -547,7 +543,7 @@ G
should_be_ruby_version_incorrect should_be_ruby_version_incorrect
end end
it "fails when ruby engine doesn't match", :jruby do it "fails when ruby engine doesn't match", :jruby_only do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo2)}" source "#{file_uri_for(gem_repo2)}"
gem "activesupport" gem "activesupport"
@ -563,7 +559,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "fails when ruby engine version doesn't match", :jruby do it "fails when ruby engine version doesn't match", :jruby_only do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo2)}" source "#{file_uri_for(gem_repo2)}"
gem "activesupport" gem "activesupport"
@ -615,7 +611,7 @@ G
expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s) expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
end end
it "prints path if ruby version is correct for any engine", :jruby do it "prints path if ruby version is correct for any engine", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rails" gem "rails"
@ -651,7 +647,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "fails if engine version doesn't match", :bundler => "< 3", :jruby => true do it "fails if engine version doesn't match", :bundler => "< 3", :jruby_only => true do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rails" gem "rails"
@ -699,7 +695,7 @@ G
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
end end
it "copies the .gem file to vendor/cache when ruby version matches for any engine", :jruby do it "copies the .gem file to vendor/cache when ruby version matches for any engine", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem 'rack' gem 'rack'
@ -735,7 +731,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "fails if the engine version doesn't match", :jruby do it "fails if the engine version doesn't match", :jruby_only do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem 'rack' gem 'rack'
@ -780,7 +776,7 @@ G
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
end end
it "copies the .gem file to vendor/cache when ruby version matches any engine", :jruby do it "copies the .gem file to vendor/cache when ruby version matches any engine", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem 'rack' gem 'rack'
@ -816,7 +812,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "fails if the engine version doesn't match", :jruby do it "fails if the engine version doesn't match", :jruby_only do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem 'rack' gem 'rack'
@ -859,7 +855,7 @@ G
expect(out).to include("0.9.1") expect(out).to include("0.9.1")
end end
it "activates the correct gem when ruby version matches any engine", :jruby do it "activates the correct gem when ruby version matches any engine", :jruby_only do
system_gems "rack-1.0.0", "rack-0.9.1", :path => default_bundle_path system_gems "rack-1.0.0", "rack-0.9.1", :path => default_bundle_path
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
@ -896,7 +892,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
# it "fails when the engine version doesn't match", :jruby do # it "fails when the engine version doesn't match", :jruby_only do
# gemfile <<-G # gemfile <<-G
# gem "rack", "0.9.1" # gem "rack", "0.9.1"
# #
@ -947,7 +943,7 @@ G
expect(out).to include("0.9.1") expect(out).to include("0.9.1")
end end
it "starts IRB with the default group loaded when ruby version matches", :readline, :jruby do it "starts IRB with the default group loaded when ruby version matches", :readline, :jruby_only do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rack" gem "rack"
@ -992,7 +988,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "fails when engine version doesn't match", :jruby do it "fails when engine version doesn't match", :jruby_only do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rack" gem "rack"
@ -1047,7 +1043,7 @@ G
expect(bundled_app_lock).to exist expect(bundled_app_lock).to exist
end end
it "makes a Gemfile.lock if setup succeeds for any engine", :jruby do it "makes a Gemfile.lock if setup succeeds for any engine", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "yard" gem "yard"
@ -1096,7 +1092,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "fails when engine version doesn't match", :jruby do it "fails when engine version doesn't match", :jruby_only do
install_gemfile <<-G, :raise_on_error => false install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "yard" gem "yard"
@ -1169,7 +1165,7 @@ G
expect(out).to match(Regexp.new(expected_output)) expect(out).to match(Regexp.new(expected_output))
end end
it "returns list of outdated gems when the ruby version matches for any engine", :jruby do it "returns list of outdated gems when the ruby version matches for any engine", :jruby_only do
bundle :install bundle :install
update_repo2 do update_repo2 do
build_gem "activesupport", "3.0" build_gem "activesupport", "3.0"
@ -1231,7 +1227,7 @@ G
should_be_engine_incorrect should_be_engine_incorrect
end end
it "fails when the engine version doesn't match", :jruby do it "fails when the engine version doesn't match", :jruby_only do
update_repo2 do update_repo2 do
build_gem "activesupport", "3.0" build_gem "activesupport", "3.0"
update_git "foo", :path => lib_path("foo") update_git "foo", :path => lib_path("foo")
@ -1249,7 +1245,7 @@ G
should_be_engine_version_incorrect should_be_engine_version_incorrect
end end
it "fails when the patchlevel doesn't match", :jruby do it "fails when the patchlevel doesn't match", :jruby_only do
update_repo2 do update_repo2 do
build_gem "activesupport", "3.0" build_gem "activesupport", "3.0"
update_git "foo", :path => lib_path("foo") update_git "foo", :path => lib_path("foo")
@ -1267,7 +1263,7 @@ G
should_be_patchlevel_incorrect should_be_patchlevel_incorrect
end end
it "fails when the patchlevel is a fixnum", :jruby do it "fails when the patchlevel is a fixnum", :jruby_only do
update_repo2 do update_repo2 do
build_gem "activesupport", "3.0" build_gem "activesupport", "3.0"
update_git "foo", :path => lib_path("foo") update_git "foo", :path => lib_path("foo")

View File

@ -291,7 +291,7 @@ RSpec.describe "Resolving platform craziness" do
describe "with mingw32" do describe "with mingw32" do
before :each do before :each do
@index = build_index do @index = build_index do
platforms "mingw32 mswin32 x64-mingw32" do |platform| platforms "mingw32 mswin32 x64-mingw32 x64-mingw-ucrt" do |platform|
gem "thin", "1.2.7", platform gem "thin", "1.2.7", platform
end end
gem "win32-api", "1.5.1", "universal-mingw32" gem "win32-api", "1.5.1", "universal-mingw32"
@ -312,7 +312,7 @@ RSpec.describe "Resolving platform craziness" do
should_resolve_as %w[thin-1.2.7-mingw32] should_resolve_as %w[thin-1.2.7-mingw32]
end end
it "finds x64-mingw gems" do it "finds x64-mingw32 gems" do
platforms "x64-mingw32" platforms "x64-mingw32"
dep "thin" dep "thin"
should_resolve_as %w[thin-1.2.7-x64-mingw32] should_resolve_as %w[thin-1.2.7-x64-mingw32]
@ -329,6 +329,22 @@ RSpec.describe "Resolving platform craziness" do
dep "win32-api" dep "win32-api"
should_resolve_as %w[win32-api-1.5.1-universal-mingw32] should_resolve_as %w[win32-api-1.5.1-universal-mingw32]
end end
if Gem.rubygems_version >= Gem::Version.new("3.2.28")
it "finds x64-mingw-ucrt gems" do
platforms "x64-mingw-ucrt"
dep "thin"
should_resolve_as %w[thin-1.2.7-x64-mingw-ucrt]
end
end
if Gem.rubygems_version >= Gem::Version.new("3.3.18")
it "finds universal-mingw gems on x64-mingw-ucrt" do
platform "x64-mingw-ucrt"
dep "win32-api"
should_resolve_as %w[win32-api-1.5.1-universal-mingw32]
end
end
end end
describe "with conflicting cases" do describe "with conflicting cases" do

View File

@ -86,7 +86,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
racc (1.5.2) racc (1.5.2)
PLATFORMS PLATFORMS
#{lockfile_platforms_for(["ruby"] + local_platforms)} #{lockfile_platforms_for(["ruby", specific_local_platform])}
DEPENDENCIES DEPENDENCIES
nokogiri (~> 1.11) nokogiri (~> 1.11)
@ -145,7 +145,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(the_bundle).not_to include_gems "nokogiri 1.11.1 #{Bundler.local_platform}" expect(the_bundle).not_to include_gems "nokogiri 1.11.1 #{Bundler.local_platform}"
end end
it "will use the java platform if both generic java and generic ruby platforms are locked", :jruby do it "will use the java platform if both generic java and generic ruby platforms are locked", :jruby_only do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "nokogiri" gem "nokogiri"
@ -204,7 +204,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 x86-darwin-100" expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 x86-darwin-100"
end end
it "allows specifying only-ruby-platform on jruby", :jruby do it "allows specifying only-ruby-platform on jruby", :jruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "nokogiri" gem "nokogiri"
@ -246,7 +246,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 RUBY" expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 RUBY"
end end
it "doesn't pull platform specific gems on truffleruby", :truffleruby do it "doesn't pull platform specific gems on truffleruby", :truffleruby_only do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "platform_specific" gem "platform_specific"
@ -255,6 +255,66 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
expect(the_bundle).to include_gems "platform_specific 1.0 RUBY" expect(the_bundle).to include_gems "platform_specific 1.0 RUBY"
end end
it "doesn't pull platform specific gems on truffleruby (except when whitelisted) even if lockfile was generated with an older version that declared RUBY as platform", :truffleruby_only do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "platform_specific"
G
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo1)}/
specs:
platform_specific (1.0)
PLATFORMS
ruby
DEPENDENCIES
platform_specific
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
expect(the_bundle).to include_gems "platform_specific 1.0 RUBY"
build_repo4 do
build_gem "libv8"
build_gem "libv8" do |s|
s.platform = Bundler.local_platform
end
end
gemfile <<-G
source "#{file_uri_for(gem_repo4)}"
gem "libv8"
G
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
libv8 (1.0)
PLATFORMS
ruby
DEPENDENCIES
libv8
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
expect(the_bundle).to include_gems "libv8 1.0 #{Bundler.local_platform}"
end
it "allows specifying only-ruby-platform on windows with dependency platforms" do it "allows specifying only-ruby-platform on windows with dependency platforms" do
simulate_windows do simulate_windows do
install_gemfile <<-G install_gemfile <<-G

View File

@ -449,8 +449,6 @@ RSpec.describe "Bundler.require with platform specific dependencies" do
end end
it "requires gems pinned to multiple platforms, including the current one" do it "requires gems pinned to multiple platforms, including the current one" do
skip "platform issues" if Gem.win_platform?
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"

View File

@ -637,6 +637,22 @@ RSpec.describe "Bundler.setup" do
expect(err).to be_empty expect(err).to be_empty
end end
it "doesn't re-resolve when deleting dependencies" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "actionpack"
G
install_gemfile <<-G, :verbose => true
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
expect(out).to include("Some dependencies were deleted, using a subset of the resolution from the lockfile")
expect(err).to be_empty
end
it "remembers --without and does not include groups passed to Bundler.setup" do it "remembers --without and does not include groups passed to Bundler.setup" do
bundle "config set --local without rails" bundle "config set --local without rails"
install_gemfile <<-G install_gemfile <<-G

View File

@ -121,6 +121,10 @@ module Spec
s.platform = "x64-mingw32" s.platform = "x64-mingw32"
end end
build_gem "platform_specific" do |s|
s.platform = "x64-mingw-ucrt"
end
build_gem "platform_specific" do |s| build_gem "platform_specific" do |s|
s.platform = "x86-darwin-100" s.platform = "x86-darwin-100"
s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 x86-darwin-100'" s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 x86-darwin-100'"

View File

@ -33,8 +33,8 @@ RSpec.configure do |config|
config.filter_run_excluding :no_color_tty => Gem.win_platform? || !ENV["GITHUB_ACTION"].nil? config.filter_run_excluding :no_color_tty => Gem.win_platform? || !ENV["GITHUB_ACTION"].nil?
config.filter_run_excluding :permissions => Gem.win_platform? config.filter_run_excluding :permissions => Gem.win_platform?
config.filter_run_excluding :readline => Gem.win_platform? config.filter_run_excluding :readline => Gem.win_platform?
config.filter_run_excluding :jruby => RUBY_ENGINE != "jruby" config.filter_run_excluding :jruby_only => RUBY_ENGINE != "jruby"
config.filter_run_excluding :truffleruby => RUBY_ENGINE != "truffleruby" config.filter_run_excluding :truffleruby_only => RUBY_ENGINE != "truffleruby"
config.filter_run_excluding :man => Gem.win_platform? config.filter_run_excluding :man => Gem.win_platform?
config.filter_run_when_matching :focus unless ENV["CI"] config.filter_run_when_matching :focus unless ENV["CI"]

View File

@ -55,13 +55,15 @@ module Spec
def local_tag def local_tag
if RUBY_PLATFORM == "java" if RUBY_PLATFORM == "java"
:jruby :jruby
elsif ["x64-mingw32", "x64-mingw-ucrt"].include?(RUBY_PLATFORM)
:x64_mingw
else else
:ruby :ruby
end end
end end
def not_local_tag def not_local_tag
[:ruby, :jruby].find {|tag| tag != local_tag } [:jruby, :x64_mingw, :ruby].find {|tag| tag != local_tag }
end end
def local_ruby_engine def local_ruby_engine
@ -74,7 +76,7 @@ module Spec
def not_local_engine_version def not_local_engine_version
case not_local_tag case not_local_tag
when :ruby when :ruby, :x64_mingw
not_local_ruby_version not_local_ruby_version
when :jruby when :jruby
"1.6.1" "1.6.1"
@ -90,15 +92,11 @@ module Spec
end end
def lockfile_platforms def lockfile_platforms
lockfile_platforms_for(local_platforms) lockfile_platforms_for([specific_local_platform])
end end
def lockfile_platforms_for(platforms) def lockfile_platforms_for(platforms)
platforms.map(&:to_s).sort.join("\n ") platforms.map(&:to_s).sort.join("\n ")
end end
def local_platforms
[specific_local_platform]
end
end end
end end

View File

@ -137,8 +137,8 @@ module Spec
ENV["BUNDLE_PATH__SYSTEM"] = "true" ENV["BUNDLE_PATH__SYSTEM"] = "true"
end end
output = `#{Gem.ruby} #{File.expand_path("support/bundle.rb", Path.spec_dir)} install --verbose` puts `#{Gem.ruby} #{File.expand_path("support/bundle.rb", Path.spec_dir)} install --verbose`
raise "Error when installing gems in #{gemfile}: #{output}" unless $?.success? raise unless $?.success?
ensure ensure
if path if path
ENV["BUNDLE_PATH"] = old_path ENV["BUNDLE_PATH"] = old_path

View File

@ -412,6 +412,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
install_gem specs["b-1"] install_gem specs["b-1"]
FileUtils.rm File.join(gemhome2, 'cache', 'b-1.gem') FileUtils.rm File.join(gemhome2, 'cache', 'b-1.gem')
Gem::Specification.reset
@cmd.options[:args] = %w[a b] @cmd.options[:args] = %w[a b]

View File

@ -280,6 +280,22 @@ class TestGemPlatform < Gem::TestCase
refute((Gem::Platform.local === arm), 'armv7 === arm') refute((Gem::Platform.local === arm), 'armv7 === arm')
end end
def test_equals3_universal_mingw
uni_mingw = Gem::Platform.new 'universal-mingw'
mingw32 = Gem::Platform.new 'x64-mingw32'
mingw_ucrt = Gem::Platform.new 'x64-mingw-ucrt'
util_set_arch 'x64-mingw32'
assert((uni_mingw === Gem::Platform.local), 'uni_mingw === mingw32')
assert((mingw32 === Gem::Platform.local), 'mingw32 === mingw32')
refute((mingw_ucrt === Gem::Platform.local), 'mingw32 === mingw_ucrt')
util_set_arch 'x64-mingw-ucrt'
assert((uni_mingw === Gem::Platform.local), 'uni_mingw === mingw32')
assert((mingw_ucrt === Gem::Platform.local), 'mingw_ucrt === mingw_ucrt')
refute((mingw32 === Gem::Platform.local), 'mingw32 === mingw_ucrt')
end
def test_equals3_version def test_equals3_version
util_set_arch 'i686-darwin8' util_set_arch 'i686-darwin8'

View File

@ -3676,6 +3676,8 @@ end
install_specs b install_specs b
Gem::Specification.reset
assert Gem::Specification.find_by_name "b" assert Gem::Specification.find_by_name "b"
assert_raise Gem::MissingSpecVersionError do assert_raise Gem::MissingSpecVersionError do

View File

@ -33,6 +33,8 @@ PLATFORMS
java java
ruby ruby
universal-java-11 universal-java-11
universal-java-18
x64-mingw-ucrt
x64-mingw32 x64-mingw32
x86_64-darwin-20 x86_64-darwin-20
x86_64-linux x86_64-linux

View File

@ -47,6 +47,8 @@ PLATFORMS
arm64-darwin-20 arm64-darwin-20
arm64-darwin-21 arm64-darwin-21
universal-java-11 universal-java-11
universal-java-18
x64-mingw-ucrt
x86_64-darwin-19 x86_64-darwin-19
x86_64-darwin-20 x86_64-darwin-20
x86_64-linux x86_64-linux

View File

@ -53,6 +53,8 @@ PLATFORMS
arm64-darwin-20 arm64-darwin-20
arm64-darwin-21 arm64-darwin-21
universal-java-11 universal-java-11
universal-java-18
x64-mingw-ucrt
x86_64-darwin-19 x86_64-darwin-19
x86_64-darwin-20 x86_64-darwin-20
x86_64-linux x86_64-linux

View File

@ -26,6 +26,8 @@ PLATFORMS
java java
ruby ruby
universal-java-11 universal-java-11
universal-java-18
x64-mingw-ucrt
x64-mingw32 x64-mingw32
x86_64-darwin-20 x86_64-darwin-20
x86_64-linux x86_64-linux