bundler 2.2.2 → 2.2.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87387b9f72e30a787aa9c773a5437015916914e31ea4938341e300a46aca04b4
4
- data.tar.gz: 3048c8736eac41c151ea005306bc5c3ed4f28c74d11f96da86dbdea47fe158d7
3
+ metadata.gz: e6d1efe11ee2c513b90baf20e54b599a1cec72355056997c53b1d62a064c4237
4
+ data.tar.gz: ac82de915bc8c58b391a19e61f3abcad69dc279a531e09cadcc59083653fc7f9
5
5
  SHA512:
6
- metadata.gz: cab74e52ba7effecbab97ce894aa5c5f8e12f5200c994198d03bbaf3984eb299f991b0044af1691ab2573c3d8e10d0ae49f9f1b626837ca9c9d3deec3deb7ebd
7
- data.tar.gz: aa1a8882ccd7375c98e7a8baccdc5f5e0bcedad47dbe39ecede1d4e326f9e4a9d939e7867309e21ef115b32274936600988fa21008208b9ea2c54841a77df2b3
6
+ metadata.gz: 835e64c01ad6e8c66e0c2e7199457f0b6ce5ecb2ff8c8e4af557e40c9186bd734cbff607a45ec9a751f6ad0e6790e81a78b206b1082a7b2a7a22526b6422b280
7
+ data.tar.gz: 07ed7766695917265535b4a5803ff799d201aaa910d73ba4b185f5f18836e1d1ec3967535b7b68c4c55d3af05c038ec6bcde8f66e8068db5576e16929ead145d
@@ -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
+
1
10
  # 2.2.2 (December 17, 2020)
2
11
 
3
12
  ## Bug fixes:
@@ -212,13 +212,10 @@ module Bundler
212
212
  end
213
213
  end
214
214
 
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
217
217
 
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
222
219
  end
223
220
 
224
221
  def ruby_scope
@@ -4,8 +4,8 @@ module Bundler
4
4
  # Represents metadata from when the Bundler gem was built.
5
5
  module BuildMetadata
6
6
  # begin ivars
7
- @built_at = "2020-12-17".freeze
8
- @git_commit_sha = "d85cd5b7c3".freeze
7
+ @built_at = "2020-12-22".freeze
8
+ @git_commit_sha = "29dc3c8398".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
@@ -82,7 +82,7 @@ module Bundler
82
82
  locked_spec = locked_info[:spec]
83
83
  new_spec = Bundler.definition.specs[name].first
84
84
  unless new_spec
85
- if Bundler.rubygems.platforms.none? {|p| locked_spec.match_platform(p) }
85
+ unless locked_spec.match_platform(Bundler.local_platform)
86
86
  Bundler.ui.warn "Bundler attempted to update #{name} but it was not considered because it is for a different platform from the current one"
87
87
  end
88
88
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "gem_parser"
4
+
3
5
  module Bundler
4
6
  class CompactIndexClient
5
7
  class Cache
@@ -92,19 +94,9 @@ module Bundler
92
94
  header ? lines[header + 1..-1] : lines
93
95
  end
94
96
 
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)
108
100
  end
109
101
 
110
102
  def info_roots
@@ -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
@@ -118,7 +118,7 @@ module Bundler
118
118
  end
119
119
  @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
120
120
 
121
- add_current_platform unless Bundler.frozen_bundle?
121
+ add_current_platform unless current_ruby_platform_locked? || Bundler.frozen_bundle?
122
122
 
123
123
  converge_path_sources_to_gemspec_sources
124
124
  @path_changes = converge_paths
@@ -157,7 +157,7 @@ module Bundler
157
157
  end
158
158
 
159
159
  def resolve_remotely!
160
- raise "Specs already loaded" if @specs
160
+ return if @specs
161
161
  @remote = true
162
162
  sources.remote!
163
163
  specs
@@ -269,9 +269,8 @@ module Bundler
269
269
  else
270
270
  # Run a resolve against the locally available gems
271
271
  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)
275
274
  end
276
275
 
277
276
  # filter out gems that _can_ be installed on multiple platforms, but don't need
@@ -507,15 +506,11 @@ module Bundler
507
506
  end
508
507
 
509
508
  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?
515
510
 
516
511
  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."
519
514
  end
520
515
 
521
516
  def add_platform(platform)
@@ -528,6 +523,12 @@ module Bundler
528
523
  raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
529
524
  end
530
525
 
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
+
531
532
  def find_resolved_spec(current_spec)
532
533
  specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
533
534
  end
@@ -549,6 +550,18 @@ module Bundler
549
550
 
