Current section

Files

Jump to
sayfa lib mix tasks sayfa.gen.block.ex
Raw

lib/mix/tasks/sayfa.gen.block.ex

defmodule Mix.Tasks.Sayfa.Gen.Block do
@moduledoc """
Generates a custom block module scaffold.
## Usage
mix sayfa.gen.block ModuleName
## Examples
mix sayfa.gen.block MyBanner
mix sayfa.gen.block MyApp.Blocks.Banner
The last segment of the module name is used to derive the block name and file name.
For example, `MyApp.Blocks.Banner` produces `lib/blocks/banner.ex` with block name `:banner`.
## After generation
Register your block in `config/config.exs`:
config :sayfa, :blocks, [MyApp.Blocks.MyBanner | Sayfa.Block.default_blocks()]
"""
use Mix.Task
@shortdoc "Scaffold a custom block module"
@impl Mix.Task
def run([module_name | _]) do
last_segment = module_name |> String.split(".") |> List.last()
block_name = to_snake_case(last_segment)
file_path = Path.join(["lib", "blocks", "#{block_name}.ex"])
if File.exists?(file_path) do
Mix.shell().error("File already exists: #{file_path}")
exit({:shutdown, 1})
end
template_path =
Path.join([to_string(:code.priv_dir(:sayfa)), "templates", "gen_block", "block.ex.eex"])
content =
EEx.eval_file(template_path,
assigns: [module_name: module_name, block_name: block_name]
)
File.mkdir_p!(Path.dirname(file_path))
File.write!(file_path, content)
Mix.shell().info("#{IO.ANSI.green()}Created#{IO.ANSI.reset()} #{file_path}")
Mix.shell().info("")
Mix.shell().info("Register your block in config/config.exs:")
Mix.shell().info("")
Mix.shell().info(
" config :sayfa, :blocks, [#{module_name} | Sayfa.Block.default_blocks()]"
)
end
def run([]) do
Mix.shell().error("Usage: mix sayfa.gen.block ModuleName")
exit({:shutdown, 1})
end
defp to_snake_case(name) do
name
|> String.replace(~r/([A-Z]+)([A-Z][a-z])/, "\\1_\\2")
|> String.replace(~r/([a-z\d])([A-Z])/, "\\1_\\2")
|> String.downcase()
end
end