From 9933312ae77442f1fc8a613c182206d0e45ea0e8 Mon Sep 17 00:00:00 2001 From: Elodie Lander Date: Mon, 2 Oct 2023 04:53:32 -0500 Subject: [PATCH] Use ghcup to install cabal head (#290) This allows `head` to be the specified cabal version. Commits: * Use ghcup to install cabal head * Add cabal head to cabal-version description * Add cabal head test and check * Add cabal head to README supported versions * Use wildcard to check that version is prefix * Make sed version grabber cross platform --- .github/workflows/workflow.yml | 15 ++++++++++++++- README.md | 1 + action.yml | 2 +- dist/index.js | 32 ++++++++++++++++++++++++++++++-- lib/installer.js | 32 ++++++++++++++++++++++++++++++-- src/installer.ts | 32 ++++++++++++++++++++++++++++++-- 6 files changed, 106 insertions(+), 8 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 5704a76..e4445fc 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -48,6 +48,9 @@ jobs: # Latest releases - ghc: latest cabal: latest + # Latest ghc with cabal head + - ghc: latest + cabal: head # Recommended releases (update according to ghcup) # 9.4 will be recommended soon - ghc: "9.4" @@ -177,7 +180,17 @@ jobs: else GHCVER_EXPECTED="${{ steps.setup.outputs.ghc-version }}" fi - [[ "${CABALVER}" == "${{ steps.setup.outputs.cabal-version }}" ]] && \ + if [[ "${{ steps.setup.outputs.cabal-version }}" == "head" ]] + then + CABALVER_EXPECTED=$( \ + curl --silent https://raw.githubusercontent.com/haskell/cabal/master/cabal-install/cabal-install.cabal | \ + sed -E -n 's/^Version:[[:space:]]+//p' \ + ) + echo "Cabal head: ${CABALVER_EXPECTED}" + else + CABALVER_EXPECTED="${{ steps.setup.outputs.cabal-version }}" + fi + [[ "${CABALVER_EXPECTED}" == ${CABALVER}* ]] && \ [[ "${GHCVER}" == "${GHCVER_EXPECTED}" ]] - name: Test runghc diff --git a/README.md b/README.md index f3e185b..d76f0c9 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,7 @@ Suggestion: Try to support at least the three latest major versions of GHC. **Cabal:** +- `head` (the [cabal-head](https://github.com/haskell/cabal/releases/tag/cabal-head) release of the most recent build of the `master` branch) - `latest` (default, recommended) - `3.10.1.0` `3.10` - `3.8.1.0` `3.8` diff --git a/action.yml b/action.yml index ba95487..1347ef4 100644 --- a/action.yml +++ b/action.yml @@ -8,7 +8,7 @@ inputs: default: 'latest' cabal-version: required: false - description: 'Version of Cabal to use. If set to "latest", it will always get the latest stable version.' + description: 'Version of Cabal to use. If set to "latest", it will always get the latest stable version. If set to "head", it will always get the latest build of cabal.' default: 'latest' stack-version: required: false diff --git a/dist/index.js b/dist/index.js index 5a81909..4d86528 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13663,9 +13663,37 @@ exports.addGhcupReleaseChannel = addGhcupReleaseChannel; async function ghcup(tool, version, os) { core.info(`Attempting to install ${tool} ${version} using ghcup`); const bin = await ghcupBin(os); - const returnCode = await exec(bin, ['install', tool, version]); + if (tool === 'cabal' && version === 'head') { + await ghcupCabalHead(os, bin); + } + else { + const returnCode = await exec(bin, ['install', tool, version]); + if (returnCode === 0) + await exec(bin, ['set', tool, version]); + } +} +function cabalHeadUrlTag(os) { + switch (os) { + case 'linux': + return 'Linux'; + case 'darwin': + return 'macOS'; + case 'win32': + return 'Windows'; + } +} +async function ghcupCabalHead(os, bin) { + const osTag = cabalHeadUrlTag(os); + const cabalHeadUrl = `https://github.com/haskell/cabal/releases/download/cabal-head/cabal-head-${osTag}-x86_64.tar.gz`; + const returnCode = await exec(bin, [ + 'install', + 'cabal', + '-u', + cabalHeadUrl, + 'head' + ]); if (returnCode === 0) - await exec(bin, ['set', tool, version]); + await exec(bin, ['set', 'cabal', 'head']); } async function ghcupGHCHead() { core.info(`Attempting to install ghc head using ghcup`); diff --git a/lib/installer.js b/lib/installer.js index 52df7c4..c5f3ca5 100644 --- a/lib/installer.js +++ b/lib/installer.js @@ -299,9 +299,37 @@ exports.addGhcupReleaseChannel = addGhcupReleaseChannel; async function ghcup(tool, version, os) { core.info(`Attempting to install ${tool} ${version} using ghcup`); const bin = await ghcupBin(os); - const returnCode = await exec(bin, ['install', tool, version]); + if (tool === 'cabal' && version === 'head') { + await ghcupCabalHead(os, bin); + } + else { + const returnCode = await exec(bin, ['install', tool, version]); + if (returnCode === 0) + await exec(bin, ['set', tool, version]); + } +} +function cabalHeadUrlTag(os) { + switch (os) { + case 'linux': + return 'Linux'; + case 'darwin': + return 'macOS'; + case 'win32': + return 'Windows'; + } +} +async function ghcupCabalHead(os, bin) { + const osTag = cabalHeadUrlTag(os); + const cabalHeadUrl = `https://github.com/haskell/cabal/releases/download/cabal-head/cabal-head-${osTag}-x86_64.tar.gz`; + const returnCode = await exec(bin, [ + 'install', + 'cabal', + '-u', + cabalHeadUrl, + 'head' + ]); if (returnCode === 0) - await exec(bin, ['set', tool, version]); + await exec(bin, ['set', 'cabal', 'head']); } async function ghcupGHCHead() { core.info(`Attempting to install ghc head using ghcup`); diff --git a/src/installer.ts b/src/installer.ts index e95cbb2..96e664c 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -346,8 +346,36 @@ export async function addGhcupReleaseChannel( async function ghcup(tool: Tool, version: string, os: OS): Promise { core.info(`Attempting to install ${tool} ${version} using ghcup`); const bin = await ghcupBin(os); - const returnCode = await exec(bin, ['install', tool, version]); - if (returnCode === 0) await exec(bin, ['set', tool, version]); + if (tool === 'cabal' && version === 'head') { + await ghcupCabalHead(os, bin); + } else { + const returnCode = await exec(bin, ['install', tool, version]); + if (returnCode === 0) await exec(bin, ['set', tool, version]); + } +} + +function cabalHeadUrlTag(os: OS): string { + switch (os) { + case 'linux': + return 'Linux'; + case 'darwin': + return 'macOS'; + case 'win32': + return 'Windows'; + } +} + +async function ghcupCabalHead(os: OS, bin: string): Promise { + const osTag = cabalHeadUrlTag(os); + const cabalHeadUrl = `https://github.com/haskell/cabal/releases/download/cabal-head/cabal-head-${osTag}-x86_64.tar.gz`; + const returnCode = await exec(bin, [ + 'install', + 'cabal', + '-u', + cabalHeadUrl, + 'head' + ]); + if (returnCode === 0) await exec(bin, ['set', 'cabal', 'head']); } async function ghcupGHCHead(): Promise {