From c988d8903173ac77794bd200584b624d61661e22 Mon Sep 17 00:00:00 2001 From: "Paulo F. Oliveira" Date: Tue, 3 Aug 2021 18:56:12 +0100 Subject: [PATCH] Add Gleam (#67) --- .github/workflows/ubuntu.yml | 22 ++++- .github/workflows/windows.yml | 22 ++++- 3RD_PARTY_LICENSES | 2 +- README.md | 69 ++++++---------- __tests__/setup-beam.test.js | 43 ++++++++++ action.yml | 4 + dist/index.js | 80 +++++++++++++++++-- dist/install-elixir.ps1 | 2 +- dist/install-gleam.ps1 | 19 +++++ dist/install-gleam.sh | 17 ++++ src/install-elixir.ps1 | 2 +- src/install-gleam.ps1 | 19 +++++ src/install-gleam.sh | 17 ++++ src/installer.js | 16 ++++ src/setup-beam.js | 64 +++++++++++++-- .../{mix => elixir_mix}/.formatter.exs | 0 test-projects/{mix => elixir_mix}/.gitignore | 0 test-projects/{mix => elixir_mix}/README.md | 0 test-projects/{mix => elixir_mix}/lib/test.ex | 0 test-projects/{mix => elixir_mix}/mix.exs | 0 test-projects/{mix => elixir_mix}/mix.lock | 0 .../{mix => elixir_mix}/test/test_helper.exs | 0 .../{mix => elixir_mix}/test/test_test.exs | 0 .../{rebar3 => erlang_rebar3}/.gitignore | 0 .../{rebar3 => erlang_rebar3}/LICENSE | 0 .../{rebar3 => erlang_rebar3}/README.md | 0 .../{rebar3 => erlang_rebar3}/rebar.config | 0 .../{rebar3 => erlang_rebar3}/rebar.lock | 0 .../src/mylib.app.src | 0 .../{rebar3 => erlang_rebar3}/src/mylib.erl | 0 .../test/mylib_SUITE.erl | 0 .../gleam_rebar3/.github/workflows/test.yml | 23 ++++++ test-projects/gleam_rebar3/.gitignore | 21 +++++ test-projects/gleam_rebar3/README.md | 24 ++++++ test-projects/gleam_rebar3/gleam.toml | 3 + test-projects/gleam_rebar3/rebar.config | 12 +++ .../gleam_rebar3/src/gleam_rebar3.app.src | 15 ++++ .../gleam_rebar3/src/gleam_rebar3.gleam | 3 + .../gleam_rebar3/test/gleam_rebar3_test.gleam | 7 ++ 39 files changed, 442 insertions(+), 64 deletions(-) create mode 100644 dist/install-gleam.ps1 create mode 100755 dist/install-gleam.sh create mode 100644 src/install-gleam.ps1 create mode 100755 src/install-gleam.sh rename test-projects/{mix => elixir_mix}/.formatter.exs (100%) rename test-projects/{mix => elixir_mix}/.gitignore (100%) rename test-projects/{mix => elixir_mix}/README.md (100%) rename test-projects/{mix => elixir_mix}/lib/test.ex (100%) rename test-projects/{mix => elixir_mix}/mix.exs (100%) rename test-projects/{mix => elixir_mix}/mix.lock (100%) rename test-projects/{mix => elixir_mix}/test/test_helper.exs (100%) rename test-projects/{mix => elixir_mix}/test/test_test.exs (100%) rename test-projects/{rebar3 => erlang_rebar3}/.gitignore (100%) rename test-projects/{rebar3 => erlang_rebar3}/LICENSE (100%) rename test-projects/{rebar3 => erlang_rebar3}/README.md (100%) rename test-projects/{rebar3 => erlang_rebar3}/rebar.config (100%) rename test-projects/{rebar3 => erlang_rebar3}/rebar.lock (100%) rename test-projects/{rebar3 => erlang_rebar3}/src/mylib.app.src (100%) rename test-projects/{rebar3 => erlang_rebar3}/src/mylib.erl (100%) rename test-projects/{rebar3 => erlang_rebar3}/test/mylib_SUITE.erl (100%) create mode 100644 test-projects/gleam_rebar3/.github/workflows/test.yml create mode 100644 test-projects/gleam_rebar3/.gitignore create mode 100644 test-projects/gleam_rebar3/README.md create mode 100644 test-projects/gleam_rebar3/gleam.toml create mode 100644 test-projects/gleam_rebar3/rebar.config create mode 100644 test-projects/gleam_rebar3/src/gleam_rebar3.app.src create mode 100644 test-projects/gleam_rebar3/src/gleam_rebar3.gleam create mode 100644 test-projects/gleam_rebar3/test/gleam_rebar3_test.gleam diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index a535a48..a361119 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -14,6 +14,7 @@ jobs: name: > OTP ${{matrix.combo.otp-version}}, Elixir ${{matrix.combo.elixir-version}}, + Gleam ${{matrix.combo.gleam-version}}, rebar3 ${{matrix.combo.rebar3-version}} runs-on: ${{matrix.combo.os}} strategy: @@ -106,6 +107,10 @@ jobs: - elixir-version: 'master' otp-version: '23.1' os: 'ubuntu-20.04' + - gleam-version: '0.16' + otp-version: '24' + rebar3-version: '3.16' + os: 'ubuntu-latest' steps: - uses: actions/checkout@v2 - name: Use erlef/setup-beam @@ -114,6 +119,7 @@ jobs: with: otp-version: ${{matrix.combo.otp-version}} elixir-version: ${{matrix.combo.elixir-version}} + gleam-version: ${{matrix.combo.gleam-version}} rebar3-version: ${{matrix.combo.rebar3-version}} version-type: ${{matrix.combo.version-type}} - name: Erlang/OTP version (action) @@ -121,6 +127,9 @@ jobs: - name: Elixir version (action) run: echo "Elixir ${{steps.setup-beam.outputs.elixir-version}}" if: ${{matrix.combo.elixir-version}} + - name: Gleam version (action) + run: echo "Gleam ${{steps.setup-beam.outputs.gleam-version}}" + if: ${{matrix.combo.gleam-version}} - name: rebar3 version (action) run: echo "rebar3 ${{steps.setup-beam.outputs.rebar3-version}}" if: ${{matrix.combo.rebar3-version}} @@ -130,14 +139,19 @@ jobs: mix help local.rebar mix help local.hex if: ${{matrix.combo.elixir-version}} - - name: Run Mix project tests + - name: Run Elixir/Mix project tests run: | - cd test-projects/mix + cd test-projects/elixir_mix mix deps.get mix test if: ${{matrix.combo.elixir-version}} - - name: Run rebar3 project tests + - name: Run Erlang/rebar3 project tests run: | - cd test-projects/rebar3 + cd test-projects/erlang_rebar3 rebar3 ct if: ${{matrix.combo.rebar3-version}} + - name: Run Gleam/rebar3 project tests + run: | + cd test-projects/gleam_rebar3 + rebar3 eunit + if: ${{matrix.combo.gleam-version}} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6bb1b47..42a44cd 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -14,6 +14,7 @@ jobs: name: > OTP ${{matrix.combo.otp-version}}, Elixir ${{matrix.combo.elixir-version}}, + Gleam ${{matrix.combo.gleam-version}}, rebar3 ${{matrix.combo.rebar3-version}} runs-on: ${{matrix.combo.os}} strategy: @@ -52,6 +53,10 @@ jobs: otp-version: '24' rebar3-version: '3.15' os: 'windows-latest' + - gleam-version: '0.16' + otp-version: '24' + rebar3-version: '3.16' + os: 'windows-latest' steps: - uses: actions/checkout@v2 - name: Use erlef/setup-beam @@ -60,12 +65,16 @@ jobs: with: otp-version: ${{matrix.combo.otp-version}} elixir-version: ${{matrix.combo.elixir-version}} + gleam-version: ${{matrix.combo.gleam-version}} rebar3-version: ${{matrix.combo.rebar3-version}} - name: Erlang/OTP version (action) run: echo "Erlang/OTP ${{steps.setup-beam.outputs.otp-version}}" - name: Elixir version (action) run: echo "Elixir ${{steps.setup-beam.outputs.elixir-version}}" if: ${{matrix.combo.elixir-version}} + - name: Gleam version (action) + run: echo "Gleam ${{steps.setup-beam.outputs.gleam-version}}" + if: ${{matrix.combo.gleam-version}} - name: rebar3 version (action) run: echo "rebar3 ${{steps.setup-beam.outputs.rebar3-version}}" - name: mix version and help (CLI) @@ -74,14 +83,19 @@ jobs: mix help local.rebar mix help local.hex if: ${{matrix.combo.elixir-version}} - - name: Run Mix project tests + - name: Run Elixir/Mix project tests run: | - cd test-projects/mix + cd test-projects/elixir_mix mix deps.get mix test if: ${{matrix.combo.elixir-version}} - - name: Run rebar3 project tests + - name: Run Erlang/rebar3 project tests run: | - cd test-projects/rebar3 + cd test-projects/erlang_rebar3 rebar3 ct if: ${{matrix.combo.rebar3-version}} + - name: Run Gleam/rebar3 project tests + run: | + cd test-projects/gleam_rebar3 + rebar3 eunit + if: ${{matrix.combo.gleam-version}} diff --git a/3RD_PARTY_LICENSES b/3RD_PARTY_LICENSES index f596459..7079bc9 100644 --- a/3RD_PARTY_LICENSES +++ b/3RD_PARTY_LICENSES @@ -1810,7 +1810,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ----- -The following software may be included in this product: has-bigints, unbox-primitive, which-boxed-primitive. A copy of the source code may be downloaded from git+https://github.com/ljharb/has-bigints.git (has-bigints), git+https://github.com/ljharb/unbox-primitive.git (unbox-primitive), git+https://github.com/inspect-js/which-boxed-primitive.git (which-boxed-primitive). This software contains the following license and notice below: +The following software may be included in this product: has-bigints, internal-slot, side-channel, unbox-primitive, which-boxed-primitive. A copy of the source code may be downloaded from git+https://github.com/ljharb/has-bigints.git (has-bigints), git+https://github.com/ljharb/internal-slot.git (internal-slot), git+https://github.com/ljharb/side-channel.git (side-channel), git+https://github.com/ljharb/unbox-primitive.git (unbox-primitive), git+https://github.com/inspect-js/which-boxed-primitive.git (which-boxed-primitive). This software contains the following license and notice below: MIT License diff --git a/README.md b/README.md index d24b36a..12757e4 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ workflow by: - installing Erlang/OTP - optionally, installing Elixir +- optionally, installing Gleam - optionally, installing `rebar3` - optionally, installing `hex` @@ -24,13 +25,13 @@ See [action.yml](action.yml) for the action's specification. **Note**: The Erlang/OTP release version specification is [relatively complex](http://erlang.org/doc/system_principles/versions.html#version-scheme). -For best results, we recommend specifying exact Erlang/OTP, Elixir versions, and -`rebar3` versions, and setting option `version-type` to `strict`. +For best results, we recommend specifying exact +versions, and setting option `version-type` to `strict`. However, values like `22.x`, or even `>22`, are also accepted, and we attempt to resolve them according to semantic versioning rules. This implicitly means `version-type` is `loose`, which is also the default value for this option. -Additionally, it is recommended that one specifies Erlang/OTP, Elixir and `rebar3` versions +Additionally, it is recommended that one specifies versions using YAML strings, as these examples do, so that numbers like `23.0` don't end up being parsed as `23`, which is not equivalent. @@ -82,44 +83,7 @@ jobs: ... ``` -### Basic example (Erlang/OTP + Elixir, on Ubuntu) - -```yaml -# create this in .github/workflows/ci.yml -on: push - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: erlef/setup-beam@v1 - with: - otp-version: '22.2' - elixir-version: '1.9.4' - - run: mix deps.get - - run: mix test -``` - -### Basic example (Erlang/OTP + `rebar3`, on Ubuntu) - -```yaml -# create this in .github/workflows/ci.yml -on: push - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: erlef/setup-beam@v1 - with: - otp-version: '22.2' - rebar3-version: '3.14.2' - - run: rebar3 ct -``` - -### Matrix example (Erlang/OTP + Elixir, on Ubuntu) +### Example (Erlang/OTP + Elixir, on Ubuntu) ```yaml # create this in .github/workflows/ci.yml @@ -143,7 +107,7 @@ jobs: - run: mix test ``` -### Matrix example (Erlang/OTP + `rebar3`, on Ubuntu) +### Example (Erlang/OTP + `rebar3`, on Ubuntu) ```yaml # create this in .github/workflows/ci.yml @@ -166,7 +130,7 @@ jobs: - run: rebar3 ct ``` -### Basic example (Erlang/OTP + `rebar3`, on Windows) +### Example (Erlang/OTP + `rebar3`, on Windows) ```yaml # create this in .github/workflows/ci.yml @@ -184,6 +148,25 @@ jobs: - run: rebar3 ct ``` +### Example (Gleam + `rebar3`, on Ubuntu) + +```yaml +# create this in .github/workflows/ci.yml +on: push + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: erlef/setup-beam@v1 + with: + otp-version: '24' + gleam-version: '0.16' + rebar3-version: '3.16' + - run: rebar3 ct +``` + ## Elixir Problem Matchers The Elixir Problem Matchers in this repository are adapted from [here](https://github.com/fr1zle/vscode-elixir/blob/45eddb589acd7ac98e0c7305d1c2b24668ca709a/package.json#L70-L118). See [MATCHER_NOTICE](MATCHER_NOTICE.md) for license details. diff --git a/__tests__/setup-beam.test.js b/__tests__/setup-beam.test.js index f1e71ff..b3af58d 100644 --- a/__tests__/setup-beam.test.js +++ b/__tests__/setup-beam.test.js @@ -11,10 +11,12 @@ const installer = require('../src/installer') async function all() { await testFailInstallOTP() await testFailInstallElixir() + await testFailInstallGleam() await testFailInstallRebar3() await testOTPVersions() await testElixirVersions() + await testGleamVersions() await testRebar3Versions() await testGetVersionFromSpec() @@ -63,6 +65,20 @@ async function testFailInstallElixir() { ) } +async function testFailInstallGleam() { + const gleamVersion = '0.1.3' + assert.rejects( + async () => { + await installer.installGleam(gleamVersion) + }, + (err) => { + assert.ok(err instanceof Error) + return true + }, + `Installing Gleam ${gleamVersion} is supposed to fail`, + ) +} + async function testFailInstallRebar3() { const r3Version = '0.14.4' assert.rejects( @@ -197,6 +213,33 @@ async function testElixirVersions() { simulateInput('version-type', 'loose') } +async function testGleamVersions() { + let got + let expected + let spec + let otpVersion + + spec = 'v0.3.0' + otpVersion = 'OTP-23' + expected = 'v0.3.0' + got = await setupBeam.getGleamVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + + spec = '0.13.2' + otpVersion = 'OTP-24' + expected = 'v0.13.2' + got = await setupBeam.getGleamVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + + simulateInput('version-type', 'strict') + spec = 'v0.14.0-rc2' + otpVersion = 'OTP-22' + expected = 'v0.14.0-rc2' + got = await setupBeam.getGleamVersion(spec, otpVersion) + assert.deepStrictEqual(got, expected) + simulateInput('version-type', 'loose') +} + async function testRebar3Versions() { let got let expected diff --git a/action.yml b/action.yml index 59063c7..10c0433 100644 --- a/action.yml +++ b/action.yml @@ -12,6 +12,8 @@ inputs: description: Version range or exact version of Elixir to use otp-version: description: Version range or exact version of Erlang/OTP to use + gleam-version: + description: Version range or exact version of Gleam to use install-hex: description: Whether to install Hex (with Mix) default: true @@ -29,6 +31,8 @@ outputs: description: Exact version of Elixir that was installed otp-version: description: Exact version of Erlang/OTP that was installed + gleam-version: + description: Exact version of Gleam that was installed rebar3-version: description: Exact version of rebar3 that was installed runs: diff --git a/dist/index.js b/dist/index.js index bbe5fd5..3fa3898 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4618,6 +4618,21 @@ async function installElixir(elixirVersion) { } } +/** + * Install Gleam. + * + * @param {string} gleamVersion + */ +async function installGleam(gleamVersion) { + const OS = process.platform + if (OS === 'linux') { + await exec(__nccwpck_require__.ab + "install-gleam.sh", [gleamVersion]) + } else if (OS === 'win32') { + const script = __nccwpck_require__.ab + "install-gleam.ps1" + await exec(`pwsh.exe ${script} -VSN:${gleamVersion}`) + } +} + /** * Install rebar3. * @@ -4644,6 +4659,7 @@ function checkPlatform() { module.exports = { installOTP, installElixir, + installGleam, installRebar3, checkPlatform, } @@ -4686,6 +4702,9 @@ async function main() { await mix(shouldMixHex, 'hex') } + const gleamSpec = core.getInput('gleam-version', { required: false }) + await maybeInstallGleam(gleamSpec) + const rebar3Spec = core.getInput('rebar3-version', { required: false }) await maybeInstallRebar3(rebar3Spec) } @@ -4742,6 +4761,23 @@ async function mix(shouldMix, what) { } } +async function maybeInstallGleam(gleamSpec) { + let installed = false + + if (gleamSpec) { + const gleamVersion = await getGleamVersion(gleamSpec) + console.log(`##[group]Installing Gleam ${gleamVersion}`) + await installer.installGleam(gleamVersion) + core.setOutput('gleam-version', gleamVersion) + core.addPath(`${process.env.RUNNER_TEMP}/.setup-beam/gleam/bin`) + console.log('##[endgroup]') + + installed = true + } + + return installed +} + async function maybeInstallRebar3(rebar3Spec) { let installed = false @@ -4830,10 +4866,21 @@ async function getElixirVersion(exSpec0, otpVersion) { ) } - const DigitStart = new RegExp('^\\d+') - return DigitStart.test(elixirVersion) - ? `v${elixirVersionWithOTP}` - : elixirVersionWithOTP + return maybePrependWithV(elixirVersionWithOTP, elixirVersion) +} + +async function getGleamVersion(gleamSpec0) { + const gleamSpec = gleamSpec0.match(/^v?(.+)/) + const gleamVersions = await getGleamVersions() + const gleamVersion = getVersionFromSpec(gleamSpec[1], gleamVersions) + if (gleamVersion === null) { + throw new Error( + `Requested Gleam version (${gleamSpec0}) not found in version list ` + + "(should you be using option 'version-type': 'strict'?)", + ) + } + + return maybePrependWithV(gleamVersion, gleamVersion) } async function getRebar3Version(r3Spec) { @@ -4916,6 +4963,21 @@ async function getElixirVersions() { return otpVersionsForElixirMap } +async function getGleamVersions() { + const resultJSONs = await get( + 'https://api.github.com/repos/gleam-lang/gleam/releases?per_page=100', + [1, 2, 3], + ) + const gleamVersionsListing = [] + resultJSONs.forEach((resultJSON) => { + JSON.parse(resultJSON) + .map((x) => x.tag_name) + .sort() + .forEach((v) => gleamVersionsListing.push(v)) + }) + return gleamVersionsListing +} + async function getRebar3Versions() { const resultJSONs = await get( 'https://api.github.com/repos/erlang/rebar3/releases?per_page=100', @@ -4959,7 +5021,7 @@ function getVersionFromSpec(spec, versions) { } } - return version + return version === null || version === undefined ? null : version } function maybeCoerced(v) { @@ -5066,9 +5128,17 @@ async function get(url0, pageIdxs) { return ret } +function maybePrependWithV(versionToPrepend, specVersion) { + const digitStart = new RegExp('^\\d+') + return digitStart.test(specVersion) + ? `v${versionToPrepend}` + : versionToPrepend +} + module.exports = { getOTPVersion, getElixirVersion, + getGleamVersion, getRebar3Version, getVersionFromSpec, } diff --git a/dist/install-elixir.ps1 b/dist/install-elixir.ps1 index f822de2..019b947 100644 --- a/dist/install-elixir.ps1 +++ b/dist/install-elixir.ps1 @@ -15,5 +15,5 @@ New-Item "$DIR_FOR_BIN" -ItemType Directory | Out-Null $ProgressPreference="SilentlyContinue" Expand-Archive -DestinationPath "${DIR_FOR_BIN}" -Path "${FILE_OUTPUT}" $ProgressPreference="Continue" -Write-Output "Installed Erlang/OTP version follows" +Write-Output "Installed Elixir version follows" & "$DIR_FOR_BIN/bin/iex" "-v" | Write-Output diff --git a/dist/install-gleam.ps1 b/dist/install-gleam.ps1 new file mode 100644 index 0000000..b80b527 --- /dev/null +++ b/dist/install-gleam.ps1 @@ -0,0 +1,19 @@ +param([Parameter(Mandatory=$true)][string]$VSN) + +$ErrorActionPreference="Stop" + +Set-Location $Env:RUNNER_TEMP + +$FILE_INPUT="gleam-${VSN}-windows-64bit.zip" +$FILE_OUTPUT="gleam.zip" +$DIR_FOR_BIN=".setup-beam/gleam/bin" + +$ProgressPreference="SilentlyContinue" +Invoke-WebRequest "https://github.com/gleam-lang/gleam/releases/download/${VSN}/${FILE_INPUT}" -OutFile "$FILE_OUTPUT" +$ProgressPreference="Continue" +New-Item "$DIR_FOR_BIN" -ItemType Directory | Out-Null +$ProgressPreference="SilentlyContinue" +Expand-Archive -DestinationPath "${DIR_FOR_BIN}" -Path "${FILE_OUTPUT}" +$ProgressPreference="Continue" +Write-Output "Installed Gleam version follows" +& "$DIR_FOR_BIN/gleam" "--version" | Write-Output diff --git a/dist/install-gleam.sh b/dist/install-gleam.sh new file mode 100755 index 0000000..3ae577d --- /dev/null +++ b/dist/install-gleam.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -eo pipefail + +cd "$RUNNER_TEMP" + +VSN=${1} +FILE_INPUT=gleam-${VSN}-linux-amd64.tar.gz +FILE_OUTPUT=gleam.tar.gz +DIR_FOR_BIN=.setup-beam/gleam/bin + +wget -q -O "${FILE_OUTPUT}" "https://github.com/gleam-lang/gleam/releases/download/${VSN}/${FILE_INPUT}" +mkdir -p "${DIR_FOR_BIN}" +tar zxf "${FILE_OUTPUT}" -C "${DIR_FOR_BIN}" + +echo "Installed Gleam version follows" +${DIR_FOR_BIN}/gleam --version diff --git a/src/install-elixir.ps1 b/src/install-elixir.ps1 index f822de2..019b947 100644 --- a/src/install-elixir.ps1 +++ b/src/install-elixir.ps1 @@ -15,5 +15,5 @@ New-Item "$DIR_FOR_BIN" -ItemType Directory | Out-Null $ProgressPreference="SilentlyContinue" Expand-Archive -DestinationPath "${DIR_FOR_BIN}" -Path "${FILE_OUTPUT}" $ProgressPreference="Continue" -Write-Output "Installed Erlang/OTP version follows" +Write-Output "Installed Elixir version follows" & "$DIR_FOR_BIN/bin/iex" "-v" | Write-Output diff --git a/src/install-gleam.ps1 b/src/install-gleam.ps1 new file mode 100644 index 0000000..b80b527 --- /dev/null +++ b/src/install-gleam.ps1 @@ -0,0 +1,19 @@ +param([Parameter(Mandatory=$true)][string]$VSN) + +$ErrorActionPreference="Stop" + +Set-Location $Env:RUNNER_TEMP + +$FILE_INPUT="gleam-${VSN}-windows-64bit.zip" +$FILE_OUTPUT="gleam.zip" +$DIR_FOR_BIN=".setup-beam/gleam/bin" + +$ProgressPreference="SilentlyContinue" +Invoke-WebRequest "https://github.com/gleam-lang/gleam/releases/download/${VSN}/${FILE_INPUT}" -OutFile "$FILE_OUTPUT" +$ProgressPreference="Continue" +New-Item "$DIR_FOR_BIN" -ItemType Directory | Out-Null +$ProgressPreference="SilentlyContinue" +Expand-Archive -DestinationPath "${DIR_FOR_BIN}" -Path "${FILE_OUTPUT}" +$ProgressPreference="Continue" +Write-Output "Installed Gleam version follows" +& "$DIR_FOR_BIN/gleam" "--version" | Write-Output diff --git a/src/install-gleam.sh b/src/install-gleam.sh new file mode 100755 index 0000000..3ae577d --- /dev/null +++ b/src/install-gleam.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -eo pipefail + +cd "$RUNNER_TEMP" + +VSN=${1} +FILE_INPUT=gleam-${VSN}-linux-amd64.tar.gz +FILE_OUTPUT=gleam.tar.gz +DIR_FOR_BIN=.setup-beam/gleam/bin + +wget -q -O "${FILE_OUTPUT}" "https://github.com/gleam-lang/gleam/releases/download/${VSN}/${FILE_INPUT}" +mkdir -p "${DIR_FOR_BIN}" +tar zxf "${FILE_OUTPUT}" -C "${DIR_FOR_BIN}" + +echo "Installed Gleam version follows" +${DIR_FOR_BIN}/gleam --version diff --git a/src/installer.js b/src/installer.js index 4860929..b19a3b4 100644 --- a/src/installer.js +++ b/src/installer.js @@ -32,6 +32,21 @@ async function installElixir(elixirVersion) { } } +/** + * Install Gleam. + * + * @param {string} gleamVersion + */ +async function installGleam(gleamVersion) { + const OS = process.platform + if (OS === 'linux') { + await exec(path.join(__dirname, 'install-gleam.sh'), [gleamVersion]) + } else if (OS === 'win32') { + const script = path.join(__dirname, 'install-gleam.ps1') + await exec(`pwsh.exe ${script} -VSN:${gleamVersion}`) + } +} + /** * Install rebar3. * @@ -58,6 +73,7 @@ function checkPlatform() { module.exports = { installOTP, installElixir, + installGleam, installRebar3, checkPlatform, } diff --git a/src/setup-beam.js b/src/setup-beam.js index 3225d4c..50adc96 100644 --- a/src/setup-beam.js +++ b/src/setup-beam.js @@ -30,6 +30,9 @@ async function main() { await mix(shouldMixHex, 'hex') } + const gleamSpec = core.getInput('gleam-version', { required: false }) + await maybeInstallGleam(gleamSpec) + const rebar3Spec = core.getInput('rebar3-version', { required: false }) await maybeInstallRebar3(rebar3Spec) } @@ -86,6 +89,23 @@ async function mix(shouldMix, what) { } } +async function maybeInstallGleam(gleamSpec) { + let installed = false + + if (gleamSpec) { + const gleamVersion = await getGleamVersion(gleamSpec) + console.log(`##[group]Installing Gleam ${gleamVersion}`) + await installer.installGleam(gleamVersion) + core.setOutput('gleam-version', gleamVersion) + core.addPath(`${process.env.RUNNER_TEMP}/.setup-beam/gleam/bin`) + console.log('##[endgroup]') + + installed = true + } + + return installed +} + async function maybeInstallRebar3(rebar3Spec) { let installed = false @@ -174,10 +194,21 @@ async function getElixirVersion(exSpec0, otpVersion) { ) } - const DigitStart = new RegExp('^\\d+') - return DigitStart.test(elixirVersion) - ? `v${elixirVersionWithOTP}` - : elixirVersionWithOTP + return maybePrependWithV(elixirVersionWithOTP, elixirVersion) +} + +async function getGleamVersion(gleamSpec0) { + const gleamSpec = gleamSpec0.match(/^v?(.+)/) + const gleamVersions = await getGleamVersions() + const gleamVersion = getVersionFromSpec(gleamSpec[1], gleamVersions) + if (gleamVersion === null) { + throw new Error( + `Requested Gleam version (${gleamSpec0}) not found in version list ` + + "(should you be using option 'version-type': 'strict'?)", + ) + } + + return maybePrependWithV(gleamVersion, gleamVersion) } async function getRebar3Version(r3Spec) { @@ -260,6 +291,21 @@ async function getElixirVersions() { return otpVersionsForElixirMap } +async function getGleamVersions() { + const resultJSONs = await get( + 'https://api.github.com/repos/gleam-lang/gleam/releases?per_page=100', + [1, 2, 3], + ) + const gleamVersionsListing = [] + resultJSONs.forEach((resultJSON) => { + JSON.parse(resultJSON) + .map((x) => x.tag_name) + .sort() + .forEach((v) => gleamVersionsListing.push(v)) + }) + return gleamVersionsListing +} + async function getRebar3Versions() { const resultJSONs = await get( 'https://api.github.com/repos/erlang/rebar3/releases?per_page=100', @@ -303,7 +349,7 @@ function getVersionFromSpec(spec, versions) { } } - return version + return version === null || version === undefined ? null : version } function maybeCoerced(v) { @@ -410,9 +456,17 @@ async function get(url0, pageIdxs) { return ret } +function maybePrependWithV(versionToPrepend, specVersion) { + const digitStart = new RegExp('^\\d+') + return digitStart.test(specVersion) + ? `v${versionToPrepend}` + : versionToPrepend +} + module.exports = { getOTPVersion, getElixirVersion, + getGleamVersion, getRebar3Version, getVersionFromSpec, } diff --git a/test-projects/mix/.formatter.exs b/test-projects/elixir_mix/.formatter.exs similarity index 100% rename from test-projects/mix/.formatter.exs rename to test-projects/elixir_mix/.formatter.exs diff --git a/test-projects/mix/.gitignore b/test-projects/elixir_mix/.gitignore similarity index 100% rename from test-projects/mix/.gitignore rename to test-projects/elixir_mix/.gitignore diff --git a/test-projects/mix/README.md b/test-projects/elixir_mix/README.md similarity index 100% rename from test-projects/mix/README.md rename to test-projects/elixir_mix/README.md diff --git a/test-projects/mix/lib/test.ex b/test-projects/elixir_mix/lib/test.ex similarity index 100% rename from test-projects/mix/lib/test.ex rename to test-projects/elixir_mix/lib/test.ex diff --git a/test-projects/mix/mix.exs b/test-projects/elixir_mix/mix.exs similarity index 100% rename from test-projects/mix/mix.exs rename to test-projects/elixir_mix/mix.exs diff --git a/test-projects/mix/mix.lock b/test-projects/elixir_mix/mix.lock similarity index 100% rename from test-projects/mix/mix.lock rename to test-projects/elixir_mix/mix.lock diff --git a/test-projects/mix/test/test_helper.exs b/test-projects/elixir_mix/test/test_helper.exs similarity index 100% rename from test-projects/mix/test/test_helper.exs rename to test-projects/elixir_mix/test/test_helper.exs diff --git a/test-projects/mix/test/test_test.exs b/test-projects/elixir_mix/test/test_test.exs similarity index 100% rename from test-projects/mix/test/test_test.exs rename to test-projects/elixir_mix/test/test_test.exs diff --git a/test-projects/rebar3/.gitignore b/test-projects/erlang_rebar3/.gitignore similarity index 100% rename from test-projects/rebar3/.gitignore rename to test-projects/erlang_rebar3/.gitignore diff --git a/test-projects/rebar3/LICENSE b/test-projects/erlang_rebar3/LICENSE similarity index 100% rename from test-projects/rebar3/LICENSE rename to test-projects/erlang_rebar3/LICENSE diff --git a/test-projects/rebar3/README.md b/test-projects/erlang_rebar3/README.md similarity index 100% rename from test-projects/rebar3/README.md rename to test-projects/erlang_rebar3/README.md diff --git a/test-projects/rebar3/rebar.config b/test-projects/erlang_rebar3/rebar.config similarity index 100% rename from test-projects/rebar3/rebar.config rename to test-projects/erlang_rebar3/rebar.config diff --git a/test-projects/rebar3/rebar.lock b/test-projects/erlang_rebar3/rebar.lock similarity index 100% rename from test-projects/rebar3/rebar.lock rename to test-projects/erlang_rebar3/rebar.lock diff --git a/test-projects/rebar3/src/mylib.app.src b/test-projects/erlang_rebar3/src/mylib.app.src similarity index 100% rename from test-projects/rebar3/src/mylib.app.src rename to test-projects/erlang_rebar3/src/mylib.app.src diff --git a/test-projects/rebar3/src/mylib.erl b/test-projects/erlang_rebar3/src/mylib.erl similarity index 100% rename from test-projects/rebar3/src/mylib.erl rename to test-projects/erlang_rebar3/src/mylib.erl diff --git a/test-projects/rebar3/test/mylib_SUITE.erl b/test-projects/erlang_rebar3/test/mylib_SUITE.erl similarity index 100% rename from test-projects/rebar3/test/mylib_SUITE.erl rename to test-projects/erlang_rebar3/test/mylib_SUITE.erl diff --git a/test-projects/gleam_rebar3/.github/workflows/test.yml b/test-projects/gleam_rebar3/.github/workflows/test.yml new file mode 100644 index 0000000..1d08ac6 --- /dev/null +++ b/test-projects/gleam_rebar3/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: test + +on: + push: + branches: + - master + - main + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.0.0 + - uses: gleam-lang/setup-erlang@v1.1.2 + with: + otp-version: 23.2 + - uses: gleam-lang/setup-gleam@v1.0.2 + with: + gleam-version: 0.16.1 + - run: rebar3 install_deps + - run: rebar3 eunit + - run: gleam format --check src test diff --git a/test-projects/gleam_rebar3/.gitignore b/test-projects/gleam_rebar3/.gitignore new file mode 100644 index 0000000..3e67663 --- /dev/null +++ b/test-projects/gleam_rebar3/.gitignore @@ -0,0 +1,21 @@ +*.beam +*.iml +*.o +*.plt +*.swo +*.swp +*~ +.erlang.cookie +.eunit +.idea +.rebar +.rebar3 +_* +_build +docs +ebin +erl_crash.dump +gen +log +logs +rebar3.crashdump diff --git a/test-projects/gleam_rebar3/README.md b/test-projects/gleam_rebar3/README.md new file mode 100644 index 0000000..cc4243c --- /dev/null +++ b/test-projects/gleam_rebar3/README.md @@ -0,0 +1,24 @@ +# gleam_rebar3 + +A Gleam project + +## Quick start + +```sh +# Run the eunit tests +rebar3 eunit + +# Run the Erlang REPL +rebar3 shell +``` + +## Installation + +If [available in Hex](https://rebar3.org/docs/configuration/dependencies/#declaring-dependencies) +this package can be installed by adding `gleam_rebar3` to your `rebar.config` dependencies: + +```erlang +{deps, [ + gleam_rebar3 +]}. +``` diff --git a/test-projects/gleam_rebar3/gleam.toml b/test-projects/gleam_rebar3/gleam.toml new file mode 100644 index 0000000..9cf4499 --- /dev/null +++ b/test-projects/gleam_rebar3/gleam.toml @@ -0,0 +1,3 @@ +name = "gleam_rebar3" + +# repository = { type = "github", user = "my-user", repo = "gleam_rebar3" } diff --git a/test-projects/gleam_rebar3/rebar.config b/test-projects/gleam_rebar3/rebar.config new file mode 100644 index 0000000..e36d020 --- /dev/null +++ b/test-projects/gleam_rebar3/rebar.config @@ -0,0 +1,12 @@ +{erl_opts, [debug_info]}. +{src_dirs, ["src", "gen/src"]}. + +{profiles, [ + {test, [{src_dirs, ["src", "test", "gen/src", "gen/test"]}]} +]}. + +{project_plugins, [rebar_gleam]}. + +{deps, [ + {gleam_stdlib, "0.16.0"} +]}. diff --git a/test-projects/gleam_rebar3/src/gleam_rebar3.app.src b/test-projects/gleam_rebar3/src/gleam_rebar3.app.src new file mode 100644 index 0000000..d9746bc --- /dev/null +++ b/test-projects/gleam_rebar3/src/gleam_rebar3.app.src @@ -0,0 +1,15 @@ +{application, gleam_rebar3, + [{description, "A Gleam project"}, + {vsn, "0.1.0"}, + {registered, []}, + {applications, + [kernel, + stdlib, + gleam_stdlib + ]}, + {env,[]}, + {modules, []}, + + {include_files, ["gleam.toml", "gen"]}, + {links, []} +]}. diff --git a/test-projects/gleam_rebar3/src/gleam_rebar3.gleam b/test-projects/gleam_rebar3/src/gleam_rebar3.gleam new file mode 100644 index 0000000..5b8cdef --- /dev/null +++ b/test-projects/gleam_rebar3/src/gleam_rebar3.gleam @@ -0,0 +1,3 @@ +pub fn hello_world() -> String { + "Hello, from gleam_rebar3!" +} diff --git a/test-projects/gleam_rebar3/test/gleam_rebar3_test.gleam b/test-projects/gleam_rebar3/test/gleam_rebar3_test.gleam new file mode 100644 index 0000000..7494e5c --- /dev/null +++ b/test-projects/gleam_rebar3/test/gleam_rebar3_test.gleam @@ -0,0 +1,7 @@ +import gleam_rebar3 +import gleam/should + +pub fn hello_world_test() { + gleam_rebar3.hello_world() + |> should.equal("Hello, from gleam_rebar3!") +}