rubygems-update 2.5.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

@@ -1,3 +1,3 @@
1
1
  module Gem::Resolver::Molinillo
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -12,13 +12,15 @@ module Gem::Resolver::Molinillo
12
12
  # @attr [Object] locked_requirement the relevant locking requirement.
13
13
  # @attr [Array<Array<Object>>] requirement_trees the different requirement
14
14
  # trees that led to every requirement for the conflicting name.
15
+ # @attr [{String=>Object}] activated_by_name the already-activated specs.
15
16
  Conflict = Struct.new(
16
17
  :requirement,
17
18
  :requirements,
18
19
  :existing,
19
20
  :possibility,
20
21
  :locked_requirement,
21
- :requirement_trees
22
+ :requirement_trees,
23
+ :activated_by_name
22
24
  )
23
25
 
24
26
  # @return [SpecificationProvider] the provider that knows about
@@ -164,7 +166,7 @@ module Gem::Resolver::Molinillo
164
166
  # @return [DependencyState] the initial state for the resolution
165
167
  def initial_state
166
168
  graph = DependencyGraph.new.tap do |dg|
167
- original_requested.each { |r| dg.add_root_vertex(name_for(r), nil).tap { |v| v.explicit_requirements << r } }
169
+ original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } }
168
170
  end
169
171
 
170
172
  requirements = sort_dependencies(original_requested, graph, {})
@@ -216,7 +218,7 @@ module Gem::Resolver::Molinillo
216
218
  return nil unless requirement
217
219
  seen = false
218
220
  state = states.reverse_each.find do |s|
219
- seen ||= s.requirement == requirement
221
+ seen ||= s.requirement == requirement || s.requirements.include?(requirement)
220
222
  seen && s.requirement != requirement && !s.requirements.include?(requirement)
221
223
  end
222
224
  state && state.requirement
@@ -250,21 +252,23 @@ module Gem::Resolver::Molinillo
250
252
  name_for_explicit_dependency_source => vertex.explicit_requirements,
251
253
  name_for_locking_dependency_source => Array(locked_requirement_named(name)),
252
254
  }
253
- vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(*edge.requirements) }
255
+ vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) }
254
256
  conflicts[name] = Conflict.new(
255
257
  requirement,
256
258
  Hash[requirements.select { |_, r| !r.empty? }],
257
259
  vertex.payload,
258
260
  possibility,
259
261
  locked_requirement_named(name),
260
- requirement_trees
262
+ requirement_trees,
263
+ Hash[activated.map { |v| [v.name, v.payload] }.select(&:last)]
261
264
  )
262
265
  end
263
266
 
264
267
  # @return [Array<Array<Object>>] The different requirement
265
268
  # trees that led to every requirement for the current spec.
266
269
  def requirement_trees
267
- activated.vertex_named(name).requirements.map { |r| requirement_tree_for(r) }
270
+ vertex = activated.vertex_named(name)
271
+ vertex.requirements.map { |r| requirement_tree_for(r) }
268
272
  end
269
273
 
270
274
  # @return [Array<Object>] the list of requirements that led to
@@ -322,7 +326,7 @@ module Gem::Resolver::Molinillo
322
326
  existing_spec = existing_node.payload
323
327
  if requirement_satisfied_by?(requirement, activated, existing_spec)
324
328
  new_requirements = requirements.dup
325
- push_state_for_requirements(new_requirements)
329
+ push_state_for_requirements(new_requirements, false)
326
330
  else
327
331
  return if attempt_to_swap_possibility
328
332
  create_conflict
@@ -389,17 +393,17 @@ module Gem::Resolver::Molinillo
389
393
  def require_nested_dependencies_for(activated_spec)
390
394
  nested_dependencies = dependencies_for(activated_spec)
391
395
  debug(depth) { "Requiring nested dependencies (#{nested_dependencies.map(&:to_s).join(', ')})" }
392
- nested_dependencies.each { |d| activated.add_child_vertex name_for(d), nil, [name_for(activated_spec)], d }
396
+ nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) }
393
397
 
394
- push_state_for_requirements(requirements + nested_dependencies)
398
+ push_state_for_requirements(requirements + nested_dependencies, nested_dependencies.size > 0)
395
399
  end
396
400
 
397
401
  # Pushes a new {DependencyState} that encapsulates both existing and new
398
402
  # requirements
399
403
  # @param [Array] new_requirements
400
404
  # @return [void]
401
- def push_state_for_requirements(new_requirements, new_activated = activated.dup)
402
- new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts)
405
+ def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated.dup)
406
+ new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
403
407
  new_requirement = new_requirements.shift
