Current section

Files

Jump to
igniter_new lib task.ex
Raw

lib/task.ex

defmodule Igniter.Installer.Task do
@moduledoc false
@spinners "⠁⠂⠄⡀⡁⡂⡄⡅⡇⡏⡗⡧⣇⣏⣗⣧⣯⣷⣿⢿⣻⢻⢽⣹⢹⢸⠸⢘⠘⠨⢈⠈⠐⠠⢀" |> String.graphemes()
def with_spinner(name, fun, opts \\ []) do
if opts[:verbose?] do
Mix.shell().info(name <> ":")
result = fun.()
Mix.shell().info(name <> ": " <> "#{IO.ANSI.green()}#{IO.ANSI.reset()}")
result
else
shell = Mix.shell()
# I don't understand why I have to do this
if !Code.ensure_loaded?(Mix.Shell.ActuallyQuiet) do
Code.eval_quoted(
quote do
defmodule Mix.Shell.ActuallyQuiet do
@behaviour Mix.Shell
def print_app, do: :ok
def info(_message), do: :ok
def error(_message), do: :ok
def prompt(_message), do: :ok
def yes?(_message, _options \\ []), do: :ok
def cmd(command, opts \\ []) do
Mix.Shell.cmd(command, opts, fn data -> data end)
end
end
end
)
end
{:ok, _} = Igniter.Installer.CaptureServer.start_link([])
loader =
if shell == Mix.Shell.IO do
spawn_loader(name)
end
Mix.shell(Mix.Shell.ActuallyQuiet)
{:ok, ref} =
Igniter.Installer.CaptureServer.device_capture_on(:standard_error, :unicode, "")
try do
fun.()
rescue
e ->
IO.puts(Igniter.Installer.CaptureServer.device_output(:standard_error, ref))
reraise e, __STACKTRACE__
after
if shell == Mix.Shell.IO do
loader_ref = make_ref()
send(loader, {:stop, self(), loader_ref})
receive do
{:loader_stopped, ^loader_ref} ->
nil
after
500 ->
:ok
end
end
Mix.shell(shell)
Igniter.Installer.CaptureServer.device_capture_off(ref)
GenServer.stop(Igniter.Installer.CaptureServer)
end
end
end
def spawn_loader(task_name) do
spawn_link(fn ->
@spinners
|> Stream.cycle()
|> Stream.map(fn next ->
receive do
{:stop, pid, ref} ->
IO.puts("\r\e[K" <> task_name <> " " <> "#{IO.ANSI.green()}#{IO.ANSI.reset()}")
send(pid, {:loader_stopped, ref})
exit(:normal)
after
0 ->
IO.write("\r\e[K" <> task_name <> " " <> next)
:timer.sleep(50)
end
end)
|> Stream.run()
end)
end
end