rubygems-update 3.2.7 → 3.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Manifest.txt +2 -0
  4. data/Rakefile +10 -14
  5. data/bundler/CHANGELOG.md +15 -0
  6. data/bundler/lib/bundler/build_metadata.rb +2 -2
  7. data/bundler/lib/bundler/cli.rb +1 -0
  8. data/bundler/lib/bundler/cli/gem.rb +12 -0
  9. data/bundler/lib/bundler/definition.rb +14 -20
  10. data/bundler/lib/bundler/index.rb +6 -5
  11. data/bundler/lib/bundler/installer/standalone.rb +2 -1
  12. data/bundler/lib/bundler/lazy_specification.rb +8 -17
  13. data/bundler/lib/bundler/resolver.rb +47 -28
  14. data/bundler/lib/bundler/resolver/spec_group.rb +53 -38
  15. data/bundler/lib/bundler/shared_helpers.rb +2 -2
  16. data/bundler/lib/bundler/source_list.rb +2 -4
  17. data/bundler/lib/bundler/spec_set.rb +4 -3
  18. data/bundler/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  19. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -1
  20. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  21. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  22. data/bundler/lib/bundler/vendor/thor/lib/thor.rb +5 -6
  23. data/bundler/lib/bundler/vendor/thor/lib/thor/actions.rb +1 -1
  24. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +4 -2
  25. data/bundler/lib/bundler/vendor/thor/lib/thor/error.rb +1 -1
  26. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
  27. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +9 -8
  28. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +5 -2
  29. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
  30. data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  31. data/bundler/lib/bundler/version.rb +1 -1
  32. data/lib/rubygems.rb +1 -1
  33. data/lib/rubygems/resolver/index_specification.rb +4 -1
  34. data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb +7 -0
  35. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +0 -1
  36. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb +10 -4
  37. data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +1 -1
  38. data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb +11 -0
  39. data/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +11 -7
  40. data/rubygems-update.gemspec +1 -1
  41. data/test/rubygems/data/null-required-ruby-version.gemspec.rz +0 -0
  42. data/test/rubygems/test_gem_dependency_installer.rb +25 -0
  43. data/test/rubygems/test_gem_requirement.rb +1 -1
  44. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c18e3412218b88b1351a2dcd3096240a1b5fa833aa26c58efee7a70e72601d4
4
- data.tar.gz: 9f8fff96b275641a2fd60220cbfa98343af11c177c8797261f1d99089f4345c0
3
+ metadata.gz: 8c88809da851f0467214e490fb43a1d4c54b9980d7c0099881d10b19bd5f668c
4
+ data.tar.gz: adc3c7278c9bca2021b7bfb3f3ba0a215447512d2af3cc7bba8bd8c3781944d5
5
5
  SHA512:
6
- metadata.gz: cb78b68b419a3ffa8e70a9688c563510c93982c0d3c26969594639bcf41ba6345b3a48cf1c4f756689a202d1b8d9be416d19715d18acea2640dd6dcb53cee2d1
7
- data.tar.gz: 98fb817e049053336bd47a5525a4247096558eef13efd10e5a7c38ea407569ef62fe29d135142854759874424c624bf51ed292606257a9539e60d991f891abd2
6
+ metadata.gz: 6ce421e400fcb3e38ad14f83e5614f0ee77ad0f9cfba73c7a51b8afca807f1ef3f166a585e4ec377fb41f2526d02055dcaff66bf54d9dde221f68f256e0bf777
7
+ data.tar.gz: b8da7349c0f8c7c71e95405a8748006c70c5917613f85f5ed56d7188d1cc6afa7b348d07e133535e9959c9505c9b86dc9087c1d4af25501a93535e0301d31bf4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # 3.2.8 / 2021-02-02
2
+
3
+ ## Bug fixes:
4
+
5
+ * Fix `gem install` crashing on gemspec with nil required_ruby_version.
6
+ Pull request #4334 by pbernays
7
+
1
8
  # 3.2.7 / 2021-01-26
2
9
 
3
10
  ## Bug fixes:
data/Manifest.txt CHANGED
@@ -189,6 +189,7 @@ bundler/lib/bundler/templates/Executable.bundler
189
189
  bundler/lib/bundler/templates/Executable.standalone
190
190
  bundler/lib/bundler/templates/Gemfile
191
191
  bundler/lib/bundler/templates/gems.rb
192
+ bundler/lib/bundler/templates/newgem/CHANGELOG.md.tt
192
193
  bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
193
194
  bundler/lib/bundler/templates/newgem/Gemfile.tt
194
195
  bundler/lib/bundler/templates/newgem/LICENSE.txt.tt
@@ -511,6 +512,7 @@ test/rubygems/child_key.pem
511
512
  test/rubygems/client.pem
512
513
  test/rubygems/data/gem-private_key.pem
513
514
  test/rubygems/data/gem-public_cert.pem
515
+ test/rubygems/data/null-required-ruby-version.gemspec.rz
514
516
  test/rubygems/data/null-required-rubygems-version.gemspec.rz
515
517
  test/rubygems/data/null-type.gemspec.rz
516
518
  test/rubygems/encrypted_private_key.pem
data/Rakefile CHANGED
@@ -52,20 +52,16 @@ RDoc::Task.new :rdoc => 'docs', :clobber_rdoc => 'clobber_docs' do |doc|
52
52
  doc.rdoc_dir = 'doc'
53
53
  end
54
54
 
55
- begin
56
- require "automatiek"
57
-
58
- Automatiek::RakeTask.new("molinillo") do |lib|
59
- lib.version = "0.7.0"
60
- lib.download = { :github => "https://github.com/CocoaPods/Molinillo" }
61
- lib.namespace = "Molinillo"
62
- lib.prefix = "Gem::Resolver"
63
- lib.vendor_lib = "lib/rubygems/resolver/molinillo"
64
- end
65
- rescue LoadError
66
- namespace :vendor do
67
- task(:molinillo) { abort "Install the automatiek gem to be able to vendor gems." }
68
- end
55
+ load "util/automatiek.rake"
56
+
57
+ # We currently ship Molinillo master branch as of
58
+ # https://github.com/CocoaPods/Molinillo/commit/7cc27a355e861bdf593e2cde7bf1bca3daae4303
59
+ Automatiek::RakeTask.new("molinillo") do |lib|
60
+ lib.version = "master"
61
+ lib.download = { :github => "https://github.com/CocoaPods/Molinillo" }
62
+ lib.namespace = "Molinillo"
63
+ lib.prefix = "Gem::Resolver"
64
+ lib.vendor_lib = "lib/rubygems/resolver/molinillo"
69
65
  end
