Skip to content

Commit a3b4dae

Browse files
Merge pull request #5700 from rubygems/linux-by-default
Make lockfiles generated on macOS include a lock for Linux by default
2 parents 9363daf + 5f24f06 commit a3b4dae

File tree

14 files changed

+250
-92
lines changed

14 files changed

+250
-92
lines changed

bundler/lib/bundler/current_ruby.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class CurrentRuby
4343
].freeze
4444

4545
def ruby?
46-
return true if Bundler::GemHelpers.generic_local_platform == Gem::Platform::RUBY
46+
return true if Bundler::GemHelpers.generic_local_platform_is_ruby?
4747

4848
!windows? && (RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev" || RUBY_ENGINE == "truffleruby")
4949
end

bundler/lib/bundler/definition.rb

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
8484
@new_platform = nil
8585
@removed_platform = nil
8686

87-
if lockfile && File.exist?(lockfile)
87+
if lockfile_exists?
8888
@lockfile_contents = Bundler.read_file(lockfile)
8989
@locked_gems = LockfileParser.new(@lockfile_contents)
9090
@locked_platforms = @locked_gems.platforms
@@ -302,6 +302,10 @@ def resolve
302302
end
303303
end
304304

305+
def should_complete_platforms?
306+
!lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
307+
end
308+
305309
def spec_git_paths
306310
sources.git_sources.map {|s| File.realpath(s.path) if File.exist?(s.path) }.compact
307311
end
@@ -491,6 +495,10 @@ def unlocking?
491495

492496
private
493497

498+
def lockfile_exists?
499+
lockfile && File.exist?(lockfile)
500+
end
501+
494502
def resolver
495503
@resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
496504
end
@@ -567,11 +575,12 @@ def materialize(dependencies)
567575
end
568576

569577
def start_resolution
570-
result = resolver.start
578+
result = SpecSet.new(resolver.start)
571579

572580
@resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
581+
@platforms = result.complete_platforms!(platforms) if should_complete_platforms?
573582

574-
SpecSet.new(SpecSet.new(result).for(dependencies, false, @platforms))
583+
SpecSet.new(result.for(dependencies, false, @platforms))
575584
end
576585

577586
def precompute_source_requirements_for_indirect_dependencies?
@@ -592,7 +601,7 @@ def pin_locally_available_names(source_requirements)
592601
end
593602

594603
def current_ruby_platform_locked?
595-
return false unless generic_local_platform == Gem::Platform::RUBY
604+
return false unless generic_local_platform_is_ruby?
596605
return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY)
597606

598607
current_platform_locked?

bundler/lib/bundler/gem_helpers.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ def local_platform
3434
end
3535
module_function :local_platform
3636

37+
def generic_local_platform_is_ruby?
38+
generic_local_platform == Gem::Platform::RUBY
39+
end
40+
module_function :generic_local_platform_is_ruby?
41+
3742
def platform_specificity_match(spec_platform, user_platform)
3843
spec_platform = Gem::Platform.new(spec_platform)
3944

@@ -114,8 +119,6 @@ def same_specificity(platform, spec, exemplary_spec)
114119

115120
def same_deps(spec, exemplary_spec)
116121
same_runtime_deps = spec.dependencies.sort == exemplary_spec.dependencies.sort
117-
return same_runtime_deps unless spec.is_a?(Gem::Specification) && exemplary_spec.is_a?(Gem::Specification)
118-
119122
same_metadata_deps = spec.required_ruby_version == exemplary_spec.required_ruby_version && spec.required_rubygems_version == exemplary_spec.required_rubygems_version
120123
same_runtime_deps && same_metadata_deps
121124
end

bundler/lib/bundler/lazy_specification.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,23 @@ class LazySpecification
77
include MatchPlatform
88
include ForcePlatform
99

10-
attr_reader :name, :version, :dependencies, :platform
11-
attr_accessor :source, :remote, :force_ruby_platform
10+
attr_reader :name, :version, :platform
11+
attr_accessor :source, :remote, :force_ruby_platform, :dependencies, :required_ruby_version, :required_rubygems_version
12+
13+
def self.from_spec(s)
14+
lazy_spec = new(s.name, s.version, s.platform, s.source)
15+
lazy_spec.dependencies = s.dependencies
16+
lazy_spec.required_ruby_version = s.required_ruby_version
17+
lazy_spec.required_rubygems_version = s.required_rubygems_version
18+
lazy_spec
19+
end
1220

