2025-03-07 15:44:13 -08:00
|
|
|
# typed: strict
|
2021-09-09 13:30:55 -07:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require "tsort"
|
|
|
|
|
|
|
|
module Utils
|
|
|
|
# Topologically sortable hash map.
|
|
|
|
class TopologicalHash < Hash
|
2025-03-07 15:44:13 -08:00
|
|
|
extend T::Generic
|
2021-09-09 13:30:55 -07:00
|
|
|
include TSort
|
|
|
|
|
2025-03-07 15:44:13 -08:00
|
|
|
CaskOrFormula = T.type_alias { T.any(Cask::Cask, Formula) }
|
|
|
|
|
|
|
|
K = type_member { { fixed: CaskOrFormula } }
|
|
|
|
V = type_member { { fixed: T::Array[CaskOrFormula] } }
|
|
|
|
Elem = type_member(:out) { { fixed: [CaskOrFormula, T::Array[CaskOrFormula]] } }
|
|
|
|
|
2021-09-09 13:30:55 -07:00
|
|
|
sig {
|
|
|
|
params(
|
2025-03-07 15:44:13 -08:00
|
|
|
packages: T.any(CaskOrFormula, T::Array[CaskOrFormula]),
|
2021-09-09 13:30:55 -07:00
|
|
|
accumulator: TopologicalHash,
|
|
|
|
).returns(TopologicalHash)
|
|
|
|
}
|
|
|
|
def self.graph_package_dependencies(packages, accumulator = TopologicalHash.new)
|
|
|
|
packages = Array(packages)
|
|
|
|
|
|
|
|
packages.each do |cask_or_formula|
|
2021-11-12 13:50:53 -08:00
|
|
|
next if accumulator.key?(cask_or_formula)
|
2021-09-09 13:30:55 -07:00
|
|
|
|
2025-03-13 10:26:41 -07:00
|
|
|
case cask_or_formula
|
|
|
|
when Cask::Cask
|
2021-09-09 13:30:55 -07:00
|
|
|
formula_deps = cask_or_formula.depends_on
|
|
|
|
.formula
|
|
|
|
.map { |f| Formula[f] }
|
|
|
|
cask_deps = cask_or_formula.depends_on
|
|
|
|
.cask
|
|
|
|
.map { |c| Cask::CaskLoader.load(c, config: nil) }
|
2025-03-13 10:26:41 -07:00
|
|
|
when Formula
|
2021-09-09 13:30:55 -07:00
|
|
|
formula_deps = cask_or_formula.deps
|
|
|
|
.reject(&:build?)
|
2023-08-17 04:16:02 -07:00
|
|
|
.reject(&:test?)
|
2021-09-09 13:30:55 -07:00
|
|
|
.map(&:to_formula)
|
|
|
|
cask_deps = cask_or_formula.requirements
|
2024-02-22 23:29:55 +00:00
|
|
|
.filter_map(&:cask)
|
2021-09-09 13:30:55 -07:00
|
|
|
.map { |c| Cask::CaskLoader.load(c, config: nil) }
|
2025-03-13 10:26:41 -07:00
|
|
|
else
|
|
|
|
T.absurd(cask_or_formula)
|
2021-09-09 13:30:55 -07:00
|
|
|
end
|
|
|
|
|
2021-11-12 13:50:53 -08:00
|
|
|
accumulator[cask_or_formula] = formula_deps + cask_deps
|
2021-09-09 13:30:55 -07:00
|
|
|
|
|
|
|
graph_package_dependencies(formula_deps, accumulator)
|
|
|
|
graph_package_dependencies(cask_deps, accumulator)
|
|
|
|
end
|
|
|
|
|
|
|
|
accumulator
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2025-03-07 15:44:13 -08:00
|
|
|
sig { params(block: T.proc.params(arg0: K).void).void }
|
2021-09-09 13:30:55 -07:00
|
|
|
def tsort_each_node(&block)
|
|
|
|
each_key(&block)
|
|
|
|
end
|
|
|
|
|
2025-03-07 15:44:13 -08:00
|
|
|
sig { params(node: K, block: T.proc.params(arg0: CaskOrFormula).void).returns(V) }
|
2021-09-09 13:30:55 -07:00
|
|
|
def tsort_each_child(node, &block)
|
|
|
|
fetch(node).each(&block)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|