2017-06-28 17:53:59 +02:00
|
|
|
require "delegate"
|
|
|
|
|
2016-08-18 22:11:42 +03:00
|
|
|
require "hbc/topological_hash"
|
|
|
|
|
2016-09-24 13:52:43 +02:00
|
|
|
module Hbc
|
2017-06-28 17:53:59 +02:00
|
|
|
class CaskDependencies < DelegateClass(Array)
|
|
|
|
attr_reader :cask, :graph
|
2016-08-18 22:11:42 +03:00
|
|
|
|
2016-09-24 13:52:43 +02:00
|
|
|
def initialize(cask)
|
|
|
|
@cask = cask
|
|
|
|
@graph = graph_dependencies
|
2017-06-28 17:53:59 +02:00
|
|
|
super(sort)
|
2016-09-24 13:52:43 +02:00
|
|
|
end
|
2016-08-18 22:11:42 +03:00
|
|
|
|
2017-06-28 17:53:59 +02:00
|
|
|
private
|
2016-08-18 22:11:42 +03:00
|
|
|
|
2017-06-28 17:53:59 +02:00
|
|
|
def graph_dependencies(cask = self.cask, acc = TopologicalHash.new)
|
|
|
|
return acc if acc.key?(cask)
|
|
|
|
deps = cask.depends_on.cask.map(&CaskLoader.public_method(:load))
|
|
|
|
acc[cask] = deps
|
|
|
|
deps.each do |dep|
|
|
|
|
graph_dependencies(dep, acc)
|
|
|
|
end
|
|
|
|
acc
|
2016-09-24 13:52:43 +02:00
|
|
|
end
|
2016-08-18 22:11:42 +03:00
|
|
|
|
2016-09-24 13:52:43 +02:00
|
|
|
def sort
|
2017-06-28 17:53:59 +02:00
|
|
|
raise CaskSelfReferencingDependencyError, cask.token if graph[cask].include?(cask)
|
|
|
|
graph.tsort - [cask]
|
2016-09-24 13:52:43 +02:00
|
|
|
rescue TSort::Cyclic
|
2017-06-28 17:53:59 +02:00
|
|
|
strongly_connected_components = graph.strongly_connected_components.sort_by(&:count)
|
|
|
|
cyclic_dependencies = strongly_connected_components.last - [cask]
|
|
|
|
raise CaskCyclicDependencyError.new(cask.token, cyclic_dependencies.join(", "))
|
2016-09-24 13:52:43 +02:00
|
|
|
end
|
2016-08-18 22:11:42 +03:00
|
|
|
end
|
|
|
|
end
|