Packages
pow
1.0.1
1.0.39
1.0.38
1.0.37
1.0.36
1.0.35
1.0.34
1.0.33
1.0.32
1.0.31
1.0.30
1.0.29
1.0.28
1.0.27
1.0.26
1.0.25
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.1.0-rc.1
0.1.0-alpha.8
0.1.0-alpha.7
retired
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
0.1.0-alpha
Robust user authentication solution
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/mix/pow.ex
defmodule Mix.Pow do
@moduledoc """
Utilities module for mix tasks.
"""
alias Mix.{Dep, Project}
@doc """
Raises an exception if the project is an umbrella app.
"""
@spec no_umbrella!(binary()) :: :ok | no_return
def no_umbrella!(task) do
if Project.umbrella?() do
Mix.raise("mix #{task} can only be run inside an application directory")
end
:ok
end
@doc """
Raises an exception if the application doesn't have the dependency.
"""
@spec ensure_dep!(binary(), atom(), OptionParser.argv()) :: :ok | no_return
def ensure_dep!(task, dep, _args) do
fetch_deps()
|> dep_in_deps?(dep)
|> case do
true ->
:ok
false ->
Mix.raise("mix #{task} can only be run inside an application directory that has #{inspect dep} as dependency")
end
end
# TODO: Remove by 1.1.0 and only support Elixir 1.7
defp fetch_deps do
System.version()
|> Version.match?("~> 1.6.0")
|> case do
true -> apply(Dep, :loaded, [[]])
false -> apply(Dep, :load_on_environment, [[]])
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)
@doc """
Parses argument options into a map.
"""
@spec parse_options(OptionParser.argv(), Keyword.t(), Keyword.t()) :: {map(), OptionParser.argv(), OptionParser.errors()}
def parse_options(args, switches, default_opts) do
{opts, parsed, invalid} = OptionParser.parse(args, switches: switches)
default_opts = to_map(default_opts)
opts = to_map(opts)
config =
default_opts
|> Map.merge(opts)
|> context_app_to_atom()
{config, parsed, invalid}
end
defp to_map(keyword) do
Enum.reduce(keyword, %{}, fn {key, value}, map ->
case Map.get(map, key) do
nil ->
Map.put(map, key, value)
existing_value ->
value = List.wrap(existing_value) ++ [value]
Map.put(map, key, value)
end
end)
end
defp context_app_to_atom(%{context_app: context_app} = config),
do: Map.put(config, :context_app, String.to_atom(context_app))
defp context_app_to_atom(config),
do: config
@doc """
Fetches context app for the project.
"""
@spec context_app :: atom() | no_return
def context_app do
this_app = otp_app()
this_app
|> Application.get_env(:generators, [])
|> Keyword.get(:context_app)
|> case do
nil -> this_app
false -> Mix.raise("No context_app configured for current application")
{app, _path} -> app
app -> app
end
end
defp otp_app do
Keyword.fetch!(Mix.Project.config(), :app)
end
@doc """
Fetches the context base module for the app.
"""
@spec context_base(atom()) :: atom()
def context_base(app) do
case Application.get_env(app, :namespace, app) do
^app ->
app
|> to_string()
|> Macro.camelize()
|> List.wrap()
|> Module.concat()
mod ->
mod
end
end
@doc """
Fetches the library path for the context app.
"""
@spec context_lib_path(atom(), Path.t()) :: Path.t()
def context_lib_path(ctx_app, rel_path) do
context_app_path(ctx_app, Path.join(["lib", to_string(ctx_app), rel_path]))
end
defp context_app_path(ctx_app, rel_path) when is_atom(ctx_app) do
this_app = otp_app()
if ctx_app == this_app do
rel_path
else
app_path =
case Application.get_env(this_app, :generators)[:context_app] do
{^ctx_app, path} -> Path.relative_to_cwd(path)
_ -> mix_app_path(ctx_app, this_app)
end
Path.join(app_path, rel_path)
end
end
defp mix_app_path(app, this_otp_app) do
case Mix.Project.deps_paths() do
%{^app => path} ->
Path.relative_to_cwd(path)
_deps ->
Mix.raise("No directory for context_app #{inspect(app)} found in #{this_otp_app}'s deps.")
end
end
end