Current section

Files

Jump to
nerves_hub_cli lib mix nerves_hub bulk.ex
Raw

lib/mix/nerves_hub/bulk.ex

defmodule Mix.NervesHubCLI.Bulk do
alias Mix.NervesHubCLI.Shell
import Mix.NervesHubCLI.Utils
@acc %{data: [], error: [], malformed: [], success: [], tasks: []}
def create_devices(data, org, product, auth) do
%{@acc | data: data}
|> filter_malformed()
|> do_create_devices(org, product, auth)
|> accumulate_results()
end
def display_results(%{error: error, malformed: malformed, success: success}, csv_path) do
_ = Enum.each(error, &display_error/1)
_ = Enum.each(malformed, &display_malformed(&1, csv_path))
Shell.info("""
Results:
#{IO.ANSI.yellow()}malformed: #{length(malformed)}
#{IO.ANSI.red()}errors: #{length(error)}
#{IO.ANSI.green()}successful: #{length(success)}
#{IO.ANSI.default_color()}
""")
end
defp accumulate_results(acc) do
Enum.reduce(acc.tasks, acc, fn
{task, nil}, acc ->
_ = Task.shutdown(task, :brutal_kill)
acc
{_task, {:ok, {{:ok, %{} = device}, _}}}, acc ->
%{acc | success: [device | acc.success]}
{_task, {:ok, {_error, [_i, _d_, _t]} = err}}, acc ->
%{acc | error: [err | acc.error]}
end)
end
defp display_error({error, [identifier, description, tags]}) do
Shell.error("""
Error creating #{identifier} with tags: #{inspect(tags)} and description: #{description} ¬
#{inspect(error)}
""")
end
defp display_malformed({line, line_num}, csv_path) do
Shell.info("""
#{IO.ANSI.yellow()} Malformed CSV line - #{inspect(line)}
(CSV) #{csv_path}:#{line_num}
#{IO.ANSI.default_color()}
""")
end
defp do_create_devices(acc, org, product, auth) do
tasks =
Enum.map(acc.data, fn [identifier, tags, description] ->
tags = split_tag_string(tags)
Task.async(fn ->
result =
NervesHubUserAPI.Device.create(org, product, identifier, description, tags, auth)
{result, [identifier, description, tags]}
end)
end)
%{acc | tasks: Task.yield_many(tasks, :infinity)}
end
defp filter_malformed(acc) do
Enum.with_index(acc.data)
|> Enum.reduce(%{acc | data: []}, fn
{[_identifier, _tags, _description] = line, _i}, acc ->
%{acc | data: [line | acc.data]}
{_line, _line_num} = bad_line, acc ->
%{acc | malformed: [bad_line | acc.malformed]}
end)
end
end