Fix calculating `-otp-` major for Elixir (#351)

8fc1380 · Paulo F. Oliveira · 2025-07-01 21:13

11 files +192 -123
Message
{commit_body(@commit)}

Files changed

modified .github/workflows/action.yml
+1 −0
@@ -76,6 +76,7 @@ jobs:
76 76 uses: ./
77 77 with:
78 78 install-rebar: false
79 + install-hex: false
79 80 version-file: test/.tool-versions
80 81 version-type: strict
81 82
modified .github/workflows/ubuntu.yml
+9 −0
@@ -25,6 +25,15 @@ jobs:
25 25 fail-fast: false
26 26 matrix:
27 27 combo:
28 + - otp-version: '<26'
29 + elixir-version: '<1.17'
30 + os: 'ubuntu-22.04'
31 + - otp-version: 'master'
32 + elixir-version: '> 0'
33 + os: 'ubuntu-24.04'
34 + - otp-version: 'master'
35 + elixir-version: 'main'
36 + os: 'ubuntu-24.04'
28 37 - otp-version: '27'
29 38 elixir-version: 'v1.17.0'
30 39 rebar3-version: '3.23'
modified .github/workflows/windows.yml
+6 −0
@@ -25,6 +25,12 @@ jobs:
25 25 fail-fast: false
26 26 matrix:
27 27 combo:
28 + - otp-version: '<26'
29 + elixir-version: '<1.17'
30 + os: 'ubuntu-22.04'
31 + - otp-version: 'master'
32 + elixir-version: '> 0'
33 + os: 'ubuntu-24.04'
28 34 - otp-version: '27'
29 35 elixir-version: 'v1.17.0'
30 36 rebar3-version: '3.23'
modified dist/index.js
+59 −27
@@ -25890,9 +25890,11 @@ const _ = __nccwpck_require__(2356)
25890 25890
25891 25891 const MAX_HTTP_RETRIES = 3
25892 25892
25893 main().catch((err) => {
25894 core.setFailed(err.message)
25895 })
25893 +if (process.env.NODE_ENV !== 'test') {
25894 + main().catch((err) => {
25895 + core.setFailed(err.message)
25896 + })
25897 +}
25896 25898
25897 25899 async function main() {
25898 25900 checkOtpArchitecture()
@@ -25908,15 +25910,14 @@ async function main() {
25908 25910 versions = parseVersionFile(versionFilePath)
25909 25911 }
25910 25912
25911 const osVersion = getRunnerOSVersion()
25912 25913 const otpSpec = getInput('otp-version', true, 'erlang', versions)
25913 25914 const elixirSpec = getInput('elixir-version', false, 'elixir', versions)
25914 25915 const gleamSpec = getInput('gleam-version', false, 'gleam', versions)
25915 25916 const rebar3Spec = getInput('rebar3-version', false, 'rebar', versions)
25916 25917
25917 25918 if (otpSpec !== 'false') {
25918 await installOTP(otpSpec, osVersion)
25919 const elixirInstalled = await maybeInstallElixir(elixirSpec, otpSpec)
25919 + await installOTP(otpSpec)
25920 + const elixirInstalled = await maybeInstallElixir(elixirSpec)
25920 25921 if (elixirInstalled === true) {
25921 25922 const shouldMixRebar = getInput('install-rebar', false)
25922 25923 await mix(shouldMixRebar, 'rebar')
@@ -25936,7 +25937,8 @@ async function main() {
25936 25937 core.setOutput('setup-beam-version', setupBeamVersion)
25937 25938 }
25938 25939
25939 async function installOTP(otpSpec, osVersion) {
25940 +async function installOTP(otpSpec) {
25941 + const osVersion = getRunnerOSVersion()
25940 25942 const otpVersion = await getOTPVersion(otpSpec, osVersion)
25941 25943 core.startGroup(
25942 25944 `Installing Erlang/OTP ${otpVersion} - built on ${getRunnerOSArchitecture()}/${osVersion}`,
@@ -25958,10 +25960,10 @@ async function installOTP(otpSpec, osVersion) {
25958 25960 return otpVersion
25959 25961 }
25960 25962
25961 async function maybeInstallElixir(elixirSpec, otpSpec) {
25963 +async function maybeInstallElixir(elixirSpec) {
25962 25964 let installed = false
25963 25965 if (elixirSpec) {
25964 const elixirVersion = await getElixirVersion(elixirSpec, otpSpec)
25966 + const elixirVersion = await getElixirVersion(elixirSpec)
25965 25967 core.startGroup(`Installing Elixir ${elixirVersion}`)
25966 25968 await doWithMirrors({
25967 25969 hexMirrors: hexMirrorsInput(),
@@ -26070,16 +26072,30 @@ function requestedVersionFor(tool, version, originListing, mirrors) {
26070 26072 const knownBranches = ['main', 'master', 'maint']
26071 26073 const nonSpecificVersions = ['nightly', 'latest']
26072 26074
26073 async function getElixirVersion(exSpec0, otpVersion0) {
26074 const otpVersion = otpVersion0.match(/^(?:OTP-)?(.+)$/)[1]
26075 const regex = `^(\\d{1,3}|${knownBranches.join('|')}|${nonSpecificVersions.join('|')})?.*$`
26076 let otpVersionMajor = otpVersion.match(new RegExp(regex))[1]
26077
26075 +async function getElixirVersion(exSpec0) {
26078 26076 const otpSuffix = /-otp-(\d+)/
26079 26077 const userSuppliedOtp = exSpec0.match(otpSuffix)?.[1] ?? null
26078 + let otpVersionMajor = ''
26080 26079
26081 26080 if (userSuppliedOtp && isVersion(userSuppliedOtp)) {
26082 26081 otpVersionMajor = userSuppliedOtp
26082 + } else {
26083 + let cmd = 'erl'
26084 + if (process.platform === 'win32') {
26085 + cmd = 'erl.exe'
26086 + }
26087 + const args = [
26088 + '-noshell',
26089 + '-eval',
26090 + 'io:format(erlang:system_info(otp_release)), halt().',
26091 + ]
26092 + await exec(cmd, args, {
26093 + listeners: {
26094 + stdout: (data) => {
26095 + otpVersionMajor = data.toString()
26096 + },
26097 + },
26098 + })
26083 26099 }
26084 26100
26085 26101 const [otpVersionsForElixirMap, elixirVersions, originListing, hexMirrors] =
@@ -26094,17 +26110,29 @@ async function getElixirVersion(exSpec0, otpVersion0) {
26094 26110 )
26095 26111 }
26096 26112
26097 const elixirVersionComp = otpVersionsForElixirMap[elixirVersionFromSpec]
26098 if (
26099 (elixirVersionComp && elixirVersionComp.includes(otpVersionMajor)) ||
26100 !isVersion(otpVersionMajor)
26101 ) {
26102 core.info(
26103 `Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajor})`,
26104 )
26105 } else {
26113 + let foundCombo = false
26114 + let otpVersionMajorIter = parseInt(otpVersionMajor)
26115 + let otpVersionsMajor = []
26116 + while (otpVersionMajorIter > otpVersionMajor - 3) {
26117 + otpVersionMajorIter += ''
26118 + otpVersionsMajor.push(otpVersionMajorIter)
26119 + const elixirVersionComp = otpVersionsForElixirMap[elixirVersionFromSpec]
26120 + if (
26121 + (elixirVersionComp && elixirVersionComp.includes(otpVersionMajorIter)) ||
26122 + !isVersion(otpVersionMajorIter)
26123 + ) {
26124 + core.info(
26125 + `Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajorIter})`,
26126 + )
26127 + foundCombo = true
26128 + break
26129 + }
26130 + otpVersionMajorIter = parseInt(otpVersionMajorIter) - 1
26131 + }
26132 +
26133 + if (!foundCombo) {
26106 26134 throw new Error(
26107 `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion0}) not ` +
26135 + `Requested Elixir / Erlang/OTP version (${exSpec0} / tried ${otpVersionsMajor}) not ` +
26108 26136 'found in version list (did you check Compatibility between Elixir and Erlang/OTP?).' +
26109 26137 'Elixir and Erlang/OTP compatibility can be found at: ' +
26110 26138 'https://hexdocs.pm/elixir/compatibility-and-deprecations.html',
@@ -26113,8 +26141,8 @@ async function getElixirVersion(exSpec0, otpVersion0) {
26113 26141
26114 26142 let elixirVersionForDownload = elixirVersionFromSpec
26115 26143
26116 if (isVersion(otpVersionMajor)) {
26117 elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajor}`
26144 + if (isVersion(otpVersionMajorIter)) {
26145 + elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajorIter}`
26118 26146 }
26119 26147
26120 26148 return maybePrependWithV(elixirVersionForDownload)
@@ -27073,14 +27101,18 @@ function debugLoggingEnabled() {
27073 27101
27074 27102 module.exports = {
27075 27103 get,
27076 getOTPVersion,
27077 27104 getElixirVersion,
27078 27105 getGleamVersion,
27106 + getOTPVersion,
27079 27107 getRebar3Version,
27080 27108 getVersionFromSpec,
27081 27109 githubAMDRunnerArchs,
27082 27110 githubARMRunnerArchs,
27083 27111 install,
27112 + installOTP,
27113 + maybeInstallElixir,
27114 + maybeInstallGleam,
27115 + maybeInstallRebar3,
27084 27116 parseVersionFile,
27085 27117 }
27086 27118
modified src/setup-beam.js
+59 −27
@@ -10,9 +10,11 @@ const _ = require('lodash')
10 10
11 11 const MAX_HTTP_RETRIES = 3
12 12
13 main().catch((err) => {
14 core.setFailed(err.message)
15 })
13 +if (process.env.NODE_ENV !== 'test') {
14 + main().catch((err) => {
15 + core.setFailed(err.message)
16 + })
17 +}
16 18
17 19 async function main() {
18 20 checkOtpArchitecture()
@@ -28,15 +30,14 @@ async function main() {
28 30 versions = parseVersionFile(versionFilePath)
29 31 }
30 32
31 const osVersion = getRunnerOSVersion()
32 33 const otpSpec = getInput('otp-version', true, 'erlang', versions)
33 34 const elixirSpec = getInput('elixir-version', false, 'elixir', versions)
34 35 const gleamSpec = getInput('gleam-version', false, 'gleam', versions)
35 36 const rebar3Spec = getInput('rebar3-version', false, 'rebar', versions)
36 37
37 38 if (otpSpec !== 'false') {
38 await installOTP(otpSpec, osVersion)
39 const elixirInstalled = await maybeInstallElixir(elixirSpec, otpSpec)
39 + await installOTP(otpSpec)
40 + const elixirInstalled = await maybeInstallElixir(elixirSpec)
40 41 if (elixirInstalled === true) {
41 42 const shouldMixRebar = getInput('install-rebar', false)
42 43 await mix(shouldMixRebar, 'rebar')
@@ -56,7 +57,8 @@ async function main() {
56 57 core.setOutput('setup-beam-version', setupBeamVersion)
57 58 }
58 59
59 async function installOTP(otpSpec, osVersion) {
60 +async function installOTP(otpSpec) {
61 + const osVersion = getRunnerOSVersion()
60 62 const otpVersion = await getOTPVersion(otpSpec, osVersion)
61 63 core.startGroup(
62 64 `Installing Erlang/OTP ${otpVersion} - built on ${getRunnerOSArchitecture()}/${osVersion}`,
@@ -78,10 +80,10 @@ async function installOTP(otpSpec, osVersion) {
78 80 return otpVersion
79 81 }
80 82
81 async function maybeInstallElixir(elixirSpec, otpSpec) {
83 +async function maybeInstallElixir(elixirSpec) {
82 84 let installed = false
83 85 if (elixirSpec) {
84 const elixirVersion = await getElixirVersion(elixirSpec, otpSpec)
86 + const elixirVersion = await getElixirVersion(elixirSpec)
85 87 core.startGroup(`Installing Elixir ${elixirVersion}`)
86 88 await doWithMirrors({
87 89 hexMirrors: hexMirrorsInput(),
@@ -195,16 +197,30 @@ function requestedVersionFor(tool, version, originListing, mirrors) {
195 197 const knownBranches = ['main', 'master', 'maint']
196 198 const nonSpecificVersions = ['nightly', 'latest']
197 199
198 async function getElixirVersion(exSpec0, otpVersion0) {
199 const otpVersion = otpVersion0.match(/^(?:OTP-)?(.+)$/)[1]
200 const regex = `^(\\d{1,3}|${knownBranches.join('|')}|${nonSpecificVersions.join('|')})?.*$`
201 let otpVersionMajor = otpVersion.match(new RegExp(regex))[1]
202
200 +async function getElixirVersion(exSpec0) {
203 201 const otpSuffix = /-otp-(\d+)/
204 202 const userSuppliedOtp = exSpec0.match(otpSuffix)?.[1] ?? null
203 + let otpVersionMajor = ''
205 204
206 205 if (userSuppliedOtp && isVersion(userSuppliedOtp)) {
207 206 otpVersionMajor = userSuppliedOtp
207 + } else {
208 + let cmd = 'erl'
209 + if (process.platform === 'win32') {
210 + cmd = 'erl.exe'
211 + }
212 + const args = [
213 + '-noshell',
214 + '-eval',
215 + 'io:format(erlang:system_info(otp_release)), halt().',
216 + ]
217 + await exec(cmd, args, {
218 + listeners: {
219 + stdout: (data) => {
220 + otpVersionMajor = data.toString()
221 + },
222 + },
223 + })
208 224 }
209 225
210 226 const [otpVersionsForElixirMap, elixirVersions, originListing, hexMirrors] =
@@ -219,17 +235,29 @@ async function getElixirVersion(exSpec0, otpVersion0) {
219 235 )
220 236 }
221 237
222 const elixirVersionComp = otpVersionsForElixirMap[elixirVersionFromSpec]
223 if (
224 (elixirVersionComp && elixirVersionComp.includes(otpVersionMajor)) ||
225 !isVersion(otpVersionMajor)
226 ) {
227 core.info(
228 `Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajor})`,
229 )
230 } else {
238 + let foundCombo = false
239 + let otpVersionMajorIter = parseInt(otpVersionMajor)
240 + let otpVersionsMajor = []
241 + while (otpVersionMajorIter > otpVersionMajor - 3) {
242 + otpVersionMajorIter += ''
243 + otpVersionsMajor.push(otpVersionMajorIter)
244 + const elixirVersionComp = otpVersionsForElixirMap[elixirVersionFromSpec]
245 + if (
246 + (elixirVersionComp && elixirVersionComp.includes(otpVersionMajorIter)) ||
247 + !isVersion(otpVersionMajorIter)
248 + ) {
249 + core.info(
250 + `Using Elixir ${elixirVersionFromSpec} (built for Erlang/OTP ${otpVersionMajorIter})`,
251 + )
252 + foundCombo = true
253 + break
254 + }
255 + otpVersionMajorIter = parseInt(otpVersionMajorIter) - 1
256 + }
257 +
258 + if (!foundCombo) {
231 259 throw new Error(
232 `Requested Elixir / Erlang/OTP version (${exSpec0} / ${otpVersion0}) not ` +
260 + `Requested Elixir / Erlang/OTP version (${exSpec0} / tried ${otpVersionsMajor}) not ` +
233 261 'found in version list (did you check Compatibility between Elixir and Erlang/OTP?).' +
234 262 'Elixir and Erlang/OTP compatibility can be found at: ' +
235 263 'https://hexdocs.pm/elixir/compatibility-and-deprecations.html',
@@ -238,8 +266,8 @@ async function getElixirVersion(exSpec0, otpVersion0) {
238 266
239 267 let elixirVersionForDownload = elixirVersionFromSpec
240 268
241 if (isVersion(otpVersionMajor)) {
242 elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajor}`
269 + if (isVersion(otpVersionMajorIter)) {
270 + elixirVersionForDownload = `${elixirVersionFromSpec}-otp-${otpVersionMajorIter}`
243 271 }
244 272
245 273 return maybePrependWithV(elixirVersionForDownload)
@@ -1198,13 +1226,17 @@ function debugLoggingEnabled() {
1198 1226
1199 1227 module.exports = {
1200 1228 get,
1201 getOTPVersion,
1202 1229 getElixirVersion,
1203 1230 getGleamVersion,
1231 + getOTPVersion,
1204 1232 getRebar3Version,
1205 1233 getVersionFromSpec,
1206 1234 githubAMDRunnerArchs,
1207 1235 githubARMRunnerArchs,
1208 1236 install,
1237 + installOTP,
1238 + maybeInstallElixir,
1239 + maybeInstallGleam,
1240 + maybeInstallRebar3,
1209 1241 parseVersionFile,
1210 1242 }
modified test/setup-beam.test.js
+58 −69
@@ -1,3 +1,5 @@
1 +process.env.NODE_ENV = 'test'
2 +
1 3 simulateInput('otp-version', '25.1.2')
2 4 simulateInput('otp-architecture', '64')
3 5 simulateInput('elixir-version', '1.14.2')
@@ -536,77 +538,70 @@ describe('.getOTPVersion(_) - Elixir', () => {
536 538 let spec
537 539 let otpVersion
538 540 let before
539 const hexMirrors = simulateInput('hexpm-mirrors', 'https://repo.hex.pm', {
540 multiline: true,
541 })
542
543 it('returns the expected value', async () => {
544 spec = '1.1.x'
545 otpVersion = 'OTP-17'
546 expected = 'v1.1.1-otp-17'
547 got = await setupBeam.getElixirVersion(spec, otpVersion)
548 assert.deepStrictEqual(got, expected)
541 + const previousRunnerArch = process.env.RUNNER_ARCH
549 542
550 spec = '1.10.4'
551 otpVersion = 'OTP-23'
552 expected = 'v1.10.4-otp-23'
553 got = await setupBeam.getElixirVersion(spec, otpVersion)
554 assert.deepStrictEqual(got, expected)
543 + if (process.platform === 'linux') {
544 + process.env.RUNNER_ARCH = 'X64'
555 545
556 spec = '1.16.2-otp-26'
557 otpVersion = 'OTP-27'
558 expected = 'v1.16.2-otp-26'
559 got = await setupBeam.getElixirVersion(spec, otpVersion)
560 assert.deepStrictEqual(got, expected)
546 + it('returns the expected value', async () => {
547 + spec = '1.18.x'
548 + otpVersion = 'OTP-27'
549 + expected = 'v1.18.4-otp-27'
550 + await setupBeam.installOTP(otpVersion)
551 + got = await setupBeam.getElixirVersion(spec, otpVersion)
552 + assert.deepStrictEqual(got, expected)
561 553
562 spec = '1.12.1'
563 otpVersion = 'OTP-24.0.2'
564 expected = 'v1.12.1-otp-24'
565 got = await setupBeam.getElixirVersion(spec, otpVersion)
566 assert.deepStrictEqual(got, expected)
554 + spec = '1.18.2'
555 + otpVersion = 'OTP-27'
556 + expected = 'v1.18.2-otp-27'
557 + await setupBeam.installOTP(otpVersion)
558 + got = await setupBeam.getElixirVersion(spec, otpVersion)
559 + assert.deepStrictEqual(got, expected)
567 560
568 before = simulateInput('version-type', 'strict')
569 spec = '1.14.0'
570 otpVersion = 'main'
571 expected = 'v1.14.0'
572 got = await setupBeam.getElixirVersion(spec, otpVersion)
573 assert.deepStrictEqual(got, expected)
574 simulateInput('version-type', before)
561 + spec = '1.16.2-otp-26'
562 + otpVersion = 'OTP-27'
563 + expected = 'v1.16.2-otp-26'
564 + await setupBeam.installOTP(otpVersion)
565 + got = await setupBeam.getElixirVersion(spec, otpVersion)
566 + assert.deepStrictEqual(got, expected)
575 567
576 before = simulateInput('version-type', 'strict')
577 spec = 'v1.11.0-rc.0'
578 otpVersion = 'OTP-23'
579 expected = 'v1.11.0-rc.0-otp-23'
580 got = await setupBeam.getElixirVersion(spec, otpVersion)
581 assert.deepStrictEqual(got, expected)
582 simulateInput('version-type', before)
568 + spec = '1.12.1'
569 + otpVersion = 'OTP-24.3.4'
570 + expected = 'v1.12.1-otp-24'
571 + await setupBeam.installOTP(otpVersion)
572 + got = await setupBeam.getElixirVersion(spec, otpVersion)
573 + assert.deepStrictEqual(got, expected)
583 574
584 before = simulateInput('version-type', 'strict')
585 spec = 'v1.11.0-rc.0-otp-23'
586 otpVersion = 'OTP-23'
587 expected = 'v1.11.0-rc.0-otp-23'
588 got = await setupBeam.getElixirVersion(spec, otpVersion)
589 assert.deepStrictEqual(got, expected)
590 simulateInput('version-type', before)
575 + before = simulateInput('version-type', 'strict')
576 + spec = '1.17'
577 + otpVersion = 'master'
578 + expected = 'v1.17-otp-27'
579 + await setupBeam.installOTP(otpVersion)
580 + got = await setupBeam.getElixirVersion(spec, otpVersion)
581 + assert.deepStrictEqual(got, expected)
582 + simulateInput('version-type', before)
591 583
592 before = simulateInput('version-type', 'strict')
593 spec = 'v1.11.0'
594 otpVersion = '22.3.4.2'
595 expected = 'v1.11.0-otp-22'
596 got = await setupBeam.getElixirVersion(spec, otpVersion)
597 assert.deepStrictEqual(got, expected)
598 simulateInput('version-type', before)
584 + before = simulateInput('version-type', 'strict')
585 + spec = 'v1.15.0-rc.2'
586 + otpVersion = 'OTP-26'
587 + expected = 'v1.15.0-rc.2-otp-26'
588 + await setupBeam.installOTP(otpVersion)
589 + got = await setupBeam.getElixirVersion(spec, otpVersion)
590 + assert.deepStrictEqual(got, expected)
591 + simulateInput('version-type', before)
599 592
600 before = simulateInput('version-type', 'strict')
601 spec = 'main'
602 otpVersion = '23.1'
603 expected = 'main-otp-23'
604 got = await setupBeam.getElixirVersion(spec, otpVersion)
605 assert.deepStrictEqual(got, expected)
606 simulateInput('version-type', before)
607 })
593 + before = simulateInput('version-type', 'strict')
594 + spec = 'main'
595 + otpVersion = '25.2'
596 + expected = 'main-otp-25'
597 + await setupBeam.installOTP(otpVersion)
598 + got = await setupBeam.getElixirVersion(spec, otpVersion)
599 + assert.deepStrictEqual(got, expected)
600 + simulateInput('version-type', before)
601 + })
602 + }
608 603
609 simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
604 + process.env.RUNNER_ARCH = previousRunnerArch
610 605 })
611 606
612 607 describe('.getOTPVersion(_) - Gleam', () => {
@@ -941,18 +936,16 @@ describe('version file', () => {
941 936 const otpVersion = unsimulateInput('otp-version')
942 937 const elixirVersion = unsimulateInput('elixir-version')
943 938 const gleamVersion = unsimulateInput('gleam-version')
944 const rebar3Version = unsimulateInput('rebar3-version')
945 939
946 940 it('is parsed correctly', async () => {
947 941 const erlang = '27'
948 942 const elixir = '1.17.0'
949 943 const gleam = '0.23.0'
950 const rebar3 = '3.24.0'
951 944 const toolVersions = `# a comment
952 945 erlang ref:v${erlang}# comment, no space, and ref:v
953 946 elixir ref:${elixir} # comment, with space and ref:
954 947 not-gleam 0.23 # not picked up
955 gleam ${gleam} \nrebar ${rebar3}`
948 +gleam ${gleam} \n`
956 949 const filename = 'test/.tool-versions'
957 950 fs.writeFileSync(filename, toolVersions)
958 951 process.env.GITHUB_WORKSPACE = ''
@@ -977,15 +970,11 @@ gleam ${gleam} \nrebar ${rebar3}`
977 970 assert.ok(async () => {
978 971 await setupBeam.install('gleam', { toolVersion: gleam })
979 972 })
980 assert.ok(async () => {
981 await setupBeam.install('rebar3', { toolVersion: rebar3 })
982 })
983 973 })
984 974
985 975 simulateInput('otp-version', otpVersion)
986 976 simulateInput('elixir-version', elixirVersion)
987 977 simulateInput('gleam-version', gleamVersion)
988 simulateInput('rebar3-version', rebar3Version)
989 978 })
990 979
991 980 describe('.get(_)', () => {

Parents: 3c915dd