-
-
Save bryanhuntesl/2605c712d261e184e45b6299c13280a6 to your computer and use it in GitHub Desktop.
elixir diff(extracted from ExUnit code)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Diff do | |
def diff(left, right, %{diff_type: :cli} = config) do | |
# %{enabled: true} | |
Diff.Cli.diff(left, right, config) | |
end | |
def format_sides(left, right, formatter) do | |
case format_diff(left, right, formatter) do | |
{left, right} -> | |
{IO.iodata_to_binary(left), IO.iodata_to_binary(right)} | |
nil -> | |
{left, right} | |
end | |
end | |
defp format_diff(left, right, formatter) do | |
if left && right && formatter.(:diff_enabled?, false) do | |
if script = edit_script(left, right) do | |
colorize_diff(script, formatter, {[], []}) | |
end | |
end | |
end | |
defp colorize_diff(script, formatter, acc) when is_list(script) do | |
Enum.reduce(script, acc, &colorize_diff(&1, formatter, &2)) | |
end | |
defp colorize_diff({:eq, content}, _formatter, {left, right}) do | |
{[left | content], [right | content]} | |
end | |
defp colorize_diff({:del, content}, formatter, {left, right}) do | |
format = colorize_format(content, :diff_delete, :diff_delete_whitespace) | |
{[left | formatter.(format, content)], right} | |
end | |
defp colorize_diff({:ins, content}, formatter, {left, right}) do | |
format = colorize_format(content, :diff_insert, :diff_insert_whitespace) | |
{left, [right | formatter.(format, content)]} | |
end | |
defp colorize_format(content, normal, whitespace) do | |
if String.trim_leading(content) == "", do: whitespace, else: normal | |
end | |
defp edit_script(left, right) do | |
task = Task.async(ExUnit.Diff, :script, [left, right]) | |
case Task.yield(task, 1500) || Task.shutdown(task, :brutal_kill) do | |
{:ok, script} -> script | |
nil -> nil | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Diff.Cli do | |
def diff(left, right, config) do | |
formatter = &formatter(&1, &2, config) | |
Diff.format_sides(left, right, formatter) | |
end | |
defp formatter(:diff_enabled?, _, %{enabled: enabled}), do: enabled | |
defp formatter(:diff_delete, msg, config), do: colorize(:red, msg, config) | |
defp formatter(:diff_delete_whitespace, msg, config), | |
do: colorize(IO.ANSI.color_background(2, 0, 0), msg, config) | |
defp formatter(:diff_insert, msg, config), do: colorize(:green, msg, config) | |
defp formatter(:diff_insert_whitespace, msg, config), | |
do: colorize(IO.ANSI.color_background(0, 2, 0), msg, config) | |
defp formatter(_, msg, _config), do: msg | |
defp colorize(escape, string, %{enabled: enabled}) do | |
if enabled do | |
[escape, string, :reset] | |
|> IO.ANSI.format_fragment(true) | |
|> IO.iodata_to_binary() | |
else | |
string | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
m1 = %{a: %{b: 1}} | |
m2 = %{a: %{b: 2}} | |
Diff.diff(m1, m2, %{diff_type: :cli, enabled: true}) | |
{"%{a: %{b: \e[31m1\e[0m}}", "%{a: %{b: \e[32m2\e[0m}}"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment