Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions lib/mix/lib/mix/local.ex
Original file line number Diff line number Diff line change
Expand Up @@ -198,26 +198,32 @@ defmodule Mix.Local do

defp find_latest_eligible_version(entries, artifact_version) do
elixir_version = Version.parse!(System.version())
otp_release = System.otp_release()

entries
|> Enum.reverse()
|> find_version(artifact_version, elixir_version)
|> find_version(artifact_version, elixir_version, otp_release)
end

defp find_version(entries, artifact_version, elixir_version) do
defp find_version(entries, artifact_version, elixir_version, otp_release) do
entries =
if artifact_version do
Enum.filter(entries, &(hd(&1) == artifact_version))
else
entries
end

Enum.find_value(entries, &find_by_elixir_version(&1, elixir_version))
Enum.find_value(entries, &find_by_elixir_version(&1, elixir_version, otp_release))
end

defp find_by_elixir_version([artifact_version, digest, hex_elixir_version | _], elixir_version) do
if Version.compare(hex_elixir_version, elixir_version) != :gt do
{hex_elixir_version, artifact_version, digest}
defp find_by_elixir_version(
[artifact_version, digest, hex_elixir_version, hex_otp_release | _],
elixir_version,
otp_release
) do
if Version.compare(hex_elixir_version, elixir_version) != :gt and
hex_otp_release <= otp_release do
{hex_elixir_version, artifact_version, digest, hex_otp_release}
end
end
end
10 changes: 8 additions & 2 deletions lib/mix/lib/mix/rebar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,18 @@ defmodule Mix.Rebar do
@doc """
Returns the path supposed to host the local copy of `rebar`.

The rebar3 installation is specific to the Elixir version,
The rebar3 installation is specific to the Elixir version and OTP release,
in order to force updates when new Elixir versions come out.
"""
def local_rebar_path(:rebar3) do
[major, minor | _] = String.split(System.version(), ".")
Path.join([Mix.Utils.mix_home(), "elixir", "#{major}-#{minor}", "rebar3"])

Path.join([
Mix.Utils.mix_home(),
"elixir",
"#{major}-#{minor}-otp-#{System.otp_release()}",
"rebar3"
])
end

@doc """
Expand Down
7 changes: 4 additions & 3 deletions lib/mix/lib/mix/tasks/local.hex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
defmodule Mix.Tasks.Local.Hex do
use Mix.Task

@hex_list_path "/installs/hex-1.x.csv"
@hex_archive_path "/installs/[ELIXIR_VERSION]/hex-[HEX_VERSION].ez"
@hex_list_path "/installs/hex.csv"
@hex_archive_path "/installs/[ELIXIR_VERSION]/hex-[HEX_VERSION]-otp-[OTP_RELEASE].ez"

@shortdoc "Installs Hex locally"

Expand Down Expand Up @@ -72,12 +72,13 @@ defmodule Mix.Tasks.Local.Hex do
defp run_install(version, argv) do
hex_url = Mix.Hex.url()

{elixir_version, hex_version, sha512} =
{elixir_version, hex_version, sha512, otp_release} =
Mix.Local.find_matching_versions!("Hex", version, hex_url <> @hex_list_path)

url =
(hex_url <> @hex_archive_path)
|> String.replace("[ELIXIR_VERSION]", elixir_version)
|> String.replace("[OTP_RELEASE]", otp_release)
|> String.replace("[HEX_VERSION]", hex_version)

# Unload the Hex module we loaded earlier to avoid conflicts when Hex is updated
Expand Down
7 changes: 4 additions & 3 deletions lib/mix/lib/mix/tasks/local.rebar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
defmodule Mix.Tasks.Local.Rebar do
use Mix.Task

@rebar3_list_url "/installs/rebar3-1.x.csv"
@rebar3_escript_url "/installs/[ELIXIR_VERSION]/rebar3-[REBAR_VERSION]"
@rebar3_list_url "/installs/rebar.csv"
@rebar3_escript_url "/installs/[ELIXIR_VERSION]/rebar3-[REBAR_VERSION]-otp-[OTP_RELEASE]"

@shortdoc "Installs Rebar locally"

Expand Down Expand Up @@ -114,13 +114,14 @@ defmodule Mix.Tasks.Local.Rebar do
hex_url = Mix.Hex.url()
list_url = hex_url <> list_url

{elixir_version, rebar_version, sha512} =
{elixir_version, rebar_version, sha512, otp_release} =
Mix.Local.find_matching_versions!("Rebar", _version = nil, list_url)

url =
(hex_url <> escript_url)
|> String.replace("[ELIXIR_VERSION]", elixir_version)
|> String.replace("[REBAR_VERSION]", rebar_version)
|> String.replace("[OTP_RELEASE]", otp_release)

install_from_path(manager, url, Keyword.put(opts, :sha512, sha512))
end
Expand Down
12 changes: 6 additions & 6 deletions lib/mix/test/mix/local_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ defmodule Mix.LocalTest do
use MixTest.Case

@csv """
1.2.5,ABC,0.9.0
1.2.3,DEF,1.0.0
1.2.4,GHI,1.0.0
1.2.5,ABC,0.9.0,26
1.2.3,DEF,1.0.0,26
1.2.4,GHI,1.0.0,26
"""

@tag :tmp_dir
test "select correct versions from csv", %{tmp_dir: tmp_dir} do
File.cd!(tmp_dir, fn ->
File.write!("csv", @csv)

assert {"1.0.0", "1.2.4", "GHI"} =
assert {"1.0.0", "1.2.4", "GHI", "26"} =
Mix.Local.find_matching_versions!("name", nil, "csv")
end)
end
Expand All @@ -28,10 +28,10 @@ defmodule Mix.LocalTest do
File.cd!(tmp_dir, fn ->
File.write!("csv", @csv)

assert {"0.9.0", "1.2.5", "ABC"} =
assert {"0.9.0", "1.2.5", "ABC", "26"} =
Mix.Local.find_matching_versions!("name", "1.2.5", "csv")

assert {"1.0.0", "1.2.3", "DEF"} =
assert {"1.0.0", "1.2.3", "DEF", "26"} =
Mix.Local.find_matching_versions!("name", "1.2.3", "csv")

assert_raise Mix.Error, "Could not find a version of name matching: 1.3.0", fn ->
Expand Down
3 changes: 2 additions & 1 deletion lib/mix/test/test_helper.exs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ Enum.each(

rebar3_source = System.get_env("REBAR3") || Path.expand("fixtures/rebar3", __DIR__)
[major, minor | _] = String.split(System.version(), ".")
rebar3_target = Path.join([mix, "elixir", "#{major}-#{minor}", "rebar3"])
version_dir = "#{major}-#{minor}-otp-#{System.otp_release()}"
rebar3_target = Path.join([mix, "elixir", version_dir, "rebar3"])
File.mkdir_p!(Path.dirname(rebar3_target))
File.cp!(rebar3_source, rebar3_target)

Expand Down
Loading