From 1293479ac63641f1fd0b5453b7552e943a17c047 Mon Sep 17 00:00:00 2001
From: Dan Schultzer <dan@dreamconception.com>
Date: Sun, 3 Mar 2019 10:46:06 -0800
Subject: [PATCH] Remove deprecations and up requirements

New minimum:

- Elixir 1.7
- Ecto 3.0
- Phoenix 1.4
---
 .travis.yml                                   |  2 +-
 CHANGELOG.md                                  | 15 ++++++
 lib/extensions/reset_password/ecto/context.ex |  4 --
 lib/mix/pow.ex                                | 31 +----------
 lib/mix/pow/ecto/migration.ex                 | 14 +----
 lib/pow.ex                                    | 16 ------
 lib/pow/ecto/schema.ex                        |  4 --
 lib/pow/extension/config.ex                   | 16 ------
 .../phoenix/controllers/controller/base.ex    | 21 ++------
 .../controllers/controller_callbacks/base.ex  |  6 +--
 lib/pow/phoenix/html/bootstrap.ex             | 54 -------------------
 lib/pow/phoenix/html/form_template.ex         | 18 +------
 mix.exs                                       |  6 +--
 test/pow/phoenix/html/form_template_test.exs  | 13 -----
 14 files changed, 31 insertions(+), 189 deletions(-)
 delete mode 100644 lib/pow/phoenix/html/bootstrap.ex

diff --git a/.travis.yml b/.travis.yml
index 4106c6cd..a55137b7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,7 @@ env:
   - MIX_ENV=test
 matrix:
   include:
-    - elixir: 1.6
+    - elixir: 1.7
       otp_release: 20.0
     - elixir: 1.8
       otp_release: 21.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d9224f22..8e227792 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
 # Changelog
 
+## v1.1.0 (TBA)
+
+### Changes
+
+- Requires Elixir 1.7 or higher
+- Requires Ecto 3.0 or higher
+- Requires Phoenix 1.4 or higher
+
+### Deprecations
+
+- Removed deprecated method `PowResetPassword.Ecto.Context.password_changeset/2`
+- Removed deprecated method `Pow.Extension.Config.underscore_extension/1`
+- Config fallback set with `:messages_backend_fallback` configuration option removed in `Pow.Extension.Phoenix.Controller.Base`
+- Removed deprecated Bootstrap support in `Pow.Phoenix.HTML.FormTemplate`
+
 ## v1.0.4 (TBA)
 
 * Added `PowInvitation` to the `mix pow.extension.phoenix.gen.templates` and `mix pow.extension.phoenix.mailer.gen.templates` tasks
diff --git a/lib/extensions/reset_password/ecto/context.ex b/lib/extensions/reset_password/ecto/context.ex
index 77f5b02e..3cb20488 100644
--- a/lib/extensions/reset_password/ecto/context.ex
+++ b/lib/extensions/reset_password/ecto/context.ex
@@ -15,8 +15,4 @@ defmodule PowResetPassword.Ecto.Context do
     |> Schema.reset_password_changeset(params)
     |> Context.do_update(config)
   end
-
-  # TODO: Remove by 1.1.0
-  @deprecated "Use `PowResetPassword.Ecto.Schema.reset_password_changeset/2` instead"
-  def password_changeset(user, params), do: Schema.reset_password_changeset(user, params)
 end
diff --git a/lib/mix/pow.ex b/lib/mix/pow.ex
index 46a09f49..73dc9ebd 100644
--- a/lib/mix/pow.ex
+++ b/lib/mix/pow.ex
@@ -21,7 +21,8 @@ defmodule Mix.Pow do
   """
   @spec ensure_dep!(binary(), atom(), OptionParser.argv()) :: :ok | no_return
   def ensure_dep!(task, dep, _args) do
-    fetch_deps()
+    []
+    |> Dep.load_on_environment()
     |> dep_in_deps?(dep)
     |> case do
       true ->
@@ -32,16 +33,6 @@ defmodule Mix.Pow do
     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
@@ -131,24 +122,6 @@ defmodule Mix.Pow do
     """)
   end
 
-  # TODO: Remove by 1.1.0
-  @doc false
-  @deprecated "Please use `Pow.Phoenix.parse_structure/1` instead"
-  @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
-
   @doc false
   @spec otp_app :: atom() | no_return
   def otp_app do
