rubygems-update 3.5.10 → 3.5.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -1
  3. data/CODE_OF_CONDUCT.md +79 -28
  4. data/CONTRIBUTING.md +2 -2
  5. data/Manifest.txt +2 -0
  6. data/bundler/CHANGELOG.md +48 -0
  7. data/bundler/lib/bundler/build_metadata.rb +2 -2
  8. data/bundler/lib/bundler/cli/install.rb +1 -1
  9. data/bundler/lib/bundler/cli.rb +5 -8
  10. data/bundler/lib/bundler/compact_index_client/cache.rb +47 -72
  11. data/bundler/lib/bundler/compact_index_client/parser.rb +84 -0
  12. data/bundler/lib/bundler/compact_index_client.rb +51 -80
  13. data/bundler/lib/bundler/constants.rb +8 -1
  14. data/bundler/lib/bundler/definition.rb +21 -27
  15. data/bundler/lib/bundler/errors.rb +14 -0
  16. data/bundler/lib/bundler/fetcher/compact_index.rb +15 -24
  17. data/bundler/lib/bundler/gem_helper.rb +1 -1
  18. data/bundler/lib/bundler/installer/gem_installer.rb +0 -1
  19. data/bundler/lib/bundler/installer.rb +8 -8
  20. data/bundler/lib/bundler/man/bundle-add.1 +1 -1
  21. data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
  22. data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
  23. data/bundler/lib/bundler/man/bundle-check.1 +1 -1
  24. data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
  25. data/bundler/lib/bundler/man/bundle-config.1 +2 -2
  26. data/bundler/lib/bundler/man/bundle-config.1.ronn +1 -1
  27. data/bundler/lib/bundler/man/bundle-console.1 +1 -1
  28. data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
  29. data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
  30. data/bundler/lib/bundler/man/bundle-gem.1 +1 -1
  31. data/bundler/lib/bundler/man/bundle-help.1 +1 -1
  32. data/bundler/lib/bundler/man/bundle-info.1 +1 -1
  33. data/bundler/lib/bundler/man/bundle-init.1 +1 -1
  34. data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
  35. data/bundler/lib/bundler/man/bundle-install.1 +1 -1
  36. data/bundler/lib/bundler/man/bundle-list.1 +1 -1
  37. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  38. data/bundler/lib/bundler/man/bundle-open.1 +1 -1
  39. data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
  40. data/bundler/lib/bundler/man/bundle-platform.1 +1 -1
  41. data/bundler/lib/bundler/man/bundle-plugin.1 +1 -1
  42. data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
  43. data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
  44. data/bundler/lib/bundler/man/bundle-show.1 +1 -1
  45. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  46. data/bundler/lib/bundler/man/bundle-version.1 +1 -1
  47. data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
  48. data/bundler/lib/bundler/man/bundle.1 +1 -1
  49. data/bundler/lib/bundler/man/gemfile.5 +1 -1
  50. data/bundler/lib/bundler/rubygems_ext.rb +20 -12
  51. data/bundler/lib/bundler/rubygems_integration.rb +14 -0
  52. data/bundler/lib/bundler/self_manager.rb +6 -1
  53. data/bundler/lib/bundler/settings.rb +12 -8
  54. data/bundler/lib/bundler/setup.rb +3 -0
  55. data/bundler/lib/bundler/shared_helpers.rb +6 -4
  56. data/bundler/lib/bundler/source/git/git_proxy.rb +8 -0
  57. data/bundler/lib/bundler/source/git.rb +14 -0
  58. data/bundler/lib/bundler/source/metadata.rb +2 -0
  59. data/bundler/lib/bundler/source/path.rb +0 -13
  60. data/bundler/lib/bundler/source/rubygems.rb +32 -15
  61. data/bundler/lib/bundler/source_list.rb +13 -2
  62. data/bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +77 -29
  63. data/bundler/lib/bundler/version.rb +1 -1
  64. data/bundler/lib/bundler/yaml_serializer.rb +1 -8
  65. data/bundler/lib/bundler.rb +6 -1
  66. data/exe/update_rubygems +1 -1
  67. data/lib/rubygems/basic_specification.rb +27 -0
  68. data/lib/rubygems/commands/pristine_command.rb +12 -9
  69. data/lib/rubygems/commands/setup_command.rb +2 -0
  70. data/lib/rubygems/commands/uninstall_command.rb +1 -1
  71. data/lib/rubygems/dependency.rb +1 -13
  72. data/lib/rubygems/ext/cargo_builder.rb +1 -16
  73. data/lib/rubygems/installer.rb +1 -1
  74. data/lib/rubygems/package/tar_header.rb +20 -4
  75. data/lib/rubygems/package.rb +0 -1
  76. data/lib/rubygems/platform.rb +1 -0
  77. data/lib/rubygems/specification.rb +45 -118
  78. data/lib/rubygems/specification_policy.rb +3 -1
  79. data/lib/rubygems/specification_record.rb +212 -0
  80. data/lib/rubygems/stub_specification.rb +21 -0
  81. data/lib/rubygems/uninstaller.rb +26 -19
  82. data/lib/rubygems/util/licenses.rb +25 -0
  83. data/lib/rubygems/yaml_serializer.rb +1 -8
  84. data/lib/rubygems.rb +8 -1
  85. data/rubygems-update.gemspec +1 -1
  86. metadata +5 -3
