json.ex (1921B)
1 defmodule Credo.CLI.Output.Formatter.JSON do 2 @moduledoc false 3 4 alias Credo.CLI.Output.UI 5 alias Credo.Issue 6 7 def print_issues(issues) do 8 %{ 9 "issues" => Enum.map(issues, &issue_to_json/1) 10 } 11 |> print_map() 12 end 13 14 def print_map(map) do 15 map 16 |> prepare_for_json() 17 |> Jason.encode!(pretty: true) 18 |> UI.puts() 19 end 20 21 def prepare_for_json(term) 22 when is_atom(term) or is_number(term) or is_binary(term) do 23 term 24 end 25 26 def prepare_for_json(term) when is_list(term), do: Enum.map(term, &prepare_for_json/1) 27 28 def prepare_for_json(%Regex{} = regex), do: inspect(regex) 29 30 def prepare_for_json(%{} = term) do 31 Enum.into(term, %{}, fn {key, value} -> 32 {prepare_key_for_json(key), prepare_for_json(value)} 33 end) 34 end 35 36 def prepare_for_json(term) when is_tuple(term) do 37 term 38 |> Tuple.to_list() 39 |> prepare_for_json() 40 end 41 42 def prepare_for_json(term) do 43 inspect(term) 44 end 45 46 defp prepare_key_for_json(key) when is_atom(key) or is_binary(key) or is_number(key) do 47 key 48 end 49 50 defp prepare_key_for_json(key) do 51 inspect(key) 52 end 53 54 def issue_to_json( 55 %Issue{ 56 check: check, 57 category: category, 58 message: message, 59 filename: filename, 60 priority: priority, 61 scope: scope 62 } = issue 63 ) do 64 check_name = 65 check 66 |> to_string() 67 |> String.replace(~r/^(Elixir\.)/, "") 68 69 column_end = 70 if issue.column && issue.trigger do 71 issue.column + String.length(to_string(issue.trigger)) 72 end 73 74 %{ 75 "check" => check_name, 76 "category" => to_string(category), 77 "filename" => to_string(filename), 78 "line_no" => issue.line_no, 79 "column" => issue.column, 80 "column_end" => column_end, 81 "trigger" => issue.trigger, 82 "message" => message, 83 "priority" => priority, 84 "scope" => scope 85 } 86 end 87 end