defmodule Archeometer.Analysis.Apps.Xref do
@moduledoc """
Functions for generating a dependency graph from applications in an Elixir
project.
Accepted output formats are "dot" (graphviz), "png" and "mermaid".
"""
alias Archeometer.Graphs.{Graphviz, Mermaid}
alias Archeometer.Repo
import Archeometer.Query
@supported_formats ["png", "dot", "mermaid", "svg"]
@doc """
Creates a dependency graph between the applications of the current project.
## Parameters
- 'format' can be one of "dot" (graphviz), "png", or "mermaid".
- 'db' is the database path
## Returns
- The binary representing the graph, if the operation was completed successfully.
- `{:error, reason}` if not.
"""
def gen_graph(format, db \\ Repo.default_db_name())
def gen_graph(format, db) when format in @supported_formats do
do_gen_graph(format, db)
end
def gen_graph(_format, _db) do
{:error, :unsupported_format}
end
defp do_gen_graph(format, db) do
Repo.all(
from(xref in Archeometer.Schema.AppXRef,
select: [caller: xref.caller.name, callee: xref.callee.name]
),
[],
db
).rows
|> Enum.group_by(fn [caller, _] -> caller end, fn [_, callee] -> callee end)
|> render(format)
end
defp render(refs, "dot") do
Graphviz.render_dot(refs)
end
defp render(refs, format) when format in ["png", "svg"] do
Graphviz.render_image(refs, format)
end
defp render(refs, "mermaid") do
Mermaid.render(refs)
end
end