defmodule Mix.Tasks.PermitEx.Install do @moduledoc """ Installs PermitEx migrations into the host application. mix permit_ex.install mix permit_ex.install --migrations-path priv/repo/migrations """ use Mix.Task @shortdoc "Copies PermitEx migrations" @switches [migrations_path: :string] @impl Mix.Task def run(args) do Mix.Project.get!() {opts, _} = OptionParser.parse!(args, strict: @switches) target_dir = Keyword.get(opts, :migrations_path, Path.join(["priv", "repo", "migrations"])) File.mkdir_p!(target_dir) case existing_migration(target_dir) do {:ok, path} -> Mix.shell().info("Migration already exists: #{path}") :none -> path = write_migration(target_dir) Mix.shell().info("Created #{path}") Mix.shell().info("Run `mix ecto.migrate` to apply it.") end end defp existing_migration(dir) do case Path.wildcard(Path.join(dir, "*_create_permit_ex_tables.exs")) do [path | _] -> {:ok, path} [] -> :none end end defp write_migration(dir) do filename = "#{timestamp()}_create_permit_ex_tables.exs" path = Path.join(dir, filename) module = "CreatePermitExTables" contents = template_path() |> File.read!() |> EEx.eval_string(module: module) File.write!(path, contents) Mix.Task.run("format", [path]) path end defp template_path do :permit_ex |> :code.priv_dir() |> to_string() |> Path.join("templates/create_permit_ex_tables.exs") end defp timestamp do {{year, month, day}, {hour, minute, second}} = :calendar.universal_time() [year, month, day, hour, minute, second] |> Enum.map_join(&(&1 |> Integer.to_string() |> String.pad_leading(2, "0"))) end end