diff --git a/lib/mix/pow/ecto/migration.ex b/lib/mix/pow/ecto/migration.ex
index f49d81aa..1f7e0c2e 100644
--- a/lib/mix/pow/ecto/migration.ex
+++ b/lib/mix/pow/ecto/migration.ex
@@ -2,7 +2,7 @@ defmodule Mix.Pow.Ecto.Migration do
   @moduledoc """
   Utilities module for ecto migrations in mix tasks.
   """
-  alias Mix.Generator
+  alias Mix.{EctoSQL, Generator}
 
   @doc """
   Creates a migration file for the repo.
@@ -12,7 +12,7 @@ defmodule Mix.Pow.Ecto.Migration do
     base_name = "#{Macro.underscore(name)}.exs"
     path      =
       repo
-      |> source_repo_priv()
+      |> EctoSQL.source_repo_priv()
       |> Path.join("migrations")
       |> maybe_create_directory()
     timestamp = timestamp(path)
@@ -63,14 +63,4 @@ defmodule Mix.Pow.Ecto.Migration do
 
   defp pad(i) when i < 10, do: <<?0, ?0 + i>>
   defp pad(i), do: to_string(i)
-
-  # TODO: Remove by 1.1.0 and only use Ecto 3.0
-  defp source_repo_priv(repo) do
-    mod =
-      if Pow.dependency_vsn_match?(:ecto, "< 3.0.0"),
-        do: Mix.Ecto,
-        else: Mix.EctoSQL
-
-    mod.source_repo_priv(repo)
-  end
 end
diff --git a/lib/pow.ex b/lib/pow.ex
index b8e6462c..614122b4 100644
--- a/lib/pow.ex
+++ b/lib/pow.ex
@@ -1,19 +1,3 @@
 defmodule Pow do
   @moduledoc false
-
-  @doc """
-  Checks for version requirement in dependencies.
-  """
-  @spec dependency_vsn_match?(atom(), binary()) :: boolean()
-  def dependency_vsn_match?(dep, req) do
-    case :application.get_key(dep, :vsn) do
-      {:ok, actual} ->
-        actual
-        |> List.to_string()
-        |> Version.match?(req)
-
-      _any ->
-        false
-    end
-  end
 end
diff --git a/lib/pow/ecto/schema.ex b/lib/pow/ecto/schema.ex
index 2957a198..4f028da4 100644
--- a/lib/pow/ecto/schema.ex
+++ b/lib/pow/ecto/schema.ex
@@ -215,10 +215,6 @@ defmodule Pow.Ecto.Schema do
     Enum.filter(fields, &not Enum.member?(existing_fields, {elem(&1, 0), elem(&1, 1)}))
   end
 
-  # TODO: Remove by 1.1.0
-  @deprecated "No longer public method"
-  def filter_new_fields(fields, existing_fields), do: __filter_new_fields__(fields, existing_fields)
-
   @doc false
   defmacro __register_fields__ do
     quote do
diff --git a/lib/pow/extension/config.ex b/lib/pow/extension/config.ex
index 76a6aef9..241946fa 100644
--- a/lib/pow/extension/config.ex
+++ b/lib/pow/extension/config.ex
@@ -25,20 +25,4 @@ defmodule Pow.Extension.Config do
     |> Enum.map(&Module.concat([&1] ++ module_list))
     |> Enum.filter(&Code.ensure_compiled?/1)
   end
-
-  # TODO: Remove by 1.1.0
-  @doc """
-  Returns a binary of the extension atom.
-
-  This is usually used to create extension namespaces for methods to be used
-  in shared modules.
-  """
-  @deprecated "Create the namespace directly in your module"
-  @spec underscore_extension(atom()) :: binary()
-  def underscore_extension(extension) do
-    extension
-    |> Module.split()
-    |> List.first()
-    |> Macro.underscore()
-  end
 end
diff --git a/lib/pow/extension/phoenix/controllers/controller/base.ex b/lib/pow/extension/phoenix/controllers/controller/base.ex
index 461ffdf3..b3d7bdf8 100644
--- a/lib/pow/extension/phoenix/controllers/controller/base.ex
+++ b/lib/pow/extension/phoenix/controllers/controller/base.ex
@@ -10,21 +10,21 @@ defmodule Pow.Extension.Phoenix.Controller.Base do
         # ...
       end
   """
