Skip to content

Instantly share code, notes, and snippets.

@garthk
Created March 12, 2020 04:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save garthk/daf61aaf3d68d5d0fdb8c9504a77cac8 to your computer and use it in GitHub Desktop.
Save garthk/daf61aaf3d68d5d0fdb8c9504a77cac8 to your computer and use it in GitHub Desktop.
Find Emoji in git log output using Elixir
#! /usr/bin/env elixir
defmodule FindEmoji do
def find_emoji_in_git_log do
:ok =
stream_executable("git", ["log"])
|> Stream.filter(&contains_emoji?/1)
|> Stream.each(&IO.puts/1)
|> Stream.run()
end
defp contains_emoji?(string) do
string
|> String.graphemes()
|> Enum.map(&byte_size/1)
|> Enum.find_value(false, fn size -> size > 1 end)
end
defp stream_executable(cmd, args) when is_binary(cmd) and is_list(args) do
Stream.resource(
fn ->
filename = System.find_executable(cmd)
port =
Port.open({:spawn_executable, filename}, [
:stderr_to_stdout,
:exit_status,
:binary,
line: 1024,
args: args
])
{port, []}
end,
&se_next_fun/1,
&se_after_fun/1
)
end
defp se_next_fun({nil, status}) when is_integer(status), do: {:halt, status}
defp se_next_fun({port, acc}) when is_port(port) and is_list(acc) do
receive do
{^port, {:data, {:noeol, chunk}}} -> {[], {port, [acc, chunk]}}
{^port, {:data, {:eol, chunk}}} -> {[IO.iodata_to_binary([acc, chunk])], {port, []}}
{^port, {:exit_status, status}} -> {[IO.iodata_to_binary(acc)], {nil, status}}
end
end
defp se_after_fun(0), do: nil
defp se_after_fun(status) when is_integer(status), do: IO.warn("exit code #{status}")
end
FindEmoji.find_emoji_in_git_log()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment