Skip to content

Commit

Permalink
Add :reloadable_args to code server
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Apr 28, 2023
1 parent ed121ed commit 7547df0
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 23 deletions.
6 changes: 5 additions & 1 deletion lib/phoenix/code_reloader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ defmodule Phoenix.CodeReloader do
config :your_app, YourAppWeb.Endpoint,
reloadable_compilers: [:gettext, :elixir],
reloadable_apps: [:ui, :backend]
reloadable_apps: [:ui, :backend],
reloadable_args: ["--no-all-warnings"]
Keep in mind `:reloadable_compilers` must be a subset of the
`:compilers` specified in `project/0` in your `mix.exs`.
Expand All @@ -29,6 +30,9 @@ defmodule Phoenix.CodeReloader do
effectively disable the code reloader, or include external
applications from library dependencies.
`:reloadable_args` is a list of command line options to give
to `mix compile` and its underlying compilers.
This function is a no-op and returns `:ok` if Mix is not available.
"""
@spec reload(module) :: :ok | {:error, binary()}
Expand Down
31 changes: 16 additions & 15 deletions lib/phoenix/code_reloader/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ defmodule Phoenix.CodeReloader.Server do

def handle_call({:reload!, endpoint}, from, state) do
compilers = endpoint.config(:reloadable_compilers)
reloadable_apps = endpoint.config(:reloadable_apps) || default_reloadable_apps()
apps = endpoint.config(:reloadable_apps) || default_reloadable_apps()
args = endpoint.config(:reloadable_args) || []

# We do a backup of the endpoint in case compilation fails.
# If so we can bring it back to finish the request handling.
Expand All @@ -70,7 +71,7 @@ defmodule Phoenix.CodeReloader.Server do
{res, out} =
proxy_io(fn ->
try do
mix_compile(Code.ensure_loaded(Mix.Task), compilers, reloadable_apps, state.timestamp)
mix_compile(Code.ensure_loaded(Mix.Task), compilers, apps, args, state.timestamp)
catch
:exit, {:shutdown, 1} ->
:error
Expand Down Expand Up @@ -174,7 +175,7 @@ defmodule Phoenix.CodeReloader.Server do
defp purge_protocols(_path), do: :ok
end

defp mix_compile({:module, Mix.Task}, compilers, apps_to_reload, timestamp) do
defp mix_compile({:module, Mix.Task}, compilers, apps_to_reload, compile_args, timestamp) do
config = Mix.Project.config()
path = Mix.Project.consolidation_path(config)

Expand All @@ -183,8 +184,8 @@ defmodule Phoenix.CodeReloader.Server do
purge_protocols(path)
end

mix_compile_deps(Mix.Dep.cached(), apps_to_reload, compilers, timestamp, path)
mix_compile_project(config[:app], apps_to_reload, compilers, timestamp, path)
mix_compile_deps(Mix.Dep.cached(), apps_to_reload, compile_args, compilers, timestamp, path)
mix_compile_project(config[:app], apps_to_reload, compile_args, compilers, timestamp, path)

if config[:consolidate_protocols] do
Code.prepend_path(path)
Expand All @@ -193,30 +194,30 @@ defmodule Phoenix.CodeReloader.Server do
:ok
end

defp mix_compile({:error, _reason}, _, _, _) do
defp mix_compile({:error, _reason}, _, _, _, _) do
raise "the Code Reloader is enabled but Mix is not available. If you want to " <>
"use the Code Reloader in production or inside an escript, you must add " <>
":mix to your applications list. Otherwise, you must disable code reloading " <>
"in such environments"
end

defp mix_compile_deps(deps, apps_to_reload, compilers, timestamp, path) do
defp mix_compile_deps(deps, apps_to_reload, compile_args, compilers, timestamp, path) do
for dep <- deps, dep.app in apps_to_reload do
Mix.Dep.in_dependency(dep, fn _ ->
mix_compile_unless_stale_config(compilers, timestamp, path)
mix_compile_unless_stale_config(compilers, compile_args, timestamp, path)
end)
end
end

defp mix_compile_project(nil, _, _, _, _), do: :ok
defp mix_compile_project(nil, _, _, _, _, _), do: :ok

defp mix_compile_project(app, apps_to_reload, compilers, timestamp, path) do
defp mix_compile_project(app, apps_to_reload, compile_args, compilers, timestamp, path) do
if app in apps_to_reload do
mix_compile_unless_stale_config(compilers, timestamp, path)
mix_compile_unless_stale_config(compilers, compile_args, timestamp, path)
end
end

defp mix_compile_unless_stale_config(compilers, timestamp, path) do
defp mix_compile_unless_stale_config(compilers, compile_args, timestamp, path) do
manifests = Mix.Tasks.Compile.Elixir.manifests()
configs = Mix.Project.config_files()
config = Mix.Project.config()
Expand All @@ -229,7 +230,7 @@ defmodule Phoenix.CodeReloader.Server do
purge_modules(Path.join(Mix.Project.app_path(config), "ebin"))
end

mix_compile(compilers, config, path)
mix_compile(compilers, compile_args, config, path)

files ->
raise """
Expand All @@ -243,7 +244,7 @@ defmodule Phoenix.CodeReloader.Server do
end
end

defp mix_compile(compilers, config, consolidation_path) do
defp mix_compile(compilers, compile_args, config, consolidation_path) do
all = config[:compilers] || Mix.compilers()

compilers =
Expand All @@ -255,7 +256,7 @@ defmodule Phoenix.CodeReloader.Server do
# We call build_structure mostly for Windows so new
# assets in priv are copied to the build directory.
Mix.Project.build_structure(config)
args = ["--purge-consolidation-path-if-stale", consolidation_path]
args = ["--purge-consolidation-path-if-stale", consolidation_path | compile_args]
result = run_compilers(compilers, args, [])

cond do
Expand Down
10 changes: 3 additions & 7 deletions test/phoenix/code_reloader_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ defmodule Phoenix.CodeReloaderTest do
use RouterHelper

defmodule Endpoint do
def config(:reloadable_compilers) do
[:unknown_compiler, :elixir]
end

def config(:reloadable_apps) do
nil
end
def config(:reloadable_compilers), do: [:unknown_compiler, :elixir]
def config(:reloadable_apps), do: nil
def config(:reloadable_args), do: nil
end

def reload(_) do
Expand Down

0 comments on commit 7547df0

Please sign in to comment.