Skip to content

Commit

Permalink
add some formatting to nerves_hub.device bulk_create
Browse files Browse the repository at this point in the history
  • Loading branch information
jjcarstens authored and fhunleth committed Aug 12, 2020
1 parent 40dd0de commit ac76ea5
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 33 deletions.
101 changes: 69 additions & 32 deletions lib/mix/nerves_hub/bulk.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,82 @@ 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
data
|> Enum.filter(fn
[_identifier, _tags, _description] ->
true

_ ->
# maybe raise/exit here?
false
%{@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)
|> Enum.map(fn [identifier, tags, description] ->
tags = split_tag_string(tags)
end

Task.async(fn ->
result = NervesHubUserAPI.Device.create(org, product, identifier, description, tags, auth)
{result, [identifier, description, tags]}
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)
end)
|> Task.yield_many(:infinity)
|> Enum.filter(fn
{task, nil} ->
_ = Task.shutdown(task, :brutal_kill)
false

{_task, {:ok, {{:ok, %{} = _device}, _}}} ->
true
%{acc | tasks: Task.yield_many(tasks, :infinity)}
end

{_task, {:ok, {error, [identifier, description, tags]}}} ->
Shell.error(
"Error creating #{identifier} with tags: #{inspect(tags)} and description: #{
description
}"
)
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]}

Shell.render_error(error, false)
false
end)
|> Enum.map(fn {_task, {:ok, {{:ok, %{} = device}, _}}} ->
device
{_line, _line_num} = bad_line, acc ->
%{acc | malformed: [bad_line | acc.malformed]}
end)
end
end
3 changes: 2 additions & 1 deletion lib/mix/tasks/nerves_hub.device.ex
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ defmodule Mix.Tasks.NervesHub.Device do
end
end

@spec bulk_create(String.t(), String.t(), keyword()) :: [any()]
@spec bulk_create(String.t(), String.t(), keyword()) :: :ok
def bulk_create(org, product, args) do
auth = Shell.request_auth()
path = args[:csv]
Expand All @@ -303,6 +303,7 @@ defmodule Mix.Tasks.NervesHub.Device do
|> CSV.parse_stream()
|> Enum.to_list()
|> Bulk.create_devices(org, product, auth)
|> Bulk.display_results(path)
end

@spec update(String.t(), String.t(), String.t(), [String.t()]) :: :ok
Expand Down

0 comments on commit ac76ea5

Please sign in to comment.