550
551
  private
551
552
 
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
+
552
565
  def add_current_platform
553
566
  add_platform(local_platform)
554
567
  end
@@ -871,8 +884,7 @@ module Bundler
871
884
  end
872
885
  end
873
886
 
874
- def expand_dependencies(dependencies, remote = false, platforms = nil)
875
- platforms ||= @platforms
887
+ def expand_dependencies(dependencies, remote = false)
876
888
  deps = []
877
889
  dependencies.each do |dep|
878
890
  dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
@@ -35,41 +35,33 @@ module Bundler
35
35
 
36
36
  def platform_specificity_match(spec_platform, user_platform)
37
37
  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)
46
40
  end
47
41
  module_function :platform_specificity_match
48
42
 
49
43
  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) }
52
52
  end
53
53
  module_function :select_best_platform_match
54
54
 
55
- PlatformMatch = Struct.new(:os_match, :cpu_match, :platform_version_match)
56
55
  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
59
59
 
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
68
63
  end
69
64
 
70
- EXACT_MATCH = new(-1, -1, -1).freeze
71
- WORST_MATCH = new(1_000_000, 1_000_000, 1_000_000).freeze
72
-
73
65
  def self.os_match(spec_platform, user_platform)
74
66
  if spec_platform.os == user_platform.os
75
67
  0
@@ -100,5 +92,19 @@ module Bundler
100
92
  end
101
93
  end
102
94
  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
103
109
  end
104
110
  end
@@ -4,7 +4,7 @@ require_relative "match_platform"
4
4
 
5
5
  module Bundler
6
6
  class LazySpecification
7
- Identifier = Struct.new(:name, :version, :source, :platform, :dependencies)
7
+ Identifier = Struct.new(:name, :version, :platform)
8
8
  class Identifier
9
9
  include Comparable
10
10
  def <=>(other)
@@ -108,7 +108,7 @@ module Bundler
108
108
  end
109
109
 
110
110
  def identifier
111
- @__identifier ||= Identifier.new(name, version, source, platform, dependencies)
111
+ @__identifier ||= Identifier.new(name, version, platform)
112
112
  end
113
113
 
114
114
  def git_version
@@ -131,17 +131,16 @@ module Bundler
131
131
  end
132
132
 
133
133
  #
134
- # Bundler 2.2.0 was the first version that records the full resolution
135
- # including platform specific gems in the lockfile, which means that if a
136
- # gem with RUBY platform is recorded, the RUBY platform version of the gem
137
- # should be installed. Previously bundler would record only generic versions
138
- # in the lockfile and then install the most specific platform variant if
139
- # available.
134
+ # For backwards compatibility with existing lockfiles, if the most specific
135
+ # locked platform is RUBY, we keep the previous behaviour of resolving the
136
+ # best platform variant at materiliazation time. For previous bundler
137
+ # versions (before 2.2.0) this was always the case (except when the lockfile
138
+ # only included non-ruby platforms), but we're also keeping this behaviour
139
+ # on newer bundlers unless users generate the lockfile from scratch or
140
+ # explicitly add a more specific platform.
140
141
  #
141
142
  def ruby_platform_materializes_to_ruby_platform?
142
- locked_bundler_version = Bundler.locked_bundler_version
143
-
144
- locked_bundler_version.nil? || Gem::Version.new(locked_bundler_version) >= Gem::Version.new("2.2.0")
143
+ !Bundler.most_specific_locked_platform?(Gem::Platform::RUBY)
145
144
  end
146
145
  end
147
146
  end
@@ -25,11 +25,15 @@ module Bundler
25
25
 
26
26
  def to_specs
27
27
  @activated_platforms.map do |p|
28
- next unless s = @specs[p]
29
- lazy_spec = LazySpecification.new(name, version, s.platform, source)
30
- lazy_spec.dependencies.replace s.dependencies
31
- lazy_spec
32
- end.compact.uniq
28
+ specs = @specs[p]
29
+ next unless specs.any?
30
+
31
+ specs.map do |s|
32
+ lazy_spec = LazySpecification.new(name, version, s.platform, source)
33
+ lazy_spec.dependencies.replace s.dependencies
34
+ lazy_spec
35
+ end
36
+ end.flatten.compact.uniq
33
37
  end
34
38
 
35
39
  def copy_for(platforms)
@@ -42,12 +46,8 @@ module Bundler
42
46
  copied_sg
43
47
  end
44
48
 
45
- def spec_for(platform)
46
- @specs[platform]
47
- end
48
-
49
49
  def for?(platform)
