bundler 2.3.21 → 2.3.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/bundler.gemspec +6 -8
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli.rb +2 -1
  6. data/lib/bundler/current_ruby.rb +14 -5
  7. data/lib/bundler/definition.rb +5 -8
  8. data/lib/bundler/dependency.rb +18 -85
  9. data/lib/bundler/endpoint_specification.rb +1 -1
  10. data/lib/bundler/feature_flag.rb +0 -1
  11. data/lib/bundler/gem_version_promoter.rb +4 -18
  12. data/lib/bundler/injector.rb +2 -1
  13. data/lib/bundler/lockfile_generator.rb +1 -1
  14. data/lib/bundler/man/bundle-add.1 +6 -2
  15. data/lib/bundler/man/bundle-add.1.ronn +4 -1
  16. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  17. data/lib/bundler/man/bundle-cache.1 +1 -1
  18. data/lib/bundler/man/bundle-check.1 +1 -1
  19. data/lib/bundler/man/bundle-clean.1 +1 -1
  20. data/lib/bundler/man/bundle-config.1 +1 -1
  21. data/lib/bundler/man/bundle-console.1 +53 -0
  22. data/lib/bundler/man/bundle-console.1.ronn +44 -0
  23. data/lib/bundler/man/bundle-doctor.1 +1 -1
  24. data/lib/bundler/man/bundle-exec.1 +1 -1
  25. data/lib/bundler/man/bundle-gem.1 +1 -1
  26. data/lib/bundler/man/bundle-help.1 +13 -0
  27. data/lib/bundler/man/bundle-help.1.ronn +12 -0
  28. data/lib/bundler/man/bundle-info.1 +1 -1
  29. data/lib/bundler/man/bundle-init.1 +1 -1
  30. data/lib/bundler/man/bundle-inject.1 +1 -1
  31. data/lib/bundler/man/bundle-install.1 +1 -1
  32. data/lib/bundler/man/bundle-list.1 +1 -1
  33. data/lib/bundler/man/bundle-lock.1 +1 -1
  34. data/lib/bundler/man/bundle-open.1 +1 -1
  35. data/lib/bundler/man/bundle-outdated.1 +1 -1
  36. data/lib/bundler/man/bundle-platform.1 +1 -1
  37. data/lib/bundler/man/bundle-plugin.1 +1 -1
  38. data/lib/bundler/man/bundle-pristine.1 +1 -1
  39. data/lib/bundler/man/bundle-remove.1 +1 -1
  40. data/lib/bundler/man/bundle-show.1 +1 -1
  41. data/lib/bundler/man/bundle-update.1 +1 -1
  42. data/lib/bundler/man/bundle-version.1 +35 -0
  43. data/lib/bundler/man/bundle-version.1.ronn +24 -0
  44. data/lib/bundler/man/bundle-viz.1 +1 -1
  45. data/lib/bundler/man/bundle.1 +6 -2
  46. data/lib/bundler/man/bundle.1.ronn +4 -1
  47. data/lib/bundler/man/gemfile.5 +8 -38
  48. data/lib/bundler/man/gemfile.5.ronn +9 -27
  49. data/lib/bundler/man/index.txt +3 -0
  50. data/lib/bundler/match_remote_metadata.rb +4 -1
  51. data/lib/bundler/resolver/base.rb +50 -0
  52. data/lib/bundler/resolver.rb +67 -84
  53. data/lib/bundler/rubygems_ext.rb +13 -3
  54. data/lib/bundler/settings.rb +0 -1
  55. data/lib/bundler/spec_set.rb +10 -0
  56. data/lib/bundler/version.rb +1 -1
  57. metadata +11 -4
@@ -3,12 +3,11 @@
3
3
  module Bundler
4
4
  class Resolver
5
5
  require_relative "vendored_molinillo"
6
+ require_relative "resolver/base"
6
7
  require_relative "resolver/spec_group"
7
8
 
8
9
  include GemHelpers
9
10
 
10
- attr_writer :platforms
11
-
12
11
  # Figures out the best possible configuration of gems that satisfies
13
12
  # the list of passed dependencies and any child dependencies without
14
13
  # causing any gem activation errors.
@@ -27,15 +26,13 @@ module Bundler
27
26
 
28
27
  def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
29
28
  @source_requirements = source_requirements
