Skip to content

Commit f957d2f

Browse files
ericmjjosevalim
authored andcommitted
Store only filename of beam files in elixir manifest (#4767)
1 parent 0303993 commit f957d2f

File tree

6 files changed

+62
-46
lines changed

6 files changed

+62
-46
lines changed

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

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ defmodule Mix.Compilers.Elixir do
2929
"""
3030
def compile(manifest, srcs, dest, force, opts) do
3131
all = Mix.Utils.extract_files(srcs, [:ex])
32-
{all_modules, all_sources} = parse_manifest(manifest)
32+
{all_modules, all_sources} = parse_manifest(manifest, dest)
3333
modified = Mix.Utils.last_modified(manifest)
3434

3535
removed =
@@ -73,7 +73,7 @@ defmodule Mix.Compilers.Elixir do
7373
compile_manifest(manifest, modules, sources, stale, dest, opts)
7474
:ok
7575
removed != [] ->
76-
write_manifest(manifest, modules, sources)
76+
write_manifest(manifest, modules, sources, dest)
7777
:ok
7878
true ->
7979
:noop
@@ -91,34 +91,36 @@ defmodule Mix.Compilers.Elixir do
9191
@doc """
9292
Removes compiled files for the given `manifest`.
9393
"""
94-
def clean(manifest) do
95-
Enum.each read_manifest(manifest), fn
94+
def clean(manifest, compile_path) do
95+
Enum.each(read_manifest(manifest, compile_path), fn
9696
module(beam: beam) ->
9797
File.rm(beam)
9898
_ ->
9999
:ok
100-
end
100+
end)
101101
end
102102

103103
@doc """
104104
Returns protocols and implementations for the given `manifest`.
105105
"""
106-
def protocols_and_impls(manifest) do
107-
for module(beam: beam, module: module, kind: kind) <- read_manifest(manifest),
106+
def protocols_and_impls(manifest, compile_path) do
107+
for module(beam: beam, module: module, kind: kind) <- read_manifest(manifest, compile_path),
108108
match?(:protocol, kind) or match?({:impl, _}, kind),
109109
do: {module, kind, beam}
110110
end
111111

112112
@doc """
113113
Reads the manifest.
114114
"""
115-
def read_manifest(manifest) do
115+
def read_manifest(manifest, compile_path) do
116116
# TODO: No longer support file consult once v1.3 is out
117117
try do
118118
manifest |> File.read!() |> :erlang.binary_to_term()
119119
else
120-
[@manifest_vsn | t] -> t
121-
_ -> []
120+
[@manifest_vsn | t] ->
121+
expand_beam_paths(t, compile_path)
122+
_ ->
123+
[]
122124
rescue
123125
_ -> []
124126
end
@@ -149,12 +151,12 @@ defmodule Mix.Compilers.Elixir do
149151

150152
try do
151153
_ = Kernel.ParallelCompiler.files stale,
152-
[each_module: &each_module(pid, dest, cwd, &1, &2, &3),
154+
[each_module: &each_module(pid, cwd, &1, &2, &3),
153155
each_long_compilation: &each_long_compilation(&1, long_compilation_threshold),
154156
long_compilation_threshold: long_compilation_threshold,
155157
dest: dest] ++ extra
156158
Agent.cast pid, fn {modules, sources} ->
157-
write_manifest(manifest, modules, sources)
159+
write_manifest(manifest, modules, sources, dest)
158160
{modules, sources}
159161
end
160162
after
@@ -170,11 +172,8 @@ defmodule Mix.Compilers.Elixir do
170172
|> Code.compiler_options()
171173
end
172174

173-
defp each_module(pid, dest, cwd, source, module, binary) do
174-
beam =
175-
dest
176-
|> Path.join(Atom.to_string(module) <> ".beam")
177-
|> Path.relative_to(cwd)
175+
defp each_module(pid, cwd, source, module, binary) do
176+
beam = Atom.to_string(module) <> ".beam"
178177

179178
{compile_references, runtime_references} = Kernel.LexicalTracker.remote_references(module)
180179

@@ -338,9 +337,7 @@ defmodule Mix.Compilers.Elixir do
338337
## Manifest handling
339338

340339
# Similar to read_manifest, but supports data migration.
341-
defp parse_manifest(manifest) do
342-
state = {[], []}
343-
340+
defp parse_manifest(manifest, compile_path) do
344341
# TODO: No longer support file consult once v1.3 is out
345342
manifest =
346343
try do
@@ -351,37 +348,53 @@ defmodule Mix.Compilers.Elixir do
351348

352349
case manifest do
353350
{:ok, [@manifest_vsn | data]} ->
354-
parse_manifest(data, state)
351+
do_parse_manifest(data, compile_path)
355352
{:ok, [:v2 | data]} ->
356-
for {beam, module, _, _, _, _, _, _} <- data do
357-
remove_and_purge(beam, module)
358-
end
359-
state
353+
for {beam, module, _, _, _, _, _, _} <- data,
354+
do: remove_and_purge(beam, module)
355+
{[], []}
360356
_ ->
361-
state
357+
{[], []}
362358
end
363359
end
364360

365-
defp parse_manifest(data, state) do
366-
Enum.reduce data, state, fn
361+
defp do_parse_manifest(data, compile_path) do
362+
Enum.reduce(data, {[], []}, fn
367363
module() = module, {modules, sources} ->
368-
{[module | modules], sources}
364+
{[expand_beam_path(module, compile_path) | modules], sources}
369365
source() = source, {modules, sources} ->
370366
{modules, [source | sources]}
371-
end
367+
end)
368+
end
369+
370+
defp expand_beam_path(module(beam: beam) = module, compile_path) do
371+
module(module, beam: Path.join(compile_path, beam))
372372
end
373373

374-
defp write_manifest(manifest, [], []) do
374+
defp expand_beam_paths(modules, ""), do: modules
375+
defp expand_beam_paths(modules, compile_path) do
376+
Enum.map(modules, fn
377+
module() = module ->
378+
expand_beam_path(module, compile_path)
379+
other ->
380+
other
381+
end)
382+
end
383+
384+
defp write_manifest(manifest, [], [], _compile_path) do
375385
File.rm(manifest)
376386
:ok
377387
end
378388

379-
defp write_manifest(manifest, modules, sources) do
389+
defp write_manifest(manifest, modules, sources, compile_path) do
380390
File.mkdir_p!(Path.dirname(manifest))
381391

382392
modules =
383393
for module(beam: beam, binary: binary) = module <- modules do
384-
if binary, do: File.write!(beam, binary)
394+
if binary do
395+
beam_path = Path.join(compile_path, beam)
396+
File.write!(beam_path, binary)
397+
end
385398
module(module, binary: nil)
386399
end
387400

lib/mix/lib/mix/compilers/test.ex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ defmodule Mix.Compilers.Test do
2121
It expects all of the test patterns, the test files that were matched for the
2222
test patterns, the test paths, and the opts from the test task.
2323
"""
24-
def require_and_run(test_patterns, matched_test_files, test_paths, opts) do
24+
def require_and_run(test_patterns, matched_test_files, test_paths, compile_path, opts) do
2525
stale = opts[:stale]
2626

2727
{test_files_to_run, stale_manifest_pid, parallel_require_callbacks} =
2828
if stale do
29-
set_up_stale(matched_test_files, test_paths, opts)
29+
set_up_stale(matched_test_files, test_paths, compile_path, opts)
3030
else
3131
{matched_test_files, nil, []}
3232
end
@@ -58,7 +58,7 @@ defmodule Mix.Compilers.Test do
5858
end
5959
end
6060

61-
defp set_up_stale(matched_test_files, test_paths, opts) do
61+
defp set_up_stale(matched_test_files, test_paths, compile_path, opts) do
6262
manifest = manifest()
6363
modified = Mix.Utils.last_modified(manifest)
6464
all_sources = read_manifest()
@@ -95,7 +95,7 @@ defmodule Mix.Compilers.Test do
9595

9696
test_files_to_run =
9797
sources
98-
|> tests_with_changed_references()
98+
|> tests_with_changed_references(compile_path)
9999
|> MapSet.union(stale)
100100
|> MapSet.to_list()
101101

@@ -192,13 +192,13 @@ defmodule Mix.Compilers.Test do
192192

193193
## Test changed dependency resolution
194194

195-
defp tests_with_changed_references(test_sources) do
195+
defp tests_with_changed_references(test_sources, compile_path) do
196196
test_manifest = manifest()
197197
[elixir_manifest] = Mix.Tasks.Compile.Elixir.manifests()
198198

199199
if Mix.Utils.stale?([elixir_manifest], [test_manifest]) do
200200
elixir_manifest_entries =
201-
CE.read_manifest(elixir_manifest)
201+
CE.read_manifest(elixir_manifest, compile_path)
202202
|> Enum.group_by(&elem(&1, 0))
203203

204204
stale_modules =

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ defmodule Mix.Tasks.Compile.Elixir do
7171
Cleans up compilation artifacts.
7272
"""
7373
def clean do
74-
Mix.Compilers.Elixir.clean(manifest())
74+
dest = Mix.Project.compile_path
75+
Mix.Compilers.Elixir.clean(manifest(), dest)
7576
end
7677
end

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ defmodule Mix.Tasks.Compile.Protocols do
8383

8484
protocols_and_impls =
8585
for path <- [app | deps] do
86-
elixir = Path.join(path, ".compile.elixir")
87-
Mix.Compilers.Elixir.protocols_and_impls(elixir)
86+
manifest_path = Path.join(path, ".compile.elixir")
87+
compile_path = Path.join(path, "ebin")
88+
Mix.Compilers.Elixir.protocols_and_impls(manifest_path, compile_path)
8889
end
8990

9091
Enum.concat(protocols_and_impls)

lib/mix/lib/mix/tasks/test.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,13 @@ defmodule Mix.Tasks.Test do
184184
end
185185

186186
project = Mix.Project.config
187+
compile_path = Mix.Project.compile_path(project)
187188

188189
# Start cover after we load deps but before we start the app.
189190
cover =
190191
if opts[:cover] do
191192
cover = Keyword.merge(@cover, project[:test_coverage] || [])
192-
cover[:tool].start(Mix.Project.compile_path(project), cover)
193+
cover[:tool].start(compile_path, cover)
193194
end
194195

195196
# Start the app and configure exunit with command line options
@@ -226,7 +227,7 @@ defmodule Mix.Tasks.Test do
226227

227228
display_warn_test_pattern(matched_warn_test_files, test_pattern)
228229

229-
case CT.require_and_run(files, matched_test_files, test_paths, opts) do
230+
case CT.require_and_run(files, matched_test_files, test_paths, compile_path, opts) do
230231
{:ok, %{failures: failures}} ->
231232
cover && cover.()
232233

lib/mix/lib/mix/tasks/xref.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule Mix.Tasks.Xref do
22
use Mix.Task
33

44
alias Mix.Tasks.Compile.Elixir, as: E
5-
import Mix.Compilers.Elixir, only: [read_manifest: 1, source: 1, source: 2]
5+
import Mix.Compilers.Elixir, only: [read_manifest: 2, source: 1, source: 2]
66

77
@shortdoc "Performs cross reference checks"
88
@recursive true
@@ -289,7 +289,7 @@ defmodule Mix.Tasks.Xref do
289289

290290
defp each_source_entries(entries_fun, pair_fun) do
291291
for manifest <- E.manifests(),
292-
source(source: file) = source <- read_manifest(manifest),
292+
source(source: file) = source <- read_manifest(manifest, ""),
293293
entries = entries_fun.(source),
294294
entries != [] and entries != %{},
295295
do: pair_fun.(file, entries)

0 commit comments

Comments
 (0)