improvement: Add Ash.Resource.Igniter.domain to get the domain of a resource

fix: properly convert extension string into a module

fix: only display available to extend
This commit is contained in:
Zach Daniel 2024-07-18 12:57:40 -04:00
parent 69c77acedd
commit eb2f5f40f1
5 changed files with 67 additions and 28 deletions

View file

@ -1,2 +1,2 @@
erlang 26.0.2
elixir 1.17.0
erlang 27.0.1
elixir 1.17.2-otp-27

View file

@ -3285,6 +3285,8 @@ defmodule Ash.Changeset do
end
def run_before_transaction_hooks(changeset) do
warn_on_transaction_hooks(changeset, changeset.before_transaction, "before_transaction")
Enum.reduce_while(
changeset.before_transaction,
set_phase(changeset, :before_transaction),

View file

@ -3,24 +3,44 @@ defmodule Ash.Resource.Igniter do
@doc "List all resource modules found in the project"
def list_resources(igniter) do
Igniter.Code.Module.find_all_matching_modules(igniter, fn _mod, zipper ->
zipper
|> Igniter.Code.Module.move_to_use(resource_mods())
|> case do
{:ok, _} ->
true
_ ->
false
end
end)
end
@doc "Gets the domain from the given resource module"
@spec domain(Igniter.t(), Ash.Resource.t()) ::
{:ok, Igniter.t(), Ash.Domain.t()} | {:error, Igniter.t()}
def domain(igniter, resource) do
with {:ok, {igniter, _source, zipper}} <-
Igniter.Code.Module.find_module(igniter, resource),
{:ok, zipper} <- Igniter.Code.Common.move_to_do_block(zipper),
{:ok, zipper} <-
Igniter.Code.Module.move_to_use(zipper, resource_mods()),
{:ok, zipper} <-
Igniter.Code.Function.move_to_nth_argument(zipper, 1),
{:ok, zipper} <- Igniter.Code.Keyword.get_key(zipper, :domain),
module when not is_nil(module) <-
Igniter.Code.Module.to_module_name(zipper.node) do
{:ok, igniter, module}
else
_ ->
:error
end
end
def resource_mods do
app_name = Igniter.Project.Application.app_name()
resources =
[Ash.Resource | List.wrap(Application.get_env(app_name, :base_resources))]
Igniter.Code.Module.find_all_matching_modules(igniter, fn _mod, zipper ->
Enum.any?(resources, fn resource ->
zipper
|> Igniter.Code.Module.move_to_use(resource)
|> case do
{:ok, _} ->
true
_ ->
false
end
end)
end)
[Ash.Resource | List.wrap(Application.get_env(app_name, :base_resources))]
end
@doc "Adds the given code block to the resource's `attributes` block"

View file

@ -50,9 +50,15 @@ defmodule Ash.Mix.Tasks.Helpers do
fn app ->
app
|> :application.get_key(:modules)
|> elem(1)
|> List.wrap()
|> Enum.filter(&Spark.implements_behaviour?(&1, Spark.Dsl.Extension))
|> case do
:undefined ->
[]
{_, mods} ->
mods
|> List.wrap()
|> Enum.filter(&Spark.implements_behaviour?(&1, Spark.Dsl.Extension))
end
end,
timeout: :infinity
)

View file

@ -138,7 +138,7 @@ defmodule Mix.Tasks.Ash.Patch.Extend do
if is_function(extension) do
{extension, install}
else
Module.concat([extension])
extension = Module.concat([extension])
if Code.ensure_loaded?(extension) do
fun =
@ -156,11 +156,11 @@ defmodule Mix.Tasks.Ash.Patch.Extend do
extensions = Enum.map(Ash.Mix.Tasks.Helpers.extensions!([]), &inspect/1)
short_codes = [
"json_api",
"postgres",
"graphql",
"mysql",
"sqlite",
{AshJsonApi.Resource, "json_api"},
{AshPostgres.DataLayer, "postgres"},
{AshGraphql.Resource, "graphql"},
{AshMySql.DataLayer, "mysql"},
{AshSqlite.DataLayer, "sqlite"},
"ets",
"mnesia",
"embedded"
@ -169,7 +169,18 @@ defmodule Mix.Tasks.Ash.Patch.Extend do
installable =
short_codes
|> Enum.concat(extensions)
|> Enum.map_join("\n", &" * #{&1}")
|> Enum.flat_map(fn
{dependency, name} ->
if Code.ensure_loaded?(dependency) do
[" * #{name}"]
else
[]
end
dependency ->
[" * #{dependency}"]
end)
|> Enum.join("\n")
{:error,
"""