30
- @base = base
29
+ @base = Resolver::Base.new(base, additional_base_requirements)
31
30
  @resolver = Molinillo::Resolver.new(self, self)
32
31
  @results_for = {}
33
32
  @search_for = {}
34
- @additional_base_requirements = additional_base_requirements
35
33
  @platforms = platforms
36
34
  @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
37
35
  @gem_version_promoter = gem_version_promoter
38
- @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
39
36
  end
40
37
 
41
38
  def start(requirements, exclude_specs: [])
@@ -45,18 +42,11 @@ module Bundler
45
42
  remove_from_candidates(spec)
46
43
  end
47
44
 
48
- @base_dg = Molinillo::DependencyGraph.new
49
- @base.each do |ls|
50
- dep = Dependency.new(ls.name, ls.version)
51
- @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
52
- end
53
- @additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
54
-
55
45
  @gem_version_promoter.prerelease_specified = @prerelease_specified = {}
56
46
  requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
57
47
 
58
48
  verify_gemfile_dependencies_are_found!(requirements)
59
- result = @resolver.resolve(requirements, @base_dg).
49
+ result = @resolver.resolve(requirements).
60
50
  map(&:payload).
61
51
  reject {|sg| sg.name.end_with?("\0") }.
62
52
  map(&:to_specs).
@@ -64,8 +54,20 @@ module Bundler
64
54
 
65
55
  SpecSet.new(SpecSet.new(result).for(regular_requirements, false, @platforms))
66
56
  rescue Molinillo::VersionConflict => e
57
+ conflicts = e.conflicts
58
+
59
+ deps_to_unlock = conflicts.values.inject([]) do |deps, conflict|
60
+ deps |= conflict.requirement_trees.flatten.map {|req| base_requirements[req.name] }.compact
61
+ end
62
+
63
+ if deps_to_unlock.any?
64
+ @base.unlock_deps(deps_to_unlock)
65
+ reset_spec_cache
66
+ retry
67
+ end
68
+
67
69
  message = version_conflict_message(e)
68
- raise VersionConflict.new(e.conflicts.keys.uniq, message)
70
+ raise VersionConflict.new(conflicts.keys.uniq, message)
69
71
  rescue Molinillo::CircularDependencyError => e
70
72
  names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
71
73
  raise CyclicDependencyError, "Your bundle requires gems that depend" \
@@ -120,31 +122,22 @@ module Bundler
120
122
  dependency = dependency_proxy.dep
121
123
  name = dependency.name
122
124
  @search_for[dependency_proxy] ||= begin
123
- results = results_for(dependency) + @base[name].select {|spec| requirement_satisfied_by?(dependency, nil, spec) }
124
-
125
- if vertex = @base_dg.vertex_named(name)
126
- locked_requirement = vertex.payload.requirement
127
- end
125
+ locked_results = @base[name].select {|spec| requirement_satisfied_by?(dependency, nil, spec) }
126
+ locked_requirement = base_requirements[name]
127
+ results = results_for(dependency) + locked_results
128
+ results = results.select {|spec| requirement_satisfied_by?(locked_requirement, nil, spec) } if locked_requirement
128
129
 
129
- if !@prerelease_specified[name] && (!@use_gvp || locked_requirement.nil?)
130
+ if !@prerelease_specified[name] && locked_results.empty?
130
131
  # Move prereleases to the beginning of the list, so they're considered
131
132
  # last during resolution.
132
133
  pre, results = results.partition {|spec| spec.version.prerelease? }
133
134
  results = pre + results
134
135
  end
135
136
 
136
- spec_groups = if results.any?
137
- nested = []
138
- results.each do |spec|
139
- version, specs = nested.last
140
- if version == spec.version
141
- specs << spec
142
- else
143
- nested << [spec.version, [spec]]
144
- end
145
- end
146
- nested.reduce([]) do |groups, (version, specs)|
147
- next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
137
+ if results.any?
138
+ results = @gem_version_promoter.sort_versions(dependency, results)
139
+
140
+ results.group_by(&:version).reduce([]) do |groups, (_, specs)|
148
141
  next groups unless specs.any? {|spec| spec.match_platform(platform) }
149
142
 
150
143
  specs_by_platform = Hash.new do |current_specs, current_platform|