@@ -11,6 +11,7 @@ require_relative "deprecate"
11
11
  require_relative "basic_specification"
12
12
  require_relative "stub_specification"
13
13
  require_relative "platform"
14
+ require_relative "specification_record"
14
15
  require_relative "util/list"
15
16
 
16
17
  require "rbconfig"
@@ -179,22 +180,12 @@ class Gem::Specification < Gem::BasicSpecification
179
180
  @@default_value[k].nil?
180
181
  end
181
182
 
182
- def self.clear_specs # :nodoc:
183
- @@all = nil
184
- @@stubs = nil
185
- @@stubs_by_name = {}
186
- @@spec_with_requirable_file = {}
187
- @@active_stub_with_requirable_file = {}
188
- end
189
- private_class_method :clear_specs
190
-
191
- clear_specs
192
-
193
183
  # Sentinel object to represent "not found" stubs
194
184
  NOT_FOUND = Struct.new(:to_spec, :this).new # :nodoc:
185
+ deprecate_constant :NOT_FOUND
195
186
 
196
187
  # Tracking removed method calls to warn users during build time.
197
- REMOVED_METHODS = [:rubyforge_project=].freeze # :nodoc:
188
+ REMOVED_METHODS = [:rubyforge_project=, :mark_version].freeze # :nodoc:
198
189
  def removed_method_calls
199
190
  @removed_method_calls ||= []
200
191
  end
@@ -770,7 +761,7 @@ class Gem::Specification < Gem::BasicSpecification
770
761
  attr_accessor :specification_version
771
762
 
772
763
  def self._all # :nodoc:
773
- @@all ||= Gem.loaded_specs.values | stubs.map(&:to_spec)
764
+ specification_record.all
774
765
  end
775
766
 
776
767
  def self.clear_load_cache # :nodoc:
@@ -780,6 +771,11 @@ class Gem::Specification < Gem::BasicSpecification
780
771
  end
781
772
  private_class_method :clear_load_cache
782
773
 
774
+ def self.gem_path # :nodoc:
775
+ Gem.path
776
+ end
777
+ private_class_method :gem_path
778
+
783
779
  def self.each_gemspec(dirs) # :nodoc:
784
780
  dirs.each do |dir|
785
781
  Gem::Util.glob_files_in_dir("*.gemspec", dir).each do |path|
@@ -788,26 +784,9 @@ class Gem::Specification < Gem::BasicSpecification
788
784
  end
789
785
  end
790
786
 
791
- def self.gemspec_stubs_in(dir, pattern)
787
+ def self.gemspec_stubs_in(dir, pattern) # :nodoc:
792
788
  Gem::Util.glob_files_in_dir(pattern, dir).map {|path| yield path }.select(&:valid?)
793
789
  end
794
- private_class_method :gemspec_stubs_in
795
-
796
- def self.installed_stubs(dirs, pattern)
797
- map_stubs(dirs, pattern) do |path, base_dir, gems_dir|
798
- Gem::StubSpecification.gemspec_stub(path, base_dir, gems_dir)
799
- end
800
- end
801
- private_class_method :installed_stubs
802
-
803
- def self.map_stubs(dirs, pattern) # :nodoc:
804
- dirs.flat_map do |dir|
805
- base_dir = File.dirname dir
806
- gems_dir = File.join base_dir, "gems"
807
- gemspec_stubs_in(dir, pattern) {|path| yield path, base_dir, gems_dir }
808
- end
809
- end
810
- private_class_method :map_stubs
811
790
 
812
791
  def self.each_spec(dirs) # :nodoc:
813
792
  each_gemspec(dirs) do |path|
@@ -820,13 +799,7 @@ class Gem::Specification < Gem::BasicSpecification
820
799
  # Returns a Gem::StubSpecification for every installed gem
821
800
 
822
801
  def self.stubs
823
- @@stubs ||= begin
824
- pattern = "*.gemspec"
825
- stubs = stubs_for_pattern(pattern, false)
826
-
827
- @@stubs_by_name = stubs.select {|s| Gem::Platform.match_spec? s }.group_by(&:name)
828
- stubs
829
- end
802
+ specification_record.stubs
830
803
  end
831
804
 
832
805
  ##
@@ -845,13 +818,7 @@ class Gem::Specification < Gem::BasicSpecification
845
818
  # only returns stubs that match Gem.platforms
846
819
 
847
820
  def self.stubs_for(name)
848
- if @@stubs
849
- @@stubs_by_name[name] || []
850
- else
851
- @@stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec").select do |s|
852
- s.name == name
853
- end
854
- end
821
+ specification_record.stubs_for(name)
855
822
  end
856
823
 
857
824
  ##
@@ -859,12 +826,7 @@ class Gem::Specification < Gem::BasicSpecification
859
826
  # optionally filtering out specs not matching the current platform
860
827
  #
861
828
  def self.stubs_for_pattern(pattern, match_platform = true) # :nodoc:
862
- installed_stubs = installed_stubs(Gem::Specification.dirs, pattern)
863
- installed_stubs.select! {|s| Gem::Platform.match_spec? s } if match_platform
864
- stubs = installed_stubs + default_stubs(pattern)
865
- stubs = stubs.uniq(&:full_name)
866
- _resort!(stubs)
867
- stubs
829
+ specification_record.stubs_for_pattern(pattern, match_platform)
868
830
  end
869
831
 
870
832
  def self._resort!(specs) # :nodoc:
@@ -873,7 +835,11 @@ class Gem::Specification < Gem::BasicSpecification
873
835
  next names if names.nonzero?
874
836
  versions = b.version <=> a.version
875
837
  next versions if versions.nonzero?
876
- Gem::Platform.sort_priority(b.platform)
838
+ platforms = Gem::Platform.sort_priority(b.platform) <=> Gem::Platform.sort_priority(a.platform)
839
+ next platforms if platforms.nonzero?
840
+ default_gem = a.default_gem_priority <=> b.default_gem_priority
841
+ next default_gem if default_gem.nonzero?
842
+ a.base_dir_priority(gem_path) <=> b.base_dir_priority(gem_path)
877
843
  end
878
844
  end
879
845
 
@@ -893,23 +859,14 @@ class Gem::Specification < Gem::BasicSpecification
893
859
  # properly sorted.
894
860
 
895
861
  def self.add_spec(spec)
896
- return if _all.include? spec
897
-
898
- _all << spec
899
- stubs << spec
900
- (@@stubs_by_name[spec.name] ||= []) << spec
901
-
902
- _resort!(@@stubs_by_name[spec.name])
903
- _resort!(stubs)
862
+ specification_record.add_spec(spec)
904
863
  end
