mix-test.watch
mix-test.watch copied to clipboard
Is it possible to make a logger output colorful like in `mix test`?
defmodule Test do
use ExUnit.Case
require Logger
test "color" do
Logger.warn "warn"
Logger.error "error"
end
end
Huh, interesting. I thought it would have been coloured. Thanks for the report.
You can also see this happening if you run the dialyzer
task from here: https://github.com/jeremyjh/dialyxir.
Running the task on its own produces colored output, whereas using test.watch removes the colors.
Interestingly, as shown in the screenshots above, not ALL colors are removed, just some...
Without watch:
With watch:
It's a lot easier to see the green "done" vs red errors with a quick glance. Without "done" being green it's harder to see that everything passed.
@lpil gentle bump, any news on this?
Hi @shawarmaz , I am busy working on Gleam I'm afraid!
This fixed all color issues for me:
config :mix_test_watch,
cli_executable: "elixir --erl \"-elixir ansi_enabled true\" -S mix"
The root of the issue was whether ANSI escapes are enabled or not. Elixir configures this automatically based on whether stdout and stderr are attached to ttys or not (unless it has already been configured, but more on that later). This helps https://github.com/lpil/mix-test.watch/blob/f5235c247520b132d50994efd9bca40ce62d312e/lib/mix_test_watch/port_runner/port_runner.ex#L44 for things that query the config after it has ran, for example, test dots being green or not. But it does not help for things that already queried it before it ran and don't check again. Notably, Logger starts before it gets updated which causes its formatter's color's enabled key to be false, resulting in dreary Logger logs.
The fix works by using elixir
instead of mix
as the initial command so we can use --erl
to pass a user flag to Erlang. In particular, it is passing -Application Par Val
as -elixir ansi_enabled true
. This causes that value to be set in the application env before any applications are started (preventing Elixir from automatically configuring it to false in this case). So when Logger eventually does start, the value is true already, instead of it still being false because the port runner update hasn't had a chance to run yet.