Skip to Content Skip to Search

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

Methods
A
C
D
E
F
N
O
R
S
T
W
Included Modules

Attributes

[RW] development

Allows enabling/disabling use of development dependencies

[R] specs

Class Public methods

from_specs()

Creates a DependencyList from the current specs.

# File ruby/lib/rubygems/dependency_list.rb, line 34
def self.from_specs
  list = new
  list.add(*Gem::Specification.to_a)
  list
end

new(development = false)

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

# File ruby/lib/rubygems/dependency_list.rb, line 44
def initialize(development = false)
  @specs = []

  @development = development
end

Instance Public methods

add(*gemspecs)

Adds gemspecs to the dependency list.

# File ruby/lib/rubygems/dependency_list.rb, line 53
def add(*gemspecs)
  @specs.concat gemspecs
end

clear()

# File ruby/lib/rubygems/dependency_list.rb, line 57
def clear
  @specs.clear
end

dependency_order()

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 ruby/lib/rubygems/dependency_list.rb, line 76
def dependency_order
  sorted = strongly_connected_components.flatten

  result = []
  seen = {}

  sorted.each do |spec|
    if index = seen[spec.name]
      if result[index].version < spec.version
        result[index] = spec
      end
    else
      seen[spec.name] = result.length
      result << spec
    end
  end

  result.reverse
end

each(&block)

Iterator over dependency_order

# File ruby/lib/rubygems/dependency_list.rb, line 99
def each(&block)
  dependency_order.each(&block)
end

find_name(full_name)

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

ok?()

Are all the dependencies in the list satisfied?

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

ok_to_remove?(full_name, check_dev=true)

It 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 ruby/lib/rubygems/dependency_list.rb, line 143
def ok_to_remove?(full_name, check_dev=true)
  gem_to_remove = find_name full_name

  # If the state is inconsistent, at least don't crash
  return true unless gem_to_remove

  siblings = @specs.find_all do |s|
    s.name == gem_to_remove.name &&
      s.full_name != gem_to_remove.full_name
  end

  deps = []

  @specs.each do |spec|
    check = check_dev ? spec.dependencies : spec.runtime_dependencies

    check.each do |dep|
      deps << dep if gem_to_remove.satisfies_requirement?(dep)
    end
  end

  deps.all? do |dep|
    siblings.any? do |s|
      s.satisfies_requirement? dep
    end
  end
end

remove_by_name(full_name)

Removes the gemspec matching full_name from the dependency list

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

remove_specs_unsatisfied_by(dependencies)

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

# File ruby/lib/rubygems/dependency_list.rb, line 176
def remove_specs_unsatisfied_by(dependencies)
  specs.reject! do |spec|
    dep = dependencies[spec.name]
    dep && !dep.requirement.satisfied_by?(spec.version)
  end
end

spec_predecessors()

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

# File ruby/lib/rubygems/dependency_list.rb, line 194
def spec_predecessors
  result = Hash.new {|h,k| h[k] = [] }

  specs = @specs.sort.reverse

  specs.each do |spec|
    specs.each do |other|
      next if spec == other

      other.dependencies.each do |dep|
        if spec.satisfies_requirement? dep
          result[spec] << other
        end
      end
    end
  end

  result
end

tsort_each_child(node)

# File ruby/lib/rubygems/dependency_list.rb, line 218
def tsort_each_child(node)
  specs = @specs.sort.reverse

  dependencies = node.runtime_dependencies
  dependencies.push(*node.development_dependencies) if @development

  dependencies.each do |dep|
    specs.each do |spec|
      if spec.satisfies_requirement? dep
        yield spec
        break
      end
    end
  end
end

tsort_each_node(&block)

# File ruby/lib/rubygems/dependency_list.rb, line 214
def tsort_each_node(&block)
  @specs.each(&block)
end

why_not_ok?(quick = false)

# File ruby/lib/rubygems/dependency_list.rb, line 118
def why_not_ok?(quick = false)
  unsatisfied = Hash.new {|h,k| h[k] = [] }
  each do |spec|
    spec.runtime_dependencies.each do |dep|
      inst = Gem::Specification.any? do |installed_spec|
        dep.name == installed_spec.name &&
          dep.requirement.satisfied_by?(installed_spec.version)
      end

      unless inst || @specs.find {|s| s.satisfies_requirement? dep }
        unsatisfied[spec.name] << dep
        return unsatisfied if quick
      end
    end
  end

  unsatisfied
end