1321
def initialize(name, version, platform, source = nil)
1422
@name = name
1523
@version = version
1624
@dependencies = []
25+
@required_ruby_version = Gem::Requirement.default
26+
@required_rubygems_version = Gem::Requirement.default
1727
@platform = platform || Gem::Platform::RUBY
1828
@source = source
1929
@force_ruby_platform = default_force_ruby_platform

bundler/lib/bundler/lockfile_parser.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ def parse_spec(line)
251251

252252
version = Gem::Version.new(version)
253253
platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
254-
@current_spec = LazySpecification.new(name, version, platform)
255-
@current_spec.source = @current_source
254+
@current_spec = LazySpecification.new(name, version, platform, @current_source)
256255
@current_source.add_dependency_names(name)
257256

258257
@specs[@current_spec.full_name] = @current_spec

bundler/lib/bundler/resolver/spec_group.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ def source
2525

2626
def to_specs(force_ruby_platform)
2727
@specs.map do |s|
28-
lazy_spec = LazySpecification.new(name, version, s.platform, source)
28+
lazy_spec = LazySpecification.from_spec(s)
2929
lazy_spec.force_ruby_platform = force_ruby_platform
30-
lazy_spec.dependencies.replace s.dependencies
3130
lazy_spec
3231
end
3332
end
@@ -64,8 +63,6 @@ def __dependencies(spec)
6463
end
6564

