-
-
Save rmoorman/ee0624da64cf425736342fc97be1c919 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