Class Gem::DependencyList
In: lib/rubygems/dependency_list.rb
Parent: Object

Gem::DependencyList is used for installing and uninstalling gems in the correct order to avoid conflicts.

Methods

Included Modules

Enumerable TSort

Attributes

development  [RW]  Allows enabling/disabling use of development dependencies
specs  [R] 

Public Class methods

Creates a DependencyList from a Gem::SourceIndex source_index

[Source]

    # File lib/rubygems/dependency_list.rb, line 27
27:   def self.from_source_index(source_index)
28:     list = new
29: 
30:     source_index.each do |full_name, spec|
31:       list.add spec
32:     end
33: 
34:     list
35:   end

Creates a new DependencyList. If development is true, development dependencies will be included.

[Source]

    # File lib/rubygems/dependency_list.rb, line 41
41:   def initialize development = false
42:     @specs = []
43: 
44:     @development = development
45:   end

Public Instance methods

Adds gemspecs to the dependency list.

[Source]

    # File lib/rubygems/dependency_list.rb, line 50
50:   def add(*gemspecs)
51:     @specs.push(*gemspecs)
52:   end

[Source]

    # File lib/rubygems/dependency_list.rb, line 54
54:   def clear
55:     @specs.clear
56:   end

Return a list of the gem specifications in the dependency list, sorted in order so that no gemspec in the list depends on a gemspec earlier in the list.

This is useful when removing gems from a set of installed gems. By removing them in the returned order, you don‘t get into as many dependency issues.

If there are circular dependencies (yuck!), then gems will be returned in order until only the circular dependents and anything they reference are left. Then arbitrary gemspecs will be returned until the circular dependency is broken, after which gems will be returned in dependency order again.

[Source]

    # File lib/rubygems/dependency_list.rb, line 73
73:   def dependency_order
74:     sorted = strongly_connected_components.flatten
75: 
76:     result = []
77:     seen = {}
78: 
79:     sorted.each do |spec|
80:       if index = seen[spec.name] then
81:         if result[index].version < spec.version then
82:           result[index] = spec
83:         end
84:       else
85:         seen[spec.name] = result.length
86:         result << spec
87:       end
88:     end
89: 
90:     result.reverse
91:   end

Iterator over dependency_order

[Source]

    # File lib/rubygems/dependency_list.rb, line 96
96:   def each(&block)
97:     dependency_order.each(&block)
98:   end

[Source]

     # File lib/rubygems/dependency_list.rb, line 100
100:   def find_name(full_name)
101:     @specs.find { |spec| spec.full_name == full_name }
102:   end

Are all the dependencies in the list satisfied?

[Source]

     # File lib/rubygems/dependency_list.rb, line 111
111:   def ok?
112:     why_not_ok?(:quick).empty?
113:   end

Is is ok to remove a gemspec from the dependency list?

If removing the gemspec creates breaks a currently ok dependency, then it is NOT ok to remove the gemspec.

[Source]

     # File lib/rubygems/dependency_list.rb, line 140
140:   def ok_to_remove?(full_name)
141:     gem_to_remove = find_name full_name
142: 
143:     siblings = @specs.find_all { |s|
144:       s.name == gem_to_remove.name &&
145:         s.full_name != gem_to_remove.full_name
146:     }
147: 
148:     deps = []
149: 
150:     @specs.each do |spec|
151:       spec.dependencies.each do |dep|
152:         deps << dep if gem_to_remove.satisfies_requirement?(dep)
153:       end
154:     end
155: 
156:     deps.all? { |dep|
157:       siblings.any? { |s|
158:         s.satisfies_requirement? dep
159:       }
160:     }
161:   end

Removes the gemspec matching full_name from the dependency list

[Source]

     # File lib/rubygems/dependency_list.rb, line 178
178:   def remove_by_name(full_name)
179:     @specs.delete_if { |spec| spec.full_name == full_name }
180:   end

Remove everything in the DependencyList that matches but doesn‘t satisfy items in dependencies (a hash of gem names to arrays of dependencies).

[Source]

     # File lib/rubygems/dependency_list.rb, line 168
168:   def remove_specs_unsatisfied_by dependencies
169:     specs.reject! { |spec|
170:       dep = dependencies[spec.name]
171:       dep and not dep.requirement.satisfied_by? spec.version
172:     }
173:   end

Return a hash of predecessors. result[spec] is an Array of gemspecs that have a dependency satisfied by the named gemspec.

[Source]

     # File lib/rubygems/dependency_list.rb, line 186
186:   def spec_predecessors
187:     result = Hash.new { |h,k| h[k] = [] }
188: 
189:     specs = @specs.sort.reverse
190: 
191:     specs.each do |spec|
192:       specs.each do |other|
193:         next if spec == other
194: 
195:         other.dependencies.each do |dep|
196:           if spec.satisfies_requirement? dep then
197:             result[spec] << other
198:           end
199:         end
200:       end
201:     end
202: 
203:     result
204:   end

[Source]

     # File lib/rubygems/dependency_list.rb, line 210
210:   def tsort_each_child(node, &block)
211:     specs = @specs.sort.reverse
212: 
213:     dependencies = node.runtime_dependencies
214:     dependencies.push(*node.development_dependencies) if @development
215: 
216:     dependencies.each do |dep|
217:       specs.each do |spec|
218:         if spec.satisfies_requirement? dep then
219:           begin
220:             yield spec
221:           rescue TSort::Cyclic
222:             # do nothing
223:           end
224:           break
225:         end
226:       end
227:     end
228:   end

[Source]

     # File lib/rubygems/dependency_list.rb, line 206
206:   def tsort_each_node(&block)
207:     @specs.each(&block)
208:   end

[Source]

     # File lib/rubygems/dependency_list.rb, line 115
115:   def why_not_ok? quick = false
116:     unsatisfied = Hash.new { |h,k| h[k] = [] }
117:     source_index = Gem.source_index
118:     each do |spec|
119:       spec.runtime_dependencies.each do |dep|
120:         inst = source_index.any? { |_, installed_spec|
121:           dep.name == installed_spec.name and
122:             dep.requirement.satisfied_by? installed_spec.version
123:         }
124: 
125:         unless inst or @specs.find { |s| s.satisfies_requirement? dep } then
126:           unsatisfied[spec.name] << dep
127:           return unsatisfied if quick
128:         end
129:       end
130:     end
131:     unsatisfied
132:   end

[Validate]