diff --git a/lib/mix/lib/mix/local.ex b/lib/mix/lib/mix/local.ex index 79ed8bb5c95..7070ad8d524 100644 --- a/lib/mix/lib/mix/local.ex +++ b/lib/mix/lib/mix/local.ex @@ -198,13 +198,14 @@ 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)) @@ -212,12 +213,17 @@ defmodule Mix.Local do 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 diff --git a/lib/mix/lib/mix/rebar.ex b/lib/mix/lib/mix/rebar.ex index addc367b2ba..6f4d021e498 100644 --- a/lib/mix/lib/mix/rebar.ex +++ b/lib/mix/lib/mix/rebar.ex @@ -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 """ diff --git a/lib/mix/lib/mix/tasks/local.hex.ex b/lib/mix/lib/mix/tasks/local.hex.ex index a8fc2b8c366..3f8882a5c1d 100644 --- a/lib/mix/lib/mix/tasks/local.hex.ex +++ b/lib/mix/lib/mix/tasks/local.hex.ex @@ -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" @@ -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 diff --git a/lib/mix/lib/mix/tasks/local.rebar.ex b/lib/mix/lib/mix/tasks/local.rebar.ex index d1496839774..2c960bef144 100644 --- a/lib/mix/lib/mix/tasks/local.rebar.ex +++ b/lib/mix/lib/mix/tasks/local.rebar.ex @@ -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" @@ -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 diff --git a/lib/mix/test/mix/local_test.exs b/lib/mix/test/mix/local_test.exs index 3bbe1af46fb..e08371e8dc9 100644 --- a/lib/mix/test/mix/local_test.exs +++ b/lib/mix/test/mix/local_test.exs @@ -8,9 +8,9 @@ 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 @@ -18,7 +18,7 @@ defmodule Mix.LocalTest 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 @@ -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 -> diff --git a/lib/mix/test/test_helper.exs b/lib/mix/test/test_helper.exs index 3ea41635404..e6bce9251b0 100644 --- a/lib/mix/test/test_helper.exs +++ b/lib/mix/test/test_helper.exs @@ -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)