70
66
 
71
67
  namespace :rubocop do
data/bundler/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # 2.2.8 (February 2, 2021)
2
+
3
+ ## Enhancements:
4
+
5
+ - Add a CHANGELOG.md file to gems generated by `bundle gem` [#4093](https://github.com/rubygems/rubygems/pull/4093)
6
+ - Support gemified `set` [#4297](https://github.com/rubygems/rubygems/pull/4297)
7
+
8
+ ## Bug fixes:
9
+
10
+ - Fix standalone Kernel.require visibility [#4337](https://github.com/rubygems/rubygems/pull/4337)
11
+
12
+ ## Performance:
13
+
14
+ - Fix resolver edge cases and speed up bundler [#4277](https://github.com/rubygems/rubygems/pull/4277)
15
+
1
16
  # 2.2.7 (January 26, 2021)
2
17
 
3
18
  ## Enhancements:
@@ -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 = "2021-01-27".freeze
8
- @git_commit_sha = "7bc7ecb660".freeze
7
+ @built_at = "2021-02-02".freeze
8
+ @git_commit_sha = "4015e550dc".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
@@ -586,6 +586,7 @@ module Bundler
586
586
  method_option :git, :type => :boolean, :default => true, :desc => "Initialize a git repo inside your library."
587
587
  method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config set --global gem.mit true`."
588
588
  method_option :rubocop, :type => :boolean, :desc => "Add rubocop to the generated Rakefile and gemspec. Set a default with `bundle config set --global gem.rubocop true`."
589
+ method_option :changelog, :type => :boolean, :desc => "Generate changelog file. Set a default with `bundle config set --global gem.changelog true`."
589
590
  method_option :test, :type => :string, :lazy_default => Bundler.settings["gem.test"] || "", :aliases => "-t", :banner => "Use the specified test framework for your library",
590
591
  :desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
591
592
  method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
@@ -142,6 +142,18 @@ module Bundler
142
142
  templates.merge!("CODE_OF_CONDUCT.md.tt" => "CODE_OF_CONDUCT.md")
143
143
  end
144
144
 
145
+ if ask_and_set(:changelog, "Do you want to include a changelog?",
146
+ "A changelog is a file which contains a curated, chronologically ordered list of notable " \
147
+ "changes for each version of a project. To make it easier for users and contributors to" \
148
+ " see precisely what notable changes have been made between each release (or version) of" \
149
+ " the project. Whether consumers or developers, the end users of software are" \
150
+ " human beings who care about what's in the software. When the software changes, people " \
151
+ "want to know why and how. see https://keepachangelog.com")
152
+ config[:changelog] = true
153
+ Bundler.ui.info "Changelog enabled in config"
154
+ templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
155
+ end
156
+
145
157
  if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
146
158
  "RuboCop is a static code analyzer that has out-of-the-box rules for many " \
147
159
  "of the guidelines in the community style guide. " \
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "lockfile_parser"
4
- require "set"
5
4
 
6
5
  module Bundler
7
6
  class Definition
@@ -259,23 +258,18 @@ module Bundler
259
258
  def resolve
260
259
  @resolve ||= begin
261
260
  last_resolve = converge_locked_specs
262
- resolve =
263
- if Bundler.frozen_bundle?
264
- Bundler.ui.debug "Frozen, using resolution from the lockfile"
265
- last_resolve
266
- elsif !unlocking? && nothing_changed?
267
- Bundler.ui.debug("Found no changes, using resolution from the lockfile")
268
- last_resolve
269
- else
270
- # Run a resolve against the locally available gems
271
- Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
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)
274
- end
275
-
276
- # filter out gems that _can_ be installed on multiple platforms, but don't need
277
- # to be
278
- resolve.for(expand_dependencies(dependencies, true), [], false, false, false)
261
+ if Bundler.frozen_bundle?
262
+ Bundler.ui.debug "Frozen, using resolution from the lockfile"
263
+ last_resolve
264
+ elsif !unlocking? && nothing_changed?
265
+ Bundler.ui.debug("Found no changes, using resolution from the lockfile")
266
+ last_resolve
267
+ else
268
+ # Run a resolve against the locally available gems
269
+ Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
270
+ expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote)
271
+ Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
272
+ end
279
273
  end
280
274
  end
281
275
 
@@ -604,7 +598,7 @@ module Bundler
604
598
  deps_for_source = @dependencies.select {|s| s.source == source }
605
599
  locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
606
600
 
607
- Set.new(deps_for_source) != Set.new(locked_deps_for_source)
601
+ deps_for_source.sort != locked_deps_for_source.sort
608
602
  end
609
603
 
610
604
  def specs_for_source_changed?(source)
@@ -884,7 +878,7 @@ module Bundler
884
878
  dependencies.each do |dep|
885
879
  dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
886
880
  next unless remote || dep.current_platform?
887
- target_platforms = dep.gem_platforms(remote ? Resolver.sort_platforms(@platforms) : [generic_local_platform])
881
+ target_platforms = dep.gem_platforms(remote ? @platforms : [generic_local_platform])
888
882
  deps += expand_dependency_with_platforms(dep, target_platforms)
889
883
  end
890
884
  deps
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
4
-
5
3
  module Bundler
6
4
  class Index
7
5
  include Enumerable
@@ -65,11 +63,14 @@ module Bundler
65
63
  def unsorted_search(query, base)
66
64
  results = local_search(query, base)
67
65
 
68
- seen = results.map(&:full_name).to_set unless @sources.empty?
66
+ seen = results.map(&:full_name).uniq unless @sources.empty?
69
67
 
70
68
  @sources.each do |source|
71
69
  source.unsorted_search(query, base).each do |spec|
72
- results << spec if seen.add?(spec.full_name)
70
+ next if seen.include?(spec.full_name)
71
+
72
+ seen << spec.full_name
73
+ results << spec
73
74
  end
74
75
  end
75
76
 
@@ -170,7 +171,7 @@ module Bundler
170
171
  def dependencies_eql?(spec, other_spec)
171
172
  deps = spec.dependencies.select {|d| d.type != :development }
172
173
  other_deps = other_spec.dependencies.select {|d| d.type != :development }
173
- Set.new(deps) == Set.new(other_deps)
174
+ deps.sort == other_deps.sort
174
175
  end
175
176
 
176
177
  def add_source(index)
@@ -55,9 +55,10 @@ module Bundler
55
55
  kernel = (class << ::Kernel; self; end)
56
56
  [kernel, ::Kernel].each do |k|
57
57
  if k.private_method_defined?(:gem_original_require)
58
+ private_require = k.private_method_defined?(:require)
58
59
  k.send(:remove_method, :require)
59
60
  k.send(:define_method, :require, k.instance_method(:gem_original_require))
60
- k.send(:private, :require)
61
+ k.send(:private, :require) if private_require
61
62
  end
62
63
  end
63
64
  END
@@ -4,22 +4,6 @@ require_relative "match_platform"
4
4
 
5
5
  module Bundler
6
6
  class LazySpecification
7
- Identifier = Struct.new(:name, :version, :platform)
8
- class Identifier
9
- include Comparable
10
- def <=>(other)
11
- return unless other.is_a?(Identifier)
12
- [name, version, platform_string] <=> [other.name, other.version, other.platform_string]
13
- end
14
-
15
- protected
16
-
17
- def platform_string
18
- platform_string = platform.to_s
19
- platform_string == Index::RUBY ? Index::NULL : platform_string
20
- end
21
- end
22
-
23
7
  include MatchPlatform
24
8
 
25
9
  attr_reader :name, :version, :dependencies, :platform
@@ -108,7 +92,7 @@ module Bundler
108
92
  end
109
93
 
110
94
  def identifier
111
- @__identifier ||= Identifier.new(name, version, platform)
95
+ @__identifier ||= [name, version, platform_string]
112
96
  end
113
97
 
114
98
  def git_version
@@ -116,6 +100,13 @@ module Bundler
116
100
  " #{source.revision[0..6]}"
117
101
  end
118
102
 
103
+ protected
104
+
105
+ def platform_string
106
+ platform_string = platform.to_s
107
+ platform_string == Index::RUBY ? Index::NULL : platform_string
108
+ end
109
+
119
110
  private
120
111
 
121
112
  def to_ary
@@ -5,6 +5,8 @@ module Bundler
5
5
  require_relative "vendored_molinillo"
6
6
  require_relative "resolver/spec_group"
7
7
 
8
+ include GemHelpers
9
+
8
10
  # Figures out the best possible configuration of gems that satisfies
9
11
  # the list of passed dependencies and any child dependencies without
10
12
  # causing any gem activation errors.
@@ -16,7 +18,6 @@ module Bundler
16
18
  # <GemBundle>,nil:: If the list of dependencies can be resolved, a
17
19
  # collection of gemspecs is returned. Otherwise, nil is returned.
18
20
  def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
19
- platforms = Set.new(platforms) if platforms
20
21
  base = SpecSet.new(base) unless base.is_a?(SpecSet)
21
22
  resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
22
23
  result = resolver.start(requirements)
@@ -36,9 +37,13 @@ module Bundler
36
37
  end
37
38
  additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
38
39
  @platforms = platforms
40
+ @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
39
41
  @gem_version_promoter = gem_version_promoter
40
42
  @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
41
43
  @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
44
+
45
+ @variant_specific_names = []
46
+ @generic_names = []
42
47
  end
43
48
 
44
49
  def start(requirements)
@@ -102,14 +107,24 @@ module Bundler
102
107
  include Molinillo::SpecificationProvider
103
108
 
104
109
  def dependencies_for(specification)
105
- specification.dependencies_for_activated_platforms
110
+ all_dependencies = specification.dependencies_for_activated_platforms
111
+
112
+ if @variant_specific_names.include?(specification.name)
113
+ @variant_specific_names |= all_dependencies.map(&:name) - @generic_names
114
+ else
115
+ generic_names, variant_specific_names = specification.partitioned_dependency_names_for_activated_platforms
116
+ @variant_specific_names |= variant_specific_names - @generic_names
117
+ @generic_names |= generic_names
118
+ end
119
+
120
+ all_dependencies
106
121
  end
107
122
 
108
123
  def search_for(dependency_proxy)
109
124
  platform = dependency_proxy.__platform
110
125
  dependency = dependency_proxy.dep
111
- @search_for[dependency_proxy] ||= begin
112
- name = dependency.name
126
+ name = dependency.name
127
+ search_result = @search_for[dependency_proxy] ||= begin
113
128
  index = index_for(dependency)
114
129
  results = index.search(dependency, @base[name])
115
130
 
@@ -136,37 +151,48 @@ module Bundler
136
151
  end
137
152
  nested.reduce([]) do |groups, (version, specs)|
138
153
  next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
139
- spec_group = SpecGroup.new(specs)
140
- groups << spec_group
154
+
155
+ specs_by_platform = Hash.new do |current_specs, current_platform|
156
+ current_specs[current_platform] = select_best_platform_match(specs, current_platform)
157
+ end
158
+
159
+ spec_group_ruby = SpecGroup.create_for(specs_by_platform, [Gem::Platform::RUBY], Gem::Platform::RUBY)
160
+ groups << spec_group_ruby if spec_group_ruby
161
+
162
+ next groups if @resolving_only_for_ruby
163
+
164
+ spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform)
165
+ groups << spec_group if spec_group
166
+
167
+ groups
141
168
  end
142
169
  else
143
170
  []
144
171
  end
145
172
  # GVP handles major itself, but it's still a bit risky to trust it with it
146
173
  # until we get it settled with new behavior. For 2.x it can take over all cases.
147
- search = if !@use_gvp
174
+ if !@use_gvp
148
175
  spec_groups
149
176
  else
150
177
  @gem_version_promoter.sort_versions(dependency, spec_groups)
151
178
  end
152
- selected_sgs = []
153
- search.each do |sg|
154
- next unless sg.for?(platform)
155
- sg_all_platforms = sg.copy_for(self.class.sort_platforms(@platforms).reverse)
156
- next unless sg_all_platforms
157
-
158
- selected_sgs << sg_all_platforms
179
+ end
159
180
 
160
- next if sg_all_platforms.activated_platforms == [Gem::Platform::RUBY]
161
- # Add a spec group for "non platform specific spec" as the fallback
162
- # spec group.
163
- sg_ruby = sg.copy_for([Gem::Platform::RUBY])
164
- next unless sg_ruby
181
+ unless search_result.empty?
182
+ specific_dependency = @variant_specific_names.include?(name)
183
+ return search_result unless specific_dependency
165
184
 
166
- selected_sgs.insert(-2, sg_ruby)
185
+ search_result.each do |sg|
186
+ if @generic_names.include?(name)
187
+ @variant_specific_names -= [name]
188
+ sg.activate_all_platforms!
189
+ else
190
+ sg.activate_platform!(platform)
191
+ end
167
192
  end
168
- selected_sgs
169
193
  end
194
+
195
+ search_result
170
196
  end
171
197
 
172
198
  def index_for(dependency)
@@ -237,13 +263,6 @@ module Bundler
237
263
  end
238
264
  end
239
265
 
240
- # Sort platforms from most general to most specific
241
- def self.sort_platforms(platforms)
242
- platforms.sort_by do |platform|
243
- platform_sort_key(platform)
244
- end
245
- end
246
-
247
266
  def self.platform_sort_key(platform)
248
267
  # Prefer specific platform to not specific platform
249
268
  return ["99-LAST", "", "", ""] if Gem::Platform::RUBY == platform
@@ -3,27 +3,37 @@
3
3
  module Bundler
4
4
  class Resolver
5
5
  class SpecGroup
6
- include GemHelpers
7
-
8
6
  attr_accessor :name, :version, :source
9
7
  attr_accessor :activated_platforms
10
8
 
11
- def initialize(all_specs)
12
- @all_specs = all_specs
13
- raise ArgumentError, "cannot initialize with an empty value" unless exemplary_spec = all_specs.first
9
+ def self.create_for(specs, all_platforms, specific_platform)
10
+ specific_platform_specs = specs[specific_platform]
11
+ return unless specific_platform_specs.any?
12
+
13
+ platforms = all_platforms.select {|p| specs[p].any? }
14
+
15
+ new(specific_platform_specs.first, specs, platforms)
16
+ end
17
+
18
+ def initialize(exemplary_spec, specs, relevant_platforms)
19
+ @exemplary_spec = exemplary_spec
14
20
  @name = exemplary_spec.name
15
21
  @version = exemplary_spec.version
16
22
  @source = exemplary_spec.source
17
23
 
18
- @activated_platforms = []
19
- @dependencies = nil
20
- @specs = Hash.new do |specs, platform|
21
- specs[platform] = select_best_platform_match(all_specs, platform)
24
+ @all_platforms = relevant_platforms
25
+ @activated_platforms = relevant_platforms
26
+ @dependencies = Hash.new do |dependencies, platforms|
27
+ dependencies[platforms] = dependencies_for(platforms)
22
28
  end
29
+ @partitioned_dependency_names = Hash.new do |partitioned_dependency_names, platforms|
30
+ partitioned_dependency_names[platforms] = partitioned_dependency_names_for(platforms)
31
+ end
32
+ @specs = specs
23
33
  end
24
34
 
25
35
  def to_specs
26
- @activated_platforms.map do |p|
36
+ activated_platforms.map do |p|
27
37
  specs = @specs[p]
28
38
  next unless specs.any?
29
39
 
@@ -35,17 +45,12 @@ module Bundler
35
45
  end.flatten.compact.uniq
36
46
  end
37
47
 
38
- def copy_for(platforms)
39
- platforms.select! {|p| for?(p) }
40
- return unless platforms.any?
41
-
42
- copied_sg = self.class.new(@all_specs)
43
- copied_sg.activated_platforms = platforms
44
- copied_sg
48
+ def activate_platform!(platform)
49
+ self.activated_platforms = [platform]
45
50
  end
46
51
 
47
- def for?(platform)
48
- @specs[platform].any?
52
+ def activate_all_platforms!
53
+ self.activated_platforms = @all_platforms
49
54
  end
50
55
 
51
56
  def to_s
@@ -54,11 +59,11 @@ module Bundler
54
59
  end
55
60
 
56
61
  def dependencies_for_activated_platforms
57
- dependencies = @activated_platforms.map {|p| __dependencies[p] }
58
- metadata_dependencies = @activated_platforms.map do |platform|
59
- metadata_dependencies(@specs[platform].first, platform)
60
- end
61
- dependencies.concat(metadata_dependencies).flatten
62
+ @dependencies[activated_platforms]
63
+ end
64
+
65
+ def partitioned_dependency_names_for_activated_platforms
66
+ @partitioned_dependency_names[activated_platforms]
62
67
  end
63
68
 
64
69
  def ==(other)
@@ -84,27 +89,37 @@ module Bundler
84
89
  protected
85
90
 
86
91
  def sorted_activated_platforms
87
- @activated_platforms.sort_by(&:to_s)
92
+ activated_platforms.sort_by(&:to_s)
88
93
  end
89
94
 
90
95
  private
91
96
 
92
- def __dependencies
93
- @dependencies = Hash.new do |dependencies, platform|
94
- dependencies[platform] = []
95
- specs = @specs[platform]
96
- if spec = specs.first
97
- spec.dependencies.each do |dep|
98
- next if dep.type == :development
99
- dependencies[platform] << DepProxy.get_proxy(dep, platform)
100
- end
101
- end
102
- dependencies[platform]
97
+ def dependencies_for(platforms)
98
+ platforms.map do |platform|
99
+ __dependencies(platform) + metadata_dependencies(platform)
100
+ end.flatten
101
+ end
102
+
103
+ def partitioned_dependency_names_for(platforms)
104
+ return @dependencies[platforms].map(&:name), [] if platforms.size == 1
105
+
106
+ @dependencies[platforms].partition do |dep_proxy|
107
+ @dependencies[platforms].count {|dp| dp.dep == dep_proxy.dep } == platforms.size
108
+ end.map {|deps| deps.map(&:name) }
109
+ end
110
+
111
+ def __dependencies(platform)
112
+ dependencies = []
113
+ @specs[platform].first.dependencies.each do |dep|
114
+ next if dep.type == :development
115
+ dependencies << DepProxy.get_proxy(dep, platform)
103
116
  end
117
+ dependencies
104
118
  end
105
119
 
106
- def metadata_dependencies(spec, platform)
107
- return [] unless spec && spec.is_a?(Gem::Specification)
120
+ def metadata_dependencies(platform)
121
+ spec = @specs[platform].first
122
+ return [] unless spec.is_a?(Gem::Specification)
108
123
  dependencies = []
109
124
  if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
110
125
  dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
@@ -194,11 +194,11 @@ module Bundler
194
194
  return @md5_available if defined?(@md5_available)
195
195
  @md5_available = begin
196
196
  require "openssl"
197
- OpenSSL::Digest.digest("MD5", "")
197
+ ::OpenSSL::Digest.digest("MD5", "")
198
198
  true
199
199
  rescue LoadError
200
200
  true
201
- rescue OpenSSL::Digest::DigestError
201
+ rescue ::OpenSSL::Digest::DigestError
202
202
  false
203
203
  end
204
204
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "set"
4
-
5
3
  module Bundler
6
4
  class SourceList
7
5
  attr_reader :path_sources,
@@ -99,7 +97,7 @@ module Bundler
99
97
  @rubygems_aggregate = replacement_rubygems if replacement_rubygems
100
98
 
101
99
  return true if !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
102
- return true if replacement_rubygems && rubygems_remotes.to_set != replacement_rubygems.remotes.to_set
100
+ return true if replacement_rubygems && rubygems_remotes.sort_by(&:to_s) != replacement_rubygems.remotes.sort_by(&:to_s)
103
101
 
104
102
  false
105
103
  end
@@ -153,7 +151,7 @@ module Bundler
153
151
  end
154
152
 
155
153
  def equal_sources?(lock_sources, replacement_sources)
156
- lock_sources.to_set == replacement_sources.to_set
154
+ lock_sources.sort_by(&:to_s) == replacement_sources.sort_by(&:to_s)
157
155
  end
158
156
 
159
157
  def equal_source?(source, other_source)
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "tsort"
4
- require "set"
5
4
 
6
5
  module Bundler
7
6
  class SpecSet
@@ -13,14 +12,16 @@ module Bundler
13
12
  end
14
13
 
15
14
  def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
16
- handled = Set.new
15
+ handled = []
17
16
  deps = dependencies.dup
18
17
  specs = []
19
18
  skip += ["bundler"]
20
19
 
21
20
  loop do
22
21
  break unless dep = deps.shift
23
- next if !handled.add?(dep) || skip.include?(dep.name)
22
+ next if handled.include?(dep) || skip.include?(dep.name)
23
+
24
+ handled << dep
24
25
 
25
26
  specs_for_dep = spec_for_dependency(dep, match_current_platform)
26
27
  if specs_for_dep.any?
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - <%= Time.now.strftime('%F') %>
4
+
5
+ - Initial release
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require 'tsort'
5
4
 
6
5
  require_relative 'dependency_graph/log'
@@ -59,7 +59,7 @@ module Bundler::Molinillo
59
59
  # @param [Set<Vertex>] vertices the set to add the predecessors to
60
60
  # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
61
61
  # {#descendent?}
62
- def _recursive_predecessors(vertices = Set.new)
62
+ def _recursive_predecessors(vertices = new_vertex_set)
63
63
  incoming_edges.each do |edge|
64
64
  vertex = edge.origin
65
65
  next unless vertices.add?(vertex)
@@ -85,7 +85,7 @@ module Bundler::Molinillo
85
85
  # @param [Set<Vertex>] vertices the set to add the successors to
86
86
  # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
87
87
  # {#ancestor?}
88
- def _recursive_successors(vertices = Set.new)
88
+ def _recursive_successors(vertices = new_vertex_set)
89
89
  outgoing_edges.each do |edge|
90
90
  vertex = edge.destination
91
91
  next unless vertices.add?(vertex)
@@ -128,7 +128,7 @@ module Bundler::Molinillo
128
128
 
129
129
  # Is there a path from `self` to `other` following edges in the
130
130
  # dependency graph?
131
- # @return true iff there is a path following edges within this {#graph}
131
+ # @return whether there is a path following edges within this {#graph}
132
132
  def path_to?(other)
133
133
  _path_to?(other)
134
134
  end
@@ -138,7 +138,7 @@ module Bundler::Molinillo
138
138
  # @param [Vertex] other the vertex to check if there's a path to
139
139
  # @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
140
140
  # @return [Boolean] whether there is a path to `other` from `self`
141
- def _path_to?(other, visited = Set.new)
141
+ def _path_to?(other, visited = new_vertex_set)
142
142
  return false unless visited.add?(self)
143
143
  return true if equal?(other)
144
144
  successors.any? { |v| v._path_to?(other, visited) }
@@ -147,12 +147,18 @@ module Bundler::Molinillo
147
147
 
148
148
  # Is there a path from `other` to `self` following edges in the
149
149
  # dependency graph?
150
- # @return true iff there is a path following edges within this {#graph}
150
+ # @return whether there is a path following edges within this {#graph}
151
151
  def ancestor?(other)
152
152
  other.path_to?(self)
153
153
  end
154
154
 
155
155
  alias is_reachable_from? ancestor?
156
+
157
+ def new_vertex_set
158
+ require 'set'
159
+ Set.new
160
+ end
161
+ private :new_vertex_set
156
162
  end
157
163
  end
158
164
  end
@@ -34,7 +34,7 @@ module Bundler::Molinillo
34
34
 
35
35
  # An error caused by attempting to fulfil a dependency that was circular
36
36
  #
37
- # @note This exception will be thrown iff a {Vertex} is added to a
37
+ # @note This exception will be thrown if and only if a {Vertex} is added to a
38
38
  # {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
39
39
  # existing {DependencyGraph::Vertex}
40
40
  class CircularDependencyError < ResolverError
@@ -1,7 +1,7 @@
1
- require "set"
2
1
  require_relative "thor/base"
3
2
 
4
3
  class Bundler::Thor
4
+ $thor_runner ||= false
5
5
  class << self
6
6
  # Allows for custom "Command" package naming.
7
7
  #
@@ -323,7 +323,7 @@ class Bundler::Thor
323
323
  # ==== Parameters
324
324
  # Symbol ...:: A list of commands that should be affected.
325
325
  def stop_on_unknown_option!(*command_names)
326
- stop_on_unknown_option.merge(command_names)
326
+ @stop_on_unknown_option = stop_on_unknown_option | command_names
327
327
  end
328
328
 
329
329
  def stop_on_unknown_option?(command) #:nodoc:
@@ -337,7 +337,7 @@ class Bundler::Thor
337
337
  # ==== Parameters
338
338
  # Symbol ...:: A list of commands that should be affected.
339
339
  def disable_required_check!(*command_names)
340
- disable_required_check.merge(command_names)
340
+ @disable_required_check = disable_required_check | command_names
341
341
  end
342
342
 
343
343
  def disable_required_check?(command) #:nodoc:
@@ -347,12 +347,12 @@ class Bundler::Thor
347
347
  protected
348
348
 
349
349
  def stop_on_unknown_option #:nodoc:
350
- @stop_on_unknown_option ||= Set.new
350
+ @stop_on_unknown_option ||= []
351
351
  end
352
352
 
353
353
  # help command has the required check disabled by default.
354
354
  def disable_required_check #:nodoc:
355
- @disable_required_check ||= Set.new([:help])
355
+ @disable_required_check ||= [:help]
356
356
  end
357
357
 
358
358
  # The method responsible for dispatching given the args.
@@ -398,7 +398,6 @@ class Bundler::Thor
398
398
  # the namespace should be displayed as arguments.
399
399
  #
400
400
  def banner(command, namespace = nil, subcommand = false)
401
- $thor_runner ||= false
402
401
  command.formatted_usage(self, $thor_runner, subcommand).split("\n").map do |formatted_usage|
403
402
  "#{basename} #{formatted_usage}"
404
403
  end.join("\n")
@@ -219,7 +219,7 @@ class Bundler::Thor
219
219
 
220
220
  contents = if is_uri
221
221
  require "open-uri"
222
- open(path, "Accept" => "application/x-thor-template", &:read)
222
+ URI.open(path, "Accept" => "application/x-thor-template", &:read)
223
223
  else
224
224
  open(path, &:read)
225
225
  end
@@ -251,7 +251,8 @@ class Bundler::Thor
251
251
  # path<String>:: path of the file to be changed
252
252
  # flag<Regexp|String>:: the regexp or string to be replaced
253
253
  # replacement<String>:: the replacement, can be also given as a block
254
- # config<Hash>:: give :verbose => false to not log the status.
254
+ # config<Hash>:: give :verbose => false to not log the status, and
255
+ # :force => true, to force the replacement regardles of runner behavior.
255
256
  #
256
257
  # ==== Example
257
258
  #
@@ -262,9 +263,10 @@ class Bundler::Thor
262
263
  # end
263
264
  #
264
265
  def gsub_file(path, flag, *args, &block)
265
- return unless behavior == :invoke
266
266
  config = args.last.is_a?(Hash) ? args.pop : {}
267
267
 
268
+ return unless behavior == :invoke || config.fetch(:force, false)
269
+
268
270
  path = File.expand_path(path, destination_root)
269
271
  say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
270
272
 
@@ -1,5 +1,5 @@
1
1
  class Bundler::Thor
2
- Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable)
2
+ Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName
3
3
  # In order to support versions of Ruby that don't have keyword
4
4
  # arguments, we need our own spell checker class that doesn't take key
5
5
  # words. Even though this code wouldn't be hit because of the check
@@ -30,7 +30,11 @@ class Bundler::Thor
30
30
 
31
31
  arguments.each do |argument|
32
32
  if !argument.default.nil?
33
- @assigns[argument.human_name] = argument.default
33
+ begin
34
+ @assigns[argument.human_name] = argument.default.dup
35
+ rescue TypeError # Compatibility shim for un-dup-able Fixnum in Ruby < 2.4
36
+ @assigns[argument.human_name] = argument.default
37
+ end
34
38
  elsif argument.required?
35
39
  @non_assigned_required << argument
36
40
  end
@@ -133,15 +133,16 @@ class Bundler::Thor
133
133
 
134
134
  protected
135
135
 
136
- def assign_result!(option, result)
137
- if option.repeatable && option.type == :hash
138
- (@assigns[option.human_name] ||= {}).merge!(result)
139
- elsif option.repeatable
140
- (@assigns[option.human_name] ||= []) << result
141
- else
142
- @assigns[option.human_name] = result
136
+ def assign_result!(option, result)
137
+ if option.repeatable && option.type == :hash
138
+ (@assigns[option.human_name] ||= {}).merge!(result)
139
+ elsif option.repeatable
140
+ (@assigns[option.human_name] ||= []) << result
141
+ else
142
+ @assigns[option.human_name] = result
143
+ end
143
144
  end
144
- end
145
+
145
146
  # Check if the current value in peek is a registered switch.
146
147
  #
147
148
  # Two booleans are returned. The first is true if the current value
@@ -94,6 +94,8 @@ class Bundler::Thor
94
94
  # say("I know you knew that.")
95
95
  #
96
96
  def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
97
+ return if quiet?
98
+
97
99
  buffer = prepare_message(message, *color)
98
100
  buffer << "\n" if force_new_line && !message.to_s.end_with?("\n")
99
101
 
@@ -230,8 +232,9 @@ class Bundler::Thor
230
232
  paras = message.split("\n\n")
231
233
 
232
234
  paras.map! do |unwrapped|
233
- counter = 0
234
- unwrapped.split(" ").inject do |memo, word|
235
+ words = unwrapped.split(" ")
236
+ counter = words.first.length
237
+ words.inject do |memo, word|
235
238
  word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
236
239
  counter = 0 if word.include? "\n"
237
240
  if (counter + word.length + 1) < width
@@ -97,7 +97,11 @@ class Bundler::Thor
97
97
  protected
98
98
 
99
99
  def can_display_colors?
100
- stdout.tty? && !are_colors_disabled?
100
+ are_colors_supported? && !are_colors_disabled?
101
+ end
102
+
103
+ def are_colors_supported?
104
+ stdout.tty? && ENV["TERM"] != "dumb"
101
105
  end
102
106
 
103
107
  def are_colors_disabled?
@@ -1,3 +1,3 @@
1
1
  class Bundler::Thor
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.2.7".freeze
4
+ VERSION = "2.2.8".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
data/lib/rubygems.rb CHANGED
@@ -8,7 +8,7 @@
8
8
  require 'rbconfig'
9
9
 
10
10
  module Gem
11
- VERSION = "3.2.7".freeze
11
+ VERSION = "3.2.8".freeze
12
12
  end
13
13
 
14
14
  # Must be first since it unloads the prelude from 1.9.2
@@ -35,9 +35,12 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
35
35
 
36
36
  ##
37
37
  # The required_ruby_version constraint for this specification
38
+ #
39
+ # A fallback is included because when generated, some marshalled specs have it
40
+ # set to +nil+.
38
41
 
39
42
  def required_ruby_version
40
- spec.required_ruby_version
43
+ spec.required_ruby_version || Gem::Requirement.default
41
44
  end
42
45
 
43
46
  ##
@@ -26,6 +26,13 @@ module Gem::Resolver::Molinillo
26
26
  end
27
27
  end
28
28
 
29
+ # (see Gem::Resolver::Molinillo::SpecificationProvider#dependencies_equal?)
30
+ def dependencies_equal?(dependencies, other_dependencies)
31
+ with_no_such_dependency_error_handling do
32
+ specification_provider.dependencies_equal?(dependencies, other_dependencies)
33
+ end
34
+ end
35
+
29
36
  # (see Gem::Resolver::Molinillo::SpecificationProvider#name_for)
30
37
  def name_for(dependency)
31
38
  with_no_such_dependency_error_handling do
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require 'tsort'
5
4
 
6
5
  require_relative 'dependency_graph/log'
@@ -59,7 +59,7 @@ module Gem::Resolver::Molinillo
59
59
  # @param [Set<Vertex>] vertices the set to add the predecessors to
60
60
  # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
61
61
  # {#descendent?}
62
- def _recursive_predecessors(vertices = Set.new)
62
+ def _recursive_predecessors(vertices = new_vertex_set)
63
63
  incoming_edges.each do |edge|
64
64
  vertex = edge.origin
65
65
  next unless vertices.add?(vertex)
@@ -85,7 +85,7 @@ module Gem::Resolver::Molinillo
85
85
  # @param [Set<Vertex>] vertices the set to add the successors to
86
86
  # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
87
87
  # {#ancestor?}
88
- def _recursive_successors(vertices = Set.new)
88
+ def _recursive_successors(vertices = new_vertex_set)
89
89
  outgoing_edges.each do |edge|
90
90
  vertex = edge.destination
91
91
  next unless vertices.add?(vertex)
@@ -138,7 +138,7 @@ module Gem::Resolver::Molinillo
138
138
  # @param [Vertex] other the vertex to check if there's a path to
139
139
  # @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
140
140
  # @return [Boolean] whether there is a path to `other` from `self`
141
- def _path_to?(other, visited = Set.new)
141
+ def _path_to?(other, visited = new_vertex_set)
142
142
  return false unless visited.add?(self)
143
143
  return true if equal?(other)
144
144
  successors.any? { |v| v._path_to?(other, visited) }
@@ -147,12 +147,18 @@ module Gem::Resolver::Molinillo
147
147
 
148
148
  # Is there a path from `other` to `self` following edges in the
149
149
  # dependency graph?
150
- # @return true iff there is a path following edges within this {#graph}
150
+ # @return whether there is a path following edges within this {#graph}
151
151
  def ancestor?(other)
152
152
  other.path_to?(self)
153
153
  end
154
154
 
155
155
  alias is_reachable_from? ancestor?
156
+
157
+ def new_vertex_set
158
+ require 'set'
159
+ Set.new
160
+ end
161
+ private :new_vertex_set
156
162
  end
157
163
  end
158
164
  end
@@ -121,7 +121,7 @@ module Gem::Resolver::Molinillo
121
121
  t = ''.dup
122
122
  depth = 2
123
123
  tree.each do |req|
124
- t << ' ' * depth << req.to_s
124
+ t << ' ' * depth << printable_requirement.call(req)
125
125
  unless tree.last == req
126
126
  if spec = conflict.activated_by_name[name_for(req)]
127
127
  t << %( was resolved to #{version_for_spec.call(spec)}, which)
@@ -45,6 +45,17 @@ module Gem::Resolver::Molinillo
45
45
  true
46
46
  end
47
47
 
48
+ # Determines whether two arrays of dependencies are equal, and thus can be
49
+ # grouped.
50
+ #
51
+ # @param [Array<Object>] dependencies
52
+ # @param [Array<Object>] other_dependencies
53
+ # @return [Boolean] whether `dependencies` and `other_dependencies` should
54
+ # be considered equal.
55
+ def dependencies_equal?(dependencies, other_dependencies)
56
+ dependencies == other_dependencies
57
+ end
58
+
48
59
  # Returns the name for the given `dependency`.
49
60
  # @note This method should be 'pure', i.e. the return value should depend
50
61
  # only on the `dependency` parameter.
@@ -329,11 +329,11 @@ module Gem::Resolver::Molinillo
329
329
 
330
330
  # Look for past conflicts that could be unwound to affect the
331
331
  # requirement tree for the current conflict
332
+ all_reqs = last_detail_for_current_unwind.all_requirements
333
+ all_reqs_size = all_reqs.size
332
334
  relevant_unused_unwinds = unused_unwind_options.select do |alternative|
333
- intersecting_requirements =
334
- last_detail_for_current_unwind.all_requirements &
335
- alternative.requirements_unwound_to_instead
336
- next if intersecting_requirements.empty?
335
+ diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
336
+ next if diff_reqs.size == all_reqs_size
337
337
  # Find the highest index unwind whilst looping through
338
338
  current_detail = alternative if alternative > current_detail
339
339
  alternative
@@ -344,8 +344,12 @@ module Gem::Resolver::Molinillo
344
344
  state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
345
345
 
346
346
  # Update the requirements_unwound_to_instead on any relevant unused unwinds
347
- relevant_unused_unwinds.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
348
- unwind_details.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
347
+ relevant_unused_unwinds.each do |d|
348
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
349
+ end
350
+ unwind_details.each do |d|
351
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
352
+ end
349
353
 
350
354
  current_detail
351
355
  end
@@ -803,7 +807,7 @@ module Gem::Resolver::Molinillo
803
807
 
804
808
  possibilities.reverse_each do |possibility|
805
809
  dependencies = dependencies_for(possibility)
806
- if current_possibility_set && current_possibility_set.dependencies == dependencies
810
+ if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
807
811
  current_possibility_set.possibilities.unshift(possibility)
808
812
  else
809
813
  possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "rubygems-update"
5
- s.version = "3.2.7"
5
+ s.version = "3.2.8"
6
6
  s.authors = ["Jim Weirich", "Chad Fowler", "Eric Hodel", "Luis Lavena", "Aaron Patterson", "Samuel Giddins", "André Arko", "Evan Phoenix", "Hiroshi SHIBATA"]
7
7
  s.email = ["", "", "drbrain@segment7.net", "luislavena@gmail.com", "aaron@tenderlovemaking.com", "segiddins@segiddins.me", "andre@arko.net", "evan@phx.io", "hsbt@ruby-lang.org"]
8
8
 
@@ -946,6 +946,31 @@ class TestGemDependencyInstaller < Gem::TestCase
946
946
  assert_equal %w[d-2], inst.installed_gems.map {|s| s.full_name }
947
947
  end
948
948
 
949
+ def test_install_legacy_spec_with_nil_required_ruby_version
950
+ path = File.expand_path "../data/null-required-ruby-version.gemspec.rz", __FILE__
951
+ spec = Marshal.load Gem.read_binary(path)
952
+ def spec.validate(*args); end
953
+
954
+ util_build_gem spec
955
+
956
+ cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
957
+ FileUtils.mkdir_p File.dirname cache_file
958
+ FileUtils.mv spec.cache_file, cache_file
959
+
960
+ util_setup_spec_fetcher spec
961
+
962
+ data = Gem.read_binary(cache_file)
963
+
964
+ @fetcher.data['http://gems.example.com/gems/activesupport-1.0.0.gem'] = data
965
+
966
+ dep = Gem::Dependency.new 'activesupport'
967
+
968
+ inst = Gem::DependencyInstaller.new
969
+ inst.install dep
970
+
971
+ assert_equal %w[activesupport-1.0.0], Gem::Specification.map(&:full_name)
972
+ end
973
+
949
974
  def test_install_legacy_spec_with_nil_required_rubygems_version
950
975
  path = File.expand_path "../data/null-required-rubygems-version.gemspec.rz", __FILE__
951
976
  spec = Marshal.load Gem.read_binary(path)
@@ -83,7 +83,7 @@ class TestGemRequirement < Gem::TestCase
83
83
  Gem::Requirement.parse(Gem::Version.new('2'))
84
84
  end
85
85
 
86
- if RUBY_VERSION >= '2.5'
86
+ if RUBY_VERSION >= '2.5' && !(Gem.java_platform? && ENV["JRUBY_OPTS"] =~ /--debug/)
87
87
  def test_parse_deduplication
88
88
  assert_same '~>', Gem::Requirement.parse('~> 1').first
89
89
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubygems-update
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.7
4
+ version: 3.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2021-01-27 00:00:00.000000000 Z
19
+ date: 2021-02-02 00:00:00.000000000 Z
20
20
  dependencies: []
21
21
  description: |-
22
22
  A package (also known as a library) contains a set of functionality
@@ -245,6 +245,7 @@ files:
245
245
  - bundler/lib/bundler/templates/Executable.standalone
246
246
  - bundler/lib/bundler/templates/Gemfile
247
247
  - bundler/lib/bundler/templates/gems.rb
248
+ - bundler/lib/bundler/templates/newgem/CHANGELOG.md.tt
248
249
  - bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt
249
250
  - bundler/lib/bundler/templates/newgem/Gemfile.tt
250
251
  - bundler/lib/bundler/templates/newgem/LICENSE.txt.tt
@@ -567,6 +568,7 @@ files:
567
568
  - test/rubygems/client.pem
568
569
  - test/rubygems/data/gem-private_key.pem
569
570
  - test/rubygems/data/gem-public_cert.pem
571
+ - test/rubygems/data/null-required-ruby-version.gemspec.rz
570
572
  - test/rubygems/data/null-required-rubygems-version.gemspec.rz
571
573
  - test/rubygems/data/null-type.gemspec.rz
572
574
  - test/rubygems/encrypted_private_key.pem
@@ -765,7 +767,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
765
767
  - !ruby/object:Gem::Version
766
768
  version: '0'
767
769
  requirements: []
768
- rubygems_version: 3.2.7
770
+ rubygems_version: 3.2.8
769
771
  signing_key:
770
772
  specification_version: 4
771
773
  summary: RubyGems is a package management framework for Ruby.