Skip to content

Commit 9df7a54

Browse files
marcandrejosevalim
authored andcommitted
Make sure .beam files still exist for restored files (#11187)
1 parent 9137fd1 commit 9df7a54

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

lib/mix/lib/mix/compilers/elixir.ex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ defmodule Mix.Compilers.Elixir do
176176
{[], %{}, all_paths, sources_stats}
177177
end
178178

179+
# Assume that either all .beam files are missing, or none of them are
180+
defp missing_beam_file?(dest, [mod | _]), do: not File.exists?(beam_path(dest, mod))
181+
defp missing_beam_file?(_dest, []), do: false
182+
179183
defp compiler_info_from_updated(
180184
modified,
181185
all_paths,
@@ -213,7 +217,10 @@ defmodule Mix.Compilers.Elixir do
213217
times = Enum.map(external, &(sources_stats |> Map.fetch!(&1) |> elem(0))),
214218
Enum.any?(modules, &Map.has_key?(modules_to_recompile, &1)) or
215219
Mix.Utils.stale?(times, [modified]) or
216-
(size != last_size or (last_mtime > modified and digest != digest(source))),
220+
(size != last_size or
221+
(last_mtime > modified and
222+
(missing_beam_file?(dest, modules) or
223+
digest != digest(source)))),
217224
do: source
218225

219226
changed = new_paths ++ changed

lib/mix/test/mix/tasks/compile.elixir_test.exs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,41 @@ defmodule Mix.Tasks.Compile.ElixirTest do
257257
end)
258258
end
259259

260+
test "does recompile a file restored after a compile error (and .beam file were deleted)" do
261+
in_fixture("no_mixfile", fn ->
262+
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
263+
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
264+
assert_received {:mix_shell, :info, ["Compiled lib/b.ex"]}
265+
266+
Mix.shell().flush
267+
purge([A, B])
268+
269+
# Compile with error
270+
original_content = File.read!("lib/b.ex")
271+
File.write!("lib/b.ex", "this will not compile")
272+
273+
assert capture_io(fn ->
274+
{:error, _} = Mix.Tasks.Compile.Elixir.run(["--verbose"])
275+
end) =~ "Compilation error in file lib/b.ex"
276+
277+
assert_received {:mix_shell, :info, ["Compiling 1 file (.ex)"]}
278+
279+
# Revert change
280+
File.write!("lib/b.ex", original_content)
281+
future = {{2038, 1, 1}, {0, 0, 0}}
282+
File.touch!("lib/b.ex", future)
283+
284+
Mix.Tasks.Compile.Elixir.run(["--verbose"])
285+
286+
message =
287+
"warning: mtime (modified time) for \"lib/b.ex\" was set to the future, resetting to now"
288+
289+
assert_received {:mix_shell, :error, [^message]}
290+
assert_received {:mix_shell, :info, ["Compiled lib/b.ex"]}
291+
refute_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
292+
end)
293+
end
294+
260295
test "compiles size changed files" do
261296
in_fixture("no_mixfile", fn ->
262297
past = {{2010, 1, 1}, {0, 0, 0}}

0 commit comments

Comments
 (0)