aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cask/lib/hbc/cask_dependencies.rb
blob: 0edda074e3498037997caa2dd87499b5eb62b532 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
require "delegate"

require "hbc/topological_hash"

module Hbc
  class CaskDependencies < DelegateClass(Array)
    attr_reader :cask, :graph

    def initialize(cask)
      @cask = cask
      @graph = graph_dependencies
      super(sort)
    end

    private

    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
    end

    def sort
      raise CaskSelfReferencingDependencyError, cask.token if graph[cask].include?(cask)
      graph.tsort - [cask]
    rescue TSort::Cyclic
      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(", "))
    end
  end
end