Current section

Files

Jump to
archeometer lib mix tasks archeometer.xref.ex
Raw

lib/mix/tasks/archeometer.xref.ex

defmodule Mix.Tasks.Arch.Xref do
@moduledoc """
Mix Task to generate a dependency graph given some module names.
Usage:
mix arch.xref [options] mod1 mod2 .. modN
The following options are accepted:
* `--db` - Database filename
* `--format` - Can be one of `dot` or `png`
* `--out` - Output filename
"""
@shortdoc "Generates a dependency graph from a list of modules"
require Logger
require EEx
use Mix.Task
use Archeometer.Repo
@supported_formats ["png", "dot", "mermaid"]
@impl Mix.Task
def run(argv) do
case parse_args(argv) do
{:ok, [db_name: db, modules: modules, format: format, out_fname: out_fname]} ->
Archeometer.Analysis.Xref.gen_graph(modules, format, db)
|> write(out_fname)
IO.puts(:stderr, "Graph ready at: '#{out_fname}'")
{:error, error} ->
IO.puts(:stderr, "Error #{inspect(error)}")
print_help()
end
end
defp print_help() do
IO.puts(:stderr, "Usage: mix arch.xref [opts] Mod1 Mod2 ... ModN")
IO.puts(
:stderr,
"opts: --db db_file_name, --format (dot, png, mermaid), --out out_fname"
)
end
defp parse_args(argv) do
{opts, modules, invalid_switches} =
OptionParser.parse(
argv,
strict: [db: :string, format: :string, out: :string]
)
case invalid_switches do
[] ->
db_name = Keyword.get(opts, :db, default_db_name())
format = Keyword.get(opts, :format, "dot")
out_fname = Keyword.get(opts, :out, "console")
case validate_options(format, out_fname) do
:ok ->
{:ok,
[
db_name: db_name,
modules: modules,
format: format,
out_fname: out_fname
]}
{:error, error} ->
{:error, error}
end
_ ->
{:error, :wrong_arguments}
end
end
defp validate_options(format, out_fname) do
cond do
format not in @supported_formats ->
{:error, :unsuppored_output_format}
format == "png" and out_fname == "console" ->
{:error, :png_not_writable_to_console}
true ->
:ok
end
end
defp write(content, "console") do
IO.puts(content)
end
defp write(content, out_fname) do
File.write!(out_fname, content)
end
end