Skip to content

Commit 29dc3c8

Browse files
Merge pull request #4181 from rubygems/release/bundler_2.2.3_rubygems_3.2.3
Prepare rubygems 3.2.3 and bundler 2.2.3
2 parents d85cd5b + e013b76 commit 29dc3c8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+701
-301
lines changed

.github/workflows/install-rubygems.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ jobs:
6262
- name: Check bundler install didn't hit the network
6363
run: if grep -q 'GET http' output.txt; then false; else true; fi
6464
working-directory: ./bundler
65+
- name: Check rails can be installed
66+
run: gem install rails
6567
timeout-minutes: 10
6668

6769
install_rubygems_windows:

History.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
=== 3.2.3 / 2020-12-22
2+
3+
Enhancements:
4+
5+
* Fix misspellings in default API key name. Pull request #4177 by hsbt
6+
7+
Bug fixes:
8+
9+
* Respect `required_ruby_version` and `required_rubygems_version`
10+
constraints when looking for `gem install` candidates. Pull request #4110
11+
by deivid-rodriguez
12+
113
=== 3.2.2 / 2020-12-17
214

315
Bug fixes:

Manifest.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ bundler/lib/bundler/cli/update.rb
5252
bundler/lib/bundler/cli/viz.rb
5353
bundler/lib/bundler/compact_index_client.rb
5454
bundler/lib/bundler/compact_index_client/cache.rb
55+
bundler/lib/bundler/compact_index_client/gem_parser.rb
5556
bundler/lib/bundler/compact_index_client/updater.rb
5657
bundler/lib/bundler/constants.rb
5758
bundler/lib/bundler/current_ruby.rb
@@ -412,6 +413,7 @@ lib/rubygems/requirement.rb
412413
lib/rubygems/resolver.rb
413414
lib/rubygems/resolver/activation_request.rb
414415
lib/rubygems/resolver/api_set.rb
416+
lib/rubygems/resolver/api_set/gem_parser.rb
415417
lib/rubygems/resolver/api_specification.rb
416418
lib/rubygems/resolver/best_set.rb
417419
lib/rubygems/resolver/composed_set.rb

bundler/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# 2.2.3 (December 22, 2020)
2+
3+
## Bug fixes:
4+
5+
- Restore full compatibility with previous lockfiles [#4179](https://github.com/rubygems/rubygems/pull/4179)
6+
- Add all matching variants with the same platform specificity to the lockfile [#4180](https://github.com/rubygems/rubygems/pull/4180)
7+
- Fix bundler installing gems for a different platform when running in frozen mode and current platform not in the lockfile [#4172](https://github.com/rubygems/rubygems/pull/4172)
8+
- Fix crash when `bundle exec`'ing to bundler [#4175](https://github.com/rubygems/rubygems/pull/4175)
9+
110
# 2.2.2 (December 17, 2020)
211

312
## Bug fixes:

bundler/lib/bundler.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,10 @@ def locked_gems
212212
end
213213
end
214214

215-
def locked_bundler_version
216-
return nil unless defined?(@definition) && @definition
215+
def most_specific_locked_platform?(platform)
216+
return false unless defined?(@definition) && @definition
217217

218-
locked_gems = definition.locked_gems
219-
return nil unless locked_gems
220-
221-
locked_gems.bundler_version
218+
definition.most_specific_locked_platform == platform
222219
end
223220

224221
def ruby_scope

bundler/lib/bundler/cli/update.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def run
8282
locked_spec = locked_info[:spec]
8383
new_spec = Bundler.definition.specs[name].first
8484
unless new_spec
85-
if Bundler.rubygems.platforms.none? {|p| locked_spec.match_platform(p) }
85+
unless locked_spec.match_platform(Bundler.local_platform)
8686
Bundler.ui.warn "Bundler attempted to update #{name} but it was not considered because it is for a different platform from the current one"
8787
end
8888

bundler/lib/bundler/compact_index_client/cache.rb

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require_relative "gem_parser"
4+
35
module Bundler
46
class CompactIndexClient
57
class Cache
@@ -92,19 +94,9 @@ def lines(path)
9294
header ? lines[header + 1..-1] : lines
9395
end
9496

95-
def parse_gem(string)
96-
version_and_platform, rest = string.split(" ", 2)
97-
version, platform = version_and_platform.split("-", 2)
98-
dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
99-
dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
100-
requirements = requirements ? requirements.map {|r| parse_dependency(r) } : []
101-
[version, platform, dependencies, requirements]
102-
end
103-
104-
def parse_dependency(string)
105-
dependency = string.split(":")
106-
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
107-
dependency
97+
def parse_gem(line)
98+
@dependency_parser ||= GemParser.new
99+
@dependency_parser.parse(line)
108100
end
109101

110102
def info_roots
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# frozen_string_literal: true
2+
3+
module Bundler
4+
class CompactIndexClient
5+
if defined?(Gem::Resolver::APISet::GemParser)
6+
GemParser = Gem::Resolver::APISet::GemParser
7+
else
8+
class GemParser
9+
def parse(line)
10+
version_and_platform, rest = line.split(" ", 2)
11+
version, platform = version_and_platform.split("-", 2)
12+
dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
13+
dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
14+
requirements = requirements ? requirements.map {|d| parse_dependency(d) } : []
15+
[version, platform, dependencies, requirements]
16+
end
17+
18+
private
19+
20+
def parse_dependency(string)
21+
dependency = string.split(":")
22+
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
23+
dependency
24+
end
25+
end
26+
end
27+
end
28+
end

bundler/lib/bundler/definition.rb

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
118118
end
119119
@unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
120120

121-
add_current_platform unless Bundler.frozen_bundle?
121+
add_current_platform unless current_ruby_platform_locked? || Bundler.frozen_bundle?
122122

123123
converge_path_sources_to_gemspec_sources
124124
@path_changes = converge_paths
@@ -157,7 +157,7 @@ def resolve_with_cache!
157157
end
158158

159159
def resolve_remotely!
160-
raise "Specs already loaded" if @specs
160+
return if @specs
161161
@remote = true
162162
sources.remote!
163163
specs
@@ -269,9 +269,8 @@ def resolve
269269
else
270270
# Run a resolve against the locally available gems
271271
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
272-
platforms_for_resolve = platforms.one? {|p| generic(p) == Gem::Platform::RUBY } ? platforms : platforms.reject{|p| p == Gem::Platform::RUBY }
273-
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote, platforms_for_resolve.map {|p| generic(p) })
274-
last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms_for_resolve)
272+
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote)
273+
last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
275274
end
276275

277276
# filter out gems that _can_ be installed on multiple platforms, but don't need
@@ -507,15 +506,11 @@ def validate_ruby!
507506
end
508507

509508
def validate_platforms!
510-
return if @platforms.any? do |bundle_platform|
511-
Bundler.rubygems.platforms.any? do |local_platform|
512-
MatchPlatform.platforms_match?(bundle_platform, local_platform)
513-
end
514-
end
509+
return if current_platform_locked?
515510

516511
raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
517-
"but your local platforms are #{Bundler.rubygems.platforms.map(&:to_s)}, and " \
518-
"there's no compatible match between those two lists."
512+
"but your local platform is #{Bundler.local_platform}. " \
513+
"Add the current platform to the lockfile with `bundle lock --add-platform #{Bundler.local_platform}` and try again."
519514
end
520515

521516
def add_platform(platform)
@@ -528,6 +523,12 @@ def remove_platform(platform)
528523
raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
529524
end
530525

526+
def most_specific_locked_platform
527+
@platforms.min_by do |bundle_platform|
528+
platform_specificity_match(bundle_platform, local_platform)
529+
end
530+
end
531+
531532
def find_resolved_spec(current_spec)
532533
specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
533534
end
@@ -549,6 +550,18 @@ def unlocking?
549550

550551
private
551552

553+
def current_ruby_platform_locked?
554+
return false unless generic_local_platform == Gem::Platform::RUBY
555+
556+
current_platform_locked?
557+
end
558+
559+
def current_platform_locked?
560+
@platforms.any? do |bundle_platform|
561+
MatchPlatform.platforms_match?(bundle_platform, Bundler.local_platform)
562+
end
563+
end
564+
552565
def add_current_platform
553566
add_platform(local_platform)
554567
end
@@ -871,8 +884,7 @@ def ruby_version_requirements(ruby_version)
871884
end
872885
end
873886

874-
def expand_dependencies(dependencies, remote = false, platforms = nil)
875-
platforms ||= @platforms
887+
def expand_dependencies(dependencies, remote = false)
876888
deps = []
877889
dependencies.each do |dep|
878890
dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)

bundler/lib/bundler/gem_helpers.rb

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,41 +35,33 @@ def local_platform
3535

3636
def platform_specificity_match(spec_platform, user_platform)
3737
spec_platform = Gem::Platform.new(spec_platform)
38-
return PlatformMatch::EXACT_MATCH if spec_platform == user_platform
39-
return PlatformMatch::WORST_MATCH if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY
40-
41-
PlatformMatch.new(
42-
PlatformMatch.os_match(spec_platform, user_platform),
43-
PlatformMatch.cpu_match(spec_platform, user_platform),
44-
PlatformMatch.platform_version_match(spec_platform, user_platform)
45-
)
38+
39+
PlatformMatch.specificity_score(spec_platform, user_platform)
4640
end
4741
module_function :platform_specificity_match
4842

4943
def select_best_platform_match(specs, platform)
50-
specs.select {|spec| spec.match_platform(platform) }.
51-
min_by {|spec| platform_specificity_match(spec.platform, platform) }
44+
matching = specs.select {|spec| spec.match_platform(platform) }
45+
exact = matching.select {|spec| spec.platform == platform }
46+
return exact if exact.any?
47+
48+
sorted_matching = matching.sort_by {|spec| platform_specificity_match(spec.platform, platform) }
49+
exemplary_spec = sorted_matching.first
50+
51+
sorted_matching.take_while{|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) }
5252
end
5353
module_function :select_best_platform_match
5454

55-
PlatformMatch = Struct.new(:os_match, :cpu_match, :platform_version_match)
5655
class PlatformMatch
57-
def <=>(other)
58-
return nil unless other.is_a?(PlatformMatch)
56+
def self.specificity_score(spec_platform, user_platform)
57+
return -1 if spec_platform == user_platform
58+
return 1_000_000 if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY
5959

60-
m = os_match <=> other.os_match
61-
return m unless m.zero?
62-
63-
m = cpu_match <=> other.cpu_match
64-
return m unless m.zero?
65-
66-
m = platform_version_match <=> other.platform_version_match
67-
m
60+
os_match(spec_platform, user_platform) +
61+
cpu_match(spec_platform, user_platform) * 10 +
62+
platform_version_match(spec_platform, user_platform) * 100
6863
end
6964

70-
EXACT_MATCH = new(-1, -1, -1).freeze
71-
WORST_MATCH = new(1_000_000, 1_000_000, 1_000_000).freeze
72-
7365
def self.os_match(spec_platform, user_platform)
7466
if spec_platform.os == user_platform.os
7567
0
@@ -100,5 +92,19 @@ def self.platform_version_match(spec_platform, user_platform)
10092
end
10193
end
10294
end
95+
96+
def same_specificity(platform, spec, exemplary_spec)
97+
platform_specificity_match(spec.platform, platform) == platform_specificity_match(exemplary_spec.platform, platform)
98+
end
99+
module_function :same_specificity
100+
101+
def same_deps(spec, exemplary_spec)
102+
same_runtime_deps = spec.dependencies.sort == exemplary_spec.dependencies.sort
103+
return same_runtime_deps unless spec.is_a?(Gem::Specification) && exemplary_spec.is_a?(Gem::Specification)
104+
105+
same_metadata_deps = spec.required_ruby_version == exemplary_spec.required_ruby_version && spec.required_rubygems_version == exemplary_spec.required_rubygems_version
106+
same_runtime_deps && same_metadata_deps
107+
end
108+
module_function :same_deps
103109
end
104110
end

0 commit comments

Comments
 (0)