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 |
Creates a DependencyList from a Gem::SourceIndex source_index
# File lib/rubygems/dependency_list.rb, line 26 26: def self.from_source_index(source_index) 27: list = new 28: 29: source_index.each do |full_name, spec| 30: list.add spec 31: end 32: 33: list 34: end
Creates a new DependencyList. If development is true, development dependencies will be included.
# File lib/rubygems/dependency_list.rb, line 40 40: def initialize development = false 41: @specs = [] 42: 43: @development = development 44: end
Adds gemspecs to the dependency list.
# File lib/rubygems/dependency_list.rb, line 49 49: def add(*gemspecs) 50: @specs.push(*gemspecs) 51: 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 68 68: def dependency_order 69: sorted = strongly_connected_components.flatten 70: 71: result = [] 72: seen = {} 73: 74: sorted.each do |spec| 75: if index = seen[spec.name] then 76: if result[index].version < spec.version then 77: result[index] = spec 78: end 79: else 80: seen[spec.name] = result.length 81: result << spec 82: end 83: end 84: 85: result.reverse 86: end
Iterator over dependency_order
# File lib/rubygems/dependency_list.rb, line 91 91: def each(&block) 92: dependency_order.each(&block) 93: end
# File lib/rubygems/dependency_list.rb, line 95 95: def find_name(full_name) 96: @specs.find { |spec| spec.full_name == full_name } 97: end
Are all the dependencies in the list satisfied?
# File lib/rubygems/dependency_list.rb, line 106 106: def ok? 107: @specs.all? do |spec| 108: spec.runtime_dependencies.all? do |dep| 109: @specs.find { |s| s.satisfies_requirement? dep } 110: end 111: end 112: 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 120 120: def ok_to_remove?(full_name) 121: gem_to_remove = find_name full_name 122: 123: siblings = @specs.find_all { |s| 124: s.name == gem_to_remove.name && 125: s.full_name != gem_to_remove.full_name 126: } 127: 128: deps = [] 129: 130: @specs.each do |spec| 131: spec.dependencies.each do |dep| 132: deps << dep if gem_to_remove.satisfies_requirement?(dep) 133: end 134: end 135: 136: deps.all? { |dep| 137: siblings.any? { |s| 138: s.satisfies_requirement? dep 139: } 140: } 141: end
Removes the gemspec matching full_name from the dependency list
# File lib/rubygems/dependency_list.rb, line 146 146: def remove_by_name(full_name) 147: @specs.delete_if { |spec| spec.full_name == full_name } 148: 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 154 154: def spec_predecessors 155: result = Hash.new { |h,k| h[k] = [] } 156: 157: specs = @specs.sort.reverse 158: 159: specs.each do |spec| 160: specs.each do |other| 161: next if spec == other 162: 163: other.dependencies.each do |dep| 164: if spec.satisfies_requirement? dep then 165: result[spec] << other 166: end 167: end 168: end 169: end 170: 171: result 172: end
# File lib/rubygems/dependency_list.rb, line 178 178: def tsort_each_child(node, &block) 179: specs = @specs.sort.reverse 180: 181: dependencies = node.runtime_dependencies 182: dependencies.push(*node.development_dependencies) if @development 183: 184: dependencies.each do |dep| 185: specs.each do |spec| 186: if spec.satisfies_requirement? dep then 187: begin 188: yield spec 189: rescue TSort::Cyclic 190: end 191: break 192: end 193: end 194: end 195: end