Skip to content

Commit 88f65ae

Browse files
authored
Install Hex and Rebar per OTP release (Elixir v1.18) (#14509)
1 parent 14d406f commit 88f65ae

File tree

6 files changed

+99
-88
lines changed

6 files changed

+99
-88
lines changed

lib/mix/lib/mix/local.ex

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -232,40 +232,35 @@ defmodule Mix.Local do
232232

233233
defp find_latest_eligible_version(entries, artifact_version) do
234234
elixir_version = Version.parse!(System.version())
235+
otp_release = System.otp_release()
235236

236237
entries
237238
|> Enum.reverse()
238-
|> find_version(artifact_version, elixir_version)
239+
|> find_version(artifact_version, elixir_version, otp_release)
239240
end
240241

241-
defp find_version(entries, _artifact_version = nil, elixir_version) do
242-
Enum.find_value(entries, &find_by_elixir_version(&1, elixir_version))
243-
end
242+
defp find_version(entries, artifact_version, elixir_version, otp_release) do
243+
entries =
244+
if artifact_version do
245+
Enum.filter(entries, &(hd(&1) == artifact_version))
246+
else
247+
entries
248+
end
244249

245-
defp find_version(entries, artifact_version, elixir_version) do
246-
Enum.find_value(entries, &find_by_artifact_version(&1, artifact_version, elixir_version))
250+
Enum.find_value(entries, &find_by_elixir_version(&1, elixir_version, otp_release))
247251
end
248252

249-
defp find_by_elixir_version([artifact_version, digest | versions], elixir_version) do
250-
if version = Enum.find(versions, &(Version.compare(&1, elixir_version) != :gt)) do
251-
{version, artifact_version, digest}
252-
end
253-
end
254-
255-
defp find_by_artifact_version(
256-
[artifact_version, digest | versions],
257-
artifact_version,
258-
elixir_version
253+
defp find_by_elixir_version(
254+
[artifact_version, digest, hex_elixir_version, hex_otp_release | _],
255+
elixir_version,
256+
otp_release
259257
) do
260-
if version = Enum.find(versions, &(Version.compare(&1, elixir_version) != :gt)) do
261-
{version, artifact_version, digest}
258+
if Version.compare(hex_elixir_version, elixir_version) != :gt and
259+
hex_otp_release <= otp_release do
260+
{hex_elixir_version, artifact_version, digest, hex_otp_release}
262261
end
263262
end
264263

265-
defp find_by_artifact_version(_entry, _artifact_version, _elixir_version) do
266-
nil
267-
end
268-
269264
## Public keys
270265

271266
@doc """

lib/mix/lib/mix/rebar.ex

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,18 @@ defmodule Mix.Rebar do
4949
@doc """
5050
Returns the path supposed to host the local copy of `rebar`.
5151
52-
The rebar3 installation is specific to the Elixir version,
52+
The rebar3 installation is specific to the Elixir version and OTP release,
5353
in order to force updates when new Elixir versions come out.
5454
"""
5555
def local_rebar_path(:rebar3) do
5656
[major, minor | _] = String.split(System.version(), ".")
57-
Path.join([Mix.Utils.mix_home(), "elixir", "#{major}-#{minor}", "rebar3"])
57+
58+
Path.join([
59+
Mix.Utils.mix_home(),
60+
"elixir",
61+
"#{major}-#{minor}-otp-#{System.otp_release()}",
62+
"rebar3"
63+
])
5864
end
5965

6066
@doc """

lib/mix/lib/mix/tasks/local.hex.ex

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
defmodule Mix.Tasks.Local.Hex do
22
use Mix.Task
33

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

77
@shortdoc "Installs Hex locally"
88

@@ -68,16 +68,13 @@ defmodule Mix.Tasks.Local.Hex do
6868
defp run_install(version, argv) do
6969
hex_url = Mix.Hex.url()
7070

71-
{elixir_version, hex_version, sha512} =
72-
Mix.Local.find_matching_versions_from_signed_csv!(
73-
"Hex",
74-
version,
75-
hex_url <> @hex_list_path
76-
)
71+
{elixir_version, hex_version, sha512, otp_release} =
72+
Mix.Local.find_matching_versions_from_signed_csv!("Hex", version, hex_url <> @hex_list_path)
7773

7874
url =
7975
(hex_url <> @hex_archive_path)
8076
|> String.replace("[ELIXIR_VERSION]", elixir_version)
77+
|> String.replace("[OTP_RELEASE]", otp_release)
8178
|> String.replace("[HEX_VERSION]", hex_version)
8279

8380
# Unload the Hex module we loaded earlier to avoid conflicts when Hex is updated

lib/mix/lib/mix/tasks/local.rebar.ex

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
defmodule Mix.Tasks.Local.Rebar do
22
use Mix.Task
33

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

77
@shortdoc "Installs Rebar locally"
88

@@ -110,13 +110,14 @@ defmodule Mix.Tasks.Local.Rebar do
110110
hex_url = Mix.Hex.url()
111111
list_url = hex_url <> list_url
112112

113-
{elixir_version, rebar_version, sha512} =
113+
{elixir_version, rebar_version, sha512, otp_release} =
114114
Mix.Local.find_matching_versions_from_signed_csv!("Rebar", _version = nil, list_url)
115115

116116
url =
117117
(hex_url <> escript_url)
118118
|> String.replace("[ELIXIR_VERSION]", elixir_version)
119119
|> String.replace("[REBAR_VERSION]", rebar_version)
120+
|> String.replace("[OTP_RELEASE]", otp_release)
120121

121122
install_from_path(manager, url, Keyword.put(opts, :sha512, sha512))
122123
end

lib/mix/test/mix/local_test.exs

Lines changed: 63 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,67 +3,70 @@ Code.require_file("../test_helper.exs", __DIR__)
33
defmodule Mix.LocalTest do
44
use MixTest.Case
55

6-
# openssl rsa -in elixirest.pem -pubout > elixirest.pub
6+
# openssl rsa -in elixirtest.pem -pubout > elixirtest.pub
77
@public_key """
88
-----BEGIN PUBLIC KEY-----
9-
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA37moKP1dGGLhsP3d8Fwv
10-
W25SoYZUY2K+Iq7A0OBV36Rnb8yW3BWjfh5YtmPvUCfYUbNCW2HTMMgBntkQ4YmN
11-
B9tHVZazl2uX9lGCfZZPFc/9umvKRojCPkMN81MfTxqnY0oaLHr6DB86RsWHB+ld
12-
782Xf+nd9q3LFdUl8SGlKX7uzfVWd4EWYNcL7aLeLSupZWeNg8uVmY3zua0EgIlQ
13-
XryalIOZb/R+pwprWZoftCl+20FGYi/mJpo/idFtXsR0sJKF4X0W3NORT9RIRbs9
14-
WdjiFi+eIP7Nm8KSF4pbaXCqSmVf9cgvUuGTxc9/P5GcIPAlkcsSrE5peLyUCk5f
15-
2QIDAQAB
9+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkIaIn8uhwSVp9d+aV+GL
10+
tFjMt0TylxDu6x5jwjDvXCD3Of6VAriqcdXDJAqGPN1C4HNTxfihYpLZB+qXCNQM
11+
oEa/I1h6OB5CXb8zIOl2Yriforr9LS+EkP+1xVmz7w7lNAagD0rJyJrTDbYDV+2Y
12+
EnRq84FpZc/+7z6ojc3RMh9x/5t9jDE4Ft3NCujCmGsy2AcBlMpAQkcNveyplNmu
13+
fZH2vId8h8t6rABwEZgSazHObkcHwE3bndynFO7zXvBu6ebNUDuU3DrDJ1Iepy9I
14+
jEuZ6h13j7hL5l+j+9bGRQtasWgwvCkCGD+/2Lz4Ehox58voDCzAK09rsCwQ6gAT
15+
CQIDAQAB
1616
-----END PUBLIC KEY-----
1717
"""
1818

19-
# openssl genrsa -aes256 -out elixirtest.pem -passout stdin 2048
19+
# openssl genrsa -aes256 -out elixirtest.pem -passout pass:secret12 2048
2020
@private_key """
21-
-----BEGIN RSA PRIVATE KEY-----
22-
Proc-Type: 4,ENCRYPTED
23-
DEK-Info: AES-256-CBC,48BA5153DA2F120ECE063B33C1204A49
24-
25-
5gp3daNWujH7o9S/dJQEt9TYTRP0pPZtU55PlZrzWt52optr7XHW/ENOm84g5J70
26-
QCPELp12jfQsNiPwbVWXKy2zD3QlNiAelf65hqLWJTWli7XIXfdP46VXOu67OKf9
27-
Ziw4HQ+AdBEwFt20wJst77iy17sNlyxp5DhNDonnSizzIowgUAJkoNI5aBUU6D8X
28-
KTSIftZW35Z4SudkazdoHepEfItZTI8mB4rvfn71Q4oOBA1rAuUUmdPWoPBfUHDa
29-
hvIp2T2Q8zZYqm0+SjDxZUYOOreE7fuf5NSLhHHt7+jyWQmtaVxnOWms72G+9xT0
30-
NGmOEB0WEg1kBsUbYOXXwyCAZhNA6MaKCtgjQczRTK+geS1xNaFc9FDEk3ZjN4Z8
31-
PxrKQoqo+2aQGVcatZWCom80Dci3bIv7iZNA/y1rjfBn+MeitMOGscP7/CBrJAbI
32-
bh1mvCu0McSnqlN0a+EuCVfJQYFMzjibpRVzKAST0QeaxXd5QxHfcPFPBLOpiVWc
33-
NjHaZsHORyoJbUKGA4rgOiSB63mv7SDRA2mvxWpwV/+6MuwBah6t6CGoEsAr1Hbn
34-
1ySt5w27bw3QEf2KTiuxDubo8UrF0eYzP5A9MH8vRpSRZHg8T3SBVfPJ/pM16Lnn
35-
5BaMUdxDFJeet5HUYoke9Zm3udh2BvwGiKhzc9Pbw/EcsCcvChMimRTasqTaRf+S
36-
uIm0Un7o+7kTuvBo2y87j2urCEUzft5QqEynbkR7p3vZnwoLLj+supXh3V8ivW4s
37-
Z6ql+ukRcWd/ode+lbSiYfAJCLc1tCqJ3kTnMnADJBlL0TX7YnwBwWuwwPuZgeAv
38-
F6nnBE1SBQ1WK+bjSVzIqmNFqsZw34wgpnz2heX0q8msF5pzd6EIeA+uz86k8XYh
39-
4eVZYGXxa4Exodh/MqEpRuN1ytWDXvHULh0gml7xwZC3R50UD8uBNt5RGjXUkjXc
40-
V0atKuvgzVlsB4xbDhVP7EVYHBF02NfNOsvo7kh0Yl1IcT/42UaCGYuU1o9zotPv
41-
9b3SHz/HOmBVj2uCdR5XZ4EolP5Iv9vqIDt9DsuDpOyO+AFOww0FnJNCQ1Hmfb0T
42-
qBYPv994oSPYLCGR4a8i/xfmmV8KbAIVEgK3AMbz8RxKr3WBWXWnzQdr4+y4EG24
43-
hSnR52XQ42edv/fkqf9ez+fKNQ9i7PtlPE96Q21NeLMNKHh43X8hJFDh+oPz3Aio
44-
YSNMCZnoyRdrjBRCsVBpnyoLmuhWwG9RlcrEj3G0BxYPh/weaBOAKAHjSr28yuUj
45-
yIa8uddszC6XHSiVUgu7SGO8gQmq++eNdckjX/pEug5MjcWLUqaUg6+YLFWY6NLf
46-
uDPOYuivq7ErtKTvP2xl3TBEDKhdfqxA2+RFxbBDmKjffZnRkcknQsxhlzAdbg22
47-
Jwa2B1nrfjJpX5F+1Av2jHQGbIKMqZzv8fo1binMKpptFzokbWEOjcPCb3tPuomG
48-
ZRkW3qO2pdyYX2N7VXYG9tGi2HrN/oFrWnHPoYF23v85V8WxNkODOCpTz85e6R5v
49-
PVu+FCNFj5weEOTRhtEQyJo7mU5qIRwYeZvVxiC6W+XeFs95wdBE/Lvpg8yZ8D9d
50-
-----END RSA PRIVATE KEY-----
21+
-----BEGIN ENCRYPTED PRIVATE KEY-----
22+
MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQjNQQlREZJuQveXPa
23+
0ACpEwICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEFoBWTpEyO8y6xdG
24+
fuud2AIEggTQDQRXrxBpj1yIbnLcP7i43Gat2tEM+XXkvqbzwL+CdjfEzaqiBGwc
25+
FEyWnJj5hENWtNq/AAwzcEALa3QdLJ2W+tX/hc5r1vILpy2oW0vPKfv4yadNyPWq
26+
UzolKKU3MbREP4KXsuAVYepolRWAcWSZKozYBm9HUPwsSyM6E9K0aWmNr/YBbZPE
27+
UEA949Pq6buQvwT2Gj/6FQlutEvJMuY8woM2I/RKSVHeSoB8FWJGSNd7ZY2DN7DG
28+
o6kmhK0OVjxx0SYQwUm++4gh3yFRX6vnTf8ZADOwCOJE/hjMfqivNelJHGojYAD2
29+
0c3zdo0HGvVghg2bzUxhc0HJqUFiUDNW1W3AVBrUJiQgHQb/ENYaMrd6klrslHDV
30+
cnPkz+dZAq/WC3KFqufkSmHxU97dDs9G6hKdm80JVEdPG4aMJvHzVL6SvS+g/e7r
31+
IJGZCFGch9SbikmESKegIfyLJYQrfjuLdXWPHx9J+LAmtRTA1xPwLH/aqCr9ahBB
32+
JCl4RaezF0BH2GYLAV+Ailpy2jqsC3v9RW8vpQmU227H8ERFu9ZcWhZITbRhbjRB
33+
oh3ERnOmvU3VWIXQ0j1cm9Qjl52y8HZJxef2dYsW8nmTSRj32gi9UnEsyOFL9FB7
34+
KcFDq6o+go4nIfsmaAEOF1Hh01JZkbuX1SgmHvGRbNksTuljP/XZn7Wzz7fTcVZR
35+
NsTgMbBl1+ctDHUBT7YzsHeEx8tZvLPDP8lO23aEnmRb6bHD4hVorUEM/kOpSm6g
36+
DNP0buYGEAu4rZrp+5s46Y/RVAIhU4+663jqzmbmwOwEcuOJJCJn8eUGVweAgWX3
37+
1PQTfpkk7RLxxuLeMHxEIynxyZNpSgfX0VGKe5UtplwcTQL8VgeZHayDxnhFwtSm
38+
lBfPIM/i4kj7RonuehyPjuBA6n1CyqRVqc49c/3kVMgovqvbUQxQ7TtSfzfkhVyV
39+
yRnRxcek+6Gctoahas5DPQl7y8jnwgg5qvUjYo6GIwBoxLUzIw+0MBn7gdMYHNmh
40+
Xd9XZpRilAMJF5ynr2QyaE95XaQ3yK62FPgmIDdzfnN7es169O4SiXsgUyaSWsx9
41+
VxOHP4r0j6epWLH4W11MQEj4Bb8wG//pCD5Kz2xvwhWaKjkqzuqGDaXSOTKV0FQM
42+
NG5GbNNELNCy/ocvlsaC+acWcOfsx4f6yovCGVTpTr+wjbDqd1kEBoRTuyTPY+6P
43+
0OU1Vf2GpMA2NDw0ZUOAllGVLrgD+326bu7ipePgiT8SiPNNsagMJNCSk5d3C4+K
44+
bc0hakF/MIjPs3a+5/2mwtxk3QYYCIHITN8SIj+kFd7WMXALyClgWt3tcKwLTgMa
45+
BSatAvwsoi2kiBu2A49msvka7YD8fENhtUl8vU12ZZdTih1chyPDifgfRgOfkZFW
46+
a1XiLKjnWqeBqvJ3hBKuXweN6P7nvZidBYSESl3yrM00pA97Eta2in7ok80MRYH3
47+
bsqzC636h43Mu8PbTKGpK66j1ts6uY9YONAGfGCcfj/wyBWuqNViv7vK38th8wj8
48+
AG4rKyIlKxbFwo4Oh3jZTbfVF1Azl8pr0rK2P3W/EhfvWIrZVfB4Upy0wL6MjysE
49+
RZ/57N2wFq4KBb9x9hCMFxignWmgyzPK+1J0iPRkSmpn9P/SzywDBIg=
50+
-----END ENCRYPTED PRIVATE KEY-----
5151
"""
5252

5353
@csv """
54-
1.2.5,ABC,0.9.0
55-
1.2.3,DEF,1.0.0
56-
1.2.4,GHI,1.0.0
54+
1.2.5,ABC,0.9.0,25
55+
1.2.5,ABC,0.9.0,26
56+
1.2.3,DEF,1.0.0,25
57+
1.2.3,DEF,1.0.0,26
58+
1.2.4,GHI,1.0.0,25
59+
1.2.4,GHI,1.0.0,26
5760
"""
5861

5962
# openssl dgst -sha512 -sign elixirtest.pem hex-1.x.csv | openssl base64 > elixirtest.csv.signed
6063
@csv_signed """
61-
VRydmXOdEXQcKJu/SK/nKnE00T+s/T4mpXrYROMSXhD/s8ClvdimnGg61ie3YBS6
62-
LXOjlEhbtMHRM2rTOUvv4z7FcyzwvSxSjunlVi2g3c1pVOZ78MonnYhGb44tZw/q
63-
SOVmV+jJhc9EZFMIAAM3plMoyssyw2pMh7ZB/DxCQTIem3Qf0Ujzc2bYkLVlw7R+
64-
1Rn6dcYEgCzyldVkAUMaYBwieyweWALA+YVDCMudJJK2J7p1OnuoPSVV+N3OkB/Z
65-
T6Jj5ljD+54XnuxAMcgCoF9lpOwXscnw/Ma+8JqIoWo0jNFE3ji+8dGCUzQUdSe8
66-
llLXgJJE2tGpDhEXBA3idg==
64+
CVkhTiuCAfooYPhjyynDq40QhmDwLAEJvpwYytPCf6mpLXVrLXo/d/A2L8iBRJVx
65+
uk4PNVksLRZ1ChBzGFvEqaFjrH+ndQAYLbwqcaMIn743YNUjGNVfTZkU47nBybtJ
66+
BwDSBaAsow0Iitsl+UkDN/QvVoOLiX/x2cpnwCMrCgbTMroTzhH07vfLo3uCf8iY
67+
cncImd07ffCewt77AsVPpKgJNOLzn+EBnvh4LbGWQya8EkgyQKuMBuNU86MYtFiW
68+
NVpR7vbvqgWpEyr1XeknxKkhzYpna3+irXdMxGZw65WvFNWGJKnpuBTNHnHL+wX8
69+
oNQLUfakH8/VMV/8v6Irbg==
6770
"""
6871

6972
# We don't actually use it but it exists for documentation purposes.
@@ -83,8 +86,10 @@ defmodule Mix.LocalTest do
8386
File.write!("csv", @csv)
8487
File.write!("csv.signed", @csv_signed)
8588

86-
assert {"1.0.0", "1.2.4", "GHI"} =
89+
assert {"1.0.0", "1.2.4", "GHI", otp_release} =
8790
Mix.Local.find_matching_versions_from_signed_csv!("name", nil, "csv")
91+
92+
assert otp_release <= System.otp_release()
8893
end)
8994
end
9095

@@ -94,12 +99,16 @@ defmodule Mix.LocalTest do
9499
File.write!("csv", @csv)
95100
File.write!("csv.signed", @csv_signed)
96101

97-
assert {"0.9.0", "1.2.5", "ABC"} =
102+
assert {"0.9.0", "1.2.5", "ABC", otp_release} =
98103
Mix.Local.find_matching_versions_from_signed_csv!("name", "1.2.5", "csv")
99104

100-
assert {"1.0.0", "1.2.3", "DEF"} =
105+
assert otp_release <= System.otp_release()
106+
107+
assert {"1.0.0", "1.2.3", "DEF", otp_release} =
101108
Mix.Local.find_matching_versions_from_signed_csv!("name", "1.2.3", "csv")
102109

110+
assert otp_release <= System.otp_release()
111+
103112
assert_raise Mix.Error, "Could not find a version of name matching: 1.3.0", fn ->
104113
Mix.Local.find_matching_versions_from_signed_csv!("name", "1.3.0", "csv")
105114
end
@@ -109,7 +118,9 @@ defmodule Mix.LocalTest do
109118
@tag :tmp_dir
110119
test "raise on bad signature", %{tmp_dir: tmp_dir} do
111120
File.cd!(tmp_dir, fn ->
112-
csv_signed = String.replace(@csv_signed, "VRy", "BAD")
121+
<<_, _, _>> <> rest = @csv_signed
122+
csv_signed = "BAD" <> rest
123+
113124
File.write!("csv", @csv)
114125
File.write!("csv.signed", csv_signed)
115126

lib/mix/test/test_helper.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ end
254254

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

0 commit comments

Comments
 (0)