404
408
  new_name = new_requirement ? name_for(new_requirement) : ''
405
409
  possibilities = new_requirement ? search_for(new_requirement) : []
@@ -420,7 +424,7 @@ module Gem::Resolver::Molinillo
420
424
  def handle_missing_or_push_dependency_state(state)
421
425
  if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement)
422
426
  state.activated.detach_vertex_named(state.name)
423
- push_state_for_requirements(state.requirements, state.activated)
427
+ push_state_for_requirements(state.requirements.dup, false, state.activated)
424
428
  else
425
429
  states.push state
426
430
  end
@@ -175,6 +175,11 @@ class Gem::Specification < Gem::BasicSpecification
175
175
 
176
176
  @@stubs_by_name = {}
177
177
 
178
+ # Sentinel object to represent "not found" stubs
179
+ NOT_FOUND = Struct.new(:to_spec, :this).new # :nodoc:
180
+ @@spec_with_requirable_file = {}
181
+ @@active_stub_with_requirable_file = {}
182
+
178
183
  ######################################################################
179
184
  # :section: Required gemspec attributes
180
185
 
@@ -740,23 +745,41 @@ class Gem::Specification < Gem::BasicSpecification
740
745
  end
741
746
 
742
747
  def self.gemspec_stubs_in dir, pattern
743
- Dir[File.join(dir, pattern)].map { |path|
744
- if dir == default_specifications_dir
745
- Gem::StubSpecification.default_gemspec_stub(path)
746
- else
747
- Gem::StubSpecification.gemspec_stub(path)
748
- end
749
- }.select(&:valid?)
748
+ Dir[File.join(dir, pattern)].map { |path| yield path }.select(&:valid?)
750
749
  end
751
750
  private_class_method :gemspec_stubs_in
752
751
 
752
+ def self.default_stubs pattern
753
+ base_dir = Gem.default_dir
754
+ gems_dir = File.join base_dir, "gems"
755
+ gemspec_stubs_in(default_specifications_dir, pattern) do |path|
756
+ Gem::StubSpecification.default_gemspec_stub(path, base_dir, gems_dir)
757
+ end
758
+ end
759
+ private_class_method :default_stubs
760
+
761
+ def self.installed_stubs dirs, pattern
762
+ map_stubs(dirs, pattern) do |path, base_dir, gems_dir|
763
+ Gem::StubSpecification.gemspec_stub(path, base_dir, gems_dir)
764
+ end
765
+ end
766
+ private_class_method :installed_stubs
767
+
753
768
  if [].respond_to? :flat_map
754
769
  def self.map_stubs(dirs, pattern) # :nodoc:
755
- dirs.flat_map { |dir| gemspec_stubs_in(dir, pattern) }
770
+ dirs.flat_map { |dir|
771
+ base_dir = File.dirname dir
772
+ gems_dir = File.join base_dir, "gems"
773
+ gemspec_stubs_in(dir, pattern) { |path| yield path, base_dir, gems_dir }
774
+ }
756
775
  end
757
776
  else # FIXME: remove when 1.8 is dropped
758
777
  def self.map_stubs(dirs, pattern) # :nodoc:
759
- dirs.map { |dir| gemspec_stubs_in(dir, pattern) }.flatten 1
778
+ dirs.map { |dir|
779
+ base_dir = File.dirname dir
780
+ gems_dir = File.join base_dir, "gems"
781
+ gemspec_stubs_in(dir, pattern) { |path| yield path, base_dir, gems_dir }
782
+ }.flatten 1
760
783
  end
761
784
  end
762
785
  private_class_method :map_stubs
@@ -803,7 +826,8 @@ class Gem::Specification < Gem::BasicSpecification
803
826
 
804
827
  def self.stubs
805
828
  @@stubs ||= begin
806
- stubs = map_stubs([default_specifications_dir] + dirs, "*.gemspec")
829
+ pattern = "*.gemspec"
830
+ stubs = default_stubs(pattern).concat installed_stubs(dirs, pattern)
807
831
  stubs = uniq_by(stubs) { |stub| stub.full_name }
808
832
 
809
833
  _resort!(stubs)
@@ -818,10 +842,11 @@ class Gem::Specification < Gem::BasicSpecification
818
842
  # Returns a Gem::StubSpecification for installed gem named +name+
819
843
 
820
844
  def self.stubs_for name
821
- if @@stubs || @@stubs_by_name[name]
845
+ if @@stubs
822
846
  @@stubs_by_name[name] || []
823
847
  else