905
864
 
906
865
  ##
907
866
  # Removes +spec+ from the known specs.
908
867
 
909
868
  def self.remove_spec(spec)
910
- _all.delete spec.to_spec
911
- stubs.delete spec
912
- (@@stubs_by_name[spec.name] || []).delete spec
869
+ specification_record.remove_spec(spec)
913
870
  end
914
871
 
915
872
  ##
@@ -923,27 +880,17 @@ class Gem::Specification < Gem::BasicSpecification
923
880
  end
924
881
 
925
882
  ##
926
- # Sets the known specs to +specs+. Not guaranteed to work for you in
927
- # the future. Use at your own risk. Caveat emptor. Doomy doom doom.
928
- # Etc etc.
929
- #
930
- #--
931
- # Makes +specs+ the known specs
932
- # Listen, time is a river
933
- # Winter comes, code breaks
934
- #
935
- # -- wilsonb
883
+ # Sets the known specs to +specs+.
936
884
 
937
885
  def self.all=(specs)
938
- @@stubs_by_name = specs.group_by(&:name)
939
- @@all = @@stubs = specs
886
+ specification_record.all = specs
940
887
  end
941
888
 
942
889
  ##
943
890
  # Return full names of all specs in sorted order.
944
891
 
945
892
  def self.all_names
946
- _all.map(&:full_name)
893
+ specification_record.all_names
947
894
  end
948
895
 
949
896
  ##
@@ -968,9 +915,7 @@ class Gem::Specification < Gem::BasicSpecification
968
915
  # Return the directories that Specification uses to find specs.
969
916
 
970
917
  def self.dirs
971
- @@dirs ||= Gem.path.collect do |dir|
972
- File.join dir, "specifications"
973
- end
918
+ @@dirs ||= Gem::SpecificationRecord.dirs_from(gem_path)
974
919
  end
975
920
 
976
921
  ##
@@ -980,7 +925,7 @@ class Gem::Specification < Gem::BasicSpecification
980
925
  def self.dirs=(dirs)
981
926
  reset
982
927
 
983
- @@dirs = Array(dirs).map {|dir| File.join dir, "specifications" }
928
+ @@dirs = Gem::SpecificationRecord.dirs_from(Array(dirs))
984
929
  end
985
930
 
986
931
  extend Enumerable
@@ -989,21 +934,15 @@ class Gem::Specification < Gem::BasicSpecification
989
934
  # Enumerate every known spec. See ::dirs= and ::add_spec to set the list of
990
935
  # specs.
991
936
 
992
- def self.each
993
- return enum_for(:each) unless block_given?
994
-
995
- _all.each do |x|
996
- yield x
997
- end
937
+ def self.each(&block)
938
+ specification_record.each(&block)
998
939
  end
999
940
 
1000
941
  ##
1001
942
  # Returns every spec that matches +name+ and optional +requirements+.
1002
943
 
1003
944
  def self.find_all_by_name(name, *requirements)
1004
- requirements = Gem::Requirement.default if requirements.empty?
1005
-
1006
- Gem::Dependency.new(name, *requirements).matching_specs
945
+ specification_record.find_all_by_name(name, *requirements)
1007
946
  end
1008
947
 
1009
948
  ##
@@ -1033,12 +972,7 @@ class Gem::Specification < Gem::BasicSpecification
1033
972
  # Return the best specification that contains the file matching +path+.
1034
973
 
1035
974
  def self.find_by_path(path)
1036
- path = path.dup.freeze
1037
- spec = @@spec_with_requirable_file[path] ||= stubs.find do |s|
1038
- s.contains_requirable_file? path
1039
- end || NOT_FOUND
1040
-
1041
- spec.to_spec
975
+ specification_record.find_by_path(path)
1042
976
  end
1043
977
 
1044
978
  ##
@@ -1046,19 +980,15 @@ class Gem::Specification < Gem::BasicSpecification
1046
980
  # amongst the specs that are not activated.
1047
981
 
1048
982
  def self.find_inactive_by_path(path)