-  alias Pow.{Config, Phoenix.Controller, Phoenix.Routes}
+  alias Pow.{Phoenix.Controller, Phoenix.Routes}
 
   @doc false
   defmacro __using__(config) do
     quote do
       use Controller, unquote(config)
 
-      unquote(__MODULE__).__define_helper_methods__(unquote(config))
+      unquote(__MODULE__).__define_helper_methods__()
     end
   end
 
   @doc false
-  defmacro __define_helper_methods__(config) do
+  defmacro __define_helper_methods__() do
     quote do
-      @messages_fallback unquote(__MODULE__).__messages_fallback__(unquote(config), __MODULE__, __ENV__)
+      @messages_fallback unquote(__MODULE__).__messages_fallback__(__MODULE__)
 
       @doc false
       def messages(conn), do: unquote(__MODULE__).__messages_module__(conn, @messages_fallback)
@@ -54,17 +54,4 @@ defmodule Pow.Extension.Phoenix.Controller.Base do
     |> Enum.reverse()
     |> Module.concat()
   end
-
-  # TODO: Remove config fallback by 1.1.0
-  def __messages_fallback__(config, module, env) do
-    case Config.get(config, :messages_backend_fallback) do
-      nil    ->
-        __messages_fallback__(module)
-
-      module ->
-        IO.warn("Passing `:messages_backend_fallback` is deprecated", Macro.Env.stacktrace(env))
-
-        module
-    end
-  end
 end
diff --git a/lib/pow/extension/phoenix/controllers/controller_callbacks/base.ex b/lib/pow/extension/phoenix/controllers/controller_callbacks/base.ex
index d19e4639..ea4909b7 100644
--- a/lib/pow/extension/phoenix/controllers/controller_callbacks/base.ex
+++ b/lib/pow/extension/phoenix/controllers/controller_callbacks/base.ex
@@ -19,13 +19,13 @@ defmodule Pow.Extension.Phoenix.ControllerCallbacks.Base do
   @callback before_respond(atom(), atom(), any(), Config.t()) :: any()
 
   @doc false
-  defmacro __using__(config) do
+  defmacro __using__(_config) do
     quote do
       @behaviour unquote(__MODULE__)
 
-      import Base, only: [__define_helper_methods__: 1]
+      import Base, only: [__define_helper_methods__: 0]
 
-      __define_helper_methods__(unquote(config))
+      __define_helper_methods__()
 
       @before_compile unquote(__MODULE__)
     end
