defmodule Mix.Tasks.Boruta.Gen.Migration do
@moduledoc """
Migration task for Boruta.
Creates `oauth_clients`, `oauth_scopes` and `oauth_tokens` tables.
> __Note__: This task will create migration files to keep your integration up to date by checking migration file and module names to create missing ones.
> Thus it is not recommended to change naming since it will recreate the migration in further runs.
## Usage statistics gathering
This task will trigger a REPL to gather statistical info from your usage of the library. The owners are thankful to you for providing those informations since it helps better maintain the product.
## Examples
```
mix boruta.gen.migration
```
"""
use Mix.Task
import Mix.Generator
import Mix.Ecto
import Mix.EctoSQL
@shortdoc "Generates Boruta migrations"
@doc false
def run(args) do
no_umbrella!("boruta.gen.migration")
repos = parse_repo(args)
Enum.map(repos, fn repo ->
ensure_repo(repo, args)
{:ok, migration_paths} =
:code.priv_dir(:boruta)
|> Path.join("boruta/migrations")
|> File.ls()
migration_paths
|> Enum.sort()
|> Enum.with_index()
|> Enum.map(&create_migration_file(repo, &1))
end)
end
defp create_migration_file(repo, {original_path, index}) do
filename = Path.basename(original_path, ".ex")
[_filename, basename] = Regex.run(~r/\d{14}_(.+)/, filename)
migration_name = Macro.camelize(basename)
timestamp = DateTime.utc_now() |> DateTime.add(index) |> Calendar.strftime("%Y%m%d%H%M%S")
path = Path.join(source_repo_priv(repo), "migrations")
file = Path.join(path, "#{timestamp}_#{basename}.exs")
assigns = [
mod: Module.concat([repo, Migrations, migration_name]),
migration_name: migration_name
]
fuzzy_path = Path.join(path, "*_#{basename}.exs")
if Enum.empty?(Path.wildcard(fuzzy_path)) do
create_file(file, migration_template(assigns))
end
end
defp migration_module do
case Application.get_env(:ecto_sql, :migration_module, Ecto.Migration) do
migration_module when is_atom(migration_module) -> migration_module
other -> Mix.raise("Expected :migration_module to be a module, got: #{inspect(other)}")
end
end
embed_template(:migration, """
defmodule <%= inspect @mod %> do
use <%= inspect migration_module() %>
use Boruta.Migrations.<%= @migration_name %>
end
""")
end