824
- stubs = map_stubs([default_specifications_dir] + dirs, "#{name}-*.gemspec")
848
+ pattern = "#{name}-*.gemspec"
849
+ stubs = default_stubs(pattern) + installed_stubs(dirs, pattern)
825
850
  stubs = uniq_by(stubs) { |stub| stub.full_name }.group_by(&:name)
826
851
  stubs.each_value { |v| sort_by!(v) { |i| i.version } }
827
852
 
@@ -1006,10 +1031,11 @@ class Gem::Specification < Gem::BasicSpecification
1006
1031
  # Return the best specification that contains the file matching +path+.
1007
1032
 
1008
1033
  def self.find_by_path path
1009
- stub = stubs.find { |spec|
1010
- spec.contains_requirable_file? path if spec
1011
- }
1012
- stub && stub.to_spec
1034
+ path = path.dup.freeze
1035
+ spec = @@spec_with_requirable_file[path] ||= (stubs.find { |s|
1036
+ s.contains_requirable_file? path
1037
+ } || NOT_FOUND)
1038
+ spec.to_spec
1013
1039
  end
1014
1040
 
1015
1041
  ##
@@ -1018,11 +1044,18 @@ class Gem::Specification < Gem::BasicSpecification
1018
1044
 
1019
1045
  def self.find_inactive_by_path path
1020
1046
  stub = stubs.find { |s|
1021
- s.contains_requirable_file? path unless s.nil? || s.activated?
1047
+ s.contains_requirable_file? path unless s.activated?
1022
1048
  }
1023
1049
  stub && stub.to_spec
1024
1050
  end
1025
1051
 
1052
+ def self.find_active_stub_by_path path
1053
+ stub = @@active_stub_with_requirable_file[path] ||= (stubs.find { |s|
1054
+ s.activated? and s.contains_requirable_file? path
1055
+ } || NOT_FOUND)
1056
+ stub.this
1057
+ end
1058
+
1026
1059
  ##
1027
1060
  # Return currently unresolved specs that contain the file matching +path+.
1028
1061
 
@@ -1030,7 +1063,7 @@ class Gem::Specification < Gem::BasicSpecification
1030
1063
  # TODO: do we need these?? Kill it
1031
1064
  specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten
1032
1065
 
1033
- specs.find_all { |spec| spec.contains_requirable_file? path if spec }
1066
+ specs.find_all { |spec| spec.contains_requirable_file? path }
1034
1067
  end
1035
1068
 
1036
1069
  ##
@@ -1240,6 +1273,8 @@ class Gem::Specification < Gem::BasicSpecification
1240
1273
  @@all = nil
1241
1274
  @@stubs = nil
1242
1275
  @@stubs_by_name = {}
1276
+ @@spec_with_requirable_file = {}
1277
+ @@active_stub_with_requirable_file = {}
1243
1278
  _clear_load_cache
1244
1279
  unresolved = unresolved_deps
1245
1280
  unless unresolved.empty? then
@@ -1924,23 +1959,10 @@ class Gem::Specification < Gem::BasicSpecification
1924
1959
  spec
1925
1960
  end
1926
1961
 
1927
- def find_full_gem_path # :nodoc:
1928
- super || File.expand_path(File.join(gems_dir, original_name))
1929
- end
1930
- private :find_full_gem_path
1931
-
1932
1962
  def full_name
1933
1963
  @full_name ||= super
1934
1964
  end
1935
1965
 
1936
- ##
1937
- # The path to the gem.build_complete file within the extension install
1938
- # directory.
1939
-
1940
- def gem_build_complete_path # :nodoc:
1941
- File.join extension_dir, 'gem.build_complete'
1942
- end
1943
-
1944
1966
  ##
1945
1967
  # Work around bundler removing my methods
1946
1968
 
@@ -1948,6 +1970,11 @@ class Gem::Specification < Gem::BasicSpecification
1948
1970
  super
1949
1971
  end
1950
1972
 
1973
+ def gems_dir
1974
+ # TODO: this logic seems terribly broken, but tests fail if just base_dir
1975
+ @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems")
1976
+ end
1977
+
1951
1978
  ##
1952
1979
  # Deprecated and ignored, defaults to true.
1953
1980
  #
@@ -1995,6 +2022,8 @@ class Gem::Specification < Gem::BasicSpecification
1995
2022
 
1996
2023
  def initialize name = nil, version = nil
1997
2024
  super()
2025
+ @gems_dir = nil
2026
+ @base_dir = nil
1998
2027
  @loaded = false
1999
2028
  @activated = false
2000
2029
  @loaded_from = nil
@@ -2044,6 +2073,15 @@ class Gem::Specification < Gem::BasicSpecification
2044
2073
  end
