summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/bundler/definition.rb15
-rw-r--r--lib/bundler/spec_set.rb38
-rw-r--r--spec/bundler/commands/lock_spec.rb11
-rw-r--r--spec/bundler/commands/update_spec.rb26
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb30
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb136
-rw-r--r--spec/bundler/lock/lockfile_spec.rb2
-rw-r--r--spec/bundler/support/platforms.rb2
8 files changed, 216 insertions, 44 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 72fbae1984..9ef0abed93 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -84,7 +84,7 @@ module Bundler
@new_platform = nil
@removed_platform = nil
- if lockfile && File.exist?(lockfile)
+ if lockfile_exists?
@lockfile_contents = Bundler.read_file(lockfile)
@locked_gems = LockfileParser.new(@lockfile_contents)
@locked_platforms = @locked_gems.platforms
@@ -302,6 +302,10 @@ module Bundler
end
end
+ def should_complete_platforms?
+ !lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
+ end
+
def spec_git_paths
sources.git_sources.map {|s| File.realpath(s.path) if File.exist?(s.path) }.compact
end
@@ -491,6 +495,10 @@ module Bundler
private
+ def lockfile_exists?
+ lockfile && File.exist?(lockfile)
+ end
+
def resolver
@resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
end
@@ -567,11 +575,12 @@ module Bundler
end
def start_resolution
- result = resolver.start
+ result = SpecSet.new(resolver.start)
@resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
+ @platforms = result.complete_platforms!(platforms) if should_complete_platforms?
- SpecSet.new(SpecSet.new(result).for(dependencies, false, @platforms))
+ SpecSet.new(result.for(dependencies, false, @platforms))
end
def precompute_source_requirements_for_indirect_dependencies?
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 277824c34f..f4fc005ef2 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -52,6 +52,44 @@ module Bundler
specs.uniq
end
+ def complete_platforms!(platforms)
+ return platforms.concat([Gem::Platform::RUBY]).uniq if @specs.empty?
+
+ new_platforms = @specs.flat_map {|spec| spec.source.specs.search([spec.name, spec.version]).map(&:platform) }.uniq.select do |platform|
+ next if platforms.include?(platform)
+ next unless GemHelpers.generic(platform) == Gem::Platform::RUBY
+
+ new_specs = []
+
+ valid_platform = lookup.all? do |_, specs|
+ spec = specs.first
+ matching_specs = spec.source.specs.search([spec.name, spec.version])
+ platform_spec = GemHelpers.select_best_platform_match(matching_specs, platform).first
+
+ if platform_spec
+ new_specs << LazySpecification.from_spec(platform_spec)
+ true
+ else
+ false
+ end
+ end
+ next unless valid_platform
+
+ @specs.concat(new_specs.uniq)
+ end
+ return platforms if new_platforms.empty?
+
+ platforms.concat(new_platforms)
+
+ less_specific_platform = new_platforms.find {|platform| platform != Gem::Platform::RUBY && platform === Bundler.local_platform }
+ platforms.delete(Bundler.local_platform) if less_specific_platform
+
+ @sorted = nil
+ @lookup = nil
+
+ platforms
+ end
+
def [](key)
key = key.name if key.respond_to?(:name)
lookup[key].reverse
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index ac220c9318..5c6a2c0e3d 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -733,7 +733,7 @@ RSpec.describe "bundle lock" do
gem "libv8"
G
- simulate_platform(Gem::Platform.new("x86_64-darwin")) { bundle "lock" }
+ simulate_platform(Gem::Platform.new("x86_64-darwin-19")) { bundle "lock" }
expect(lockfile).to eq <<~G
GEM
@@ -743,7 +743,8 @@ RSpec.describe "bundle lock" do
libv8 (8.4.255.0-x86_64-darwin-20)
PLATFORMS
- x86_64-darwin
+ x86_64-darwin-19
+ x86_64-darwin-20
DEPENDENCIES
libv8
@@ -1237,7 +1238,7 @@ RSpec.describe "bundle lock" do
activemodel (>= 6.0.4)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
activeadmin (= 2.13.1)
@@ -1273,7 +1274,7 @@ RSpec.describe "bundle lock" do
version solving has failed.
ERR
- lockfile lockfile.gsub(/PLATFORMS\n #{lockfile_platforms}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
+ lockfile lockfile.gsub(/PLATFORMS\n #{local_platform}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
bundle "lock", :raise_on_error => false
@@ -1438,7 +1439,7 @@ RSpec.describe "bundle lock" do
nokogiri (1.14.2)
PLATFORMS
- x86_64-linux
+ #{lockfile_platforms}
DEPENDENCIES
foo!
diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb
index 8e48758c04..5c7b569fe2 100644
--- a/spec/bundler/commands/update_spec.rb
+++ b/spec/bundler/commands/update_spec.rb
@@ -559,12 +559,36 @@ RSpec.describe "bundle update" do
before do
build_repo2
- install_gemfile <<-G
+ gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
gem "rack-obama"
gem "platform_specific"
G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo2)}/
+ specs:
+ activesupport (2.3.5)
+ platform_specific (1.0-#{local_platform})
+ rack (1.0.0)
+ rack-obama (1.0)
+ rack
+
+ PLATFORMS
+ #{local_platform}
+
+ DEPENDENCIES
+ activesupport
+ platform_specific
+ rack-obama
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "install"
end
it "doesn't hit repo2" do
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index 64eed1a2f4..15ff15e46d 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -379,7 +379,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
depends_on_rack!
@@ -422,7 +422,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
depends_on_rack!
@@ -803,7 +803,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
zeitwerk (2.4.2)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
activesupport
@@ -874,7 +874,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
sidekiq (>= 6.1.0)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
activesupport
@@ -975,7 +975,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
sidekiq (>= 6.1.0)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
activesupport
@@ -1049,7 +1049,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
sidekiq (>= 6.1.0)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
activesupport
@@ -1146,7 +1146,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
nokogiri (>= 1.2.3)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
handsoap!
@@ -1209,7 +1209,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack (0.9.1)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack!
@@ -1239,7 +1239,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack (0.9.1)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack!
@@ -1261,7 +1261,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
rack (0.9.1)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
rack!
@@ -1701,7 +1701,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
mime-types (3.3.1)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
capybara (~> 2.5.0)
@@ -1732,7 +1732,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
mime-types (3.0.0)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
capybara (~> 2.5.0)
@@ -1789,7 +1789,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
pdf-writer (= 1.1.8)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
ruport (= 1.7.0.3)!
@@ -1851,7 +1851,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
pdf-writer (= 1.1.8)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
ruport (= 1.7.0.3)!
@@ -1899,7 +1899,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
pdf-writer (1.1.8)
PLATFORMS
- #{local_platform}
+ #{lockfile_platforms}
DEPENDENCIES
pdf-writer (= 1.1.8)
diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb
index 099ef35bbf..0c9816eaac 100644
--- a/spec/bundler/install/gemfile/specific_platform_spec.rb
+++ b/spec/bundler/install/gemfile/specific_platform_spec.rb
@@ -11,11 +11,11 @@ RSpec.describe "bundle install with specific platforms" do
setup_multiplatform_gem
install_gemfile(google_protobuf)
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
- expect(the_bundle.locked_gems.platforms).to eq([pl("x86_64-darwin-15")])
+ expect(the_bundle.locked_gems.platforms).to include(pl("x86_64-darwin-15"))
expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
- google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
- ])
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to include(
+ "google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin"
+ )
end
end
@@ -309,10 +309,10 @@ RSpec.describe "bundle install with specific platforms" do
G
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
- expect(the_bundle.locked_gems.platforms).to eq([pl("x86_64-darwin-15")])
+ expect(the_bundle.locked_gems.platforms).to include(pl("x86_64-darwin-15"))
expect(the_bundle).to include_gems("facter 2.4.6 universal-darwin", "CFPropertyList 1.0")
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(["CFPropertyList-1.0",
- "facter-2.4.6-universal-darwin"])
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to include("CFPropertyList-1.0",
+ "facter-2.4.6-universal-darwin")
end
end
@@ -327,8 +327,8 @@ RSpec.describe "bundle install with specific platforms" do
install_gemfile(google_protobuf)
bundle "lock --add-platform=#{x64_mingw32}"
- expect(the_bundle.locked_gems.platforms).to eq([x64_mingw32, pl("x86_64-darwin-15")])
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
+ expect(the_bundle.locked_gems.platforms).to include(x64_mingw32, pl("x86_64-darwin-15"))
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to include(*%w[
google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
google-protobuf-3.0.0.alpha.5.0.5.1-x64-mingw32
])
@@ -341,11 +341,11 @@ RSpec.describe "bundle install with specific platforms" do
install_gemfile(google_protobuf)
bundle "lock --add-platform=#{java}"
- expect(the_bundle.locked_gems.platforms).to eq([java, pl("x86_64-darwin-15")])
- expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(%w[
- google-protobuf-3.0.0.alpha.5.0.5.1
- google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
- ])
+ expect(the_bundle.locked_gems.platforms).to include(java, pl("x86_64-darwin-15"))
+ expect(the_bundle.locked_gems.specs.map(&:full_name)).to include(
+ "google-protobuf-3.0.0.alpha.5.0.5.1",
+ "google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin"
+ )
end
end
end
@@ -517,7 +517,7 @@ RSpec.describe "bundle install with specific platforms" do
sorbet-runtime (= 0.5.10160)
PLATFORMS
- #{lockfile_platforms("ruby")}
+ #{lockfile_platforms}
DEPENDENCIES
sorbet-static-and-runtime
@@ -548,7 +548,7 @@ RSpec.describe "bundle install with specific platforms" do
sorbet-runtime (= 0.5.10160)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
sorbet-static-and-runtime
@@ -601,7 +601,7 @@ RSpec.describe "bundle install with specific platforms" do
DEPENDENCIES
nokogiri
- sorbet
+ sorbet-static
BUNDLED WITH
#{Bundler::VERSION}
@@ -702,7 +702,7 @@ RSpec.describe "bundle install with specific platforms" do
sorbet-runtime (= 0.5.10160)
PLATFORMS
- #{lockfile_platforms}
+ #{local_platform}
DEPENDENCIES
sorbet-static-and-runtime
@@ -1067,6 +1067,106 @@ RSpec.describe "bundle install with specific platforms" do
end
end
+ it "locks specific platforms automatically" do
+ simulate_platform "x86_64-linux" do
+ build_repo4 do
+ build_gem "nokogiri", "1.14.0"
+ build_gem "nokogiri", "1.14.0" do |s|
+ s.platform = "x86_64-linux"
+ end
+ build_gem "nokogiri", "1.14.0" do |s|
+ s.platform = "arm-linux"
+ end
+ build_gem "nokogiri", "1.14.0" do |s|
+ s.platform = "x64-mingw32"
+ end
+ build_gem "nokogiri", "1.14.0" do |s|
+ s.platform = "java"
+ end
+
+ build_gem "sorbet-static", "0.5.10696" do |s|
+ s.platform = "x86_64-linux"
+ end
+ build_gem "sorbet-static", "0.5.10696" do |s|
+ s.platform = "universal-darwin-22"
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "nokogiri"
+ G
+
+ bundle "lock"
+
+ # locks all compatible platforms, excluding Java and Windows
+ expect(lockfile).to eq(<<~L)
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ nokogiri (1.14.0)
+ nokogiri (1.14.0-arm-linux)
+ nokogiri (1.14.0-x86_64-linux)
+
+ PLATFORMS
+ arm-linux
+ ruby
+ x86_64-linux
+
+ DEPENDENCIES
+ nokogiri
+
+ CHECKSUMS
+ #{gem_no_checksum "nokogiri", "1.14.0"}
+ #{gem_no_checksum "nokogiri", "1.14.0", "arm-linux"}
+ #{gem_no_checksum "nokogiri", "1.14.0", "x86_64-linux"}
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "nokogiri"
+ gem "sorbet-static"
+ G
+
+ FileUtils.rm bundled_app_lock
+
+ bundle "lock"
+
+ # locks only platforms compatible with all gems in the bundle
+ expect(lockfile).to eq(<<~L)
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ nokogiri (1.14.0)
+ nokogiri (1.14.0-x86_64-linux)
+ sorbet-static (0.5.10696-universal-darwin-22)
+ sorbet-static (0.5.10696-x86_64-linux)
+
+ PLATFORMS
+ universal-darwin-22
+ x86_64-linux
+
+ DEPENDENCIES
+ nokogiri
+ sorbet-static
+
+ CHECKSUMS
+ #{gem_no_checksum "nokogiri", "1.14.0"}
+ #{gem_no_checksum "nokogiri", "1.14.0", "x86_64-linux"}
+ #{gem_no_checksum "sorbet-static", "0.5.10696", "universal-darwin-22"}
+ #{gem_no_checksum "sorbet-static", "0.5.10696", "x86_64-linux"}
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
private
def setup_multiplatform_gem
diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb
index be1fdc37b5..efa5b85788 100644
--- a/spec/bundler/lock/lockfile_spec.rb
+++ b/spec/bundler/lock/lockfile_spec.rb
@@ -1212,7 +1212,7 @@ RSpec.describe "the lockfile format" do
rack (1.0.0)
PLATFORMS
- #{lockfile_platforms("java")}
+ #{lockfile_platforms("java", local_platform, :defaults => [])}
DEPENDENCIES
rack
diff --git a/spec/bundler/support/platforms.rb b/spec/bundler/support/platforms.rb
index 973d34a43a..3289d5e8e2 100644
--- a/spec/bundler/support/platforms.rb
+++ b/spec/bundler/support/platforms.rb
@@ -105,7 +105,7 @@ module Spec
end
def default_locked_platforms
- [local_platform]
+ [local_platform, generic_local_platform]
end
end
end