Skip to content

Instantly share code, notes, and snippets.

@rvcas
Last active August 4, 2017 11:36
Show Gist options
  • Save rvcas/828595c22feb47b832765a47a2aa1bc0 to your computer and use it in GitHub Desktop.
Save rvcas/828595c22feb47b832765a47a2aa1bc0 to your computer and use it in GitHub Desktop.
Concurrently counts how many files reference a certain word at least once in the sub folders of the Rails app folder
#!/usr/local/bin/elixir
import IO.ANSI, only: [yellow: 0, light_magenta: 0, light_cyan: 0]
defmodule Counter do
use GenServer
@cmd "rg"
def start do
GenServer.start(__MODULE__, [])
end
def count_and_format(pid, dir, word) do
GenServer.cast(pid, {:count_and_format, dir, word})
end
def handle_cast({:count_and_format, dir, word}, _state) do
IO.puts "#{light_magenta()}#{dir}: #{light_cyan()}#{count(dir, word)}"
{:stop, :done, []}
end
defp count(dir, word) when is_binary(dir) do
@cmd
|> System.cmd(["-l", word, dir])
|> get_str()
|> String.split("\n")
|> Enum.count
end
def get_str({str, _}), do: str
end
defmodule Count do
@dirs [
"app/assets",
"app/controllers",
"app/datatubes",
"app/helpers",
"app/mailers",
"app/models",
"app/presenters",
"app/services",
"app/views",
"app/workers"
]
def refs(word) when is_binary(word) do
IO.puts """
#{yellow()}Number of files with references to "#{word}"
--------------------------------------------
"""
@dirs
|> Enum.map(fn dir ->
{:ok, pid} = Counter.start
Counter.count_and_format(pid, dir, word)
pid
end)
|> wait
end
defp wait([]), do: []
defp wait(pids) do
pids
|> Enum.map(&({Process.alive?(&1), &1}))
|> Enum.filter(fn {alive, _pid} -> alive == true end)
|> Enum.map(fn {_bool, pid} -> pid end)
|> wait
end
end
[word | _] = System.argv()
Count.refs word
@rvcas
Copy link
Author

rvcas commented Jun 9, 2017

Rust + Elixir in action

This uses ripgrep to do the file searching.

usage:

$ chmod +x count.exs
$ ./count.exs `word_to_search`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment