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.
development | [RW] | Allows enabling/disabling use of development dependencies |
specs | [R] |
Creates a DependencyList from a Gem::SourceIndex source_index
# File lib/rubygems/dependency_list.rb, line 37 37: def self.from_source_index(ignored=nil) 38: warn "NOTE: DependencyList.from_source_index ignores it's arg" if ignored 39: 40: from_specs 41: end
Creates a DependencyList from the current specs.
# File lib/rubygems/dependency_list.rb, line 28 28: def self.from_specs 29: list = new 30: list.add(*Gem::Specification.map) 31: list 32: end
Creates a new DependencyList. If development is true, development dependencies will be included.
# File lib/rubygems/dependency_list.rb, line 47 47: def initialize development = false 48: @specs = [] 49: 50: @development = development 51: end
Adds gemspecs to the dependency list.
# File lib/rubygems/dependency_list.rb, line 56 56: def add(*gemspecs) 57: @specs.push(*gemspecs) 58: 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.
# File lib/rubygems/dependency_list.rb, line 79 79: def dependency_order 80: sorted = strongly_connected_components.flatten 81: 82: result = [] 83: seen = {} 84: 85: sorted.each do |spec| 86: if index = seen[spec.name] then 87: if result[index].version < spec.version then 88: result[index] = spec 89: end 90: else 91: seen[spec.name] = result.length 92: result << spec 93: end 94: end 95: 96: result.reverse 97: end
Iterator over dependency_order
# File lib/rubygems/dependency_list.rb, line 102 102: def each(&block) 103: dependency_order.each(&block) 104: end
# File lib/rubygems/dependency_list.rb, line 106 106: def find_name(full_name) 107: @specs.find { |spec| spec.full_name == full_name } 108: end
Are all the dependencies in the list satisfied?
# File lib/rubygems/dependency_list.rb, line 117 117: def ok? 118: why_not_ok?(:quick).empty? 119: 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.
# File lib/rubygems/dependency_list.rb, line 146 146: def ok_to_remove?(full_name) 147: gem_to_remove = find_name full_name 148: 149: siblings = @specs.find_all { |s| 150: s.name == gem_to_remove.name && 151: s.full_name != gem_to_remove.full_name 152: } 153: 154: deps = [] 155: 156: @specs.each do |spec| 157: spec.dependencies.each do |dep| 158: deps << dep if gem_to_remove.satisfies_requirement?(dep) 159: end 160: end 161: 162: deps.all? { |dep| 163: siblings.any? { |s| 164: s.satisfies_requirement? dep 165: } 166: } 167: end
Removes the gemspec matching full_name from the dependency list
# File lib/rubygems/dependency_list.rb, line 184 184: def remove_by_name(full_name) 185: @specs.delete_if { |spec| spec.full_name == full_name } 186: end
Remove everything in the DependencyList that matches but doesn‘t satisfy items in dependencies (a hash of gem names to arrays of dependencies).
# File lib/rubygems/dependency_list.rb, line 174 174: def remove_specs_unsatisfied_by dependencies 175: specs.reject! { |spec| 176: dep = dependencies[spec.name] 177: dep and not dep.requirement.satisfied_by? spec.version 178: } 179: end
Return a hash of predecessors. result[spec] is an Array of gemspecs that have a dependency satisfied by the named gemspec.
# File lib/rubygems/dependency_list.rb, line 192 192: def spec_predecessors 193: result = Hash.new { |h,k| h[k] = [] } 194: 195: specs = @specs.sort.reverse 196: 197: specs.each do |spec| 198: specs.each do |other| 199: next if spec == other 200: 201: other.dependencies.each do |dep| 202: if spec.satisfies_requirement? dep then 203: result[spec] << other 204: end 205: end 206: end 207: end 208: 209: result 210: end
# File lib/rubygems/dependency_list.rb, line 216 216: def tsort_each_child(node, &block) 217: specs = @specs.sort.reverse 218: 219: dependencies = node.runtime_dependencies 220: dependencies.push(*node.development_dependencies) if @development 221: 222: dependencies.each do |dep| 223: specs.each do |spec| 224: if spec.satisfies_requirement? dep then 225: begin 226: yield spec 227: rescue TSort::Cyclic 228: # do nothing 229: end 230: break 231: end 232: end 233: end 234: end
# File lib/rubygems/dependency_list.rb, line 212 212: def tsort_each_node(&block) 213: @specs.each(&block) 214: end
# File lib/rubygems/dependency_list.rb, line 121 121: def why_not_ok? quick = false 122: unsatisfied = Hash.new { |h,k| h[k] = [] } 123: each do |spec| 124: spec.runtime_dependencies.each do |dep| 125: inst = Gem::Specification.any? { |installed_spec| 126: dep.name == installed_spec.name and 127: dep.requirement.satisfied_by? installed_spec.version 128: } 129: 130: unless inst or @specs.find { |s| s.satisfies_requirement? dep } then 131: unsatisfied[spec.name] << dep 132: return unsatisfied if quick 133: end 134: end 135: end 136: 137: unsatisfied 138: end