defmodule Mix.Tasks.Moon.Gen.Component do
@shortdoc "Generates component and page"
@moduledoc """
Generates a component and a component page by component module name given
$ mix moon.gen.component Form.MyModule
"""
use Mix.Task
import Mix.Generator
import String, only: [replace: 3, downcase: 1, split: 2]
import Enum, only: [reverse: 1, join: 2]
import List, only: [last: 1]
defstruct name: nil,
path: nil
@doc false
def run([name]) do
name |> context() |> copy_templates() |> print_shell_instructions()
end
defp context(name) do
%{
name: name,
path: name |> replace(~r/([a-z])([A-Z])/, "\\1_\\2") |> downcase() |> replace(".", "/"),
short: name |> split(".") |> last()
}
end
defp pathes(%{path: path}) do
[
component: "lib/moon/design/#{path}.ex",
page: "lib/moon_web/pages/design/#{path}_page.ex",
example: "lib/moon_web/examples/design/#{path}_example/default.ex"
]
end
defp copy_templates(context) do
Enum.each(pathes(context), fn {template, file_path} ->
file_path |> split("/") |> reverse() |> tl() |> reverse() |> join("/") |> create_directory()
data =
EEx.eval_file(
"priv/templates/moon.gen.component/#{template}.ex",
Enum.map(context, fn {key, value} -> {key, value} end)
)
create_file(file_path, data, force: false)
end)
context
end
def print_shell_instructions(%{path: path, name: name}) do
Mix.shell().info("""
Add the resource to your lib/moon_web/router.ex
live("/components/v2/#{path}", MoonWeb.Pages.Design.#{name}Page)
And following to your lib/moon_web/schema/link.ex
MoonWeb.Pages.Design.#{name}Page
""")
end
end