50
- !spec_for(platform).nil?
50
+ @specs[platform].any?
51
51
  end
52
52
 
53
53
  def to_s
@@ -58,7 +58,7 @@ module Bundler
58
58
  def dependencies_for_activated_platforms
59
59
  dependencies = @activated_platforms.map {|p| __dependencies[p] }
60
60
  metadata_dependencies = @activated_platforms.map do |platform|
61
- metadata_dependencies(@specs[platform], platform)
61
+ metadata_dependencies(@specs[platform].first, platform)
62
62
  end
63
63
  dependencies.concat(metadata_dependencies).flatten
64
64
  end
@@ -94,7 +94,8 @@ module Bundler
94
94
  def __dependencies
95
95
  @dependencies = Hash.new do |dependencies, platform|
96
96
  dependencies[platform] = []
97
- if spec = @specs[platform]
97
+ specs = @specs[platform]
98
+ if spec = specs.first
98
99
  spec.dependencies.each do |dep|
99
100
  next if dep.type == :development
100
101
  next if @ignores_bundler_dependencies && dep.name == "bundler".freeze
@@ -106,10 +107,7 @@ module Bundler
106
107
  end
107
108
 
108
109
  def metadata_dependencies(spec, platform)
109
- return [] unless spec
110
- # Only allow endpoint specifications since they won't hit the network to
111
- # fetch the full gemspec when calling required_ruby_version
112
- return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
110
+ return [] unless spec && spec.is_a?(Gem::Specification)
113
111
  dependencies = []
114
112
  if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
115
113
  dependencies << DepProxy.new(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
@@ -110,11 +110,6 @@ module Bundler
110
110
  obj.to_s
111
111
  end
112
112
 
113
- def platforms
114
- return [Gem::Platform::RUBY] if Bundler.settings[:force_ruby_platform]
115
- Gem.platforms
116
- end
117
-
118
113
  def configuration
119
114
  require_relative "psyched_yaml"
120
115
  Gem.configuration
@@ -22,10 +22,11 @@ module Bundler
22
22
  break unless dep = deps.shift
23
23
  next if !handled.add?(dep) || skip.include?(dep.name)
24
24
 
25
- if spec = spec_for_dependency(dep, match_current_platform)
26
- specs << spec
25
+ specs_for_dep = spec_for_dependency(dep, match_current_platform)
26
+ if specs_for_dep.any?
27
+ specs += specs_for_dep
27
28
 
28
- spec.dependencies.each do |d|
29
+ specs_for_dep.first.dependencies.each do |d|
29
30
  next if d.type == :development
30
31
  d = DepProxy.new(d, dep.__platform) unless match_current_platform
31
32
  deps << d
@@ -184,11 +185,7 @@ module Bundler
184
185
  def spec_for_dependency(dep, match_current_platform)
185
186
  specs_for_platforms = lookup[dep.name]
186
187
  if match_current_platform
187
- Bundler.rubygems.platforms.reverse_each do |pl|
188
- match = GemHelpers.select_best_platform_match(specs_for_platforms, pl)
189
- return match if match
190
- end
191
- nil
188
+ GemHelpers.select_best_platform_match(specs_for_platforms, Bundler.local_platform)
192
189
  else
193
190
  GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform)
194
191
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.2.2".freeze
4
+ VERSION = "2.2.3".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Arko
@@ -22,7 +22,7 @@ authors:
22
22
  autorequire:
23
23
  bindir: exe
24
24
  cert_chain: []
25
- date: 2020-12-17 00:00:00.000000000 Z
25
+ date: 2020-12-22 00:00:00.000000000 Z
26
26
  dependencies: []
27
27
  description: Bundler manages an application's dependencies through its entire life,
28
28
  across many machines, systematically and repeatably
@@ -74,6 +74,7 @@ files:
74
74
  - lib/bundler/cli/viz.rb
75
75
  - lib/bundler/compact_index_client.rb
76
76
  - lib/bundler/compact_index_client/cache.rb
77
+ - lib/bundler/compact_index_client/gem_parser.rb
77
78
  - lib/bundler/compact_index_client/updater.rb
78
79
  - lib/bundler/constants.rb
79
80
  - lib/bundler/current_ruby.rb
@@ -350,7 +351,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
350
351
  - !ruby/object:Gem::Version
351
352
  version: 2.5.2
352
353
  requirements: []
353
- rubygems_version: 3.2.1
354
+ rubygems_version: 3.2.3
354
355
  signing_key:
355
356
  specification_version: 4
356
357
  summary: The best way to manage your application's dependencies