Current section

Files

Jump to
doggo lib mix tasks dog.classes.ex
Raw

lib/mix/tasks/dog.classes.ex

defmodule Mix.Tasks.Dog.Classes do
@shortdoc "Lists all component classes"
@moduledoc """
Returns a list of all component classes.
## Usage
List all component classes:
mix dog.classes -m MyAppWeb.CoreComponents
Write classes to file:
mix dog.classes -m MyAppWeb.CoreComponents -o assets/classes.txt
Check whether a file is up-to-date:
mix dog.classes -m MyAppWeb.CoreComponents -o assets/classes.txt --check
"""
use Mix.Task
@parser_opts [
aliases: [m: :module, o: :output],
strict: [module: :string, output: :string, check: :boolean]
]
@requirements ["app.config"]
@impl Mix.Task
def run(args) do
with {switches, [], []} <- OptionParser.parse(args, @parser_opts),
{:ok, module} <- Keyword.fetch(switches, :module) do
path = Keyword.get(switches, :output)
check = Keyword.get(switches, :check, false)
cond do
is_nil(path) -> print_classes(module)
check -> check_file(path, module)
true -> write_file(path, module)
end
else
_ ->
IO.puts(@moduledoc)
end
end
defp list_classes(module) do
[module]
|> Module.safe_concat()
|> Doggo.classes()
|> Enum.join("\n")
end
defp print_classes(module) do
module
|> list_classes()
|> IO.puts()
end
defp write_file(path, module) do
content = file_content(path, module)
File.write(path, content)
end
defp check_file(path, module) do
existing_content = File.read!(path)
expected_content = file_content(path, module)
relative_path = Path.relative_to_cwd(path)
if existing_content == expected_content do
IO.puts("The file '#{relative_path}' is up to date.")
else
IO.puts("""
The file '#{relative_path}' is out of date.
To update the file, run:
mix dog.classes -m #{module} -o #{relative_path}
""")
exit({:shutdown, 1})
end
end
defp file_content(path, module) do
file_header = file_header(path, module)
classes = list_classes(module)
file_header <> classes
end
defp file_header(path, module) do
"""
# This file was automatically generated by running:
# mix dog.classes -m #{module} -o #{path}
"""
end
end