defmodule Mix.Tasks.Template.Hex do
use Private
@moduledoc(
Path.join([__DIR__, "../../../README.md"])
|> File.read!
|> String.replace(~r/\A.*^### Use\w+/ms, "")
|> String.replace(~r/^###.*/ms, ""))
def run(_) do
Mix.Hex.start()
"gen_template"
|> search()
|> extract_stuff_we_need()
|> display_results()
end
private do
defp extract_stuff_we_need({:ok, response}) do
extract_stuff_we_need(response)
end
defp extract_stuff_we_need({:error, term}) do
Mix.raise "error #{inspect(term)} while searching hex packages"
end
defp extract_stuff_we_need({200, content, _}) do
content
|> Enum.filter(&is_a_template?/1)
end
defp extract_stuff_we_need({error, _, _}) do
Mix.raise "error #{error} while searching hex packages"
end
defp is_a_template?(%{ "name" => name }) do
name |> String.starts_with?("gen_template_")
end
defp display_results([]) do
Mix.shell.info "Strange... no templates found on hex.pm"
end
defp display_results(results) do
Mix.shell.info(["\n", :underline, "Templates on hex.pm", :reset, "\n"])
results |> Enum.each(&display_a_result/1)
Mix.shell.info("Install a template using `mix template.install «name»`\n")
end
defp display_a_result(%{ "name" => name,
"meta" => %{
"description" => description
}}) do
Mix.shell.info([:bright, :green, name,
:reset, ":\n",
indent(description)])
end
defp indent(string) do
" #{String.replace(string, "\n", "\n ") |> String.trim_trailing}\n"
end
# hex changed the internal API in fall 2017, so we have to deal with both
require Hex.API.Package
cond do
function_exported?(Hex.API.Package, :search, 1) ->
defdelegate search(package), to: Hex.API.Package
function_exported?(Hex.API.Package, :search, 2) ->
defp search(package) do
# url = Hex.State.fetch!(:api_url) <> "/"
Hex.API.Package.search(nil, package)
end
true ->
raise "Can't find Hex.API.Package.search/1 or /2"
end
end
end