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

View File

@ -78,7 +78,7 @@ module Bundler
end
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
(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|

View File

@ -235,6 +235,14 @@ module Bundler
@locked_deps.values
end
def new_deps
@new_deps ||= @dependencies - locked_dependencies
end
def deleted_deps
@deleted_deps ||= locked_dependencies - @dependencies
end
def specs_for(groups)
return specs if groups.empty?
deps = dependencies_for(groups)
@ -259,8 +267,17 @@ module Bundler
Bundler.ui.debug "Frozen, using resolution from the lockfile"
@locked_specs
elsif !unlocking? && nothing_changed?
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 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")
if @locked_gems.may_include_redundant_platform_specific_gems?
SpecSet.new(filter_specs(@locked_specs, @dependencies))
else
@locked_specs
end
end
else
last_resolve = converge_locked_specs
# Run a resolve against the locally available gems
@ -359,9 +376,6 @@ module Bundler
added.concat new_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?
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)
converge_specs(@originally_locked_specs).map do |locked_spec|
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)
end
end

View File

@ -1,13 +1,16 @@
# frozen_string_literal: true
require "rubygems/dependency"
require_relative "force_platform"
require_relative "shared_helpers"
require_relative "rubygems_ext"
module Bundler
class Dependency < Gem::Dependency
include ForcePlatform
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
PLATFORM_MAP = {
@ -109,6 +112,7 @@ module Bundler
@env = options["env"]
@should_include = options.fetch("should_include", true)
@gemfile = options["gemfile"]
@force_ruby_platform = options.fetch("force_ruby_platform", default_force_ruby_platform)
@autorequire = Array(options["require"] || []) if options.key?("require")
end
@ -122,7 +126,7 @@ module Bundler
end
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
def should_include?

View File

@ -16,7 +16,7 @@ module Bundler
VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze
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

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
GENERICS = [
[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("mswin64"), Gem::Platform.new("mswin64")],
[Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-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("x64-mingw-ucrt"), Gem::Platform.new("x64-mingw-ucrt")],
[Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
].freeze

View File

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

View File

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

View File

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

View File

@ -331,6 +331,30 @@ gem "nokogiri", platforms: [:mri_18, :jruby]
.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\.
.
.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"
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\.
.
.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
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
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
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
default group. It also adds development dependencies as gem requirements in the
`development` group. Finally, it adds a gem requirement on your project (`:path
=> '.'`). In conjunction with `Bundler.setup`, this allows you to require project
`development` group. Finally, it adds a gem requirement on your project (`path:
'.'`). 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
need not manipulate the load path manually or require project files via relative
paths.

View File

@ -15,7 +15,6 @@ module Bundler
return true if Gem::Platform::RUBY == gemspec_platform
return true if local_platform == 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
false

View File

@ -143,9 +143,12 @@ module Bundler
end
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)
groups << spec_group
@ -284,7 +287,7 @@ module Bundler
if specs_matching_requirement.any?
specs = specs_matching_requirement
matching_part = requirement_label
requirement_label = "#{requirement_label} #{requirement.__platform}"
requirement_label = "#{requirement_label}' with platform '#{requirement.__platform}"
end
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 SpecGroup
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)
specific_platform_specs = specs[specific_platform]
@ -35,6 +35,7 @@ module Bundler
specs.map do |s|
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
end
@ -88,7 +89,7 @@ module Bundler
dependencies = []
@specs[platform].first.dependencies.each do |dep|
next if dep.type == :development
dependencies << DepProxy.get_proxy(dep, platform)
dependencies << DepProxy.get_proxy(Dependency.new(dep.name, dep.requirement), platform)
end
dependencies
end
@ -98,10 +99,10 @@ module Bundler
return [] if spec.is_a?(LazySpecification)
dependencies = []
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
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
dependencies
end

View File

@ -216,32 +216,15 @@ module Gem
require "rubygems/platform"
class Platform
JAVA = Gem::Platform.new("java") unless defined?(JAVA)
MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64)
MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW)
X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW)
end
JAVA = Gem::Platform.new("java")
MSWIN = Gem::Platform.new("mswin32")
MSWIN64 = Gem::Platform.new("mswin64")
MINGW = Gem::Platform.new("x86-mingw32")
X64_MINGW = [Gem::Platform.new("x64-mingw32"),
Gem::Platform.new("x64-mingw-ucrt")].freeze
Platform.singleton_class.module_eval do
unless Platform.singleton_methods.include?(:match_spec?)
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
if RUBY_ENGINE == "truffleruby" && !defined?(REUSE_AS_BINARY_ON_TRUFFLERUBY)
REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 sorbet-static].freeze
end
end

View File

@ -24,13 +24,13 @@ module Bundler
# use a hash here to ensure constant lookup time in the `any?` call above
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?
specs.concat(specs_for_dep)
specs_for_dep.first.dependencies.each do |d|
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
end
elsif check
@ -173,12 +173,13 @@ module Bundler
@specs.sort_by(&:name).each {|s| yield s }
end
def spec_for_dependency(dep, match_current_platform)
specs_for_platforms = lookup[dep.name]
def specs_for_dependency(dep, match_current_platform)
specs_for_name = lookup[dep.name]
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
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

View File

@ -9,11 +9,6 @@ require_relative '../rubygems'
require_relative 'command_manager'
require_relative 'deprecate'
##
# Load additional plugins from $LOAD_PATH
Gem.load_env_plugins rescue nil
##
# Run an instance of the gem program.
#
@ -37,6 +32,9 @@ class Gem::GemRunner
do_configuration args
Gem.load_env_plugins rescue nil
Gem.load_plugins
cmd = @command_manager_class.instance
cmd.command_names.each do |command_name|
@ -75,5 +73,3 @@ class Gem::GemRunner
Gem::Command.extra_args = Gem.configuration[:gem]
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?
Gem::Specification.reset
Gem::Specification.add_spec(spec)
run_post_install_hooks

View File

@ -159,6 +159,10 @@ class Gem::Platform
def ===(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
([nil,'universal'].include?(@cpu) or [nil, 'universal'].include?(other.cpu) or @cpu == other.cpu or
(@cpu == 'arm' and other.cpu.start_with?("arm"))) and

View File

@ -882,6 +882,21 @@ class Gem::Specification < Gem::BasicSpecification
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.
# 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)
PLATFORMS
#{lockfile_platforms_for(["java"] + local_platforms)}
#{lockfile_platforms_for(["java", specific_local_platform])}
DEPENDENCIES
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)
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
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)
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
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)
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"
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
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")
end

View File

@ -821,7 +821,7 @@ RSpec.describe "bundle outdated" do
expect(out).to end_with("Bundle up to date!")
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
source "#{file_uri_for(gem_repo2)}"
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
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
build_lib("foo", :path => tmp.join("foo")) do |s|
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)
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|
s.add_dependency "platform_specific"
end
@ -328,83 +348,65 @@ RSpec.describe "bundle install from an existing gemspec" do
context "with a lockfile and some missing dependencies" do
let(:source_uri) { "http://localgemserver.test" }
context "previously bundled for Ruby" do
let(:platform) { "ruby" }
before do
build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "rack", "=1.0.0"
end
gemfile <<-G
source "#{source_uri}"
gemspec :path => "../foo"
G
lockfile <<-L
PATH
remote: ../foo
specs:
foo (1.0)
rack (= 1.0.0)
GEM
remote: #{source_uri}
specs:
rack (1.0.0)
PLATFORMS
#{generic_local_platform}
DEPENDENCIES
foo!
BUNDLED WITH
#{Bundler::VERSION}
L
end
context "using JRuby with explicit platform", :jruby_only do
before do
skip "not installing for some reason" if Gem.win_platform?
build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "rack", "=1.0.0"
end
gemfile <<-G
source "#{source_uri}"
gemspec :path => "../foo"
G
lockfile <<-L
PATH
remote: ../foo
specs:
foo (1.0)
rack (= 1.0.0)
GEM
remote: #{source_uri}
specs:
rack (1.0.0)
PLATFORMS
#{generic_local_platform}
DEPENDENCIES
foo!
BUNDLED WITH
#{Bundler::VERSION}
L
create_file(
tmp.join("foo", "foo-java.gemspec"),
build_spec("foo", "1.0", "java") do
dep "rack", "=1.0.0"
@spec.authors = "authors"
@spec.summary = "summary"
end.first.to_ruby
)
end
context "using JRuby with explicit platform", :jruby do
before do
create_file(
tmp.join("foo", "foo-java.gemspec"),
build_spec("foo", "1.0", "java") do
dep "rack", "=1.0.0"
@spec.authors = "authors"
@spec.summary = "summary"
end.first.to_ruby
)
end
it "should install" 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
context "using JRuby", :jruby do
it "should install" 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
context "using Windows" 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
it "should install" 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
context "bundled for ruby and jruby" do
it "should install", :jruby 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
context "bundled for multiple platforms" do
let(:platform_specific_type) { :runtime }
let(:dependency) { "platform_specific" }
before do
@ -434,6 +436,7 @@ RSpec.describe "bundle install from an existing gemspec" do
simulate_new_machine
simulate_platform("jruby") { bundle "install" }
simulate_platform(x64_mingw) { bundle "install" }
end
context "on ruby" do
@ -443,7 +446,7 @@ RSpec.describe "bundle install from an existing gemspec" do
end
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(lockfile).to eq strip_whitespace(<<-L)
PATH
@ -457,10 +460,12 @@ RSpec.describe "bundle install from an existing gemspec" do
specs:
platform_specific (1.0)
platform_specific (1.0-java)
#{x64_mingw_gems}
PLATFORMS
java
ruby
#{x64_mingw_platforms}
DEPENDENCIES
foo!
@ -474,7 +479,7 @@ RSpec.describe "bundle install from an existing gemspec" do
context "as a development dependency" do
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(lockfile).to eq strip_whitespace(<<-L)
PATH
@ -487,10 +492,12 @@ RSpec.describe "bundle install from an existing gemspec" do
specs:
platform_specific (1.0)
platform_specific (1.0-java)
#{x64_mingw_gems}
PLATFORMS
java
ruby
#{x64_mingw_platforms}
DEPENDENCIES
foo!
@ -506,7 +513,7 @@ RSpec.describe "bundle install from an existing gemspec" do
let(:platform_specific_type) { :development }
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(lockfile).to eq strip_whitespace(<<-L)
PATH
@ -521,10 +528,12 @@ RSpec.describe "bundle install from an existing gemspec" do
platform_specific
platform_specific (1.0)
platform_specific (1.0-java)
#{x64_mingw_gems}
PLATFORMS
java
ruby
#{x64_mingw_platforms}
DEPENDENCIES
foo!
@ -608,7 +617,7 @@ RSpec.describe "bundle install from an existing gemspec" do
PLATFORMS
ruby
x64-mingw32
#{x64_mingw_platforms}
x86-mingw32
DEPENDENCIES
@ -665,7 +674,7 @@ RSpec.describe "bundle install from an existing gemspec" do
railties (6.1.4)
PLATFORMS
#{lockfile_platforms_for(["java"] + local_platforms)}
#{lockfile_platforms_for(["java", specific_local_platform])}
DEPENDENCIES
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")
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|
s.platform = "java"
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")
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|
s.platform = "java"
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"
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
GEM
remote: #{file_uri_for(gem_repo1)}
@ -216,28 +216,28 @@ RSpec.describe "bundle install across platforms" do
pry
BUNDLED WITH
#{Bundler::VERSION}
1.16.1
L
aggregate_failures do
lockfile bad_lockfile
bundle :install
bundle :install, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
lockfile bad_lockfile
bundle :update, :all => true
bundle :update, :all => true, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
lockfile bad_lockfile
bundle "update ffi"
bundle "update ffi", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
lockfile bad_lockfile
bundle "update empyrean"
bundle "update empyrean", :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
lockfile bad_lockfile
bundle :lock
bundle :lock, :env => { "BUNDLER_VERSION" => Bundler::VERSION }
expect(lockfile).to eq good_lockfile
end
end
@ -332,8 +332,6 @@ end
RSpec.describe "bundle install with platform conditionals" do
it "installs gems tagged w/ the current platforms" do
skip "platform issues" if Gem.win_platform?
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@ -402,8 +400,6 @@ RSpec.describe "bundle install with platform conditionals" do
end
it "installs gems tagged w/ the current platforms inline" do
skip "platform issues" if Gem.win_platform?
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "nokogiri", :platforms => :#{local_tag}
@ -422,8 +418,6 @@ RSpec.describe "bundle install with platform conditionals" do
end
it "installs gems tagged w/ the current platform inline" do
skip "platform issues" if Gem.win_platform?
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "nokogiri", :platform => :#{local_tag}

View File