1049
- stub = stubs.find do |s|
1050
- next if s.activated?
1051
- s.contains_requirable_file? path
1052
- end
1053
- stub&.to_spec
983
+ specification_record.find_inactive_by_path(path)
1054
984
  end
1055
985
 
1056
- def self.find_active_stub_by_path(path)
1057
- stub = @@active_stub_with_requirable_file[path] ||= stubs.find do |s|
1058
- s.activated? && s.contains_requirable_file?(path)
1059
- end || NOT_FOUND
986
+ ##
987
+ # Return the best specification that contains the file matching +path+, among
988
+ # those already activated.
1060
989
 
1061
- stub.this
990
+ def self.find_active_stub_by_path(path)
991
+ specification_record.find_active_stub_by_path(path)
1062
992
  end
1063
993
 
1064
994
  ##
@@ -1125,14 +1055,14 @@ class Gem::Specification < Gem::BasicSpecification
1125
1055
  # +prerelease+ is true.
1126
1056
 
1127
1057
  def self.latest_specs(prerelease = false)
1128
- _latest_specs Gem::Specification.stubs, prerelease
1058
+ specification_record.latest_specs(prerelease)
1129
1059
  end
1130
1060
 
1131
1061
  ##
1132
1062
  # Return the latest installed spec for gem +name+.
1133
1063
 
1134
1064
  def self.latest_spec_for(name)
1135
- latest_specs(true).find {|installed_spec| installed_spec.name == name }
1065
+ specification_record.latest_spec_for(name)
1136
1066
  end
1137
1067
 
1138
1068
  def self._latest_specs(specs, prerelease = false) # :nodoc:
@@ -1270,7 +1200,7 @@ class Gem::Specification < Gem::BasicSpecification
1270
1200
  def self.reset
1271
1201
  @@dirs = nil
1272
1202
  Gem.pre_reset_hooks.each(&:call)
1273
- clear_specs
1203
+ @specification_record = nil
1274
1204
  clear_load_cache
1275
1205
  unresolved = unresolved_deps
1276
1206
  unless unresolved.empty?
@@ -1291,6 +1221,13 @@ class Gem::Specification < Gem::BasicSpecification
1291
1221
  Gem.post_reset_hooks.each(&:call)
1292
1222
  end
1293
1223
 
1224
+ ##
1225
+ # Keeps track of all currently known specifications
1226
+
1227
+ def self.specification_record
1228
+ @specification_record ||= Gem::SpecificationRecord.new(dirs)
1229
+ end
1230
+
1294
1231
  # DOC: This method needs documented or nodoc'd
1295
1232
  def self.unresolved_deps
1296
1233
  @unresolved_deps ||= Hash.new {|h, n| h[n] = Gem::Dependency.new n }
@@ -1874,8 +1811,6 @@ class Gem::Specification < Gem::BasicSpecification
1874
1811
  end
1875
1812
 
1876
1813
  def encode_with(coder) # :nodoc:
1877
- mark_version
1878
-
1879
1814
  coder.add "name", @name
1880
1815
  coder.add "version", @version
1881
1816
  platform = case @original_platform
@@ -2169,13 +2104,6 @@ class Gem::Specification < Gem::BasicSpecification
2169
2104
  @spec_file = nil
2170
2105
  end
2171
2106
 
2172
- ##
2173
- # Sets the rubygems_version to the current RubyGems version.
2174
-
2175
- def mark_version
2176
- @rubygems_version = Gem::VERSION
2177
- end
2178
-
2179
2107
  ##
2180
2108
  # Track removed method calls to warn about during build time.
2181
2109
  # Warn about unknown attributes while loading a spec.
@@ -2493,7 +2421,6 @@ class Gem::Specification < Gem::BasicSpecification
2493
2421
  # still have their default values are omitted.
2494
2422
 
2495
2423
  def to_ruby
2496
- mark_version
2497
2424
  result = []
2498
2425
  result << "# -*- encoding: utf-8 -*-"
