defmodule Mix.Tasks.Arch.Report.Html do @moduledoc """ Mix Task to generate a static HTML report. Usage: mix arch.report.html Report is generated at `reports/dev/static/html`. """ @shortdoc "Generates a code analysis HTML report" require Logger require EEx use Mix.Task use Archeometer.Repo alias Archeometer.Reports.PageDefinition alias Archeometer.Reports.Page alias Archeometer.Reports.Render alias Archeometer.Reports.Config @impl Mix.Task def run(argv) do prepare_paths() copy_asserts() _run(argv, umbrella: Mix.Project.umbrella?()) copy_images() IO.puts(:stderr, "HTML report ready at '#{report_path(:html)}'") end defp _run(_argv, umbrella: false) do Mix.Project.config() |> Keyword.get(:app) |> create_app_page() end @index_page_name :index defp _run(_argv, umbrella: true) do page_names = page_names(@index_page_name) @index_page_name |> to_string() |> PageDefinition.Project.definition() |> create_page(page_names) Mix.Project.apps_paths() |> Enum.each(fn {app, _path} -> create_app_page(app, page_names) end) end defp page_names(index_page_name) do page_names = Mix.Project.apps_paths() |> Enum.map(fn {app, _path} -> to_string(app) end) [to_string(index_page_name) | page_names] end defp create_app_page(app, page_names \\ []) do app |> to_string() |> PageDefinition.Application.definition() |> create_page(page_names) end defp create_page(%Page.Definition{} = page_def, page_names) do page_fname = page_def.id page_def |> render_page(page_names, app: page_def.id) |> write_to_file(page_fname <> ".html") end defp render_page(%Page.Definition{} = page_def, page_names, bindings) do page_def |> Page.process(bindings, default_db_name()) |> Render.Html.render(page_names) end defp write_to_file(str, fname) do path = Path.expand(fname, report_path(:html)) File.write!(path, str) end defp prepare_paths() do report_path = report_path(:html) [ Path.expand("img/", report_path), Path.expand("js/", report_path), Path.expand("css/", report_path) ] |> Enum.each(fn path -> File.mkdir_p!(path) end) report_path(:img) |> File.mkdir_p!() end defp copy_asserts() do template_base_path = Archeometer.Util.PathHelper.template_path("report") report_path = report_path(:html) ["css", "js"] |> Enum.each(fn subdir -> src_path = Path.expand(subdir, template_base_path) dest_path = Path.expand(subdir, report_path) File.cp_r!(src_path, dest_path) end) end defp copy_images() do src_path = report_path(:img) report_path = report_path(:html) dest_path = Path.expand("img", report_path) File.cp_r!(src_path, dest_path) end defp report_path(:html), do: Config.report_path(:html) defp report_path(:img), do: Config.report_path(:img) end