diff --git a/.credo.exs b/.credo.exs index c0917ff0..efb31c31 100644 --- a/.credo.exs +++ b/.credo.exs @@ -26,8 +26,7 @@ # You can customize the priority of any check # Priority values are: `low, normal, high, higher` # - {Credo.Check.Design.AliasUsage, - [priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]}, + {Credo.Check.Design.AliasUsage, false}, {Credo.Check.Design.TagTODO, [exit_status: 2]}, {Credo.Check.Design.TagFIXME, []}, diff --git a/guides/introduction/installation.md b/guides/introduction/installation.md index 4595aca6..7fc63890 100644 --- a/guides/introduction/installation.md +++ b/guides/introduction/installation.md @@ -1,5 +1,23 @@ # Installation +Oban may be installed and configured via [igniter](https://hex.pm/packages/igniter) with a single command: + +```bash +mix igniter.install oban +``` + +That will add the latest version of `oban` to your dependencies before running the installer. +Installation will use the application's default Ecto repo, select the corresponding engine, and +set the pubsub notifier accordingly. + +Use the `--repo` flag to specify an alternate repo manually: + +```bash +mix igniter.install oban --repo MyApp.LiteRepo +``` + +## Manual Installation + Oban is published on [Hex](https://hex.pm/packages/oban). Add it to your list of dependencies in `mix.exs`: diff --git a/lib/mix/tasks/oban.install.ex b/lib/mix/tasks/oban.install.ex new file mode 100644 index 00000000..2fc1b264 --- /dev/null +++ b/lib/mix/tasks/oban.install.ex @@ -0,0 +1,182 @@ +defmodule Mix.Tasks.Oban.Install.Docs do + @moduledoc false + + def short_doc do + "Install and configure Oban for use in an application." + end + + def example do + "mix oban.install" + end + + def long_doc do + """ + Install and configure Oban for use in an application. + + ## Example + + Install using the default Ecto repo and matching engine: + + ```bash + mix oban.install + ``` + + Specify a `SQLite3` repo and `Lite` engine explicitly: + + ```bash + mix oban.install --repo MyApp.LiteRepo --engine Oban.Engines.Lite + ``` + + ## Options + + * `--engine` or `-e` — Select the engine for your repo, defaults to `Oban.Engines.Postgres` + * `--notifier` or `-n` — Select the pubsub notifier, defaults to `Oban.Notifiers.Postgres` + * `--repo` or `-r` — Specify an Ecto repo for Oban to use + """ + end +end + +if Code.ensure_loaded?(Igniter) do + defmodule Mix.Tasks.Oban.Install do + @shortdoc __MODULE__.Docs.short_doc() + + @moduledoc __MODULE__.Docs.long_doc() + + use Igniter.Mix.Task + + @impl Igniter.Mix.Task + def info(_argv, _composing_task) do + %Igniter.Mix.Task.Info{ + group: :oban, + adds_deps: [oban: "oban"], + installs: [], + example: __MODULE__.Docs.example(), + only: nil, + positional: [], + composes: [], + schema: [engine: :string, notifier: :string, repo: :string], + defaults: [], + aliases: [e: :engine, n: :notifier, r: :repo], + required: [] + } + end + + @impl Igniter.Mix.Task + def igniter(igniter) do + app_name = Igniter.Project.Application.app_name(igniter) + opts = igniter.args.options + + case extract_repo(igniter, app_name, opts[:repo]) do + {:ok, repo, adapter} -> + engine = parse_engine(adapter, opts[:engine]) + notifier = parse_notifier(adapter, opts[:notifier]) + + conf_code = [engine: engine, notifier: notifier, queues: [default: 10], repo: repo] + test_code = [testing: :manual] + + tree_code = + quote do + Application.fetch_env!(unquote(app_name), Oban) + end + + migration = """ + use Ecto.Migration + + def up, do: Oban.Migration.up() + + def down, do: Oban.Migration.down(version: 1) + """ + + igniter + |> Igniter.Project.Deps.add_dep({:oban, "~> 2.18"}) + |> Igniter.Project.Config.configure("config.exs", app_name, [Oban], {:code, conf_code}) + |> Igniter.Project.Config.configure("test.exs", app_name, [Oban], {:code, test_code}) + |> Igniter.Project.Application.add_new_child({Oban, {:code, tree_code}}, after: [repo]) + |> Igniter.Project.Formatter.import_dep(:oban) + |> Igniter.Libs.Ecto.gen_migration(repo, "add_oban", body: migration) + + {:error, igniter} -> + igniter + end + end + + defp extract_repo(igniter, app_name, nil) do + case Igniter.Libs.Ecto.list_repos(igniter) do + {igniter, [repo | _]} -> + {:ok, repo, extract_adapter(igniter, repo)} + + _ -> + issue = """ + No ecto repos found for #{inspect(app_name)}. + + Ensure `:ecto` is installed and configured for the current application. + """ + + {:error, Igniter.add_issue(igniter, issue)} + end + end + + defp extract_repo(igniter, _app_name, module) do + repo = Igniter.Project.Module.parse(module) + + case Igniter.Project.Module.module_exists(igniter, repo) do + {true, igniter} -> + {:ok, repo, extract_adapter(igniter, repo)} + + {false, _} -> + {:error, Igniter.add_issue(igniter, "Provided repo (#{inspect(repo)}) doesn't exist")} + 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) + + 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 + adapter + else + _ -> Ecto.Adapters.Postgres + end + end + + defp parse_engine(adapter, nil) do + case adapter do + Ecto.Adapters.Postgres -> Oban.Engines.Basic + Ecto.Adapters.MyXQL -> Oban.Engines.Dolphin + Ecto.Adapters.SQLite3 -> Oban.Engines.Lite + end + end + + defp parse_engine(_, module), do: Igniter.Project.Module.parse(module) + + defp parse_notifier(adapter, nil) do + case adapter do + Ecto.Adapters.Postgres -> Oban.Notifiers.Postgres + _ -> Oban.Notifiers.PG + end + end + + defp parse_notifier(_, module), do: Igniter.Project.Module.parse(module) + end +else + defmodule Mix.Tasks.Oban.Install do + @shortdoc "Install `igniter` in order to install Oban." + + @moduledoc __MODULE__.Docs.long_doc() + + use Mix.Task + + def run(_argv) do + Mix.shell().error(""" + The task 'oban.install' requires igniter. Please install igniter and try again. + + For more information, see: https://hexdocs.pm/igniter/readme.html#installation + """) + + exit({:shutdown, 1}) + end + end +end diff --git a/mix.exs b/mix.exs index 163939ea..69832207 100644 --- a/mix.exs +++ b/mix.exs @@ -179,6 +179,7 @@ defmodule Oban.MixProject do {:ecto_sql, "~> 3.10"}, {:ecto_sqlite3, "~> 0.9", optional: true}, {:jason, "~> 1.1"}, + {:igniter, "~> 0.5", optional: true}, {:myxql, "~> 0.7", optional: true}, {:postgrex, "~> 0.16", optional: true}, {:telemetry, "~> 0.4 or ~> 1.0"}, diff --git a/mix.lock b/mix.lock index 7d02c2a9..dee63f28 100644 --- a/mix.lock +++ b/mix.lock @@ -7,25 +7,31 @@ "decimal": {:hex, :decimal, "2.2.0", "df3d06bb9517e302b1bd265c1e7f16cda51547ad9d99892049340841f3e15836", [:mix], [], "hexpm", "af8daf87384b51b7e611fb1a1f2c4d4876b65ef968fa8bd3adf44cff401c7f21"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.42", "f23d856f41919f17cd06a493923a722d87a2d684f143a1e663c04a2b93100682", [:mix], [], "hexpm", "6915b6ca369b5f7346636a2f41c6a6d78b5af419d61a611079189233358b8b8b"}, "ecto": {:hex, :ecto, "3.12.4", "267c94d9f2969e6acc4dd5e3e3af5b05cdae89a4d549925f3008b2b7eb0b93c3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ef04e4101688a67d061e1b10d7bc1fbf00d1d13c17eef08b71d070ff9188f747"}, "ecto_sql": {:hex, :ecto_sql, "3.12.1", "c0d0d60e85d9ff4631f12bafa454bc392ce8b9ec83531a412c12a0d415a3a4d0", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aff5b958a899762c5f09028c847569f7dfb9cc9d63bdb8133bff8a5546de6bf5"}, "ecto_sqlite3": {:hex, :ecto_sqlite3, "0.17.4", "48dd9c6d0fc10875a64545d04f0478b142898b6f0e73ae969becf5726f834d22", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.12", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:exqlite, "~> 0.22", [hex: :exqlite, repo: "hexpm", optional: false]}], "hexpm", "f67372e0eae5e5cbdd1d145e78e670fc5064d5810adf99d104d364cb920e306a"}, "elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_doc": {:hex, :ex_doc, "0.35.1", "de804c590d3df2d9d5b8aec77d758b00c814b356119b3d4455e4b8a8687aecaf", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "2121c6402c8d44b05622677b761371a759143b958c6c19f6558ff64d0aed40df"}, + "ex_doc": {:hex, :ex_doc, "0.36.1", "4197d034f93e0b89ec79fac56e226107824adcce8d2dd0a26f5ed3a95efc36b1", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d7d26a7cf965dacadcd48f9fa7b5953d7d0cfa3b44fa7a65514427da44eafd89"}, "exqlite": {:hex, :exqlite, "0.27.0", "2ef6021862e74c6253d1fb1f5701bd47e4e779b035d34daf2a13ec83945a05ba", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "b947b9db15bb7aad11da6cd18a0d8b78f7fcce89508a27a5b9be18350fe12c59"}, "file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"}, + "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, + "igniter": {:hex, :igniter, "0.5.1", "05c920bb39e2abd7a2fcc50d129d087ff99305b3ff2a270890d5b114483411b5", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "3361f6e89de1984aca67472040424565c5e733a2fe30ac3e4b04c1e9ae6d97a1"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, "makeup_diff": {:hex, :makeup_diff, "0.1.1", "01498f8c95970081297837eaf4686b6f3813e535795b8421f15ace17a59aea37", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "fadb0bf014bd328badb7be986eadbce1a29955dd51c27a9e401c3045cf24184e"}, - "makeup_elixir": {:hex, :makeup_elixir, "1.0.0", "74bb8348c9b3a51d5c589bf5aebb0466a84b33274150e3b6ece1da45584afc82", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "49159b7d7d999e836bedaf09dcf35ca18b312230cf901b725a64f3f42e407983"}, + "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, "myxql": {:hex, :myxql, "0.7.1", "7c7b75aa82227cd2bc9b7fbd4de774fb19a1cdb309c219f411f82ca8860f8e01", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:geo, "~> 3.4", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a491cdff53353a09b5850ac2d472816ebe19f76c30b0d36a43317a67c9004936"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "postgrex": {:hex, :postgrex, "0.19.3", "a0bda6e3bc75ec07fca5b0a89bffd242ca209a4822a9533e7d3e84ee80707e19", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d31c28053655b78f47f948c85bb1cf86a9c1f8ead346ba1aa0d0df017fa05b61"}, + "rewrite": {:hex, :rewrite, "1.1.1", "0e6674eb5f8cb11aabe5ad6207151b4156bf173aa9b43133a68f8cc882364570", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "fcd688b3ca543c3a1f1f4615ccc054ec37cfcde91133a27a683ec09b35ae1496"}, + "sourceror": {:hex, :sourceror, "1.7.1", "599d78f4cc2be7d55c9c4fd0a8d772fd0478e3a50e726697c20d13d02aa056d4", [:mix], [], "hexpm", "cd6f268fe29fa00afbc535e215158680a0662b357dc784646d7dff28ac65a0fc"}, + "spitfire": {:hex, :spitfire, "0.1.3", "7ea0f544005dfbe48e615ed90250c9a271bfe126914012023fd5e4b6b82b7ec7", [:mix], [], "hexpm", "d53b5107bcff526a05c5bb54c95e77b36834550affd5830c9f58760e8c543657"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, "stream_data": {:hex, :stream_data, "1.1.2", "05499eaec0443349ff877aaabc6e194e82bda6799b9ce6aaa1aadac15a9fdb4d", [:mix], [], "hexpm", "129558d2c77cbc1eb2f4747acbbea79e181a5da51108457000020a906813a1a9"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, + "text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"}, "tz": {:hex, :tz, "0.26.5", "bfe8efa345670f90351c5c31d22455d0307c5d9895fbdede7deeb215a7b60dbe", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:mint, "~> 1.5", [hex: :mint, repo: "hexpm", optional: true]}], "hexpm", "c4f9392d710582c7108b6b8c635f4981120ec4b2072adbd242290fc842338183"}, } diff --git a/test/mix/tasks/oban.install_test.exs b/test/mix/tasks/oban.install_test.exs new file mode 100644 index 00000000..53ce343d --- /dev/null +++ b/test/mix/tasks/oban.install_test.exs @@ -0,0 +1,83 @@ +defmodule Mix.Tasks.Oban.InstallTest do + use ExUnit.Case, async: true + + import Igniter.Test + + describe "install" do + test "installing without an available ecto repo" do + assert {:error, [warning]} = + test_project() + |> Igniter.compose_task("oban.install", []) + |> apply_igniter() + + assert warning =~ "No ecto repos found for :test" + end + + test "installing with an ecto 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 Ecto.Repo, otp_app: :oban, adapter: Ecto.Adapters.Postgres + 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 + @moduledoc false + + use Ecto.Repo, otp_app: :oban, adapter: Ecto.Adapters.SQLite3 + end + """ + + [app_name: :oban, files: %{"lib/oban/repo.ex" => repo}] + |> test_project() + |> Igniter.compose_task("oban.install", ["--repo", "Oban.Test.LiteRepo"]) + |> assert_has_patch("config/config.exs", """ + | config :oban, Oban, + | engine: Oban.Engines.Lite, + | notifier: Oban.Notifiers.PG, + | queues: [default: 10], + | repo: Oban.Test.LiteRepo + """) + end + end +end