2499
2426
  result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{raw_require_paths.join("\0")}"
@@ -274,7 +274,9 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
274
274
 
275
275
  return if rubygems_version == Gem::VERSION
276
276
 
277
- error "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
277
+ warning "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
278
+
279
+ @specification.rubygems_version = Gem::VERSION
278
280
  end
279
281
 
280
282
  def validate_required_attributes
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gem
4
+ class SpecificationRecord
5
+ def self.dirs_from(paths)
6
+ paths.map do |path|
7
+ File.join(path, "specifications")
8
+ end
9
+ end
10
+
11
+ def self.from_path(path)
12
+ new(dirs_from([path]))
13
+ end
14
+
15
+ def initialize(dirs)
16
+ @all = nil
17
+ @stubs = nil
18
+ @stubs_by_name = {}
19
+ @spec_with_requirable_file = {}
20
+ @active_stub_with_requirable_file = {}
21
+
22
+ @dirs = dirs
23
+ end
24
+
25
+ # Sentinel object to represent "not found" stubs
26
+ NOT_FOUND = Struct.new(:to_spec, :this).new
27
+ private_constant :NOT_FOUND
28
+
29
+ ##
30
+ # Returns the list of all specifications in the record
31
+
32
+ def all
33
+ @all ||= Gem.loaded_specs.values | stubs.map(&:to_spec)
34
+ end
35
+
36
+ ##
37
+ # Returns a Gem::StubSpecification for every specification in the record
38
+
39
+ def stubs
40
+ @stubs ||= begin
41
+ pattern = "*.gemspec"
42
+ stubs = stubs_for_pattern(pattern, false)
43
+
44
+ @stubs_by_name = stubs.select {|s| Gem::Platform.match_spec? s }.group_by(&:name)
45
+ stubs
46
+ end
47
+ end
48
+
49
+ ##
50
+ # Returns a Gem::StubSpecification for every specification in the record
51
+ # named +name+ only returns stubs that match Gem.platforms
52
+
53
+ def stubs_for(name)
54
+ if @stubs
55
+ @stubs_by_name[name] || []
56
+ else
57
+ @stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec").select do |s|
58
+ s.name == name
59
+ end
60
+ end
61
+ end
62
+
63
+ ##
64
+ # Finds stub specifications matching a pattern in the record, optionally
65
+ # filtering out specs not matching the current platform
66
+
67
+ def stubs_for_pattern(pattern, match_platform = true)
68
+ installed_stubs = installed_stubs(pattern)
69
+ installed_stubs.select! {|s| Gem::Platform.match_spec? s } if match_platform
70
+ stubs = installed_stubs + Gem::Specification.default_stubs(pattern)
71
+ Gem::Specification._resort!(stubs)
72
+ stubs
73
+ end
74
+
75
+ ##
76
+ # Adds +spec+ to the the record, keeping the collection properly sorted.
77
+
78
+ def add_spec(spec)
79
+ return if all.include? spec
80
+
81
+ all << spec
82
+ stubs << spec
83
+ (@stubs_by_name[spec.name] ||= []) << spec
84
+
85
+ Gem::Specification._resort!(@stubs_by_name[spec.name])
86
+ Gem::Specification._resort!(stubs)
87
+ end
88
+
89
+ ##
90
+ # Removes +spec+ from the record.
91
+
92
+ def remove_spec(spec)
93
+ all.delete spec.to_spec
94
+ stubs.delete spec
95
+ (@stubs_by_name[spec.name] || []).delete spec
96
+ end
97
+
98
+ ##
99
+ # Sets the specs known by the record to +specs+.
100
+
101
+ def all=(specs)
102
+ @stubs_by_name = specs.group_by(&:name)
103
+ @all = @stubs = specs
104
+ end
105
+
106
+ ##
107
+ # Return full names of all specs in the record in sorted order.
108
+
109
+ def all_names
110
+ all.map(&:full_name)
111
+ end
112
+
113
+ include Enumerable
114
+
115
+ ##
116
+ # Enumerate every known spec.
117
+
118
+ def each
119
+ return enum_for(:each) unless block_given?
120
+
121
+ all.each do |x|
122
+ yield x
123
+ end
124
+ end
125
+
126
+ ##
127
+ # Returns every spec in the record that matches +name+ and optional +requirements+.
128
+
129
+ def find_all_by_name(name, *requirements)
130
+ req = Gem::Requirement.create(*requirements)
131
+ env_req = Gem.env_requirement(name)
132
+
133
+ matches = stubs_for(name).find_all do |spec|
134
+ req.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
135
+ end.map(&:to_spec)
136
+
137
+ if name == "bundler" && !req.specific?
138
+ require_relative "bundler_version_finder"
139
+ Gem::BundlerVersionFinder.prioritize!(matches)
140
+ end
141
+
142
+ matches
143
+ end
144
+
145
+ ##
146
+ # Return the best specification in the record that contains the file matching +path+.
147
+
148
+ def find_by_path(path)
149
+ path = path.dup.freeze
150
+ spec = @spec_with_requirable_file[path] ||= stubs.find do |s|
151
+ s.contains_requirable_file? path
152
+ end || NOT_FOUND
153
+
154
+ spec.to_spec
155
+ end
156
+
157
+ ##
158
+ # Return the best specification in the record that contains the file
159
+ # matching +path+ amongst the specs that are not activated.
160
+
161
+ def find_inactive_by_path(path)
162
+ stub = stubs.find do |s|
163
+ next if s.activated?
164
+ s.contains_requirable_file? path
165
+ end
166
+ stub&.to_spec
167
+ end
168
+
169
+ ##
170
+ # Return the best specification in the record that contains the file
171
+ # matching +path+, among those already activated.
172
+
173
+ def find_active_stub_by_path(path)
174
+ stub = @active_stub_with_requirable_file[path] ||= stubs.find do |s|
175
+ s.activated? && s.contains_requirable_file?(path)
176
+ end || NOT_FOUND
177
+
178
+ stub.this
179
+ end
180
+
181
+ ##
182
+ # Return the latest specs in the record, optionally including prerelease
183
+ # specs if +prerelease+ is true.
184
+
185
+ def latest_specs(prerelease)
186
+ Gem::Specification._latest_specs stubs, prerelease
187
+ end
188
+
189
+ ##
190
+ # Return the latest installed spec in the record for gem +name+.
191
+
192
+ def latest_spec_for(name)
193
+ latest_specs(true).find {|installed_spec| installed_spec.name == name }
194
+ end
195
+
196
+ private
197
+
198
+ def installed_stubs(pattern)
199
+ map_stubs(pattern) do |path, base_dir, gems_dir|
200
+ Gem::StubSpecification.gemspec_stub(path, base_dir, gems_dir)
201
+ end
202
+ end
203
+
204
+ def map_stubs(pattern)
205
+ @dirs.flat_map do |dir|
206
+ base_dir = File.dirname dir
207
+ gems_dir = File.join base_dir, "gems"
208
+ Gem::Specification.gemspec_stubs_in(dir, pattern) {|path| yield path, base_dir, gems_dir }
209
+ end
210
+ end
211
+ end
212
+ end
@@ -210,4 +210,25 @@ class Gem::StubSpecification < Gem::BasicSpecification
210
210
  def stubbed?
211
211
  data.is_a? StubLine
212
212
  end
213
+
214
+ def ==(other) # :nodoc:
215
+ self.class === other &&
216
+ name == other.name &&
217
+ version == other.version &&
218
+ platform == other.platform
219
+ end
220
+
221
+ alias_method :eql?, :== # :nodoc:
222
+
223
+ def hash # :nodoc:
224
+ name.hash ^ version.hash ^ platform.hash
225
+ end
226
+
227
+ def <=>(other) # :nodoc:
228
+ sort_obj <=> other.sort_obj
229
+ end
230
+
231
+ def sort_obj # :nodoc:
232
+ [name, version, Gem::Platform.sort_priority(platform)]
233
+ end
213
234
  end