@@ -167,13 +160,6 @@ module Bundler
167
160
  else
168
161
  []
169
162
  end
170
- # GVP handles major itself, but it's still a bit risky to trust it with it
171
- # until we get it settled with new behavior. For 2.x it can take over all cases.
172
- if !@use_gvp
173
- spec_groups
174
- else
175
- @gem_version_promoter.sort_versions(dependency, spec_groups)
176
- end
177
163
  end
178
164
  end
179
165
 
@@ -199,12 +185,6 @@ module Bundler
199
185
  "Gemfile"
200
186
  end
201
187
 
202
- def name_for_locking_dependency_source
203
- Bundler.default_lockfile.basename.to_s
204
- rescue StandardError
205
- "Gemfile.lock"
206
- end
207
-
208
188
  def requirement_satisfied_by?(requirement, activated, spec)
209
189
  requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
210
190
  end
@@ -218,7 +198,7 @@ module Bundler
218
198
  name = name_for(dependency)
219
199
  vertex = activated.vertex_named(name)
220
200
  [
221
- @base_dg.vertex_named(name) ? 0 : 1,
201
+ @base[name].any? ? 0 : 1,
222
202
  vertex.payload ? 0 : 1,
223
203
  vertex.root? ? 0 : 1,
224
204
  amount_constrained(dependency),
@@ -237,9 +217,12 @@ module Bundler
237
217
 
238
218
  private
239
219
 
220
+ def base_requirements
221
+ @base.base_requirements
222
+ end
223
+
240
224
  def remove_from_candidates(spec)
241
225
  @base.delete(spec)
242
- @gem_version_promoter.reset
243
226
 
244
227
  @results_for.keys.each do |dep|
245
228
  next unless dep.name == spec.name
@@ -247,7 +230,12 @@ module Bundler
247
230
  @results_for[dep].reject {|s| s.name == spec.name && s.version == spec.version }
248
231
  end
249
232
 
233
+ reset_spec_cache
234
+ end
235
+
236
+ def reset_spec_cache
250
237
  @search_for = {}
238
+ @gem_version_promoter.reset
251
239
  end
252
240
 
253
241
  # returns an integer \in (-\infty, 0]
@@ -339,18 +327,6 @@ module Bundler
339
327
 
340
328
  e.message_with_trees(
341
329
  :full_message_for_conflict => lambda do |name, conflict|
342
- o = if name.end_with?("\0")
343
- String.new("Bundler found conflicting requirements for the #{name} version:")
344
- else
345
- String.new("Bundler could not find compatible versions for gem \"#{name}\":")
346
- end
347
- o << %(\n)
348
- if conflict.locked_requirement
349
- o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
350
- o << %( #{SharedHelpers.pretty_dependency(conflict.locked_requirement)}\n)
351
- o << %(\n)
352
- end
353
- o << %( In #{name_for_explicit_dependency_source}:\n)
354
330
  trees = conflict.requirement_trees
355
331
 
356
332
  # called first, because we want to reduce the amount of work required to find maximal empty sets
@@ -369,30 +345,41 @@ module Bundler
369
345
  trees.sort_by! {|t| t.reverse.map(&:name) }
370
346
  end
371
347
 
372
- o << trees.map do |tree|
373
- t = "".dup
374
- depth = 2
348
+ if trees.size > 1 || name == "bundler"
349
+ o = if name.end_with?("\0")
350
+ String.new("Bundler found conflicting requirements for the #{name} version:")
351
+ else
352
+ String.new("Bundler could not find compatible versions for gem \"#{name}\":")
353
+ end
354
+ o << %(\n)
355
+ o << %( In #{name_for_explicit_dependency_source}:\n)
356
+ o << trees.map do |tree|
357
+ t = "".dup
358
+ depth = 2
375
359
 
376
- base_tree = tree.first
377
- base_tree_name = base_tree.name
360
+ base_tree = tree.first
361
+ base_tree_name = base_tree.name
378
362
 
379
- if base_tree_name.end_with?("\0")
380
- t = nil
381
- else
382
- tree.each do |req|
383
- t << " " * depth << SharedHelpers.pretty_dependency(req)
384
- unless tree.last == req
385
- if spec = conflict.activated_by_name[req.name]
386
- t << %( was resolved to #{spec.version}, which)
363
+ if base_tree_name.end_with?("\0")
364
+ t = nil
365
+ else
366
+ tree.each do |req|
367
+ t << " " * depth << SharedHelpers.pretty_dependency(req)
368
+ unless tree.last == req
369
+ if spec = conflict.activated_by_name[req.name]
370
+ t << %( was resolved to #{spec.version}, which)
371
+ end
372
+ t << %( depends on)
387
373
  end
388
- t << %( depends on)
374
+ t << %(\n)
375
+ depth += 1
389
376
  end
390
- t << %(\n)
391
- depth += 1
392
377
  end
393
- end
394
- t
395
- end.compact.join("\n")
378
+ t
379
+ end.compact.join("\n")
380
+ else
381
+ o = String.new
382
+ end
396
383
 
397
384
  if name == "bundler"
398
385
  o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
@@ -416,17 +403,13 @@ module Bundler
416
403
  end
417
404
  elsif name.end_with?("\0")
418
405
  o << %(\n Current #{name} version:\n #{SharedHelpers.pretty_dependency(@metadata_requirements.find {|req| req.name == name })}\n\n)
419
- elsif conflict.locked_requirement
420
- o << "\n"
421
- o << %(Deleting your #{name_for_locking_dependency_source} file and running `bundle install` will rebuild your snapshot from scratch, using only\n)
422
- o << %(the gems in your Gemfile, which may resolve the conflict.\n)
423
406
  elsif !conflict.existing
424
407
  o << "\n"
425
408
 
426
409
  relevant_source = conflict.requirement.source || source_for(name)
427
410
 
428
- extra_message = if conflict.requirement_trees.first.size > 1
429
- ", which is required by gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
411
+ extra_message = if trees.first.size > 1
412
+ ", which is required by gem '#{SharedHelpers.pretty_dependency(trees.first[-2])}',"
430
413
  else
431
414
  ""
432
415
  end
@@ -237,8 +237,11 @@ module Gem
237
237
  MINGW = Gem::Platform.new("x86-mingw32")
238
238
  X64_MINGW = [Gem::Platform.new("x64-mingw32"),
239
239
  Gem::Platform.new("x64-mingw-ucrt")].freeze
240
+ WINDOWS = [MSWIN, MSWIN64, MINGW, X64_MINGW].flatten.freeze
241
+ X64_LINUX = Gem::Platform.new("x86_64-linux")
242
+ X64_LINUX_MUSL = Gem::Platform.new("x86_64-linux-musl")
240
243
 
241
- if Gem::Platform.new("x86_64-linux-musl") === Gem::Platform.new("x86_64-linux")
244
+ if X64_LINUX === X64_LINUX_MUSL
242
245
  remove_method :===
243
246
 
244
247
  def ===(other)
@@ -258,7 +261,7 @@ module Gem
258
261
  # version
259
262
  (
260
263
  (@os != "linux" && (@version.nil? || other.version.nil?)) ||
261
- (@os == "linux" && ((@version.nil? && ["gnu", "musl"].include?(other.version)) || (@version == "gnu" && other.version.nil?))) ||
264
+ (@os == "linux" && (other.version == "gnu#{@version}" || other.version == "musl#{@version}" || @version == "gnu#{other.version}")) ||
262
265
  @version == other.version
263
266
  )
264
267
  end
@@ -274,14 +277,21 @@ module Gem
274
277
  def match_gem?(platform, gem_name)
275
278
  match_platforms?(platform, Gem.platforms)
276
279
  end
280
+ end
281
+
282
+ match_platforms_defined = Gem::Platform.respond_to?(:match_platforms?, true)
283
+
284
+ if !match_platforms_defined || Gem::Platform.send(:match_platforms?, Gem::Platform::X64_LINUX_MUSL, [Gem::Platform::X64_LINUX])
277
285
 
278
286
  private
279
287
 
288
+ remove_method :match_platforms? if match_platforms_defined
289
+
280
290
  def match_platforms?(platform, platforms)
281
291
  platforms.any? do |local_platform|
282
292
  platform.nil? ||
283
293
  local_platform == platform ||
284
- (local_platform != Gem::Platform::RUBY && local_platform =~ platform)
294
+ (local_platform != Gem::Platform::RUBY && platform =~ local_platform)
285
295
  end
286
296
  end
287
297
  end
@@ -45,7 +45,6 @@ module Bundler
45
45
  silence_root_warning
46
46
  suppress_install_using_messages
47
47
  update_requires_all_flag
48
- use_gem_version_promoter_for_major_updates
49
48
  ].freeze
50
49
 
51
50
  NUMBER_KEYS = %w[
@@ -114,10 +114,20 @@ module Bundler
114
114
  SpecSet.new(arr)
115
115
  end
116
116
 
117
+ def -(other)
118
+ SpecSet.new(to_a - other.to_a)
119
+ end
120
+
117
121
  def find_by_name_and_platform(name, platform)
118
122
  @specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
119
123
  end
120
124
 
125
+ def delete_by_name_and_version(name, version)
126
+ @specs.reject! {|spec| spec.name == name && spec.version == version }
127
+ @lookup = nil
128
+ @sorted = nil
129
+ end
130
+
121
131
  def what_required(spec)
122
132
  unless req = find {|s| s.dependencies.any? {|d| d.type == :runtime && d.name == spec.name } }
123
133
  return [spec]
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.3.21".freeze
4
+ VERSION = "2.3.22".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.3.21
4
+ version: 2.3.22
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: 2022-08-24 00:00:00.000000000 Z
25
+ date: 2022-09-07 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
@@ -126,12 +126,16 @@ files:
126
126
  - lib/bundler/man/bundle-clean.1.ronn
127
127
  - lib/bundler/man/bundle-config.1
128
128
  - lib/bundler/man/bundle-config.1.ronn
129
+ - lib/bundler/man/bundle-console.1
130
+ - lib/bundler/man/bundle-console.1.ronn
129
131
  - lib/bundler/man/bundle-doctor.1
130
132
  - lib/bundler/man/bundle-doctor.1.ronn
131
133
  - lib/bundler/man/bundle-exec.1
132
134
  - lib/bundler/man/bundle-exec.1.ronn
133
135
  - lib/bundler/man/bundle-gem.1
134
136
  - lib/bundler/man/bundle-gem.1.ronn
137
+ - lib/bundler/man/bundle-help.1
138
+ - lib/bundler/man/bundle-help.1.ronn
135
139
  - lib/bundler/man/bundle-info.1
136
140
  - lib/bundler/man/bundle-info.1.ronn
137
141
  - lib/bundler/man/bundle-init.1
@@ -160,6 +164,8 @@ files:
160
164
  - lib/bundler/man/bundle-show.1.ronn
161
165
  - lib/bundler/man/bundle-update.1
162
166
  - lib/bundler/man/bundle-update.1.ronn
167
+ - lib/bundler/man/bundle-version.1
168
+ - lib/bundler/man/bundle-version.1.ronn
163
169
  - lib/bundler/man/bundle-viz.1
164
170
  - lib/bundler/man/bundle-viz.1.ronn
165
171
  - lib/bundler/man/bundle.1
@@ -184,6 +190,7 @@ files:
184
190
  - lib/bundler/process_lock.rb
185
191
  - lib/bundler/remote_specification.rb
186
192
  - lib/bundler/resolver.rb
193
+ - lib/bundler/resolver/base.rb
187
194
  - lib/bundler/resolver/spec_group.rb
188
195
  - lib/bundler/retry.rb
189
196
  - lib/bundler/ruby_dsl.rb
@@ -357,7 +364,7 @@ metadata:
357
364
  bug_tracker_uri: https://github.com/rubygems/rubygems/issues?q=is%3Aopen+is%3Aissue+label%3ABundler
358
365
  changelog_uri: https://github.com/rubygems/rubygems/blob/master/bundler/CHANGELOG.md
359
366
  homepage_uri: https://bundler.io/
360
- source_code_uri: https://github.com/rubygems/rubygems/
367
+ source_code_uri: https://github.com/rubygems/rubygems/tree/master/bundler
361
368
  post_install_message:
362
369
  rdoc_options: []
363
370
  require_paths:
@@ -373,7 +380,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
373
380
  - !ruby/object:Gem::Version
374
381
  version: 2.5.2
375
382
  requirements: []
376
- rubygems_version: 3.3.21
383
+ rubygems_version: 3.4.0.dev
377
384
  signing_key:
378
385
  specification_version: 4
379
386
  summary: The best way to manage your application's dependencies