Skip to content

Commit e00cbe1

Browse files
committed
Revert content tracking instead of mtime.
1 parent 9df7a54 commit e00cbe1

File tree

4 files changed

+18
-107
lines changed

4 files changed

+18
-107
lines changed

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

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Mix.Compilers.Elixir do
22
@moduledoc false
33

4-
@manifest_vsn 9
4+
@manifest_vsn 8
55

66
import Record
77

@@ -10,7 +10,6 @@ defmodule Mix.Compilers.Elixir do
1010
defrecord :source,
1111
source: nil,
1212
size: 0,
13-
digest: nil,
1413
compile_references: [],
1514
export_references: [],
1615
runtime_references: [],
@@ -176,10 +175,6 @@ defmodule Mix.Compilers.Elixir do
176175
{[], %{}, all_paths, sources_stats}
177176
end
178177

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-
183178
defp compiler_info_from_updated(
184179
modified,
185180
all_paths,
@@ -211,16 +206,12 @@ defmodule Mix.Compilers.Elixir do
211206
# Sources that have changed on disk or
212207
# any modules associated with them need to be recompiled
213208
changed =
214-
for source(source: source, external: external, size: size, digest: digest, modules: modules) <-
209+
for source(source: source, external: external, size: size, modules: modules) <-
215210
all_sources,
216211
{last_mtime, last_size} = Map.fetch!(sources_stats, source),
217212
times = Enum.map(external, &(sources_stats |> Map.fetch!(&1) |> elem(0))),
218-
Enum.any?(modules, &Map.has_key?(modules_to_recompile, &1)) or
219-
Mix.Utils.stale?(times, [modified]) or
220-
(size != last_size or
221-
(last_mtime > modified and
222-
(missing_beam_file?(dest, modules) or
223-
digest != digest(source)))),
213+
size != last_size or Mix.Utils.stale?([last_mtime | times], [modified]) or
214+
Enum.any?(modules, &Map.has_key?(modules_to_recompile, &1)),
224215
do: source
225216

226217
changed = new_paths ++ changed
@@ -255,12 +246,6 @@ defmodule Mix.Compilers.Elixir do
255246
end)
256247
end
257248

258-
defp digest(file) do
259-
file
260-
|> File.read!()
261-
|> :erlang.md5()
262-
end
263-
264249
defp compile_path(stale, dest, timestamp, opts) do
265250
cwd = File.cwd!()
266251
long_compilation_threshold = opts[:long_compilation_threshold] || 10
@@ -475,8 +460,6 @@ defmodule Mix.Compilers.Elixir do
475460
source =
476461
source(
477462
source,
478-
# We preserve the digest if the file is recompiled but not changed
479-
digest: source(source, :digest) || digest(file),
480463
compile_references: compile_references,
481464
export_references: export_references,
482465
runtime_references: runtime_references,
@@ -526,11 +509,11 @@ defmodule Mix.Compilers.Elixir do
526509
# to be recompiled (but were not changed on disk)
527510
defp update_stale_sources(sources, changed) do
528511
Enum.reduce(changed, {sources, %{}}, fn file, {acc_sources, acc_modules} ->
529-
{source(size: size, digest: digest, modules: modules), acc_sources} =
512+
{source(size: size, modules: modules), acc_sources} =
530513
List.keytake(acc_sources, file, source(:source))
531514

532515
acc_modules = Enum.reduce(modules, acc_modules, &Map.put(&2, &1, true))
533-
{[source(source: file, size: size, digest: digest) | acc_sources], acc_modules}
516+
{[source(source: file, size: size) | acc_sources], acc_modules}
534517
end)
535518
end
536519

@@ -717,15 +700,11 @@ defmodule Mix.Compilers.Elixir do
717700
{@manifest_vsn, modules, sources, local_exports} ->
718701
{modules, sources, local_exports}
719702

720-
# v8-v* (v1.11)
721-
{vsn, modules, _sources, _local_exports} when is_integer(vsn) ->
722-
purge_old_manifest(compile_path, modules)
723-
724-
# v5-v7 (v1.10)
703+
# From v5 and later
725704
{vsn, modules, _sources} when is_integer(vsn) ->
726705
purge_old_manifest(compile_path, modules)
727706

728-
# v1-v4
707+
# From v4 and before
729708
[vsn | data] when is_integer(vsn) ->
730709
purge_old_manifest(compile_path, data)
731710

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

Lines changed: 8 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ defmodule Mix.Tasks.Compile.ElixirTest do
195195
end)
196196
end
197197

