defmodule Dependents.Tree do
@moduledoc """
Converts the `Dependents.Tree` of all or a single app into table maps.
The dependencies of an app are specified in the `mix.exs` file.
The _dependents_ of an app are those apps using it as a dependency.
"""
use PersistConfig
alias __MODULE__.{Digraph, Proxy}
@typedoc "Local app"
@type app :: Application.app()
@typedoc "Number of local dependencies"
@type dcys :: non_neg_integer
@typedoc "Local dependent"
@type dep :: Application.app()
@typedoc "Number of local dependents"
@type deps :: non_neg_integer
@typedoc "Topological rank"
@type rank :: pos_integer
@typedoc "Ranks of topologically ordered apps"
@type ranks :: %{app => rank}
@typedoc "Tree mapping local apps to local dependents"
@type t :: %{app => [dcys | dep]}
@typedoc "Table map for printing"
@type table_map :: %{
rank: rank,
chunk: pos_integer,
ver: String.t() | nil,
hex: String.t() | nil,
app: app | nil,
dcys: dcys | nil,
deps: deps | nil,
dependent_1: dep | nil,
dependent_2: dep | nil,
dependent_3: dep | nil,
dependent_4: dep | nil
}
@doc """
Converts the `Dependents.Tree` of all or a single app into table maps.
"""
@spec to_maps(:* | app) :: [table_map]
def to_maps(:*) do
tree = new()
digraph = Digraph.from_tree(tree)
ranks = Digraph.ranks(digraph)
to_maps(tree, ranks)
end
def to_maps(app) do
tree = new()
digraph = Digraph.from_tree(tree)
ranks = Digraph.ranks(digraph)
deps = Digraph.dependents(digraph, app)
Map.take(tree, [app | deps]) |> to_maps(ranks)
end
@spec new :: t
defdelegate new, to: Proxy
@spec to_maps(t, ranks) :: [table_map]
defdelegate to_maps(tree, ranks), to: Proxy
@doc """
Returns the _projects directory_ as set by environment variable `PROJEX_DIR`.
"""
@spec projects_dir :: String.t()
def projects_dir, do: get_env(:projects_dir)
end