2045
2074
  end
2046
2075
 
2076
+ def base_dir
2077
+ return Gem.dir unless loaded_from
2078
+ @base_dir ||= if default_gem? then
2079
+ File.dirname File.dirname File.dirname loaded_from
2080
+ else
2081
+ File.dirname File.dirname loaded_from
2082
+ end
2083
+ end
2084
+
2047
2085
  ##
2048
2086
  # Expire memoized instance variables that can incorrectly generate, replace
2049
2087
  # or miss files due changes in certain attributes used to compute them.
@@ -2569,6 +2607,7 @@ class Gem::Specification < Gem::BasicSpecification
2569
2607
  trail.push(self)
2570
2608
  begin
2571
2609
  dependencies.each do |dep|
2610
+ next unless dep.runtime?
2572
2611
  dep.to_specs.reverse_each do |dep_spec|
2573
2612
  next if visited.has_key?(dep_spec)
2574
2613
  visited[dep_spec] = true
@@ -2720,7 +2759,7 @@ class Gem::Specification < Gem::BasicSpecification
2720
2759
  "each license must be 64 characters or less"
2721
2760
  end
2722
2761
 
2723
- if !Gem::Licenses::IDENTIFIERS.include?(license) && !license.eql?(Gem::Licenses::NONSTANDARD)
2762
+ if !Gem::Licenses.match?(license)
2724
2763
  warning <<-warning
2725
2764
  WARNING: license value '#{license}' is invalid. Use a license identifier from
2726
2765
  http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
@@ -2822,7 +2861,7 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use:
2822
2861
  end
2823
2862
 
2824
2863
  warning_messages << "prerelease dependency on #{dep} is not recommended" if
2825
- prerelease_dep
2864
+ prerelease_dep && !version.prerelease?
2826
2865
 
2827
2866
  overly_strict = dep.requirement.requirements.length == 1 &&
2828
2867
  dep.requirement.requirements.any? do |op, version|
@@ -2954,6 +2993,10 @@ open-ended dependency on #{dep} is not recommended
2954
2993
  alert_warning statement
2955
2994
  end
2956
2995
 
2996
+ def raw_require_paths # :nodoc:
2997
+ @require_paths
2998
+ end
2999
+
2957
3000
  extend Gem::Deprecate
2958
3001
 
2959
3002
  # TODO:
@@ -15,33 +15,65 @@ class Gem::StubSpecification < Gem::BasicSpecification
15
15
  end
16
16
 
17
17
  class StubLine # :nodoc: all
18
- attr_reader :name, :version, :platform, :require_paths
19
-
20
- def initialize(data)
21
- parts = data[PREFIX.length..-1].split(" ")
18
+ attr_reader :name, :version, :platform, :require_paths, :extensions,
19
+ :full_name
20
+
21
+ NO_EXTENSIONS = [].freeze
22
+
23
+ # These are common require paths.
24
+ REQUIRE_PATHS = { # :nodoc:
25
+ 'lib' => 'lib'.freeze,
26
+ 'test' => 'test'.freeze,
27
+ 'ext' => 'ext'.freeze,
28
+ }
29
+
30
+ # These are common require path lists. This hash is used to optimize
31
+ # and consolidate require_path objects. Most specs just specify "lib"
32
+ # in their require paths, so lets take advantage of that by pre-allocating
33
+ # a require path list for that case.
34
+ REQUIRE_PATH_LIST = { # :nodoc:
35
+ 'lib' => ['lib'].freeze
36
+ }
37
+
38
+ def initialize data, extensions
39
+ parts = data[PREFIX.length..-1].split(" ".freeze, 4)
22
40
  @name = parts[0].freeze
23
41
  @version = Gem::Version.new parts[1]
24
42
  @platform = Gem::Platform.new parts[2]
25
- @require_paths = parts.drop(3).join(" ").split("\0")
43
+ @extensions = extensions
44
+ @full_name = if platform == Gem::Platform::RUBY
45
+ "#{name}-#{version}"
46
+ else
47
+ "#{name}-#{version}-#{platform}"
48
+ end
49
+
50
+ path_list = parts.last
51
+ @require_paths = REQUIRE_PATH_LIST[path_list] || path_list.split("\0".freeze).map! { |x|
52
+ REQUIRE_PATHS[x] || x
53
+ }
26
54
  end
27
55
  end
28
56
 
29
- def self.default_gemspec_stub filename
30
- new filename, true
57
+ def self.default_gemspec_stub filename, base_dir, gems_dir
58
+ new filename, base_dir, gems_dir, true
31
59
  end
