defmodule Credo.CLI.Command.ReportCard.Output.Html do @moduledoc false alias Credo.Execution def print_before_info(_source_files, _exec), do: nil def print_after_info(_source_files, exec, _time_load, _time_run) do exec |> Execution.get_issues() |> print_issues() end alias Credo.Issue alias Credo.Service.SourceFileLines @head_links """ """ @inline_styles """ """ @table_scripts """ """ @inline_scripts """ """ def print_issues(issues) do issues |> Enum.reduce(Map.new(), &Credo.CLI.Output.Formatter.ReportCard.categorize_module/2) |> write_html() end defp write_html(issue_map) do File.mkdir("credo") {:ok, f} = File.open("credo/index.html", [:binary, :write]) IO.binwrite(f, [ "\n\n
\n| File | \n", "Grade | \n", "Issues | \n", "Remediation Time | ", "\n
|---|
",
line_content(issue, min_line, max_line),
"\n\n" <> h(sv) <> "
\n\n" _ -> "" <> h(sv) <> "\n\n"
end
end)
end
defp is_source_explanation(<<" ", _::binary>>) do
true
end
defp is_source_explanation(_) do
false
end
defp line_indexes(
%Issue{check: Credo.Check.Warning.ExCoverallsUncovered, severity: sev} = issue
) do
exact_line = issue.line_no || 1
last_line = exact_line + sev - 1
first_line = minimum_line(exact_line)
{:ok, src_lines} = SourceFileLines.get(issue.filename)
keys = :proplists.get_keys(src_lines)
line_pointer =
case sev > 1 do
false -> exact_line
_ -> "#{exact_line}-#{last_line}"
end
{line_pointer, first_line, max_line(last_line, keys)}
end
defp line_indexes(issue) do
exact_line = issue.line_no || 1
first_line = minimum_line(exact_line)
{:ok, src_lines} = SourceFileLines.get(issue.filename)
keys = :proplists.get_keys(src_lines)
{exact_line, first_line, max_line(exact_line, keys)}
end
defp line_content(issue, min, max) do
{:ok, src_lines} = SourceFileLines.get(issue.filename)
Enum.join(
Enum.map(Range.new(min, max), fn i ->
h(:proplists.get_value(i, src_lines))
end),
"\n"
) <> "\n"
end
defp max_line(target_line, keys) do
case Enum.member?(keys, target_line + 2) do
false ->
case Enum.member?(keys, target_line + 1) do
false -> target_line
_ -> target_line + 1
end
_ ->
target_line + 2
end
end
def minimum_line(2), do: 1
def minimum_line(1), do: 1
def minimum_line(n), do: n - 2
defp h(binary) do
html_escape(binary, <<>>)
end
defp html_escape(<<>>, str) do
str
end
defp html_escape(<<"'", rest::binary>>, str) do
html_escape(rest, str <> "'")
end
defp html_escape(<<"\"", rest::binary>>, str) do
html_escape(rest, str <> """)
end
defp html_escape(<<"<", rest::binary>>, str) do
html_escape(rest, str <> "<")
end
defp html_escape(<<">", rest::binary>>, str) do
html_escape(rest, str <> ">")
end
defp html_escape(<