Skip to content

Commit 9374fbe

Browse files
author
José Valim
committed
Revert manifest changes for release (they are part of master)
1 parent 9a44775 commit 9374fbe

File tree

7 files changed

+108
-228
lines changed

7 files changed

+108
-228
lines changed

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

Lines changed: 50 additions & 104 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 :v3
4+
@manifest_vsn :v2
55

66
@doc """
77
Compiles stale Elixir files.
@@ -18,12 +18,10 @@ defmodule Mix.Compilers.Elixir do
1818
def compile(manifest, srcs, skip, exts, dest, force, on_start) do
1919
keep = srcs -- skip
2020
all = Mix.Utils.extract_files(keep, exts)
21-
{all_entries, skip_entries, all_sources, skip_sources} = parse_manifest(manifest, keep)
22-
23-
modified = Mix.Utils.last_modified(manifest)
21+
{all_entries, skip_entries} = parse_manifest(manifest, keep)
2422

2523
removed =
26-
for {source, _files} <- all_sources,
24+
for {_b, _m, _k, source, _cd, _rd, _f, _bin} <- all_entries,
2725
not(source in all),
2826
do: source
2927

@@ -33,44 +31,44 @@ defmodule Mix.Compilers.Elixir do
3331
# changed, let's just compile everything
3432
all
3533
else
36-
sources_mtimes = mtimes(all_sources)
34+
modified = Mix.Utils.last_modified(manifest)
35+
all_mtimes = mtimes(all_entries)
3736

38-
# Otherwise let's start with the new sources
37+
# Otherwise let's start with the new ones
38+
# plus the ones that have changed
3939
for(source <- all,
40-
not Map.has_key?(all_sources, source),
40+
not Enum.any?(all_entries, fn {_b, _m, _k, s, _cd, _rd, _f, _bin} -> s == source end),
4141
do: source)
4242
++
43-
# Plus the sources that have changed in disk
44-
for({source, files} <- all_sources,
45-
times = Enum.map([source|files], &Map.fetch!(sources_mtimes, &1)),
43+
for({_b, _m, _k, source, _cd, _rd, files, _bin} <- all_entries,
44+
times = Enum.map([source|files], &Map.fetch!(all_mtimes, &1)),
4645
Mix.Utils.stale?(times, [modified]),
4746
do: source)
4847
end
4948

50-
sources = update_stale_sources(all_sources, removed, changed)
51-
{entries, changed} = update_stale_entries(all_entries, removed ++ changed,
52-
stale_local_deps(modified))
53-
49+
{entries, changed} = remove_stale_entries(all_entries, removed ++ changed)
5450
stale = changed -- removed
55-
new_entries = entries ++ skip_entries
56-
new_sources = Map.merge(sources, skip_sources)
5751

5852
cond do
5953
stale != [] ->
60-
compile_manifest(manifest, new_entries, new_sources, stale, dest, on_start)
54+
compile_manifest(manifest, entries ++ skip_entries, stale, dest, on_start)
6155
:ok
6256
removed != [] ->
63-
write_manifest(manifest, new_entries, new_sources)
57+
write_manifest(manifest, entries ++ skip_entries)
6458
:ok
6559
true ->
6660
:noop
6761
end
6862
end
6963

70-
defp mtimes(sources) do
71-
Enum.reduce(sources, %{}, fn {source, files}, map ->
72-
Enum.reduce([source|files], map, fn file, map ->
73-
Map.put_new_lazy(map, file, fn -> Mix.Utils.last_modified(file) end)
64+
defp mtimes(entries) do
65+
Enum.reduce(entries, %{}, fn {_b, _m, _k, source, _cd, _rd, files, _bin}, dict ->
66+
Enum.reduce([source|files], dict, fn file, dict ->
67+
if Map.has_key?(dict, file) do
68+
dict
69+
else
70+
Map.put(dict, file, Mix.Utils.last_modified(file))
71+
end
7472
end)
7573
end)
7674
end
@@ -79,24 +77,22 @@ defmodule Mix.Compilers.Elixir do
7977
Removes compiled files.
8078
"""
8179
def clean(manifest) do
82-
Enum.each read_manifest(manifest), fn
83-
{beam, _, _, _, _, _, _} ->
84-
File.rm(beam)
85-
{_, _} ->
86-
:ok
80+
Enum.map read_manifest(manifest), fn {beam, _, _, _, _, _, _, _} ->
81+
File.rm(beam)
8782
end
83+
:ok
8884
end
8985

9086
@doc """
9187
Returns protocols and implementations for the given manifest.
9288
"""
9389
def protocols_and_impls(manifest) do
94-
for {beam, module, kind, _, _, _, _} <- read_manifest(manifest),
90+
for {_, module, kind, _, _, _, _, _} <- read_manifest(manifest),
9591
match?(:protocol, kind) or match?({:impl, _}, kind),
96-
do: {module, kind, beam}
92+
do: {module, kind}
9793
end
9894

