class Gem::DependencyList

Gem::DependencyList 用于按正确的顺序安装和卸载 gem,以避免冲突。

属性

development[RW]

允许启用/禁用开发依赖项的使用

specs[R]

公共类方法

from_specs() 点击切换源代码

从当前规范创建 DependencyList

# File rubygems/dependency_list.rb, line 34
def self.from_specs
  list = new
  list.add(*Gem::Specification.to_a)
  list
end
new(development = false) 点击切换源代码

创建一个新的 DependencyList。如果 development 为 true,则将包含开发依赖项。

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

  @development = development
end

公共实例方法

add(*gemspecs) 点击切换源代码

gemspecs 添加到依赖项列表。

# File rubygems/dependency_list.rb, line 53
def add(*gemspecs)
  @specs.concat gemspecs
end
clear() 点击切换源代码
# File rubygems/dependency_list.rb, line 57
def clear
  @specs.clear
end
dependency_order() 点击切换源代码

返回依赖项列表中 gem 规范的列表,该列表已排序,以便列表中的任何 gem 规范都不依赖于列表前面较早的 gem 规范。

这在从一组已安装的 gem 中删除 gem 时非常有用。 通过按返回的顺序删除它们,您不会遇到太多依赖问题。

如果存在循环依赖(真糟糕!),那么 gem 将按顺序返回,直到只剩下循环依赖项以及它们引用的任何内容。 然后,将返回任意 gem 规范,直到打破循环依赖关系,之后 gem 将再次按依赖顺序返回。

# File 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) 点击切换源代码

遍历 dependency_order

# File rubygems/dependency_list.rb, line 99
def each(&block)
  dependency_order.each(&block)
end
find_name(full_name) 点击切换源代码
# File rubygems/dependency_list.rb, line 103
def find_name(full_name)
  @specs.find {|spec| spec.full_name == full_name }
end
ok?() 点击切换源代码

列表中的所有依赖项都已满足吗?

# File rubygems/dependency_list.rb, line 114
def ok?
  why_not_ok?(:quick).empty?
end
ok_to_remove?(full_name, check_dev=true) 点击切换源代码

可以从依赖项列表中删除 gem 规范吗?

如果删除 gem 规范会破坏当前正常的依赖关系,则不适合删除该 gem 规范。

# File 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) 点击切换源代码

从依赖项列表中删除与 full_name 匹配的 gem 规范

# File 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) 点击切换源代码

删除 DependencyList 中匹配但不满足 dependencies(gem 名称到依赖项数组的哈希)中的项的所有内容。

# File 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() 点击切换源代码

返回前置项的哈希。 result[spec] 是一个 gemspec 数组,该数组具有由命名 gemspec 满足的依赖项。

# File 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) { |spec| ... } 点击切换源代码
# File 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 rubygems/dependency_list.rb, line 214
def tsort_each_node(&block)
  @specs.each(&block)
end
why_not_ok?(quick = false) 点击切换源代码
# File 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

私有实例方法

active_count(specs, ignored) 点击切换源代码

计算列表 specs 中不在 ignored 中的 gem 规范的数量。

# File rubygems/dependency_list.rb, line 240
def active_count(specs, ignored)
  specs.count {|spec| ignored[spec.full_name].nil? }
end