Repository: phoenixframework/phoenix
Pull request #3556 (2019-09-18 16:35:56)

Merge arguments from supervisor into endpoint configuration
This allows passing additional configuration options in supervisor spec, ex.:

```elixir
children = [
  {MyApp.Endpoint, url: [path: "/api"]}
]
```

Will be the same as setting:

```elixir
config :my_app, MyApp.Endpoint, url: [path: "/api"]
```

---

Configuration still overwrite values set in supervisor, so:

```elixir
children = [
  {MyApp.Endpoint, url: [path: "/foo"]}
]
```

and

```elixir
config :my_app, MyApp.Endpoint, url: [path: "/bar"]
```

Will result in:

```elixir
assert "/bar" == MyApp.Endpoint.config(:url)[:path]
```


Patch:
diff --git a/lib/phoenix/config.ex b/lib/phoenix/config.ex
index 1aff40c40..67dc513d7 100644
--- a/lib/phoenix/config.ex
+++ b/lib/phoenix/config.ex
@@ -70,9 +70,18 @@ defmodule Phoenix.Config do
   Useful to read a particular value at compilation time.
   """
   def from_env(otp_app, module, defaults) do
-    Keyword.merge(defaults, fetch_config(otp_app, module), &merger/3)
+    config = fetch_config(otp_app, module)
+
+    merge(defaults, config)
   end
 
+  @doc """
+  Take 2 keyword lists and merge them recursively.
+
+  Used to merge configuration values into defaults.
+  """
+  def merge(a, b), do: Keyword.merge(a, b, &merger/3)
+
   defp fetch_config(otp_app, module) do
     case Application.fetch_env(otp_app, module) do
       {:ok, conf} -> conf
diff --git a/lib/phoenix/endpoint.ex b/lib/phoenix/endpoint.ex
index 98d68b75f..147102cc2 100644
--- a/lib/phoenix/endpoint.ex
+++ b/lib/phoenix/endpoint.ex
@@ -486,8 +486,8 @@ defmodule Phoenix.Endpoint do
       @doc """
       Starts the endpoint supervision tree.
       """
-      def start_link(_opts \\ []) do
-        Phoenix.Endpoint.Supervisor.start_link(@otp_app, __MODULE__)
+      def start_link(opts \\ []) do
+        Phoenix.Endpoint.Supervisor.start_link(@otp_app, __MODULE__, opts)
       end
 
       @doc """
diff --git a/lib/phoenix/endpoint/supervisor.ex b/lib/phoenix/endpoint/supervisor.ex
index dc1f572d2..5704a4c71 100644
--- a/lib/phoenix/endpoint/supervisor.ex
+++ b/lib/phoenix/endpoint/supervisor.ex
@@ -10,8 +10,8 @@ defmodule Phoenix.Endpoint.Supervisor do
   @doc """
   Starts the endpoint supervision tree.
   """
-  def start_link(otp_app, mod) do
-    case Supervisor.start_link(__MODULE__, {otp_app, mod}, name: mod) do
+  def start_link(otp_app, mod, opts \\ []) do
+    case Supervisor.start_link(__MODULE__, {otp_app, mod, opts}, name: mod) do
       {:ok, _} = ok ->
         warmup(mod)
         log_access_info(otp_app, mod)
@@ -23,8 +23,8 @@ defmodule Phoenix.Endpoint.Supervisor do
   end
 
   @doc false
-  def init({otp_app, mod}) do
-    default_conf = defaults(otp_app, mod)
+  def init({otp_app, mod, opts}) do
+    default_conf = Phoenix.Config.merge(defaults(otp_app, mod), opts)
     env_conf = config(otp_app, mod, default_conf)
 
     secret_conf =


Test patch:
diff --git a/test/phoenix/endpoint/endpoint_test.exs b/test/phoenix/endpoint/endpoint_test.exs
index 1ed925810..c07e4368f 100644
--- a/test/phoenix/endpoint/endpoint_test.exs
+++ b/test/phoenix/endpoint/endpoint_test.exs
@@ -105,8 +105,6 @@ defmodule Phoenix.Endpoint.EndpointTest do
 
   @tag :capture_log
   test "invokes init/2 callback" do
-    Application.put_env(:phoenix, __MODULE__.InitEndpoint, parent: self())
-
     defmodule InitEndpoint do
       use Phoenix.Endpoint, otp_app: :phoenix
 
@@ -116,7 +114,7 @@ defmodule Phoenix.Endpoint.EndpointTest do
       end
     end
 
-    {:ok, pid} = InitEndpoint.start_link()
+    {:ok, pid} = InitEndpoint.start_link(parent: self())
     assert_receive {^pid, :sample}
   end