@ -250,10 +250,11 @@ RSpec.describe "bundle install with specific platforms" do
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_gem("sorbet-static", "0.5.6403") {|s| s.platform = "x86_64-linux" }
build_gem("sorbet-static", "0.5.6403") {|s| s.platform = "universal-darwin-20" }
build_gem("sorbet-static", "0.5.6403") {|s| s.platform = Bundler.local_platform }
end
gemfile <<~G
@ -266,8 +267,7 @@ RSpec.describe "bundle install with specific platforms" do
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
sorbet-static (0.5.6403-universal-darwin-20)
sorbet-static (0.5.6403-x86_64-linux)
sorbet-static (0.5.6403-#{Bundler.local_platform})
PLATFORMS
ruby
@ -283,19 +283,19 @@ RSpec.describe "bundle install with specific platforms" do
end
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 = "universal-darwin-20" }
end
gemfile <<~G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo4)}"
gem "sorbet-static", "0.5.6433"
G
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)':
* sorbet-static-0.5.6433-universal-darwin-20
@ -303,7 +303,7 @@ RSpec.describe "bundle install with specific platforms" do
ERROR
simulate_platform "arm64-darwin-21" do
bundle "install", :raise_on_error => false
bundle "lock", :raise_on_error => false
end
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
simulate_platform "arm64-darwin-21" do
bundle "install --verbose", :raise_on_error => false
bundle "lock --verbose", :raise_on_error => false
end
expect(err).to include(error_message).once
end
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-static", "0.5.6433") {|s| s.platform = "x86_64-linux" }
build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "universal-darwin-20" }
end
gemfile <<~G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo4)}"
gem "sorbet", "0.5.6433"
G
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)':
* sorbet-static-0.5.6433-universal-darwin-20
@ -339,7 +339,7 @@ RSpec.describe "bundle install with specific platforms" do
ERROR
simulate_platform "arm64-darwin-21" do
bundle "install", :raise_on_error => false
bundle "lock", :raise_on_error => false
end
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
simulate_platform "arm64-darwin-21" do
bundle "install --verbose", :raise_on_error => false
bundle "lock --verbose", :raise_on_error => false
end
expect(err).to include(error_message).once
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
def setup_multiplatform_gem

View File

@ -66,7 +66,7 @@ RSpec.describe "bundle install" do
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
install_gemfile <<-G
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" }
activated_groups = if local_platforms.any?
"net_b (1.0) (ruby), net_b (1.0) (#{local_platforms.join(", ")})"
else
"net_b (1.0) (ruby)"
end
activated_groups = "net_b (1.0) (ruby), net_b (1.0) (#{specific_local_platform})"
expect(out).to include(" net_b").
and include("BUNDLER: Starting resolution").

View File

@ -982,7 +982,7 @@ RSpec.describe "the lockfile format" do
rack (1.0.0)
PLATFORMS
#{lockfile_platforms_for(["java"] + local_platforms)}
#{lockfile_platforms_for(["java", specific_local_platform])}
DEPENDENCIES
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("x86_64-mingw32"))).to eq(pl("x64-mingw32"))
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
RSpec.describe "Gem::SourceIndex#refresh!" do

View File

