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
6 changes: 6 additions & 0 deletions lib/elixir/src/elixir.erl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ start(_Type, _Args) ->
application:set_env(elixir, ansi_enabled, prim_tty:isatty(stdout) == true)
end,

%% Store the initial dbg_callback value before any runtime modifications.
%% This allows Mix compiler to detect config changes vs runtime changes
%% (e.g., Kino wrapping dbg_callback at runtime should not trigger recompilation).
{ok, InitialDbgCallback} = application:get_env(elixir, dbg_callback),

Tokenizer = case code:ensure_loaded('Elixir.String.Tokenizer') of
{module, Mod} -> Mod;
_ -> elixir_tokenizer
Expand All @@ -90,6 +95,7 @@ start(_Type, _Args) ->
{docs, true},
{ignore_already_consolidated, false},
{ignore_module_conflict, false},
{initial_dbg_callback, InitialDbgCallback},
{infer_signatures, [elixir]},
{on_undefined_variable, raise},
{parser_options, [{columns, true}]},
Expand Down
8 changes: 7 additions & 1 deletion lib/mix/lib/mix/compilers/elixir.ex
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,13 @@ defmodule Mix.Compilers.Elixir do
end

defp deps_config_compile_env_apps(deps_config) do
if deps_config[:dbg] != Application.fetch_env!(:elixir, :dbg_callback) do
# Use initial_dbg_callback instead of dbg_callback to ignore runtime modifications.
# Tools like Kino modify dbg_callback at runtime to customize dbg/2 behavior,
# but this should not trigger recompilation since the config hasn't actually changed.
# initial_dbg_callback is set when :elixir app starts, before any runtime modifications.
initial_dbg = :elixir_config.get(:initial_dbg_callback)

if deps_config[:dbg] != initial_dbg do
[:elixir]
else
[]
Expand Down
33 changes: 32 additions & 1 deletion lib/mix/test/mix/tasks/compile.elixir_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,11 @@ defmodule Mix.Tasks.Compile.ElixirTest do
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
assert_received {:mix_shell, :info, ["Compiled lib/b.ex"]}

# Change the dbg_callback at runtime
# Simulate a config change by updating both dbg_callback and initial_dbg_callback.
# This represents the case where the user actually changed the config file.
File.touch!("_build/dev/lib/sample/.mix/compile.elixir", @old_time)
Application.put_env(:elixir, :dbg_callback, {__MODULE__, :dbg, []})
:elixir_config.put(:initial_dbg_callback, {__MODULE__, :dbg, []})

assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
Expand All @@ -289,6 +291,35 @@ defmodule Mix.Tasks.Compile.ElixirTest do
end)
after
Application.put_env(:elixir, :dbg_callback, {Macro, :dbg, []})
:elixir_config.put(:initial_dbg_callback, {Macro, :dbg, []})
end

test "does not recompile when dbg_callback is modified at runtime but initial is unchanged" do
in_fixture("no_mixfile", fn ->
Mix.Project.push(MixTest.Case.Sample)

File.write!("lib/a.ex", """
defmodule A do
def a, do: dbg(:ok)
end
""")

assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}

# Simulate a tool like Kino modifying dbg_callback at runtime.
# Since initial_dbg_callback remains unchanged, this should NOT trigger recompilation.
original_dbg = Application.fetch_env!(:elixir, :dbg_callback)
:elixir_config.put(:initial_dbg_callback, original_dbg)
Application.put_env(:elixir, :dbg_callback, {SomeDebugTool, :dbg, [original_dbg]})

# Should NOT trigger recompilation since initial_dbg_callback is unchanged
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:noop, []}
refute_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
end)
after
Application.put_env(:elixir, :dbg_callback, {Macro, :dbg, []})
:elixir_config.put(:initial_dbg_callback, {Macro, :dbg, []})
end

test "recompiles files when config changes export dependencies" do
Expand Down
Loading