defmodule Mix.Tasks.Lvn.Gen.Live do use Mix.Task alias Mix.LiveViewNative.Context @shortdoc "Generates a new format specific LiveView render component and template" @moduledoc """ #{@shortdoc} $ mix lvn.gen.live swiftui Home """ @impl true @doc false def run(args) do if Mix.Project.umbrella?() do Mix.raise( "mix lvn.gen.live must be invoked from within your *_web application root directory" ) end context = Context.build(args, __MODULE__) files = files_to_be_generated(context) Context.prompt_for_conflicts(files) copy_new_files(context, files) end @doc false def switches, do: [ context_app: :string, web: :string ] @doc false def validate_args!([format, live_view_module| _] = args) do cond do not Context.valid_format?(format) -> formats = LiveViewNative.available_formats() |> Enum.map(&("* #{&1}")) |> Enum.join("\n") Mix.raise(""" #{format} is an unregistered format. Available formats: #{formats} Please see the documentation for how to register new LiveView Native plugins """) not Context.valid_module?(live_view_module) -> Mix.raise(""" Expected "#{live_view_module}", to be a valid module name """) true -> args end end @doc false def validate_args!(_) do formats = LiveViewNative.available_formats() |> Enum.map(&("* #{&1}")) |> Enum.join("\n") Mix.raise(""" You must pass a valid format and the name of the parent LiveView module. Available formats: #{formats} Example: mix lvn.gen.live swiftui Home """) end defp files_to_be_generated(%Context{format: format, schema_module: schema_module, context_app: context_app}) do web_prefix = Mix.Phoenix.web_path(context_app) name = Module.concat([inspect(schema_module) <> "Live"]) |> Macro.underscore() live_path = Path.join(web_prefix, "live") live_format_path = Path.join(live_path, "#{format}") [ {:eex, "live.ex", Path.join(live_path, "#{name}.#{format}.ex")}, {:eex, "template.neex", Path.join(live_format_path, "#{name}.#{format}.neex")} ] end defp copy_new_files(%Context{} = context, files) do binding = [ context: context, assigns: %{ gettext: true } ] apps = Context.apps(context.format) Mix.Phoenix.copy_from(apps, "priv/templates/lvn.gen.live", binding, files) context end end