diff --git a/lib/pow/phoenix/html/bootstrap.ex b/lib/pow/phoenix/html/bootstrap.ex
deleted file mode 100644
index b9c1a123..00000000
--- a/lib/pow/phoenix/html/bootstrap.ex
+++ /dev/null
@@ -1,54 +0,0 @@
-defmodule Pow.Phoenix.HTML.Bootstrap do
-  # TODO: Remove module by 1.1.0 and only support Phoenix 1.4.0
-
-  @moduledoc """
-  Module that helps build HTML for Phoenix with Bootstrap CSS.
-  """
-  import Pow.Phoenix.HTML.FormTemplate, only: [inspect_key: 1]
-
-  @form_template EEx.compile_string(
-    """
-    <%%= form_for @changeset, @action, [as: :user], fn f -> %>
-      <%%= if @changeset.action do %>
-        <div class="alert alert-danger">
-          <p>Oops, something went wrong! Please check the errors below.</p>
-        </div>
-      <%% end %>
-    <%= for {label, input, error} <- inputs, input do %>
-      <div class="form-group">
-        <%= label %>
-        <%= input %>
-        <%= error %>
-      </div>
-    <% end %>
-      <div class="form-group">
-        <%%= submit <%= inspect button_label %>, class: "btn btn-primary" %>
-      </div>
-    <%% end %>
-    """)
-
-  @doc """
-  Renders a form.
-  """
-  @spec render_form(list(), binary()) :: Macro.t()
-  def render_form(inputs, button_label) do
-    inputs = for {type, key} <- inputs, do: input(type, key)
-
-    unquote(@form_template)
-  end
-
-  defp input(:text, key) do
-    {label(key), ~s(<%= text_input f, #{inspect_key(key)}, class: "form-control" %>), error(key)}
-  end
-  defp input(:password, key) do
-    {label(key), ~s(<%= password_input f, #{inspect_key(key)}, class: "form-control" %>), error(key)}
-  end
-
-  defp label(key) do
-    ~s(<%= label f, #{inspect_key(key)}, class: "control-label" %>)
-  end
-
-  defp error(key) do
-    ~s(<%= error_tag f, #{inspect_key(key)} %>)
-  end
-end
diff --git a/lib/pow/phoenix/html/form_template.ex b/lib/pow/phoenix/html/form_template.ex
index dfee4de1..22352e19 100644
--- a/lib/pow/phoenix/html/form_template.ex
+++ b/lib/pow/phoenix/html/form_template.ex
@@ -1,11 +1,7 @@
 defmodule Pow.Phoenix.HTML.FormTemplate do
   @moduledoc """
   Module that can build user form templates for Phoenix.
-
-  For Phoenix 1.3, or bootstrap templates, `Pow.Phoenix.HTML.Bootstrap` can be
-  used.
   """
-  alias Pow.Phoenix.HTML.Bootstrap
 
   @template EEx.compile_string(
     """
@@ -32,24 +28,12 @@ defmodule Pow.Phoenix.HTML.FormTemplate do
   ## Options
 
     * `:button_label` - the submit button label, defaults to "Submit".
-    * `:bootstrap` - to render form as bootstrap, defaults to false with
-      phoenix 1.4 and true with phoenix 1.3.
   """
   @spec render(list(), Keyword.t()) :: Macro.t()
   def render(inputs, opts \\ []) do
     button_label = Keyword.get(opts, :button_label, "Submit")
 
-    case bootstrap?(opts) do
-      true -> Bootstrap.render_form(inputs, button_label)
-      _any -> render_form(inputs, button_label)
-    end
-  end
-
-  # TODO: Remove bootstrap support by 1.1.0 and only support Phoenix 1.4.0
-  defp bootstrap?(opts) do
-    bootstrap = Pow.dependency_vsn_match?(:phoenix, "~> 1.3.0")
-
-    Keyword.get(opts, :bootstrap, bootstrap)
+    render_form(inputs, button_label)
   end
 
   defp render_form(inputs, button_label) do
diff --git a/mix.exs b/mix.exs
index 92a2ea90..4cc74f7f 100644
--- a/mix.exs
+++ b/mix.exs
@@ -7,7 +7,7 @@ defmodule Pow.MixProject do
     [
       app: :pow,
       version: @version,
-      elixir: "~> 1.6",
+      elixir: "~> 1.7",
       elixirc_paths: elixirc_paths(Mix.env()),
       start_permanent: Mix.env() == :prod,
       compilers: [:phoenix] ++ Mix.compilers(),
@@ -35,8 +35,8 @@ defmodule Pow.MixProject do
 
   defp deps do
     [
-      {:ecto, "~> 2.2 or ~> 3.0"},
-      {:phoenix, "~> 1.3.0 or ~> 1.4.0"},
+      {:ecto, "~> 3.0"},
+      {:phoenix, "~> 1.4.0"},
       {:phoenix_html, ">= 2.0.0 and <= 3.0.0"},
       {:plug, ">= 1.5.0 and < 1.8.0", optional: true},
 
diff --git a/test/pow/phoenix/html/form_template_test.exs b/test/pow/phoenix/html/form_template_test.exs
index 69cfece1..45941767 100644
--- a/test/pow/phoenix/html/form_template_test.exs
+++ b/test/pow/phoenix/html/form_template_test.exs
@@ -16,17 +16,4 @@ defmodule Pow.Phoenix.HTML.FormTemplateTest do
     assert html =~ "<%= password_input f, :password %>"
     assert html =~ "<%= error_tag f, :password %>"
   end
-
-  test "render/2 with bootstrap" do
-    html = FormTemplate.render([
-      {:text, {:changeset, :pow_user_id_field}},
-      {:password, :password},
-      {:password, :confirm_password}
-    ], bootstrap: true)
-
-    assert html =~ "<div class=\"form-group\">"
-    assert html =~ "<%= label f, :password, class: \"control-label\" %>"
-    assert html =~ "<%= password_input f, :password, class: \"form-control\" %>"
-    assert html =~ "<%= error_tag f, :password %>"
-  end
 end