Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
* Added `PowInvitation` to the `mix pow.extension.phoenix.gen.templates` and `mix pow.extension.phoenix.mailer.gen.templates` tasks
* Fixed issue in umbrella projects where extensions wasn't found in environment configuration
* Shell instructions will only be printed if the configuration is missing
* Now requires that `:ecto` or `:phoenix` are included in the dependency list for the app to run respective mix tasks
* Deprecated `Mix.Pow.context_app/0`
* Deprecated `Mix.Pow.ensure_dep!/3`

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

Expand Down
49 changes: 32 additions & 17 deletions lib/mix/pow.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ defmodule Mix.Pow do
:ok
end

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

@doc """
Raises an exception if application doesn't have Ecto as dependency.
"""
@spec ensure_ecto!(binary(), OptionParser.argv()) :: :ok | no_return
def ensure_ecto!(task, _args) do
deps = fetch_deps()

cond do
top_level_dep_in_deps?(deps, :ecto) -> :ok
top_level_dep_in_deps?(deps, :ecto_sql) -> :ok
true -> Mix.raise("mix #{task} can only be run inside an application directory that has :ecto or :ecto_sql as dependency")
end
end

defp top_level_dep_in_deps?(deps, dep) do
Enum.any?(deps, fn
%Mix.Dep{app: ^dep, top_level: true} -> true
_any -> false
end)
end

# TODO: Remove by 1.1.0 and only support Elixir 1.7
defp fetch_deps do
System.version()
Expand All @@ -42,22 +63,16 @@ defmodule Mix.Pow do
end
end

defp dep_in_deps?(deps, dep) do
Enum.any?(deps, fn
%Mix.Dep{app: ^dep} -> true
_any -> false
end)
end

@doc """
Raises an exception if application doesn't have Ecto as dependency.
"""
def ensure_ecto!(task, args), do: ensure_dep!(task, :ecto, args)

@doc """
Raises an exception if application doesn't have Phoenix as dependency.
"""
def ensure_phoenix!(task, args), do: ensure_dep!(task, :phoenix, args)
@spec ensure_phoenix!(binary(), OptionParser.argv()) :: :ok | no_return
def ensure_phoenix!(task, _args) do
case top_level_dep_in_deps?(fetch_deps(), :phoenix) do
true -> :ok
false -> Mix.raise("mix #{task} can only be run inside an application directory that has :phoenix as dependency")
end
end

@doc """
Parses argument options into a map.
Expand Down
9 changes: 8 additions & 1 deletion lib/mix/tasks/pow.install.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,14 @@ defmodule Mix.Tasks.Pow.Install do

defp no_umbrella! do
if Project.umbrella?() do
Mix.raise("mix #{@mix_task} can't be used in umbrella apps. Run mix pow.ecto.install in your ecto app directory, and optionally mix pow.phoenix.install in your phoenix app directory.")
Mix.raise(
"""
mix #{@mix_task} has to be used inside an application directory, but this is an umbrella project.

Run mix pow.ecto.install inside your Ecto application directory to create schema module and migrations.

Run mix pow.phoenix.install in your Phoenix application directory for configuration instructions.
""")
end

:ok
Expand Down
24 changes: 22 additions & 2 deletions test/mix/tasks/ecto/pow.ecto.install_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,36 @@ defmodule Mix.Tasks.Pow.Ecto.InstallTest do
use Mix.Project

def project do
[]
[
deps: [
{:ecto_job, ">= 0.0.0"}
]
]
end
end
""")

Mix.Project.in_project(:my_app, ".", fn _ ->
assert_raise Mix.Error, "mix pow.ecto.install can only be run inside an application directory that has :ecto as dependency", fn ->
Mix.Tasks.Deps.Get.run([])

# Insurance that we do test for top level ecto inclusion
assert Enum.any?(deps(), fn
%{app: :phoenix} -> true
_ -> false
end), "Ecto not loaded by dependency"

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 ->
Install.run([])
end
end)
end)
end

# TODO: Refactor to just use Elixir 1.7 or higher by Pow 1.1.0
defp deps() do
case Kernel.function_exported?(Mix.Dep, :load_on_environment, 1) do
true -> apply(Mix.Dep, :load_on_environment, [[]])
false -> apply(Mix.Dep, :loaded, [[]])
end
end
end
24 changes: 22 additions & 2 deletions test/mix/tasks/phoenix/pow.phoenix.install_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,31 @@ defmodule Mix.Tasks.Pow.Phoenix.InstallTest do
end)
end

test "raises error in app with no phoenix dep" do
test "raises error in app with no top level phoenix dep" do
File.cd!(@tmp_path, fn ->
File.write!("mix.exs", """
defmodule MyApp.MixProject do
use Mix.Project

def project do
[]
[
deps: [
{:phoenix_live_reload, ">= 0.0.0"}
]
]
end
end
""")

Mix.Project.in_project(:my_app, ".", fn _ ->
Mix.Tasks.Deps.Get.run([])

# Insurance that we do test for top level phoenix inclusion
assert Enum.any?(deps(), fn
%{app: :phoenix} -> true
_ -> false
end), "Phoenix not loaded by dependency"

assert_raise Mix.Error, "mix pow.phoenix.install can only be run inside an application directory that has :phoenix as dependency", fn ->
Install.run([])
end
Expand Down Expand Up @@ -151,4 +163,12 @@ defmodule Mix.Tasks.Pow.Phoenix.InstallTest do
end)
end)
end

# TODO: Refactor to just use Elixir 1.7 or higher by Pow 1.1.0
defp deps() do
case Kernel.function_exported?(Mix.Dep, :load_on_environment, 1) do
true -> apply(Mix.Dep, :load_on_environment, [[]])
false -> apply(Mix.Dep, :loaded, [[]])
end
end
end
2 changes: 1 addition & 1 deletion test/mix/tasks/pow.install_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ defmodule Mix.Tasks.Pow.InstallTest do
""")

Mix.Project.in_project(:umbrella, ".", fn _ ->
assert_raise Mix.Error, "mix pow.install can't be used in umbrella apps. Run mix pow.ecto.install in your ecto app directory, and optionally mix pow.phoenix.install in your phoenix app directory.", fn ->
assert_raise Mix.Error, ~r/mix pow.install has to be used inside an application directory/, fn ->
Install.run([])
end
end)
Expand Down