Skip to content

Commit c6fbfd2

Browse files
author
José Valim
committed
Copy and check elixir version in archives
Closes #2396
1 parent 56ea6e5 commit c6fbfd2

File tree

5 files changed

+45
-12
lines changed

5 files changed

+45
-12
lines changed

lib/mix/lib/mix/archive.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ defmodule Mix.Archive do
7070

7171
defp files_to_add(path, dir) do
7272
File.cd! path, fn ->
73+
evsn = Path.wildcard(".elixir")
7374
ebin = Path.wildcard("ebin/*.{beam,app}")
7475
priv = Path.wildcard("priv/**/*")
7576

76-
Enum.reduce ebin ++ priv, [], fn(f, acc) ->
77+
Enum.reduce evsn ++ ebin ++ priv, [], fn(f, acc) ->
7778
case File.read(f) do
7879
{:ok, bin} ->
7980
[{Path.join(dir, f) |> String.to_char_list, bin}|acc]

lib/mix/lib/mix/local.ex

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ defmodule Mix.Local do
1515
Append archives paths into Erlang code path.
1616
"""
1717
def append_archives do
18-
Enum.each(archives_ebin, &Code.append_path(&1))
18+
archives = archives_ebin()
19+
Enum.each(archives, &check_elixir_archive_vsn/1)
20+
Enum.each(archives, &Code.append_path/1)
1921
end
2022

2123
@doc """
@@ -49,4 +51,19 @@ defmodule Mix.Local do
4951
defp archives_ebin do
5052
Path.join(archives_path, "*.ez") |> Path.wildcard |> Enum.map(&Mix.Archive.ebin/1)
5153
end
54+
55+
defp check_elixir_archive_vsn(ebin) do
56+
elixir = ebin |> Path.dirname() |> Path.join(".elixir") |> String.to_char_list
57+
case :erl_prim_loader.get_file(elixir) do
58+
{:ok, req, _} ->
59+
unless Version.match?(System.version, req) do
60+
archive = ebin |> Path.dirname() |> Path.basename
61+
Mix.shell.error "warning: the archive #{archive} requires Elixir #{inspect req} " <>
62+
"but you are running on v#{System.version}"
63+
end
64+
:ok
65+
:error ->
66+
:ok
67+
end
68+
end
5269
end

lib/mix/lib/mix/tasks/archive.build.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ defmodule Mix.Tasks.Archive.Build do
4545
input = opts[:input] ->
4646
input
4747
project ->
48-
Mix.Project.app_path
48+
path = Mix.Project.app_path
49+
if elixir = Mix.Project.config[:elixir] do
50+
File.write Path.join(path, ".elixir"), elixir
51+
else
52+
File.rm Path.join(path, ".elixir")
53+
end
54+
path
4955
true ->
5056
Mix.raise "Cannot create archive without input directory, " <>
5157
"please pass -i as an option"

lib/mix/test/mix/archive_test.exs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@ defmodule Mix.ArchiveTest do
77

88
test "archive" do
99
in_fixture "archive", fn ->
10+
File.write ".elixir", "~> 1.0.0"
1011
Mix.Archive.create(".", "sample.ez")
1112
archive = 'sample.ez'
1213
assert File.exists?(archive)
14+
assert has_zip_file?(archive, 'sample/.elixir')
1315
assert has_zip_file?(archive, 'sample/priv/not_really_an.so')
1416
assert has_zip_file?(archive, 'sample/ebin/Elixir.Mix.Tasks.Local.Sample.beam')
1517
end
1618
end
1719

1820
defp has_zip_file?(archive, name) do
19-
:zip.list_dir(archive)
20-
|> elem(1)
21-
|> Enum.find(&match?({:zip_file, ^name, _, _, _, _}, &1))
21+
{:ok, files} = :zip.list_dir(archive)
22+
Enum.find(files, &match?({:zip_file, ^name, _, _, _, _}, &1))
2223
end
2324
end

lib/mix/test/mix/tasks/archive_test.exs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ defmodule Mix.Tasks.ArchiveTest do
55

66
defmodule ArchiveProject do
77
def project do
8-
[ app: :archive, version: "0.1.0" ]
8+
[app: :archive, version: "0.1.0", elixir: "~> 0.1.0"]
99
end
1010
end
1111

1212
defmodule ArchiveProject2 do
1313
def project do
14-
[ app: :archive, version: "0.2.0" ]
14+
[app: :archive, version: "0.2.0"]
1515
end
1616
end
1717

@@ -22,7 +22,7 @@ defmodule Mix.Tasks.ArchiveTest do
2222

2323
in_fixture "archive", fn() ->
2424
# Install it!
25-
Mix.Tasks.Archive.Build.run []
25+
Mix.Tasks.Archive.Build.run ["--no-elixir-version-check"]
2626
assert File.regular? "archive-0.1.0.ez"
2727

2828
send self, {:mix_shell_input, :yes?, true}
@@ -32,10 +32,16 @@ defmodule Mix.Tasks.ArchiveTest do
3232
archive = tmp_path("userhome/.mix/archives/archive-0.1.0.ez/archive-0.1.0/ebin")
3333
assert to_char_list(archive) in :code.get_path
3434

35-
# List it!
35+
# Load it!
3636
Mix.Local.append_archives
37+
error = "warning: the archive archive-0.1.0 requires Elixir \"~> 0.1.0\" but you are running on v#{System.version}"
38+
assert_received {:mix_shell, :error, [^error]}
39+
40+
# List it!
3741
Mix.Tasks.Local.run []
38-
assert_received {:mix_shell, :info, ["mix local.sample # A local install sample"]}
42+
info = "mix local.sample # A local install sample"
43+
assert_received {:mix_shell, :info, [^info]}
44+
3945

4046
Mix.Tasks.Archive.run []
4147
assert_received {:mix_shell, :info, ["* archive-0.1.0.ez"]}
@@ -60,12 +66,14 @@ defmodule Mix.Tasks.ArchiveTest do
6066
refute File.regular? tmp_path("userhome/.mix/archives/archive-0.1.0.ez")
6167
end
6268

69+
# Load it! No warnings because there is no :elixir in mix.exs.
6370
Mix.Local.append_archives
71+
refute_received {:mix_shell, :error, [_]}
6472

6573
# Remove it!
6674
send self, {:mix_shell_input, :yes?, true}
6775
Mix.Tasks.Archive.Uninstall.run ["archive-0.2.0.ez"]
68-
76+
6977
# See reason for previous refutation.
7078
unless match? {:win32, _}, :os.type do
7179
refute File.regular? tmp_path("userhome/.mix/archives/archive-0.2.0.ez")

0 commit comments

Comments
 (0)