Packages

A comprehensive library for working with both static and dynamic enum structures in Elixir.

Current section

Files

Jump to
enumex lib mix tasks enumex.static.gen.migration.new.ex
Raw

lib/mix/tasks/enumex.static.gen.migration.new.ex

# credo:disable-for-next-line Credo.Check.Refactor.ModuleDependencies
defmodule Mix.Tasks.Enumex.Static.Gen.Migration.New do
@shortdoc "Generates a migration for creating new database enum"
args = [
%{help: "Specifies an enum module", required: true, value_name: "MODULE"},
%{help: "Specifies an enum name", required: true, value_name: "ENUM_NAME"}
]
flags = [
%{help: "Specifies an enum adapter", long: "--adapter", short: "-a", value_name: "ADAPTER"},
%{
help: "Specifies a query prefix",
long: "--query-prefix",
short: "-q",
value_name: "QUERY_PREFIX"
}
]
task = Enumex.Generator.Task.new("enumex.static.gen.migration.new", args, flags)
if Mix.env() == :test do
try do
:meck.new(:io, [:unstick, :passthrough])
rescue
_exception -> :ok
end
:meck.expect(:io, :columns, fn -> {:ok, 80} end)
end
help = Enumex.Generator.Task.help(task, @shortdoc, true)
@moduledoc Enumex.Generator.Task.moduledoc(help)
use Mix.Task
alias Enumex.Generator.Task
alias Enumex.Static.Adapter
alias Enumex.Static.Components
alias Enumex.Value
alias Mix.Generator
alias Mix.Tasks.Ecto.Gen.Migration
require Generator
@help help
@opts [
aliases: Task.aliases(~w[adapter query_prefix]a),
return_separator: true,
strict: Task.options(adapter: :string, query_prefix: :string)
]
@task_name task.name
@version Task.version(task)
@impl Mix.Task
def run(args), do: Task.static_migration_run(@task_name, args, @help, @version, @opts, &run/4)
@spec run(
[Value.enum_module() | Value.enum_name()],
[query_prefix: Adapter.query_prefix()],
Adapter.t(),
OptionParser.argv()
) :: :ok | any()
defp run([_module], _opts, _adapter, []) do
Task.missing_args(@task_name, ~w[ENUM_NAME ECTO_GEN_MIGRATION_ARGS])
end
defp run([_module], _opts, _adapter, _ecto_args) do
Task.missing_args(@task_name, ~w[ENUM_NAME])
end
defp run([_module, _name], _opts, _adapter, []) do
Task.missing_args(@task_name, ~w[ECTO_GEN_MIGRATION_ARGS])
end
defp run([module, name], opts, adapter, ecto_args) do
if {:behaviour, [Components.List]} in module.__info__(:attributes) do
name
|> module.list()
|> Enum.map_join(",\n ", &Task.gen_value_from_template(value: &1))
|> then(
&changes_template(adapter: adapter, module: module, prefix: opts[:query_prefix], values: &1)
)
|> String.trim_trailing()
# credo:disable-for-next-line Credo.Check.Refactor.Apply
|> then(&apply(Migration, :run, [["--change", &1 | ecto_args]]))
else
Task.behaviour_not_implemented(@task_name, module, Components.List)
end
end
@spec run(
[Value.enum_module() | Value.enum_name() | String.t()],
[query_prefix: Adapter.query_prefix()],
Adapter.t(),
OptionParser.argv()
) :: :ok | any()
defp run([_enum_module, _enum_name | args], _enum_opts, _adapter, ecto_args) do
Task.static_migration_invalid_args(@task_name, args, ecto_args)
end
@spec changes_template(
adapter: Adapter.t(),
module: Value.enum_module(),
prefix: Adapter.query_prefix(),
values: String.t()
) :: String.t()
Generator.embed_template(:changes, """
alias Enumex.Static.Migration
alias Enumex.Value
alias <%= inspect(@module) %>
adapter = <%= inspect(@adapter) %>
values = [
<%= @values %>
]
Migration.create_enum(adapter, values<%= @prefix && ", query_prefix: " <> inspect(@prefix) %>)
""")
end