Skip to content

Commit ac9a659

Browse files
committed
Reset ansi escapes before newlines in Logger
Closes #14855 Closes #14841
1 parent cc5837c commit ac9a659

File tree

5 files changed

+79
-50
lines changed

5 files changed

+79
-50
lines changed

lib/ex_unit/test/ex_unit/capture_log_test.exs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ defmodule ExUnit.CaptureLogTest do
7070
end)
7171

7272
assert logged
73-
assert logged =~ "[info] one\n"
74-
assert logged =~ "[warning] two\n"
75-
assert logged =~ "[debug] three\n"
76-
assert logged =~ "[error] one\n"
73+
assert logged =~ "[info] one"
74+
assert logged =~ "[warning] two"
75+
assert logged =~ "[debug] three"
76+
assert logged =~ "[error] one"
7777

7878
receive do
7979
{:nested, logged} ->
80-
assert logged =~ "[error] one\n"
81-
refute logged =~ "[warning] two\n"
80+
assert logged =~ "[error] one"
81+
refute logged =~ "[warning] two"
8282
end
8383
end
8484

lib/ex_unit/test/ex_unit_test.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,9 @@ defmodule ExUnitTest do
375375
end
376376

377377
output = capture_io(&ExUnit.run/0)
378-
refute output =~ "[debug] one\n"
379-
assert output =~ "[debug] two\n"
380-
assert output =~ "[debug] three\n"
378+
refute output =~ "[debug] one"
379+
assert output =~ "[debug] two"
380+
assert output =~ "[debug] three"
381381
end
382382

383383
test "supports multi errors" do

lib/logger/lib/logger/formatter.ex

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,20 @@ defmodule Logger.Formatter do
244244
case if(is_function(enabled, 0), do: enabled.(), else: enabled) do
245245
true ->
246246
color = md[:ansi_color] || Map.fetch!(colors, level)
247-
[IO.ANSI.format_fragment(color, true), data | IO.ANSI.reset()]
247+
fragment = IO.ANSI.format_fragment(color, true)
248+
data = IO.iodata_to_binary(data)
249+
size = byte_size(data)
250+
251+
cond do
252+
:binary.at(data, size - 2) == ?\r and :binary.at(data, size - 1) == ?\n ->
253+
[fragment, binary_part(data, 0, size - 2), IO.ANSI.reset() | "\r\n"]
254+
255+
:binary.at(data, size - 1) == ?\n ->
256+
[fragment, binary_part(data, 0, size - 1), IO.ANSI.reset(), ?\n]
257+
258+
true ->
259+
[fragment, data | IO.ANSI.reset()]
260+
end
248261

249262
false ->
250263
data

lib/logger/test/logger/formatter_test.exs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,26 @@ defmodule Logger.FormatterTest do
9797
|> format(formatter)
9898
|> IO.chardata_to_string() =~ ~r"\d\d\d message"
9999
end
100+
101+
test "handles colorize with newlines" do
102+
{_, formatter} =
103+
new(
104+
format: "$message",
105+
colors: [enabled: true]
106+
)
107+
108+
assert %{level: :warning, msg: {:string, "message"}, meta: %{}}
109+
|> format(formatter)
110+
|> IO.chardata_to_string() == "\e[33mmessage\e[0m"
111+
112+
assert %{level: :warning, msg: {:string, "message\n"}, meta: %{}}
113+
|> format(formatter)
114+
|> IO.chardata_to_string() == "\e[33mmessage\e[0m\n"
115+
116+
assert %{level: :warning, msg: {:string, "message\r\n"}, meta: %{}}
117+
|> format(formatter)
118+
|> IO.chardata_to_string() == "\e[33mmessage\e[0m\r\n"
119+
end
100120
end
101121

102122
describe "compile + format" do

0 commit comments

Comments
 (0)