@@ -6,7 +6,7 @@ defmodule Mix.Compilers.Elixir do
66 @ moduledoc false
77
88 @ manifest_vsn 34
9- @ checkpoint_vsn 4
9+ @ checkpoint_vsn 5
1010
1111 import Record
1212
@@ -163,8 +163,7 @@ defmodule Mix.Compilers.Elixir do
163163 removed ,
164164 Map . merge ( stale_modules , removed_modules ) ,
165165 Map . merge ( stale_exports , removed_modules ) ,
166- dest ,
167- timestamp
166+ dest
168167 )
169168 end
170169
@@ -387,36 +386,17 @@ defmodule Mix.Compilers.Elixir do
387386 removed ,
388387 stale_modules ,
389388 stale_exports ,
390- dest ,
391- timestamp
389+ dest
392390 ) do
393- { checkpoint_stale_modules , checkpoint_stale_exports } =
391+ { checkpoint_stale_modules , checkpoint_stale_exports , checkpoint_changed } =
394392 case parse_checkpoint ( :update , manifest ) do
395- { :ok , { _ , _ } = data } -> data
396- :error -> { % { } , % { } }
393+ { :ok , { _ , _ , _ } = data } -> data
394+ :error -> { % { } , % { } , % { } }
397395 end
398396
399397 stale_modules = Map . merge ( checkpoint_stale_modules , stale_modules )
400398 stale_exports = Map . merge ( checkpoint_stale_exports , stale_exports )
401399
402- # Once we added semantic recompilation, the following can happen:
403- #
404- # 1. The user changes config/mix.exs/__mix_recompile__?
405- # 2. We detect the change, remove .beam files and start recompilation
406- # 3. Recompilation fails
407- # 4. The user reverts the change
408- # 5. The compiler no longer recompiles and the .beam files are missing
409- #
410- # Therefore, it is important for us to checkpoint any state that may
411- # have lead to a compilation and which can now be reverted.
412- if map_size ( stale_modules ) != map_size ( checkpoint_stale_modules ) or
413- map_size ( stale_exports ) != map_size ( checkpoint_stale_exports ) do
414- write_checkpoint ( :update , manifest , { stale_modules , stale_exports } )
415- end
416-
417- # We don't need to store those in the checkpoint because
418- # these changes come from modules and, when they are stale,
419- # we remove the .beam files and touch sources.
420400 modules_to_mix_check =
421401 for { module , module ( recompile?: true ) } <- all_modules ,
422402 not Map . has_key? ( stale_modules , module ) ,
@@ -448,33 +428,45 @@ defmodule Mix.Compilers.Elixir do
448428 # Sources that have changed on disk or
449429 # any modules associated with them need to be recompiled
450430 changed =
451- Enum . flat_map ( all_sources , fn
431+ Enum . reduce ( all_sources , checkpoint_changed , fn
452432 { source ,
453- source ( external: external , size: size , mtime: mtime , digest: digest , modules: modules ) } ->
433+ source ( external: external , size: size , mtime: mtime , digest: digest , modules: modules ) } ,
434+ acc ->
454435 { last_mtime , last_size } = Map . fetch! ( sources_stats , source )
455436
456437 cond do
457438 Enum . any? ( external , & stale_external? ( & 1 , sources_stats ) ) or
458439 has_any_key? ( modules_to_recompile , modules ) ->
459- # Mark the source as changed so the combination of a timestamp
460- # plus removed beam files (which are removed by update_stale_entries)
461- # causes it to be recompiled. Note we don't raise use touch! because
462- # in case of checkpoints the file may have been removed.
463- File . touch ( source , timestamp + 1 )
464- [ source ]
440+ Map . put ( acc , source , true )
465441
466442 size != last_size or
467443 has_any_key? ( stale_modules , modules ) or
468444 ( last_mtime != mtime and
469445 ( missing_beam_file? ( dest , modules ) or digest_changed? ( source , digest ) ) ) ->
470- [ source ]
446+ Map . put ( acc , source , true )
471447
472448 true ->
473- [ ]
449+ acc
474450 end
475451 end )
476452
477- changed = new_paths ++ changed
453+ # Once we added semantic recompilation, the following can happen:
454+ #
455+ # 1. The user changes config/mix.exs/__mix_recompile__?
456+ # 2. We detect the change, remove .beam files and start recompilation
457+ # 3. Recompilation fails
458+ # 4. The user reverts the change
459+ # 5. The compiler no longer recompiles and the .beam files are missing
460+ #
461+ # Therefore, it is important for us to checkpoint any state that may
462+ # have lead to a compilation and which can now be reverted.
463+ if map_size ( stale_modules ) != map_size ( checkpoint_stale_modules ) or
464+ map_size ( stale_exports ) != map_size ( checkpoint_stale_exports ) or
465+ map_size ( changed ) != map_size ( checkpoint_changed ) do
466+ write_checkpoint ( :update , manifest , { stale_modules , stale_exports , changed } )
467+ end
468+
469+ changed = new_paths ++ Map . keys ( changed )
478470
479471 { modules , exports , changed } =
480472 update_stale_entries (
0 commit comments