ash_sqlite/lib/mix/helpers.ex

133 lines
3.3 KiB
Elixir
Raw Normal View History

defmodule AshSqlite.Mix.Helpers do
2023-09-23 14:52:22 +12:00
@moduledoc false
def domains!(opts, args) do
2023-09-23 14:52:22 +12:00
apps =
if apps_paths = Mix.Project.apps_paths() do
apps_paths |> Map.keys() |> Enum.sort()
else
[Mix.Project.config()[:app]]
end
configured_domains = Enum.flat_map(apps, &Application.get_env(&1, :ash_domains, []))
2023-09-23 14:52:22 +12:00
domains =
if opts[:domains] && opts[:domains] != "" do
opts[:domains]
2023-09-23 14:52:22 +12:00
|> Kernel.||("")
|> String.split(",")
|> Enum.flat_map(fn
"" ->
[]
domain ->
[Module.concat([domain])]
2023-09-23 14:52:22 +12:00
end)
else
configured_domains
2023-09-23 14:52:22 +12:00
end
domains
2023-09-23 14:52:22 +12:00
|> Enum.map(&ensure_compiled(&1, args))
|> case do
[] ->
raise "must supply the --domains argument, or set `config :my_app, ash_domains: [...]` in config"
2023-09-23 14:52:22 +12:00
domains ->
domains
2023-09-23 14:52:22 +12:00
end
end
def repos!(opts, args) do
domains = domains!(opts, args)
2023-09-23 14:52:22 +12:00
resources =
domains
|> Enum.flat_map(&Ash.Domain.Info.resources/1)
2023-09-23 14:52:22 +12:00
|> Enum.filter(&(Ash.DataLayer.data_layer(&1) == AshSqlite.DataLayer))
|> case do
[] ->
raise """
No resources with `data_layer: AshSqlite.DataLayer` found in the domains #{Enum.map_join(domains, ",", &inspect/1)}.
2023-09-23 14:52:22 +12:00
Must be able to find at least one resource with `data_layer: AshSqlite.DataLayer`.
"""
resources ->
resources
end
resources
|> Enum.map(&AshSqlite.DataLayer.Info.repo(&1))
|> Enum.uniq()
|> case do
[] ->
raise """
No repos could be found configured on the resources in the domains: #{Enum.map_join(domains, ",", &inspect/1)}
2023-09-23 14:52:22 +12:00
At least one resource must have a repo configured.
The following resources were found with `data_layer: AshSqlite.DataLayer`:
#{Enum.map_join(resources, "\n", &"* #{inspect(&1)}")}
"""
repos ->
repos
end
end
def delete_flag(args, arg) do
case Enum.split_while(args, &(&1 != arg)) do
{left, [_ | rest]} ->
left ++ rest
_ ->
args
end
end
def delete_arg(args, arg) do
case Enum.split_while(args, &(&1 != arg)) do
{left, [_, _ | rest]} ->
left ++ rest
_ ->
args
end
end
defp ensure_compiled(domain, args) do
2023-09-23 14:52:22 +12:00
if Code.ensure_loaded?(Mix.Tasks.App.Config) do
Mix.Task.run("app.config", args)
else
Mix.Task.run("loadpaths", args)
"--no-compile" not in args && Mix.Task.run("compile", args)
end
case Code.ensure_compiled(domain) do
2023-09-23 14:52:22 +12:00
{:module, _} ->
domain
|> Ash.Domain.Info.resources()
2023-09-23 14:52:22 +12:00
|> Enum.each(&Code.ensure_compiled/1)
# TODO: We shouldn't need to make sure that the resources are compiled
domain
2023-09-23 14:52:22 +12:00
{:error, error} ->
Mix.raise("Could not load #{inspect(domain)}, error: #{inspect(error)}. ")
2023-09-23 14:52:22 +12:00
end
end
def migrations_path(opts, repo) do
opts[:migrations_path] || repo.config()[:migrations_path] || derive_migrations_path(repo)
end
def derive_migrations_path(repo) do
config = repo.config()
priv = config[:priv] || "priv/#{repo |> Module.split() |> List.last() |> Macro.underscore()}"
app = Keyword.fetch!(config, :otp_app)
Application.app_dir(app, Path.join(priv, "migrations"))
end
end