99-
defp compile_manifest(manifest, entries, sources, stale, dest, on_start) do
95+
defp compile_manifest(manifest, entries, stale, dest, on_start) do
10096
Mix.Project.ensure_structure()
10197
true = Code.prepend_path(dest)
10298

@@ -105,16 +101,16 @@ defmodule Mix.Compilers.Elixir do
105101

106102
# Starts a server responsible for keeping track which files
107103
# were compiled and the dependencies between them.
108-
{:ok, pid} = Agent.start_link(fn -> {entries, sources} end)
104+
{:ok, pid} = Agent.start_link(fn -> entries end)
109105

110106
try do
111107
_ = Kernel.ParallelCompiler.files :lists.usort(stale),
112108
each_module: &each_module(pid, dest, cwd, &1, &2, &3),
113109
each_file: &each_file(&1),
114110
dest: dest
115-
Agent.cast pid, fn {entries, sources} ->
116-
write_manifest(manifest, entries, sources)
117-
{entries, sources}
111+
Agent.cast pid, fn entries ->
112+
write_manifest(manifest, entries)
113+
entries
118114
end
119115
after
120116
Agent.stop(pid, :normal, :infinity)
@@ -144,12 +140,8 @@ defmodule Mix.Compilers.Elixir do
144140
kind = detect_kind(module)
145141
source = Path.relative_to(source, cwd)
146142
files = get_external_resources(module, cwd)
147-
148-
Agent.cast pid, fn {entries, sources} ->
149-
entries = List.keystore(entries, beam, 0, {beam, module, kind, source, compile, runtime, binary})
150-
sources = Map.update(sources, source, files, & files ++ &1)
151-
{entries, sources}
152-
end
143+
tuple = {beam, module, kind, source, compile, runtime, files, binary}
144+
Agent.cast pid, &:lists.keystore(beam, 1, &1, tuple)
153145
end
154146

155147
defp detect_kind(module) do
@@ -171,27 +163,22 @@ defmodule Mix.Compilers.Elixir do
171163
do: relative
172164
end
173165

174-
defp each_file(source) do
175-
Mix.shell.info "Compiled #{source}"
166+
defp each_file(file) do
167+
Mix.shell.info "Compiled #{file}"
176168
end
177169

178170
## Resolution
179171

180-
defp update_stale_sources(sources, removed, changed) do
181-
Enum.reduce changed, Map.drop(sources, removed), &Map.put(&2, &1, [])
182-
end
183-
184172
# This function receives the manifest entries and some source
185173
# files that have changed. It then, recursively, figures out
186174
# all the files that changed (via the module dependencies) and
187175
# return the non-changed entries and the removed sources.
188-
defp update_stale_entries(all, [], stale) when stale == %{} do
176+
defp remove_stale_entries(all, []) do
189177
{all, []}
190178
end
191179

192-
defp update_stale_entries(all, changed, stale) do
193-
removed = Enum.into(changed, %{}, &{&1, true})
194-
remove_stale_entries(all, stale, removed)
180+
defp remove_stale_entries(all, changed) do
181+
remove_stale_entries(all, %{}, Enum.into(changed, %{}, &{&1, true}))
195182
end
196183

197184
defp remove_stale_entries(entries, old_stale, old_removed) do
@@ -206,13 +193,15 @@ defmodule Mix.Compilers.Elixir do
206193
end
207194
end
208195

