diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e96674c..8ffd4bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,11 +14,11 @@ jobs: matrix: include: - pair: - elixir: '1.7' - otp: 20 + elixir: '1.10' + otp: 21 - pair: - elixir: '1.12' - otp: 24 + elixir: '1.14' + otp: 25 lint: lint steps: - uses: actions/checkout@v2 diff --git a/lib/phoenix_ecto/check_repo_status.ex b/lib/phoenix_ecto/check_repo_status.ex index 58930e9..924d4be 100644 --- a/lib/phoenix_ecto/check_repo_status.ex +++ b/lib/phoenix_ecto/check_repo_status.ex @@ -9,12 +9,16 @@ defmodule Phoenix.Ecto.CheckRepoStatus do * `:otp_app` - name of the application which the repos are fetched from * `:migration_paths` - a function that accepts a repo and returns a migration directory, or a list of migration directories, that is used to check for pending migrations + * `:migration_lock` - the locking strategy used by the Ecto Adapter when checking for pending migrations. Set to `false` to disable migration locks. """ @behaviour Plug alias Plug.Conn + @migration_opts [:migration_lock] + @compile {:no_warn_undefined, Ecto.Migrator} + def init(opts) do Keyword.fetch!(opts, :otp_app) opts @@ -83,20 +87,30 @@ defmodule Phoenix.Ecto.CheckRepoStatus do end def migrations(repo, migration_directories, opts) do + migration_opts = Keyword.take(opts, @migration_opts) + case Keyword.fetch(opts, :mock_migrations_fn) do {:ok, migration_fn} -> - migrations = migration_fn.(repo, migration_directories) + migrations = get_migrations(migration_fn, repo, migration_directories, migration_opts) {:ok, migrations} :error -> if Code.ensure_loaded?(Ecto.Migrator) do - {:ok, Ecto.Migrator.migrations(repo, migration_directories)} + {:ok, Ecto.Migrator.migrations(repo, migration_directories, migration_opts)} else :error end end end + defp get_migrations(fun, repo, directories, _opts) when is_function(fun, 2) do + fun.(repo, directories) + end + + defp get_migrations(fun, repo, directories, opts) when is_function(fun, 3) do + fun.(repo, directories, opts) + end + defp default_migration_directory(repo, opts) do case Keyword.fetch(opts, :mock_default_migration_directory_fn) do {:ok, migration_directories_fn} -> diff --git a/mix.exs b/mix.exs index b533ac7..f3039f7 100644 --- a/mix.exs +++ b/mix.exs @@ -8,7 +8,7 @@ defmodule PhoenixEcto.Mixfile do [ app: :phoenix_ecto, version: @version, - elixir: "~> 1.7", + elixir: "~> 1.10", deps: deps(), # Hex @@ -52,7 +52,7 @@ defmodule PhoenixEcto.Mixfile do defp deps do [ {:phoenix_html, "~> 2.14.2 or ~> 3.0", optional: true}, - {:ecto, "~> 3.3"}, + {:ecto, "~> 3.5"}, {:plug, "~> 1.9"}, {:ex_doc, ">= 0.0.0", only: :docs} ] diff --git a/mix.lock b/mix.lock index 46ed352..747b95b 100644 --- a/mix.lock +++ b/mix.lock @@ -1,7 +1,7 @@ %{ "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "earmark_parser": {:hex, :earmark_parser, "1.4.15", "b29e8e729f4aa4a00436580dcc2c9c5c51890613457c193cc8525c388ccb2f06", [:mix], [], "hexpm", "044523d6438ea19c1b8ec877ec221b008661d3c27e3b848f4c879f500421ca5c"}, - "ecto": {:hex, :ecto, "3.4.6", "08f7afad3257d6eb8613309af31037e16c36808dfda5a3cd0cb4e9738db030e4", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6f13a9e2a62e75c2dcfc7207bfc65645ab387af8360db4c89fee8b5a4bf3f70b"}, + "ecto": {:hex, :ecto, "3.9.2", "017db3bc786ff64271108522c01a5d3f6ba0aea5c84912cfb0dd73bf13684108", [:mix], [{:decimal, "~> 1.6 or ~> 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", "21466d5177e09e55289ac7eade579a642578242c7a3a9f91ad5c6583337a9d15"}, "ex_doc": {:hex, :ex_doc, "0.25.1", "4b736fa38dc76488a937e5ef2944f5474f3eff921de771b25371345a8dc810bc", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3200b0a69ddb2028365281fbef3753ea9e728683863d8cdaa96580925c891f67"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, "makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"}, diff --git a/test/phoenix_ecto/check_repo_status_test.exs b/test/phoenix_ecto/check_repo_status_test.exs index 6ee4212..b926bec 100644 --- a/test/phoenix_ecto/check_repo_status_test.exs +++ b/test/phoenix_ecto/check_repo_status_test.exs @@ -96,6 +96,27 @@ defmodule Phoenix.Ecto.CheckRepoStatusTest do Process.unregister(StorageUpRepo) end + test "supports the `ecto_migration_lock` option" do + Process.register(self(), StorageUpRepo) + Application.put_env(:check_repo_ready, :ecto_repos, [StorageUpRepo]) + mock_migrations_fn = fn _repo, _directories, _opts -> [{:down, 1, "migration"}] end + + conn = conn(:get, "/") + + assert_raise(Phoenix.Ecto.PendingMigrationError, fn -> + CheckRepoStatus.call( + conn, + otp_app: :check_repo_ready, + mock_default_migration_directory_fn: &default_mock_migration_directory_fn/1, + mock_migrations_fn: mock_migrations_fn, + migration_lock: false + ) + end) + after + Application.delete_env(:check_repo_ready, :ecto_repos) + Process.unregister(StorageUpRepo) + end + test "supports the 'migration_paths' option" do Process.register(self(), StorageUpRepo) Application.put_env(:check_repo_ready, :ecto_repos, [StorageUpRepo])