32
60
 
33
- def self.gemspec_stub filename
34
- new filename, false
61
+ def self.gemspec_stub filename, base_dir, gems_dir
62
+ new filename, base_dir, gems_dir, false
35
63
  end
36
64
 
37
- def initialize filename, default_gem
65
+ attr_reader :base_dir, :gems_dir
66
+
67
+ def initialize filename, base_dir, gems_dir, default_gem
68
+ super()
38
69
  filename.untaint
39
70
 
40
71
  self.loaded_from = filename
41
72
  @data = nil
42
- @extensions = nil
43
73
  @name = nil
44
74
  @spec = nil
75
+ @base_dir = base_dir
76
+ @gems_dir = gems_dir
45
77
  @default_gem = default_gem
46
78
  end
47
79
 
@@ -56,6 +88,8 @@ class Gem::StubSpecification < Gem::BasicSpecification
56
88
  end
57
89
  end
58
90
 
91
+ def this; self; end
92
+
59
93
  def default_gem?
60
94
  @default_gem
61
95
  end
@@ -73,8 +107,6 @@ class Gem::StubSpecification < Gem::BasicSpecification
73
107
 
74
108
  def data
75
109
  unless @data
76
- @extensions = []
77
-
78
110
  begin
79
111
  saved_lineno = $.
80
112
  open loaded_from, OPEN_MODE do |file|
@@ -82,10 +114,13 @@ class Gem::StubSpecification < Gem::BasicSpecification
82
114
  file.readline # discard encoding line
83
115
  stubline = file.readline.chomp
84
116
  if stubline.start_with?(PREFIX) then
85
- @data = StubLine.new stubline
117
+ extensions = if /\A#{PREFIX}/ =~ file.readline.chomp
118
+ $'.split "\0"
119
+ else
120
+ StubLine::NO_EXTENSIONS
121
+ end
86
122
 
87
- @extensions = $'.split "\0" if
88
- /\A#{PREFIX}/ =~ file.readline.chomp
123
+ @data = StubLine.new stubline, extensions
89
124
  end
90
125
  rescue EOFError
91
126
  end
@@ -100,41 +135,14 @@ class Gem::StubSpecification < Gem::BasicSpecification
100
135
 
101
136
  private :data
102
137
 
103
- ##
104
- # Extensions for this gem
105
-
106
- def extensions
107
- return @extensions if @extensions
108
-
109
- data # load
110
-
111
- @extensions
112
- end
113
-
114
- ##
115
- # If a gem has a stub specification it doesn't need to bother with
116
- # compatibility with original_name gems. It was installed with the
117
- # normalized name.
118
-
119
- def find_full_gem_path # :nodoc:
120
- path = File.expand_path File.join gems_dir, full_name
121
- path.untaint
122
- path
123
- end
124
-
125
- ##
126
- # Full paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
127
- # activated.
128
-
129
- def full_require_paths
130
- @require_paths ||= data.require_paths
131
-
132
- super
138
+ def raw_require_paths # :nodoc:
139
+ data.require_paths
133
140
  end
134
141
 
135
142
  def missing_extensions?
136
143
  return false if default_gem?
137
144
  return false if extensions.empty?
145
+ return false if File.exist? gem_build_complete_path
138
146
 
139
147
  to_spec.missing_extensions?
140
148
  end
@@ -154,12 +162,21 @@ class Gem::StubSpecification < Gem::BasicSpecification
154
162
  end
155
163
 
156
164
  ##
157
- # Require paths of the gem
165
+ # Extensions for this gem
158
166
 
159
- def require_paths
160
- @require_paths ||= data.require_paths
167
+ def extensions
168
+ data.extensions
169
+ end
161
170
 
162
- super
171
+ ##
172
+ # Version of the gem
173
+
174
+ def version
175
+ data.version
176
+ end
177
+
178
+ def full_name
179
+ data.full_name
163
180
  end
164
181
 
165
182
  ##
@@ -173,7 +190,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
173
190
  end
174
191
 
175
192
  @spec ||= Gem::Specification.load(loaded_from)
176
- @spec.ignored = @ignored if instance_variable_defined? :@ignored
193
+ @spec.ignored = @ignored if @spec
177
194
 
178
195
  @spec
179
196
  end
@@ -186,13 +203,6 @@ class Gem::StubSpecification < Gem::BasicSpecification
186
203
  data
187
204
  end
188
205
 
189
- ##
190
- # Version of the gem
191
-
192
- def version
193
- @version ||= data.version
194
- end
195
-
196
206
  ##
197
207
  # Is there a stub line present for this StubSpecification?
198
208