defmodule Mix.Tasks.Continuum.Gen.Workflow do @moduledoc """ Generates a Continuum workflow module. mix continuum.gen.workflow MyApp.OrderFlow mix continuum.gen.workflow MyApp.OrderFlow --path lib The generated module uses `Continuum.Workflow` and starts with a minimal deterministic `run/1` function. """ use Mix.Task @shortdoc "Generates a Continuum workflow module" @impl true def run(args) do {opts, argv, _} = OptionParser.parse(args, switches: [path: :string]) module = parse_module!(argv) root = Keyword.get(opts, :path, "lib") file = Path.join([File.cwd!(), root, module_file(module)]) if File.exists?(file), do: Mix.raise("#{Path.relative_to_cwd(file)} already exists") File.mkdir_p!(Path.dirname(file)) File.write!(file, source(module)) Mix.shell().info("Created #{Path.relative_to_cwd(file)}") end defp parse_module!([module_name]) do Module.concat([module_name]) rescue ArgumentError -> Mix.raise("expected a valid module name, got: #{inspect(module_name)}") end defp parse_module!(_argv) do Mix.raise("usage: mix continuum.gen.workflow MyApp.OrderFlow") end defp module_file(module) do module |> Module.split() |> Enum.map_join("/", &Macro.underscore/1) |> Kernel.<>(".ex") end defp source(module) do """ defmodule #{inspect(module)} do use Continuum.Workflow, version: 1 def run(input) do {:ok, input} end end """ end end