Skip to content

Commit f584028

Browse files
committed
Require top level ecto/phoenix inclusion
1 parent 5ae8a79 commit f584028

File tree

4 files changed

+78
-21
lines changed

4 files changed

+78
-21
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
* Added `PowInvitation` to the `mix pow.extension.phoenix.gen.templates` and `mix pow.extension.phoenix.mailer.gen.templates` tasks
66
* Fixed issue in umbrella projects where extensions wasn't found in environment configuration
77
* Shell instructions will only be printed if the configuration is missing
8+
* Now requires that `:ecto` or `:phoenix` are included in the dependency list for the app to run respective mix tasks
89
* Deprecated `Mix.Pow.context_app/0`
10+
* Deprecated `Mix.Pow.ensure_dep!/3`
911

1012
## v1.0.3 (2019-03-09)
1113

lib/mix/pow.ex

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ defmodule Mix.Pow do
1616
:ok
1717
end
1818

19-
@doc """
20-
Raises an exception if the application doesn't have the dependency.
21-
"""
19+
# TODO: Remove by 1.1.0
20+
@doc false
21+
@deprecated "Use `ensure_ecto!` or `ensure_phoenix!` instead"
2222
@spec ensure_dep!(binary(), atom(), OptionParser.argv()) :: :ok | no_return
2323
def ensure_dep!(task, dep, _args) do
2424
fetch_deps()
25-
|> dep_in_deps?(dep)
25+
|> top_level_dep_in_deps?(dep)
2626
|> case do
2727
true ->
2828
:ok
@@ -32,6 +32,27 @@ defmodule Mix.Pow do
3232
end
3333
end
3434

35+
@doc """
36+
Raises an exception if application doesn't have Ecto as dependency.
37+
"""
38+
@spec ensure_ecto!(binary(), OptionParser.argv()) :: :ok | no_return
39+
def ensure_ecto!(task, _args) do
40+
deps = fetch_deps()
41+
42+
cond do
43+
top_level_dep_in_deps?(deps, :ecto) -> :ok
44+
top_level_dep_in_deps?(deps, :ecto_sql) -> :ok
45+
true -> Mix.raise("mix #{task} can only be run inside an application directory that has :ecto or :ecto_sql as dependency")
46+
end
47+
end
48+
49+
defp top_level_dep_in_deps?(deps, dep) do
50+
Enum.any?(deps, fn
51+
%Mix.Dep{app: ^dep, top_level: true} -> true
52+
_any -> false
53+
end)
54+
end
55+
3556
# TODO: Remove by 1.1.0 and only support Elixir 1.7
3657
defp fetch_deps do
3758
System.version()
@@ -42,22 +63,16 @@ defmodule Mix.Pow do
4263
end
4364
end
4465

45-
defp dep_in_deps?(deps, dep) do
46-
Enum.any?(deps, fn
47-
%Mix.Dep{app: ^dep} -> true
48-
_any -> false
49-
end)
50-
end
51-
52-
@doc """
53-
Raises an exception if application doesn't have Ecto as dependency.
54-
"""
55-
def ensure_ecto!(task, args), do: ensure_dep!(task, :ecto, args)
56-
5766
@doc """
5867
Raises an exception if application doesn't have Phoenix as dependency.
5968
"""
60-
def ensure_phoenix!(task, args), do: ensure_dep!(task, :phoenix, args)
69+
@spec ensure_phoenix!(binary(), OptionParser.argv()) :: :ok | no_return
70+
def ensure_phoenix!(task, _args) do
71+
case top_level_dep_in_deps?(fetch_deps(), :phoenix) do
72+
true -> :ok
73+
false -> Mix.raise("mix #{task} can only be run inside an application directory that has :phoenix as dependency")
74+
end
75+
end
6176

6277
@doc """
6378
Parses argument options into a map.

test/mix/tasks/ecto/pow.ecto.install_test.exs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,36 @@ defmodule Mix.Tasks.Pow.Ecto.InstallTest do
6666
use Mix.Project
6767
6868
def project do
69-
[]
69+
[
70+
deps: [
71+
{:ecto_job, ">= 0.0.0"}
72+
]
73+
]
7074
end
7175
end
7276
""")
7377

7478
Mix.Project.in_project(:my_app, ".", fn _ ->
75-
assert_raise Mix.Error, "mix pow.ecto.install can only be run inside an application directory that has :ecto as dependency", fn ->
79+
Mix.Tasks.Deps.Get.run([])
80+
81+
# Insurance that we do test for top level ecto inclusion
82+
assert Enum.any?(deps(), fn
83+
%{app: :phoenix} -> true
84+
_ -> false
85+
end), "Ecto not loaded by dependency"
86+
87+
assert_raise Mix.Error, "mix pow.ecto.install can only be run inside an application directory that has :ecto or :ecto_sql as dependency", fn ->
7688
Install.run([])
7789
end
7890
end)
7991
end)
8092
end
93+
94+
# TODO: Refactor to just use Elixir 1.7 or higher by Pow 1.1.0
95+
defp deps() do
96+
case Kernel.function_exported?(Mix.Dep, :load_on_environment, 1) do
97+
true -> apply(Mix.Dep, :load_on_environment, [[]])
98+
false -> apply(Mix.Dep, :loaded, [[]])
99+
end
100+
end
81101
end

test/mix/tasks/phoenix/pow.phoenix.install_test.exs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,31 @@ defmodule Mix.Tasks.Pow.Phoenix.InstallTest do
7373
end)
7474
end
7575

76-
test "raises error in app with no phoenix dep" do
76+
test "raises error in app with no top level phoenix dep" do
7777
File.cd!(@tmp_path, fn ->
7878
File.write!("mix.exs", """
7979
defmodule MyApp.MixProject do
8080
use Mix.Project
8181
8282
def project do
83-
[]
83+
[
84+
deps: [
85+
{:phoenix_live_reload, ">= 0.0.0"}
86+
]
87+
]
8488
end
8589
end
8690
""")
8791

8892
Mix.Project.in_project(:my_app, ".", fn _ ->
93+
Mix.Tasks.Deps.Get.run([])
94+
95+
# Insurance that we do test for top level phoenix inclusion
96+
assert Enum.any?(deps(), fn
97+
%{app: :phoenix} -> true
98+
_ -> false
99+
end), "Phoenix not loaded by dependency"
100+
89101
assert_raise Mix.Error, "mix pow.phoenix.install can only be run inside an application directory that has :phoenix as dependency", fn ->
90102
Install.run([])
91103
end
@@ -151,4 +163,12 @@ defmodule Mix.Tasks.Pow.Phoenix.InstallTest do
151163
end)
152164
end)
153165
end
166+
167+
# TODO: Refactor to just use Elixir 1.7 or higher by Pow 1.1.0
168+
defp deps() do
169+
case Kernel.function_exported?(Mix.Dep, :load_on_environment, 1) do
170+
true -> apply(Mix.Dep, :load_on_environment, [[]])
171+
false -> apply(Mix.Dep, :loaded, [[]])
172+
end
173+
end
154174
end

0 commit comments

Comments
 (0)