2022-10-17 13:37:24 +13:00
|
|
|
defmodule Mix.Tasks.Ash.GenerateResourceDiagrams do
|
|
|
|
@moduledoc """
|
|
|
|
Generates a Mermaid Resource Diagram for each Ash API.
|
|
|
|
|
|
|
|
## Prerequisites
|
|
|
|
|
|
|
|
This mix task requires the Mermaid CLI to be installed on your system.
|
|
|
|
|
|
|
|
See https://github.com/mermaid-js/mermaid-cli
|
|
|
|
|
|
|
|
## Command line options
|
|
|
|
|
|
|
|
* `--type` - `er` or `class` (defaults to `class`)
|
|
|
|
* `--only` - only generates the given API file
|
2022-10-25 02:55:05 +13:00
|
|
|
* `--format` - Can be set to one of either:
|
|
|
|
* `plain` - Prints just the mermaid output as text. This is the default.
|
|
|
|
* `md` - Prints the mermaid diagram in a markdown code block.
|
|
|
|
* `svg` - Generates an SVG
|
|
|
|
* `pdf` - Generates a PDF
|
|
|
|
* `png` - Generates a PNG
|
2022-10-17 13:37:24 +13:00
|
|
|
|
|
|
|
"""
|
|
|
|
use Mix.Task
|
|
|
|
|
2023-02-21 07:26:17 +13:00
|
|
|
@recursive true
|
|
|
|
|
2022-10-17 13:37:24 +13:00
|
|
|
@shortdoc "Generates Mermaid Resource Diagrams for each Ash API"
|
|
|
|
def run(argv) do
|
|
|
|
Mix.Task.run("compile")
|
|
|
|
|
|
|
|
{opts, _} =
|
|
|
|
OptionParser.parse!(argv,
|
2022-10-25 02:55:05 +13:00
|
|
|
strict: [only: :keep, type: :string, format: :string],
|
|
|
|
aliases: [o: :only, t: :type, f: :format]
|
2022-10-17 13:37:24 +13:00
|
|
|
)
|
|
|
|
|
|
|
|
only =
|
|
|
|
if opts[:only] && opts[:only] != [] do
|
|
|
|
Enum.map(List.wrap(opts[:only]), &Path.expand/1)
|
|
|
|
end
|
|
|
|
|
2022-10-25 02:55:05 +13:00
|
|
|
format = Keyword.get(opts, :format, "plain")
|
|
|
|
|
2022-10-17 13:37:24 +13:00
|
|
|
apis()
|
|
|
|
|> Task.async_stream(
|
|
|
|
fn api ->
|
|
|
|
source = api.module_info(:compile)[:source]
|
|
|
|
|
|
|
|
if is_nil(only) || Path.expand(source) in only do
|
|
|
|
case Keyword.get(opts, :type, "class") do
|
|
|
|
"er" ->
|
2022-10-25 02:55:05 +13:00
|
|
|
Mix.Mermaid.generate_diagram(
|
|
|
|
source,
|
|
|
|
"mermaid-er-diagram",
|
|
|
|
format,
|
|
|
|
Ash.Api.Info.Diagram.mermaid_er_diagram(api),
|
|
|
|
"Generated ER Diagram for #{inspect(api)}"
|
|
|
|
)
|
2022-10-17 13:37:24 +13:00
|
|
|
|
|
|
|
"class" ->
|
2022-10-25 02:55:05 +13:00
|
|
|
Mix.Mermaid.generate_diagram(
|
|
|
|
source,
|
|
|
|
"mermaid-class-diagram",
|
|
|
|
format,
|
|
|
|
Ash.Api.Info.Diagram.mermaid_class_diagram(api),
|
|
|
|
"Generated Class Diagram for #{inspect(api)}"
|
|
|
|
)
|
2022-10-17 13:37:24 +13:00
|
|
|
|
|
|
|
type ->
|
|
|
|
Mix.shell().error("""
|
|
|
|
Invalid resource diagram type `#{type}`.
|
|
|
|
|
|
|
|
Valid options are `er` or `class`.
|
|
|
|
""")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
timeout: :infinity
|
|
|
|
)
|
|
|
|
|> Stream.run()
|
|
|
|
end
|
|
|
|
|
|
|
|
defp apis do
|
|
|
|
Mix.Project.config()[:app]
|
|
|
|
|> Application.get_env(:ash_apis, [])
|
|
|
|
end
|
|
|
|
end
|