execution_issues.ex (2229B)
1 defmodule Credo.Execution.ExecutionIssues do 2 @moduledoc false 3 4 use GenServer 5 6 alias Credo.Execution 7 alias Credo.Issue 8 alias Credo.SourceFile 9 10 def start_server(exec) do 11 {:ok, pid} = GenServer.start_link(__MODULE__, []) 12 13 %Execution{exec | issues_pid: pid} 14 end 15 16 @doc "Appends an `issue` for the specified `filename`." 17 def append(%Execution{issues_pid: pid}, issues) when is_list(issues) do 18 issues 19 |> Enum.group_by(& &1.filename) 20 |> Enum.each(fn {filename, issues} -> 21 GenServer.call(pid, {:append, filename, issues}) 22 end) 23 end 24 25 def append(%Execution{issues_pid: pid}, %Issue{} = issue) do 26 GenServer.call(pid, {:append, issue.filename, issue}) 27 end 28 29 @doc "Appends an `issue` for the specified `filename`." 30 def append(%Execution{issues_pid: pid}, %SourceFile{filename: filename}, issue) do 31 GenServer.call(pid, {:append, filename, issue}) 32 end 33 34 @doc "Returns the issues for the specified `filename`." 35 def get(%Execution{issues_pid: pid}, %SourceFile{filename: filename}) do 36 GenServer.call(pid, {:get, filename}) 37 end 38 39 @doc "Sets/overwrites all `issues` for the given Execution struct." 40 def set(%Execution{issues_pid: pid}, issues) do 41 GenServer.call(pid, {:set, issues}) 42 end 43 44 @doc "Returns all `issues` for the given Execution struct." 45 def to_map(%Execution{issues_pid: pid}) do 46 GenServer.call(pid, :to_map) 47 end 48 49 # callbacks 50 51 def init(_) do 52 {:ok, %{}} 53 end 54 55 def handle_call({:append, filename, issue_or_issue_list}, _from, current_state) do 56 existing_issues = List.wrap(current_state[filename]) 57 new_issue_list = List.wrap(issue_or_issue_list) ++ existing_issues 58 new_current_state = Map.put(current_state, filename, new_issue_list) 59 60 {:reply, new_issue_list, new_current_state} 61 end 62 63 def handle_call({:get, filename}, _from, current_state) do 64 {:reply, List.wrap(current_state[filename]), current_state} 65 end 66 67 def handle_call({:set, issues}, _from, _current_state) do 68 new_current_state = Enum.group_by(issues, fn issue -> issue.filename end) 69 70 {:reply, new_current_state, new_current_state} 71 end 72 73 def handle_call(:to_map, _from, current_state) do 74 {:reply, current_state, current_state} 75 end 76 end