209-
defp remove_stale_entry({beam, module, _kind, source, compile, runtime, _bin} = entry,
196+
defp remove_stale_entry({beam, module, _kind, source, compile, runtime, _f, _bin} = entry,
210197
{rest, stale, removed}) do
211198
cond do
212199
# If I changed in disk or have a compile time dependency
213200
# on something stale, I need to be recompiled.
214201
Map.has_key?(removed, source) or Enum.any?(compile, &Map.has_key?(stale, &1)) ->
215-
remove_and_purge(beam, module)
202+
_ = File.rm(beam)
203+
_ = :code.purge(module)
204+
_ = :code.delete(module)
216205
{rest, Map.put(stale, module, true), Map.put(removed, source, true)}
217206

218207
# If I have a runtime time dependency on something stale,
@@ -226,22 +215,6 @@ defmodule Mix.Compilers.Elixir do
226215
end
227216
end
228217

229-
defp stale_local_deps(modified) do
230-
for %{scm: scm} = dep <- Mix.Dep.children,
231-
not scm.fetchable?,
232-
path <- Mix.Dep.load_paths(dep),
233-
beam <- Path.wildcard(Path.join(path, "*.beam")),
234-
Mix.Utils.last_modified(beam) > modified,
235-
do: {beam |> Path.basename |> Path.rootname |> String.to_atom, true},
236-
into: %{}
237-
end
238-
239-
defp remove_and_purge(beam, module) do
240-
_ = File.rm(beam)
241-
_ = :code.purge(module)
242-
_ = :code.delete(module)
243-
end
244-
245218
## Manifest handling
246219

247220
defp read_manifest(manifest) do
@@ -251,58 +224,31 @@ defmodule Mix.Compilers.Elixir do
251224
end
252225
end
253226

254-
# Similar to read manifest but supports data migration.
255227
defp parse_manifest(manifest, keep_paths) do
256-
state = {[], [], %{}, %{}}
257-
258-
case :file.consult(manifest) do
259-
{:ok, [@manifest_vsn|data]} ->
260-
parse_manifest(data, keep_paths, state)
261-
{:ok, [:v2|data]} ->
262-
for {beam, module, _, _, _, _, _, _} <- data do
263-
remove_and_purge(beam, module)
264-
end
265-
state
266-
_ ->
267-
state
268-
end
269-
end
270-
271-
defp parse_manifest(data, keep_paths, state) do
272-
Enum.reduce data, state, fn
273-
{_, _, _, source, _, _, _} = entry, {keep, skip, keep_sources, skip_sources} ->
274-
if String.starts_with?(source, keep_paths) do
275-
{[entry|keep], skip, keep_sources, skip_sources}
276-
else
277-
{keep, [entry|skip], keep_sources, skip_sources}
278-
end
279-
{source, files}, {keep, skip, keep_sources, skip_sources} ->
228+
Enum.reduce read_manifest(manifest), {[], []}, fn
229+
{_, _, _, source, _, _, _, _} = entry, {keep, skip} ->
280230
if String.starts_with?(source, keep_paths) do
281-
{keep, skip, Map.put(keep_sources, source, files), skip_sources}
231+
{[entry|keep], skip}
282232
else
283-
{keep, skip, keep_sources, Map.put(skip_sources, source, files)}
233+
{keep, [entry|skip]}
284234
end
285235
end
286236
end
287237

288-
defp write_manifest(manifest, [], sources) when sources == %{} do
238+
defp write_manifest(manifest, []) do
289239
File.rm(manifest)
290240
:ok
291241
end
292242

293-
defp write_manifest(manifest, entries, sources) do
243+
defp write_manifest(manifest, entries) do
294244
File.mkdir_p!(Path.dirname(manifest))
295245

296246
File.open!(manifest, [:write], fn device ->
297247
:io.format(device, '~p.~n', [@manifest_vsn])
298248

299-
Enum.each entries, fn {beam, _, _, _, _, _, binary} = entry ->
249+
Enum.map entries, fn {beam, _, _, _, _, _, _, binary} = entry ->
300250
if binary, do: File.write!(beam, binary)
301-
:io.format(device, '~p.~n', [put_elem(entry, 6, nil)])
302-
end
303-
304-
Enum.each sources, fn {_, _} = entry ->
305-
:io.format(device, '~p.~n', [entry])
251+
:io.format(device, '~p.~n', [put_elem(entry, 7, nil)])
306252
end
307253

308254
:ok

lib/mix/lib/mix/tasks/compile.elixir.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ defmodule Mix.Tasks.Compile.Elixir do
8080
Mix.Compilers.Elixir.clean(manifest())
8181
end
8282

83+
@doc false
84+
def protocols_and_impls do
85+
Mix.Compilers.Elixir.protocols_and_impls(manifest())
86+
end
87+
8388
defp set_compiler_opts(project, opts, extra) do
8489
opts = Keyword.take(opts, Code.available_compiler_options)
8590
opts = Keyword.merge(project[:elixirc_options] || [], opts)

lib/mix/lib/mix/tasks/compile.ex

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ defmodule Mix.Tasks.Compile do
8181
Mix.Project.get!
8282
Mix.Task.run "loadpaths", args
8383

84+
if local_deps_changed?() do
85+
Mix.Dep.Lock.touch_manifest
86+
end
87+
8488
res = Mix.Task.run "compile.all", args
8589
res = if :ok in List.wrap(res), do: :ok, else: :noop
8690

@@ -101,6 +105,17 @@ defmodule Mix.Tasks.Compile do
101105
Mix.Project.config[:consolidate_protocols]
102106
end
103107

108+
defp local_deps_changed? do
109+
manifest = Path.absname(Mix.Dep.Lock.manifest())
110+
111+
Enum.any?(Mix.Dep.children(), fn %{scm: scm} = dep ->
112+
not scm.fetchable? and Mix.Dep.in_dependency(dep, fn _ ->
113+
files = Mix.Project.config_files ++ manifests()
114+
Mix.Utils.stale?(files, [manifest])
115+
end)
116+
end)
117+
end
118+
104119
@doc """
105120
Returns all compilers.
106121
"""

0 commit comments

Comments
 (0)