Skip to content

Commit

Permalink
Support ash repos in oban.install igniter task
Browse files Browse the repository at this point in the history
This handles ash wrappers around ecto repo to make composing with ash
easier. Adapter extraction now uses more expressive igniter functions
for navigation.
  • Loading branch information
zachdaniel authored and sorentwo committed Jan 7, 2025
1 parent 31b3c23 commit acf9cce
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 7 deletions.
43 changes: 36 additions & 7 deletions lib/mix/tasks/oban.install.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ if Code.ensure_loaded?(Igniter) do

use Igniter.Mix.Task

@known_repos [Ecto.Repo, AshPostgres.Repo, AshSqlite.Repo]

@impl Igniter.Mix.Task
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
Expand Down Expand Up @@ -128,17 +130,44 @@ if Code.ensure_loaded?(Igniter) do
end
end

defp extract_adapter(igniter, repo) do
match_use = &match?({:use, _, [{:__aliases__, _, [:Ecto, :Repo]} | _]}, &1.node)
match_adp = &match?({{:__block__, _, [:adapter]}, {:__aliases__, _, _}}, &1.node)
# {:ok, zipper} <- Igniter.Code.Module.move_to_module_using(zipper, @known_repos) do
# with :error <- extract_adapter_from_ecto_repo(zipper),
# :error <- extract_adapter_from_ash_postgres_repo(zipper),
# :error <- extract_adapter_from_ash_sqlite_repo(zipper) do
# Ecto.Adapters.Postgres
# else

defp extract_adapter(igniter, repo) do
with {:ok, {_, _, zipper}} <- Igniter.Project.Module.find_module(igniter, repo),
{:ok, zipper} <- Igniter.Code.Common.move_to(zipper, match_use),
{:ok, zipper} <- Igniter.Code.Common.move_to(zipper, match_adp),
{:ok, {:adapter, adapter}} <- Igniter.Code.Common.expand_literal(zipper) do
{:ok, zipper} <- Igniter.Code.Module.move_to_module_using(zipper, @known_repos) do
extract_adapter_from_repo(@known_repos, zipper)
end
end

defp extract_adapter_from_repo([], _zipper), do: Ecto.Adapters.Postgres

defp extract_adapter_from_repo([Ecto.Repo | tail], zipper) do
with {:ok, zipper} <- Igniter.Code.Module.move_to_use(zipper, Ecto.Repo),
{:ok, zipper} <- Igniter.Code.Function.move_to_nth_argument(zipper, 1),
{:ok, zipper} <- Igniter.Code.Keyword.get_key(zipper, :adapter),
{:ok, adapter} <- Igniter.Code.Common.expand_literal(zipper) do
adapter
else
_ -> Ecto.Adapters.Postgres
_ -> extract_adapter_from_repo(tail, zipper)
end
end

defp extract_adapter_from_repo([AshPostgres.Repo | tail], zipper) do
case Igniter.Code.Module.move_to_use(zipper, AshPostgres.Repo) do
{:ok, _zipper} -> Ecto.Adapters.Postgres
_ -> extract_adapter_from_repo(tail, zipper)
end
end

defp extract_adapter_from_repo([AshSqlite.Repo | tail], zipper) do
case Igniter.Code.Module.move_to_use(zipper, AshSqlite.Repo) do
{:ok, _zipper} -> Ecto.Adapters.SQLite3
_ -> extract_adapter_from_repo(tail, zipper)
end
end

Expand Down
46 changes: 46 additions & 0 deletions test/mix/tasks/oban.install_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,52 @@ defmodule Mix.Tasks.Oban.InstallTest do
""")
end

test "installing with an ash_postgres repo available" do
application = """
defmodule Oban.Application do
use Application
def start(_type, _args) do
children = [
Oban.Test.Repo,
{Ecto.Migrator, migrator_opts()},
MyWeb.Endpoint
]
end
end
"""

repo = """
defmodule Oban.Test.Repo do
@moduledoc false
use MyApp.CustomMacro, otp_app: :oban
use AshPostgres.Repo, otp_app: :oban
end
"""

files = %{"lib/oban/application.ex" => application, "lib/oban/repo.ex" => repo}

[app_name: :oban, files: files]
|> test_project()
|> Igniter.compose_task("oban.install", [])
|> assert_has_patch("config/config.exs", """
| config :oban, Oban,
| engine: Oban.Engines.Basic,
| notifier: Oban.Notifiers.Postgres,
| queues: [default: 10],
| repo: Oban.Test.Repo
""")
|> assert_has_patch("config/test.exs", """
| config :oban, Oban, testing: :manual
""")
|> assert_has_patch("lib/oban/application.ex", """
| {Oban, Application.fetch_env!(:oban, Oban)},
| MyWeb.Endpoint
""")
end

test "installing selects correct config with alternate repo" do
repo = """
defmodule Oban.Test.LiteRepo do
Expand Down

0 comments on commit acf9cce

Please sign in to comment.