6665
def metadata_dependencies(spec)
67-
return [] if spec.is_a?(LazySpecification)
68-
6966
[
7067
metadata_dependency("Ruby", spec.required_ruby_version),
7168
metadata_dependency("RubyGems", spec.required_rubygems_version),

bundler/lib/bundler/spec_set.rb

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,44 @@ def for(dependencies, check = false, platforms = [nil])
5252
specs.uniq
5353
end
5454

55+
def complete_platforms!(platforms)
56+
return platforms.concat([Gem::Platform::RUBY]).uniq if @specs.empty?
57+
58+
new_platforms = @specs.flat_map {|spec| spec.source.specs.search([spec.name, spec.version]).map(&:platform) }.uniq.select do |platform|
59+
next if platforms.include?(platform)
60+
next unless GemHelpers.generic(platform) == Gem::Platform::RUBY
61+
62+
new_specs = []
63+
64+
valid_platform = lookup.all? do |_, specs|
65+
spec = specs.first
66+
matching_specs = spec.source.specs.search([spec.name, spec.version])
67+
platform_spec = GemHelpers.select_best_platform_match(matching_specs, platform).first
68+
69+
if platform_spec
70+
new_specs << LazySpecification.from_spec(platform_spec)
71+
true
72+
else
73+
false
74+
end
75+
end
76+
next unless valid_platform
77+
78+
@specs.concat(new_specs.uniq)
79+
end
80+
return platforms if new_platforms.empty?
81+
82+
platforms.concat(new_platforms)
83+
84+
less_specific_platform = new_platforms.find {|platform| platform != Gem::Platform::RUBY && platform === Bundler.local_platform }
85+
platforms.delete(Bundler.local_platform) if less_specific_platform
86+
87+
@sorted = nil
88+
@lookup = nil
89+
90+
platforms
91+
end
92+
5593
def [](key)
5694
key = key.name if key.respond_to?(:name)
5795
lookup[key].reverse
@@ -114,16 +152,6 @@ def missing_specs
114152
@specs.select {|s| s.is_a?(LazySpecification) }
115153
end
116154

117-
def merge(set)
118-
arr = sorted.dup
119-
set.each do |set_spec|
120-
full_name = set_spec.full_name
121-
next if arr.any? {|spec| spec.full_name == full_name }
122-
arr << set_spec
123-
end
124-
SpecSet.new(arr)
125-
end
126-
127155
def -(other)
128156
SpecSet.new(to_a - other.to_a)
129157
end

bundler/spec/bundler/spec_set_spec.rb

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,6 @@
4545
end
4646
end
4747

48-
describe "#merge" do
49-
let(:other_specs) do
50-
[
51-
build_spec("f", "1.0"),
52-
build_spec("g", "2.0"),
53-
].flatten
54-
end
55-
56-
let(:other_spec_set) { described_class.new(other_specs) }
57-
58-
it "merges the items in each gemspec" do
59-
new_spec_set = subject.merge(other_spec_set)
60-
specs = new_spec_set.to_a.map(&:full_name)
61-
expect(specs).to include("a-1.0")
62-
expect(specs).to include("f-1.0")
63-
end
64-
end
65-
6648
describe "#to_a" do
6749
it "returns the specs in order" do
6850
expect(subject.to_a.map(&:full_name)).to eq %w[

bundler/spec/commands/lock_spec.rb

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@
449449

450450
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
451451
lockfile = Bundler::LockfileParser.new(read_lockfile)
452-
expect(lockfile.platforms).to match_array([java, x86_mingw32, local_platform].uniq)
452+
expect(lockfile.platforms).to match_array(default_platform_list(java, x86_mingw32))
453453
end
454454

455455
it "supports adding new platforms with force_ruby_platform = true" do
@@ -481,7 +481,7 @@
481481

482482
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
483483
lockfile = Bundler::LockfileParser.new(read_lockfile)
484-
expect(lockfile.platforms).to match_array(["ruby", local_platform].uniq)
484+
expect(lockfile.platforms).to match_array(default_platform_list("ruby"))
485485
end
486486

487487
it "warns when adding an unknown platform" do
@@ -494,12 +494,12 @@
494494

495495
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
496496
lockfile = Bundler::LockfileParser.new(read_lockfile)
497-
expect(lockfile.platforms).to match_array([java, x86_mingw32, local_platform].uniq)
497+
expect(lockfile.platforms).to match_array(default_platform_list(java, x86_mingw32))
498498

499499
bundle "lock --remove-platform java"
500500

501501
lockfile = Bundler::LockfileParser.new(read_lockfile)
502-
expect(lockfile.platforms).to match_array([x86_mingw32, local_platform].uniq)
502+
expect(lockfile.platforms).to match_array(default_platform_list(x86_mingw32))
503503
end
504504

505505
it "also cleans up redundant platform gems when removing platforms" do
@@ -733,7 +733,7 @@
733733
gem "libv8"
734734
G
735735

736-
simulate_platform(Gem::Platform.new("x86_64-darwin")) { bundle "lock" }
736+
simulate_platform(Gem::Platform.new("x86_64-darwin-19")) { bundle "lock" }
737737

738738
expect(lockfile).to eq <<~G
739739
GEM
@@ -743,7 +743,8 @@
743743
libv8 (8.4.255.0-x86_64-darwin-20)
744744
745745
PLATFORMS
746-
x86_64-darwin
746+
x86_64-darwin-19
747+
x86_64-darwin-20
747748
748749
DEPENDENCIES
749750
libv8
@@ -1237,7 +1238,7 @@
12371238
activemodel (>= 6.0.4)
12381239
12391240
PLATFORMS
1240-
#{lockfile_platforms}
1241+
#{local_platform}
12411242
12421243
DEPENDENCIES
12431244
activeadmin (= 2.13.1)
@@ -1273,7 +1274,7 @@
12731274
version solving has failed.
12741275
ERR
12751276

1276-
lockfile lockfile.gsub(/PLATFORMS\n #{lockfile_platforms}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
1277+
lockfile lockfile.gsub(/PLATFORMS\n #{local_platform}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
12771278

12781279
bundle "lock", :raise_on_error => false
12791280

@@ -1438,7 +1439,7 @@
14381439
nokogiri (1.14.2)
14391440
14401441
PLATFORMS
1441-
x86_64-linux
1442+
#{lockfile_platforms}
14421443
14431444
DEPENDENCIES
14441445
foo!

bundler/spec/commands/update_spec.rb

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,12 +559,36 @@
559559
before do
560560
build_repo2
561561

562-
install_gemfile <<-G
562+
gemfile <<-G
563563
source "#{file_uri_for(gem_repo2)}"
564564
gem "activesupport"
565565
gem "rack-obama"
566566
gem "platform_specific"
567567
G
568+
569+
lockfile <<~L
570+
GEM
571+
remote: #{file_uri_for(gem_repo2)}/
572+
specs:
573+
activesupport (2.3.5)
574+
platform_specific (1.0-#{local_platform})
575+
rack (1.0.0)
576+
rack-obama (1.0)
577+
rack
578+
579+
PLATFORMS
580+
#{local_platform}
581+
582+
DEPENDENCIES
583+
activesupport
584+
platform_specific
585+
rack-obama
586+
587+
BUNDLED WITH
588+
#{Bundler::VERSION}
589+
L
590+
591+
bundle "install"
568592
end
569593

570594
it "doesn't hit repo2" do

0 commit comments

Comments
 (0)