198-
test "compiles mtime changed files if content changed but not length" do
198+
test "compiles mtime changed files" do
199199
in_fixture("no_mixfile", fn ->
200200
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
201201
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
@@ -204,8 +204,6 @@ defmodule Mix.Tasks.Compile.ElixirTest do
204204
Mix.shell().flush
205205
purge([A, B])
206206

207-
same_length_content = "lib/a.ex" |> File.read!() |> String.replace("A", "Z")
208-
File.write!("lib/a.ex", same_length_content)
209207
future = {{2038, 1, 1}, {0, 0, 0}}
210208
File.touch!("lib/a.ex", future)
211209
Mix.Tasks.Compile.Elixir.run(["--verbose"])
@@ -227,71 +225,6 @@ defmodule Mix.Tasks.Compile.ElixirTest do
227225
end)
228226
end
229227

230-
test "does not recompile mtime changed but identical files" do
231-
in_fixture("no_mixfile", fn ->
232-
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
233-
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
234-
assert_received {:mix_shell, :info, ["Compiled lib/b.ex"]}
235-
236-
Mix.shell().flush
237-
purge([A, B])
238-
239-
future = {{2038, 1, 1}, {0, 0, 0}}
240-
File.touch!("lib/a.ex", future)
241-
Mix.Tasks.Compile.Elixir.run(["--verbose"])
242-
243-
message =
244-
"warning: mtime (modified time) for \"lib/a.ex\" was set to the future, resetting to now"
245-
246-
assert_received {:mix_shell, :error, [^message]}
247-
248-
message =
249-
"warning: mtime (modified time) for \"lib/b.ex\" was set to the future, resetting to now"
250-
251-
refute_received {:mix_shell, :error, [^message]}
252-
refute_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
253-
refute_received {:mix_shell, :info, ["Compiled lib/b.ex"]}
254-
255-
File.touch!("_build/dev/lib/sample/.mix/compile.elixir", future)
256-
assert Mix.Tasks.Compile.Elixir.run([]) == {:noop, []}
257-
end)
258-
end
259-
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-
295228
test "compiles size changed files" do
296229
in_fixture("no_mixfile", fn ->
297230
past = {{2010, 1, 1}, {0, 0, 0}}
@@ -324,7 +257,8 @@ defmodule Mix.Tasks.Compile.ElixirTest do
324257
Mix.shell().flush
325258
purge([A, B])
326259

327-
force_recompilation("lib/b.ex")
260+
future = {{2038, 1, 1}, {0, 0, 0}}
261+
File.touch!("lib/b.ex", future)
328262
Mix.Tasks.Compile.Elixir.run(["--verbose"])
329263

330264
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
@@ -349,7 +283,7 @@ defmodule Mix.Tasks.Compile.ElixirTest do
349283

350284
Code.put_compiler_option(:ignore_module_conflict, true)
351285
Code.compile_file("lib/b.ex")
352-
force_recompilation("lib/a.ex")
286+
File.touch!("lib/a.ex", {{2038, 1, 1}, {0, 0, 0}})
353287

354288
Mix.Tasks.Compile.Elixir.run(["--verbose"])
355289
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
@@ -538,7 +472,8 @@ defmodule Mix.Tasks.Compile.ElixirTest do
538472
assert_received {:mix_shell, :info, ["Compiled lib/b.ex"]}
539473
purge([A, B])
540474

541-
force_recompilation("lib/a.ex")
475+
future = {{2038, 1, 1}, {0, 0, 0}}
476+
File.touch!("lib/a.ex", future)
542477

543478
assert Mix.Tasks.Compile.Elixir.run(["--verbose"]) == {:ok, []}
544479
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}
@@ -680,7 +615,8 @@ defmodule Mix.Tasks.Compile.ElixirTest do
680615
Mix.shell().flush
681616
purge([A, B])
682617

683-
force_recompilation("lib/a.ex")
618+
future = {{2038, 1, 1}, {0, 0, 0}}
619+
File.touch!("lib/a.ex", future)
684620
Mix.Tasks.Compile.Elixir.run(["--verbose"])
685621

686622
assert_received {:mix_shell, :info, ["Compiled lib/a.ex"]}

lib/mix/test/mix/tasks/test_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ defmodule Mix.Tasks.TestTest do
6868
assert_stale_run_output("2 tests, 0 failures")
6969

7070
set_all_mtimes()
71-
force_recompilation("lib/b.ex")
71+
File.touch!("lib/b.ex")
7272

7373
assert_stale_run_output("1 test, 0 failures")
7474

7575
set_all_mtimes()
76-
force_recompilation("lib/a.ex")
76+
File.touch!("lib/a.ex")
7777

7878
assert_stale_run_output("2 tests, 0 failures")
7979
end)

lib/mix/test/test_helper.exs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,6 @@ defmodule MixTest.Case do
179179
])
180180
end
181181

182-
def force_recompilation(file) do
183-
File.write!(file, File.read!(file) <> "\n")
184-
end
185-
186182
defp mix_executable do
187183
Path.expand("../../../bin/mix", __DIR__)
188184
end

0 commit comments

Comments
 (0)