@ -2,10 +2,6 @@
RSpec.describe "bundle platform" 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
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@ -20,7 +16,7 @@ RSpec.describe "bundle platform" do
Your platform is: #{Gem::Platform.local}
Your app has gems that work on these platforms:
#{bundle_platform_platforms_string}
* #{specific_local_platform}
Your Gemfile specifies a Ruby version requirement:
* ruby #{RUBY_VERSION}
@ -43,7 +39,7 @@ G
Your platform is: #{Gem::Platform.local}
Your app has gems that work on these platforms:
#{bundle_platform_platforms_string}
* #{specific_local_platform}
Your Gemfile specifies a Ruby version requirement:
* ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}
@ -64,7 +60,7 @@ G
Your platform is: #{Gem::Platform.local}
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.
G
@ -84,7 +80,7 @@ G
Your platform is: #{Gem::Platform.local}
Your app has gems that work on these platforms:
#{bundle_platform_platforms_string}
* #{specific_local_platform}
Your Gemfile specifies a Ruby version requirement:
* ruby #{not_local_ruby_version}
@ -305,7 +301,7 @@ G
expect(bundled_app_lock).to exist
end
it "installs fine with any engine", :jruby do
it "installs fine with any engine", :jruby_only do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@ -351,7 +347,7 @@ G
should_be_engine_incorrect
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
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@ -394,7 +390,7 @@ G
expect(out).to match(/\AResolving dependencies\.\.\.\.*\nThe Gemfile's dependencies are satisfied\z/)
end
it "checks fine with any engine", :jruby do
it "checks fine with any engine", :jruby_only do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@ -445,7 +441,7 @@ G
should_be_engine_incorrect
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
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@ -511,7 +507,7 @@ G
expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0"
end
it "updates fine with any engine", :jruby do
it "updates fine with any engine", :jruby_only do
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
@ -547,7 +543,7 @@ G
should_be_ruby_version_incorrect
end
it "fails when ruby engine doesn't match", :jruby do
it "fails when ruby engine doesn't match", :jruby_only do
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
@ -563,7 +559,7 @@ G
should_be_engine_incorrect
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
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
@ -615,7 +611,7 @@ G
expect(out).to eq(default_bundle_path("gems", "rails-2.3.2").to_s)
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
source "#{file_uri_for(gem_repo1)}"
gem "rails"
@ -651,7 +647,7 @@ G
should_be_engine_incorrect
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
source "#{file_uri_for(gem_repo1)}"
gem "rails"
@ -699,7 +695,7 @@ G
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
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
source "#{file_uri_for(gem_repo1)}"
gem 'rack'
@ -735,7 +731,7 @@ G
should_be_engine_incorrect
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
source "#{file_uri_for(gem_repo1)}"
gem 'rack'
@ -780,7 +776,7 @@ G
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
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
source "#{file_uri_for(gem_repo1)}"
gem 'rack'
@ -816,7 +812,7 @@ G
should_be_engine_incorrect
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
source "#{file_uri_for(gem_repo1)}"
gem 'rack'
@ -859,7 +855,7 @@ G
expect(out).to include("0.9.1")
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
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
@ -896,7 +892,7 @@ G
should_be_engine_incorrect
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
# gem "rack", "0.9.1"
#
@ -947,7 +943,7 @@ G
expect(out).to include("0.9.1")
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
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@ -992,7 +988,7 @@ G
should_be_engine_incorrect
end
it "fails when engine version doesn't match", :jruby do
it "fails when engine version doesn't match", :jruby_only do
gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
@ -1047,7 +1043,7 @@ G
expect(bundled_app_lock).to exist
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
source "#{file_uri_for(gem_repo1)}"
gem "yard"
@ -1096,7 +1092,7 @@ G
should_be_engine_incorrect
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
source "#{file_uri_for(gem_repo1)}"
gem "yard"
@ -1169,7 +1165,7 @@ G
expect(out).to match(Regexp.new(expected_output))
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
update_repo2 do
build_gem "activesupport", "3.0"
@ -1231,7 +1227,7 @@ G
should_be_engine_incorrect
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
build_gem "activesupport", "3.0"
update_git "foo", :path => lib_path("foo")
@ -1249,7 +1245,7 @@ G
should_be_engine_version_incorrect
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
build_gem "activesupport", "3.0"
update_git "foo", :path => lib_path("foo")
@ -1267,7 +1263,7 @@ G
should_be_patchlevel_incorrect
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
build_gem "activesupport", "3.0"
update_git "foo", :path => lib_path("foo")

View File

@ -291,7 +291,7 @@ RSpec.describe "Resolving platform craziness" do
describe "with mingw32" do
before :each 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
end
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]
end
it "finds x64-mingw gems" do
it "finds x64-mingw32 gems" do
platforms "x64-mingw32"
dep "thin"
should_resolve_as %w[thin-1.2.7-x64-mingw32]
@ -329,6 +329,22 @@ RSpec.describe "Resolving platform craziness" do
dep "win32-api"
should_resolve_as %w[win32-api-1.5.1-universal-mingw32]
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
describe "with conflicting cases" do

View File

@ -86,7 +86,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
racc (1.5.2)
PLATFORMS
#{lockfile_platforms_for(["ruby"] + local_platforms)}
#{lockfile_platforms_for(["ruby", specific_local_platform])}
DEPENDENCIES
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}"
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
source "#{file_uri_for(gem_repo1)}"
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"
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
source "#{file_uri_for(gem_repo1)}"
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"
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
source "#{file_uri_for(gem_repo1)}"
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"
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
simulate_windows do
install_gemfile <<-G

View File

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

View File

@ -637,6 +637,22 @@ RSpec.describe "Bundler.setup" do
expect(err).to be_empty
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
bundle "config set --local without rails"
install_gemfile <<-G

View File

@ -121,6 +121,10 @@ module Spec
s.platform = "x64-mingw32"
end
build_gem "platform_specific" do |s|
s.platform = "x64-mingw-ucrt"
end
build_gem "platform_specific" do |s|
s.platform = "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 :permissions => Gem.win_platform?
config.filter_run_excluding :readline => Gem.win_platform?
config.filter_run_excluding :jruby => RUBY_ENGINE != "jruby"
config.filter_run_excluding :truffleruby => RUBY_ENGINE != "truffleruby"
config.filter_run_excluding :jruby_only => RUBY_ENGINE != "jruby"
config.filter_run_excluding :truffleruby_only => RUBY_ENGINE != "truffleruby"
config.filter_run_excluding :man => Gem.win_platform?
config.filter_run_when_matching :focus unless ENV["CI"]

View File

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

View File

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

View File

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

View File

@ -280,6 +280,22 @@ class TestGemPlatform < Gem::TestCase
refute((Gem::Platform.local === arm), 'armv7 === arm')
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
util_set_arch 'i686-darwin8'

View File

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

View File

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

View File

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

View File

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

View File

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