Compare commits
43 Commits
v0.1.19.3
...
async-fetc
| Author | SHA1 | Date | |
|---|---|---|---|
| a109fa00ac | |||
| a2a605ad89 | |||
|
|
8fae9a5083 | ||
| a3748507ca | |||
| 578162f461 | |||
|
|
29bc40f65b | ||
| c149ee8d2b | |||
| 6623e4b1c8 | |||
| 5170baf074 | |||
| d143daeb9a | |||
| 699b183f62 | |||
| 09d72e7c97 | |||
| d551cc8077 | |||
| 4698639da9 | |||
| e67a9c93fe | |||
| 621cc5782b | |||
| 482503ca0a | |||
| 2fb7328a6e | |||
| 06eae56646 | |||
| bdbbeb1040 | |||
| 1eed02c8c7 | |||
| 6d325a1804 | |||
| a05f272b58 | |||
| 07dfb1e94b | |||
| 6ff07d3dbc | |||
| 0da5572164 | |||
| 422b99a222 | |||
| 055df584a4 | |||
| 9798e0f1d2 | |||
| a43fa7d63e | |||
| 4361ef7a72 | |||
|
|
3218aaa378 | ||
| 186a37cf3e | |||
|
|
7b1f591cc4 | ||
| 0ecd244177 | |||
| e14600ae75 | |||
| 0884756139 | |||
| 4c539d62c1 | |||
| f5b58d1db7 | |||
| 18f6a74d08 | |||
| becb3436d0 | |||
| 1f220cd488 | |||
| 572ee06bbb |
13
.github/scripts/cabal-cache.sh
vendored
Normal file
13
.github/scripts/cabal-cache.sh
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
case "$(uname -s)" in
|
||||
MSYS_*|MINGW*)
|
||||
ext=".exe"
|
||||
;;
|
||||
*)
|
||||
ext=""
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "cabal-cache disabled (CABAL_CACHE_DISABLE set)"
|
||||
|
||||
8
.github/scripts/common.sh
vendored
8
.github/scripts/common.sh
vendored
@@ -15,7 +15,7 @@ sync_from() {
|
||||
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
||||
fi
|
||||
|
||||
cabal-cache sync-from-archive \
|
||||
cabal-cache.sh sync-from-archive \
|
||||
--host-name-override=${S3_HOST} \
|
||||
--host-port-override=443 \
|
||||
--host-ssl-override=True \
|
||||
@@ -29,7 +29,7 @@ sync_to() {
|
||||
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
||||
fi
|
||||
|
||||
cabal-cache sync-to-archive \
|
||||
cabal-cache.sh sync-to-archive \
|
||||
--host-name-override=${S3_HOST} \
|
||||
--host-port-override=443 \
|
||||
--host-ssl-override=True \
|
||||
@@ -115,6 +115,10 @@ download_cabal_cache() {
|
||||
mv "cabal-cache${exe}" "${dest}${exe}"
|
||||
chmod +x "${dest}${exe}"
|
||||
fi
|
||||
|
||||
# install shell wrapper
|
||||
cp "${CI_PROJECT_DIR}"/.github/scripts/cabal-cache.sh "$HOME"/.local/bin/
|
||||
chmod +x "$HOME"/.local/bin/cabal-cache.sh
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
74
.github/scripts/cross.sh
vendored
Normal file
74
.github/scripts/cross.sh
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
. .github/scripts/common.sh
|
||||
|
||||
run() {
|
||||
"$@"
|
||||
}
|
||||
|
||||
if [ "${OS}" = "Windows" ] ; then
|
||||
GHCUP_DIR="${GHCUP_INSTALL_BASE_PREFIX}"/ghcup
|
||||
else
|
||||
GHCUP_DIR="${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup
|
||||
fi
|
||||
|
||||
git_describe
|
||||
|
||||
rm -rf "${GHCUP_DIR}"
|
||||
mkdir -p "${GHCUP_BIN}"
|
||||
|
||||
cp "out/${ARTIFACT}"-* "$GHCUP_BIN/ghcup${ext}"
|
||||
cp "out/test-${ARTIFACT}"-* "ghcup-test${ext}"
|
||||
chmod +x "$GHCUP_BIN/ghcup${ext}"
|
||||
chmod +x "ghcup-test${ext}"
|
||||
|
||||
"$GHCUP_BIN/ghcup${ext}" --version
|
||||
eghcup --version
|
||||
sha_sum "$GHCUP_BIN/ghcup${ext}"
|
||||
sha_sum "$(raw_eghcup --offline whereis ghcup)"
|
||||
|
||||
|
||||
### cross build
|
||||
|
||||
eghcup --numeric-version
|
||||
|
||||
eghcup install ghc "${GHC_VER}"
|
||||
eghcup set ghc "${GHC_VER}"
|
||||
eghcup install cabal "${CABAL_VER}"
|
||||
|
||||
cabal --version
|
||||
|
||||
eghcup debug-info
|
||||
|
||||
ecabal update
|
||||
|
||||
"${WRAPPER}" "$GHCUP_BIN/ghcup${ext}" -c -s "file://$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" -v \
|
||||
compile ghc \
|
||||
$(if [ -n "${HADRIAN_FLAVOUR}" ] ; then printf "%s" "--flavour=${HADRIAN_FLAVOUR}" ; else true ; fi) \
|
||||
-j "$(nproc)" \
|
||||
-v "${GHC_TARGET_VERSION}" \
|
||||
-b "${GHC_VER}" \
|
||||
-x "${CROSS}" \
|
||||
-- ${BUILD_CONF_ARGS}
|
||||
eghcup set ghc "${CROSS}-${GHC_TARGET_VERSION}"
|
||||
|
||||
[ "$($(eghcup whereis ghc "${CROSS}-${GHC_TARGET_VERSION}") --numeric-version)" = "${GHC_TARGET_VERSION}" ]
|
||||
|
||||
# test that doing fishy symlinks into GHCup dir doesn't cause weird stuff on 'ghcup nuke'
|
||||
mkdir no_nuke/
|
||||
mkdir no_nuke/bar
|
||||
echo 'foo' > no_nuke/file
|
||||
echo 'bar' > no_nuke/bar/file
|
||||
ln -s "$CI_PROJECT_DIR"/no_nuke/ "${GHCUP_DIR}"/cache/no_nuke
|
||||
ln -s "$CI_PROJECT_DIR"/no_nuke/ "${GHCUP_DIR}"/logs/no_nuke
|
||||
|
||||
# nuke
|
||||
eghcup nuke
|
||||
[ ! -e "${GHCUP_DIR}" ]
|
||||
|
||||
# make sure nuke doesn't resolve symlinks
|
||||
[ -e "$CI_PROJECT_DIR"/no_nuke/file ]
|
||||
[ -e "$CI_PROJECT_DIR"/no_nuke/bar/file ]
|
||||
|
||||
140
.github/workflows/cross.yaml
vendored
Normal file
140
.github/workflows/cross.yaml
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
name: Test cross bindists
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
|
||||
env:
|
||||
CABAL_CACHE_DISABLE: ${{ vars.CABAL_CACHE_DISABLE }}
|
||||
CABAL_CACHE_NONFATAL: yes
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build linux binary
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CABAL_VER: 3.10.1.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
S3_HOST: ${{ secrets.S3_HOST }}
|
||||
ARTIFACT: "x86_64-linux-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
ARCH: 64
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- name: Run build
|
||||
uses: docker://hasufell/alpine-haskell:3.12
|
||||
with:
|
||||
args: sh .github/scripts/build.sh
|
||||
env:
|
||||
ARTIFACT: ${{ env.ARTIFACT }}
|
||||
ARCH: ${{ env.ARCH }}
|
||||
GHC_VER: ${{ env.GHC_VER }}
|
||||
DISTRO: Alpine
|
||||
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||
S3_HOST: ${{ env.S3_HOST }}
|
||||
|
||||
- if: always()
|
||||
name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts
|
||||
path: |
|
||||
./out/*
|
||||
|
||||
test-cross-linux:
|
||||
name: Test linux cross
|
||||
needs: "build"
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
container:
|
||||
image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:8d0224e6b2a08157649651e69302380b2bd24e11
|
||||
options: --user root
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
BUILD_CONF_ARGS: "--enable-unregisterised"
|
||||
HADRIAN_FLAVOUR: ""
|
||||
JSON_VERSION: "0.0.7"
|
||||
GHC_VER: 8.10.6
|
||||
GHC_TARGET_VERSION: "8.10.7"
|
||||
ARCH: 64
|
||||
DISTRO: Debian
|
||||
ARTIFACT: "x86_64-linux-ghcup"
|
||||
CROSS: "arm-linux-gnueabihf"
|
||||
WRAPPER: "run"
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out
|
||||
|
||||
- name: Run test (64 bit linux)
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip
|
||||
sudo apt-get install -y gcc-arm-linux-gnueabihf
|
||||
sudo dpkg --add-architecture armhf
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y libncurses-dev:armhf
|
||||
sh .github/scripts/cross.sh
|
||||
|
||||
test-cross-js:
|
||||
name: Test GHC JS cross
|
||||
needs: "build"
|
||||
runs-on: [self-hosted, Linux, X64]
|
||||
container:
|
||||
image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:8d0224e6b2a08157649651e69302380b2bd24e11
|
||||
options: --user root
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
BUILD_CONF_ARGS: ""
|
||||
HADRIAN_FLAVOUR: "default+native_bignum"
|
||||
JSON_VERSION: "0.0.7"
|
||||
GHC_VER: 9.6.2
|
||||
GHC_TARGET_VERSION: "9.6.2"
|
||||
ARCH: 64
|
||||
DISTRO: Debian
|
||||
ARTIFACT: "x86_64-linux-ghcup"
|
||||
CROSS: "javascript-unknown-ghcjs"
|
||||
WRAPPER: "emconfigure"
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out
|
||||
|
||||
- name: Run test (64 bit linux)
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip
|
||||
git clone https://github.com/emscripten-core/emsdk.git
|
||||
cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
. ./emsdk_env.sh
|
||||
cd ..
|
||||
bash .github/scripts/cross.sh
|
||||
|
||||
16
.github/workflows/release.yaml
vendored
16
.github/workflows/release.yaml
vendored
@@ -12,12 +12,16 @@ on:
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
|
||||
env:
|
||||
CABAL_CACHE_DISABLE: ${{ vars.CABAL_CACHE_DISABLE }}
|
||||
CABAL_CACHE_NONFATAL: yes
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
name: Build linux binary
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.8.1.0
|
||||
CABAL_VER: 3.10.1.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
@@ -81,7 +85,7 @@ jobs:
|
||||
name: Build ARM binary
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
CABAL_VER: 3.10.1.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
@@ -154,7 +158,7 @@ jobs:
|
||||
name: Build binary (Mac/Win)
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.8.1.0
|
||||
CABAL_VER: 3.10.1.0
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||
JSON_VERSION: "0.0.7"
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
@@ -247,7 +251,7 @@ jobs:
|
||||
needs: "build-linux"
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.8.1.0
|
||||
CABAL_VER: 3.10.1.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -325,7 +329,7 @@ jobs:
|
||||
needs: "build-arm"
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
CABAL_VER: 3.10.1.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -392,7 +396,7 @@ jobs:
|
||||
needs: "build-macwin"
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.8.1.0
|
||||
CABAL_VER: 3.10.1.0
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||
JSON_VERSION: "0.0.7"
|
||||
strategy:
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Revision history for ghcup
|
||||
|
||||
## 0.1.19.5 -- ????-?-??
|
||||
|
||||
* support JS cross compilers wrt [#838](https://github.com/haskell/ghcup-hs/issues/838)
|
||||
|
||||
## 0.1.19.4 -- 2023-7-02
|
||||
|
||||
* fix missing TUI for aarch64 linux binaries
|
||||
|
||||
## 0.1.19.3 -- 2023-6-29
|
||||
|
||||
* Implement support for nightlies, wrt [#824](https://github.com/haskell/ghcup-hs/issues/824)
|
||||
|
||||
@@ -156,10 +156,10 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
||||
<+> padLeft (Pad 1) (minHSize 25 $ str "Tags")
|
||||
<+> padLeft (Pad 5) (str "Notes")
|
||||
renderList' bis@BrickInternalState{..} =
|
||||
let getMinLength = length . intercalate "," . fmap tagToString
|
||||
minLength = V.maximum $ V.map (getMinLength . lTag) clr
|
||||
in withDefAttr listAttr . drawListElements (renderItem minLength) True $ bis
|
||||
renderItem minTagSize _ b listResult@ListResult{lTag = lTag', ..} =
|
||||
let minTagSize = V.maximum $ V.map (length . intercalate "," . fmap tagToString . lTag) clr
|
||||
minVerSize = V.maximum $ V.map (\ListResult{..} -> T.length $ tVerToText (GHCTargetVersion lCross lVer)) clr
|
||||
in withDefAttr listAttr . drawListElements (renderItem minTagSize minVerSize) True $ bis
|
||||
renderItem minTagSize minVerSize _ b listResult@ListResult{lTag = lTag', ..} =
|
||||
let marks = if
|
||||
| lSet -> (withAttr (attrName "set") $ str "✔✔")
|
||||
| lInstalled -> (withAttr (attrName "installed") $ str "✓ ")
|
||||
@@ -184,7 +184,7 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
||||
( minHSize 6
|
||||
(printTool lTool)
|
||||
)
|
||||
<+> minHSize 15 (str ver)
|
||||
<+> minHSize minVerSize (str ver)
|
||||
<+> (let l = catMaybes . fmap printTag $ sort lTag'
|
||||
in padLeft (Pad 1) $ minHSize minTagSize $ if null l
|
||||
then emptyWidget
|
||||
@@ -218,7 +218,6 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
||||
printNotes ListResult {..} =
|
||||
(if hlsPowered then [withAttr (attrName "hls-powered") $ str "hls-powered"] else mempty
|
||||
)
|
||||
++ (if fromSrc then [withAttr (attrName "compiled") $ str "compiled"] else mempty)
|
||||
++ (if lStray then [withAttr (attrName "stray") $ str "stray"] else mempty)
|
||||
++ (case lReleaseDay of
|
||||
Nothing -> mempty
|
||||
@@ -472,19 +471,19 @@ install' _ (_, ListResult {..}) = do
|
||||
dirs <- lift getDirs
|
||||
case lTool of
|
||||
GHC -> do
|
||||
let vi = getVersionInfo lVer GHC dls
|
||||
liftE $ installGHCBin lVer GHCupInternal False [] $> (vi, dirs, ce)
|
||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) GHC dls
|
||||
liftE $ installGHCBin (GHCTargetVersion lCross lVer) GHCupInternal False [] $> (vi, dirs, ce)
|
||||
Cabal -> do
|
||||
let vi = getVersionInfo lVer Cabal dls
|
||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) Cabal dls
|
||||
liftE $ installCabalBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||
GHCup -> do
|
||||
let vi = snd <$> getLatest dls GHCup
|
||||
liftE $ upgradeGHCup Nothing False False $> (vi, dirs, ce)
|
||||
HLS -> do
|
||||
let vi = getVersionInfo lVer HLS dls
|
||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) HLS dls
|
||||
liftE $ installHLSBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||
Stack -> do
|
||||
let vi = getVersionInfo lVer Stack dls
|
||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) Stack dls
|
||||
liftE $ installStackBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||
)
|
||||
>>= \case
|
||||
@@ -565,7 +564,7 @@ del' _ (_, ListResult {..}) = do
|
||||
let run = runE @'[NotInstalled, UninstallFailed]
|
||||
|
||||
run (do
|
||||
let vi = getVersionInfo lVer lTool dls
|
||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) lTool dls
|
||||
case lTool of
|
||||
GHC -> liftE $ rmGHCVer (GHCTargetVersion lCross lVer) $> vi
|
||||
Cabal -> liftE $ rmCabalVer lVer $> vi
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE NumericUnderscores #-}
|
||||
{-# LANGUAGE ViewPatterns #-}
|
||||
|
||||
module GHCup.OptParse.Common where
|
||||
|
||||
@@ -693,52 +694,52 @@ fromVersion' :: ( HasLog env
|
||||
] m (GHCTargetVersion, Maybe VersionInfo)
|
||||
fromVersion' SetRecommended tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
bimap mkTVer Just <$> getRecommended dls tool
|
||||
second Just <$> getRecommended dls tool
|
||||
?? TagNotFound Recommended tool
|
||||
fromVersion' (SetGHCVersion v) tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let vi = getVersionInfo (_tvVersion v) tool dls
|
||||
let vi = getVersionInfo v tool dls
|
||||
case pvp $ prettyVer (_tvVersion v) of -- need to be strict here
|
||||
Left _ -> pure (v, vi)
|
||||
Right pvpIn ->
|
||||
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
||||
Just (pvp_, vi') -> do
|
||||
lift (getLatestToolFor tool (_tvTarget v) pvpIn dls) >>= \case
|
||||
Just (pvp_, vi', mt) -> do
|
||||
v' <- lift $ pvpToVersion pvp_ ""
|
||||
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
||||
pure (GHCTargetVersion (_tvTarget v) v', Just vi')
|
||||
pure (GHCTargetVersion mt v', Just vi')
|
||||
Nothing -> pure (v, vi)
|
||||
fromVersion' (SetToolVersion v) tool = do
|
||||
fromVersion' (SetToolVersion (mkTVer -> v)) tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let vi = getVersionInfo v tool dls
|
||||
case pvp $ prettyVer v of -- need to be strict here
|
||||
Left _ -> pure (mkTVer v, vi)
|
||||
case pvp $ prettyVer (_tvVersion v) of -- need to be strict here
|
||||
Left _ -> pure (v, vi)
|
||||
Right pvpIn ->
|
||||
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
||||
Just (pvp_, vi') -> do
|
||||
lift (getLatestToolFor tool (_tvTarget v) pvpIn dls) >>= \case
|
||||
Just (pvp_, vi', mt) -> do
|
||||
v' <- lift $ pvpToVersion pvp_ ""
|
||||
when (v' /= v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
||||
pure (GHCTargetVersion mempty v', Just vi')
|
||||
Nothing -> pure (mkTVer v, vi)
|
||||
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
||||
pure (GHCTargetVersion mt v', Just vi')
|
||||
Nothing -> pure (v, vi)
|
||||
fromVersion' (SetToolTag Latest) tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
bimap mkTVer Just <$> getLatest dls tool ?? TagNotFound Latest tool
|
||||
bimap id Just <$> getLatest dls tool ?? TagNotFound Latest tool
|
||||
fromVersion' (SetToolDay day) tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
bimap mkTVer Just <$> case getByReleaseDay dls tool day of
|
||||
bimap id Just <$> case getByReleaseDay dls tool day of
|
||||
Left ad -> throwE $ DayNotFound day tool ad
|
||||
Right v -> pure v
|
||||
fromVersion' (SetToolTag LatestPrerelease) tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
bimap mkTVer Just <$> getLatestPrerelease dls tool ?? TagNotFound LatestPrerelease tool
|
||||
bimap id Just <$> getLatestPrerelease dls tool ?? TagNotFound LatestPrerelease tool
|
||||
fromVersion' (SetToolTag LatestNightly) tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
bimap mkTVer Just <$> getLatestNightly dls tool ?? TagNotFound LatestNightly tool
|
||||
bimap id Just <$> getLatestNightly dls tool ?? TagNotFound LatestNightly tool
|
||||
fromVersion' (SetToolTag Recommended) tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
bimap mkTVer Just <$> getRecommended dls tool ?? TagNotFound Recommended tool
|
||||
bimap id Just <$> getRecommended dls tool ?? TagNotFound Recommended tool
|
||||
fromVersion' (SetToolTag (Base pvp'')) GHC = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
bimap mkTVer Just <$> getLatestBaseVersion dls pvp'' ?? TagNotFound (Base pvp'') GHC
|
||||
bimap id Just <$> getLatestBaseVersion dls pvp'' ?? TagNotFound (Base pvp'') GHC
|
||||
fromVersion' SetNext tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
next <- case tool of
|
||||
@@ -783,7 +784,7 @@ fromVersion' SetNext tool = do
|
||||
. sort
|
||||
$ stacks) ?? NoToolVersionSet tool
|
||||
GHCup -> fail "GHCup cannot be set"
|
||||
let vi = getVersionInfo (_tvVersion next) tool dls
|
||||
let vi = getVersionInfo next tool dls
|
||||
pure (next, vi)
|
||||
fromVersion' (SetToolTag t') tool =
|
||||
throwE $ TagNotFound t' tool
|
||||
@@ -799,15 +800,15 @@ checkForUpdates :: ( MonadReader env m
|
||||
, MonadIO m
|
||||
, MonadFail m
|
||||
)
|
||||
=> m [(Tool, Version)]
|
||||
=> m [(Tool, GHCTargetVersion)]
|
||||
checkForUpdates = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
||||
lInstalled <- listVersions Nothing [ListInstalled True] False False (Nothing, Nothing)
|
||||
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
||||
let latestInstalled tool = (fmap (\lr -> GHCTargetVersion (lCross lr) (lVer lr)) . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
||||
|
||||
ghcup <- forMM (getLatest dls GHCup) $ \(l, _) -> do
|
||||
ghcup <- forMM (getLatest dls GHCup) $ \(GHCTargetVersion _ l, _) -> do
|
||||
(Right ghcup_ver) <- pure $ version $ prettyPVP ghcUpVer
|
||||
if (l > ghcup_ver) then pure $ Just (GHCup, l) else pure Nothing
|
||||
if (l > ghcup_ver) then pure $ Just (GHCup, mkTVer l) else pure Nothing
|
||||
|
||||
otherTools <- forM [GHC, Cabal, HLS, Stack] $ \t ->
|
||||
forMM (getLatest dls t) $ \(l, _) -> do
|
||||
|
||||
@@ -66,7 +66,7 @@ data CompileCommand = CompileGHC GHCCompileOptions
|
||||
|
||||
|
||||
data GHCCompileOptions = GHCCompileOptions
|
||||
{ targetGhc :: GHC.GHCVer Version
|
||||
{ targetGhc :: GHC.GHCVer
|
||||
, bootstrapGhc :: Either Version FilePath
|
||||
, jobs :: Maybe Int
|
||||
, buildConfig :: Maybe FilePath
|
||||
@@ -76,7 +76,7 @@ data GHCCompileOptions = GHCCompileOptions
|
||||
, setCompile :: Bool
|
||||
, ovewrwiteVer :: Maybe Version
|
||||
, buildFlavour :: Maybe String
|
||||
, hadrian :: Bool
|
||||
, buildSystem :: Maybe BuildSystem
|
||||
, isolateDir :: Maybe FilePath
|
||||
}
|
||||
|
||||
@@ -268,9 +268,15 @@ ghcCompileOpts =
|
||||
"Set the compile build flavour (this value depends on the build system type: 'make' vs 'hadrian')"
|
||||
)
|
||||
)
|
||||
<*> switch
|
||||
(long "hadrian" <> help "Use the hadrian build system instead of make (only git versions seem to be properly supported atm)"
|
||||
<*> (
|
||||
(\b -> if b then Just Hadrian else Nothing) <$> switch
|
||||
(long "hadrian" <> help "Use the hadrian build system instead of make. Tries to detect by default."
|
||||
)
|
||||
<|>
|
||||
(\b -> if b then Just Make else Nothing) <$> switch
|
||||
(long "make" <> help "Use the make build system instead of hadrian. Tries to detect by default."
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
(option
|
||||
(eitherReader isolateParser)
|
||||
@@ -511,7 +517,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
case targetHLS of
|
||||
HLS.SourceDist targetVer -> do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let vi = getVersionInfo targetVer HLS dls
|
||||
let vi = getVersionInfo (mkTVer targetVer) HLS dls
|
||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||
lift $ logInfo msg
|
||||
lift $ logInfo
|
||||
@@ -531,7 +537,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
patches
|
||||
cabalArgs
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let vi = getVersionInfo targetVer HLS dls
|
||||
let vi = getVersionInfo (mkTVer targetVer) HLS dls
|
||||
when setCompile $ void $ liftE $
|
||||
setHLS targetVer SetHLSOnly Nothing
|
||||
pure (vi, targetVer)
|
||||
@@ -555,15 +561,12 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 9
|
||||
(CompileGHC GHCCompileOptions { hadrian = True, crossTarget = Just _ }) -> do
|
||||
runLogger $ logError "Hadrian cross compile support is not yet implemented!"
|
||||
pure $ ExitFailure 9
|
||||
(CompileGHC GHCCompileOptions {..}) ->
|
||||
runCompileGHC runAppState (do
|
||||
case targetGhc of
|
||||
GHC.SourceDist targetVer -> do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let vi = getVersionInfo targetVer GHC dls
|
||||
let vi = getVersionInfo (mkTVer targetVer) GHC dls
|
||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||
lift $ logInfo msg
|
||||
lift $ logInfo
|
||||
@@ -571,10 +574,8 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||
_ -> pure ()
|
||||
targetVer <- liftE $ compileGHC
|
||||
((\case
|
||||
GHC.SourceDist v -> GHC.SourceDist $ GHCTargetVersion crossTarget v
|
||||
GHC.GitDist g -> GHC.GitDist g
|
||||
GHC.RemoteDist r -> GHC.RemoteDist r) targetGhc)
|
||||
targetGhc
|
||||
crossTarget
|
||||
ovewrwiteVer
|
||||
bootstrapGhc
|
||||
jobs
|
||||
@@ -582,10 +583,10 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
patches
|
||||
addConfArgs
|
||||
buildFlavour
|
||||
hadrian
|
||||
buildSystem
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let vi = getVersionInfo (_tvVersion targetVer) GHC dls
|
||||
let vi = getVersionInfo targetVer GHC dls
|
||||
when setCompile $ void $ liftE $
|
||||
setGHC targetVer SetGHCOnly Nothing
|
||||
pure (vi, targetVer)
|
||||
|
||||
@@ -324,7 +324,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
Nothing -> runInstGHC s' $ do
|
||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||
liftE $ runBothE' (installGHCBin
|
||||
(_tvVersion v)
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
forceInstall
|
||||
addConfArgs
|
||||
@@ -336,7 +336,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||
liftE $ runBothE' (installGHCBindist
|
||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing Nothing)
|
||||
(_tvVersion v)
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
forceInstall
|
||||
addConfArgs
|
||||
|
||||
@@ -180,7 +180,6 @@ printListResult no_color raw lr = do
|
||||
then [color Green "hls-powered"]
|
||||
else mempty
|
||||
)
|
||||
++ (if fromSrc then [color Blue "compiled"] else mempty)
|
||||
++ (if lStray then [color Yellow "stray"] else mempty)
|
||||
++ (case lReleaseDay of
|
||||
Nothing -> mempty
|
||||
|
||||
@@ -195,7 +195,7 @@ prefetch prefetchCommand runAppState runLogger =
|
||||
forM_ pfCacheDir (liftIO . createDirRecursive')
|
||||
(v, _) <- liftE $ fromVersion mt GHC
|
||||
if pfGHCSrc
|
||||
then liftE $ fetchGHCSrc (_tvVersion v) pfCacheDir
|
||||
then liftE $ fetchGHCSrc v pfCacheDir
|
||||
else liftE $ fetchToolBindist (_tvVersion v) GHC pfCacheDir
|
||||
PrefetchCabal PrefetchOptions {pfCacheDir} mt -> do
|
||||
forM_ pfCacheDir (liftIO . createDirRecursive')
|
||||
|
||||
@@ -170,7 +170,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
||||
liftE $
|
||||
rmGHCVer ghcVer
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
pure (getVersionInfo (_tvVersion ghcVer) GHC dls)
|
||||
pure (getVersionInfo ghcVer GHC dls)
|
||||
)
|
||||
>>= \case
|
||||
VRight vi -> do
|
||||
@@ -186,7 +186,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
||||
liftE $
|
||||
rmCabalVer tv
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
pure (getVersionInfo tv Cabal dls)
|
||||
pure (getVersionInfo (mkTVer tv) Cabal dls)
|
||||
)
|
||||
>>= \case
|
||||
VRight vi -> do
|
||||
@@ -201,7 +201,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
||||
liftE $
|
||||
rmHLSVer tv
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
pure (getVersionInfo tv HLS dls)
|
||||
pure (getVersionInfo (mkTVer tv) HLS dls)
|
||||
)
|
||||
>>= \case
|
||||
VRight vi -> do
|
||||
@@ -216,7 +216,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
||||
liftE $
|
||||
rmStackVer tv
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
pure (getVersionInfo tv Stack dls)
|
||||
pure (getVersionInfo (mkTVer tv) Stack dls)
|
||||
)
|
||||
>>= \case
|
||||
VRight vi -> do
|
||||
|
||||
@@ -360,7 +360,7 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||
Just v -> do
|
||||
isInstalled <- lift $ checkIfToolInstalled' GHC v
|
||||
unless isInstalled $ when (runInstTool' && isNothing (_tvTarget v)) $ void $ liftE $ installGHCBin
|
||||
(_tvVersion v)
|
||||
v
|
||||
GHCupInternal
|
||||
False
|
||||
[]
|
||||
|
||||
@@ -169,12 +169,12 @@ test testCommand settings getAppState' runLogger = case testCommand of
|
||||
(case testBindist of
|
||||
Nothing -> runTestGHC s' $ do
|
||||
(v, vi) <- liftE $ fromVersion testVer GHC
|
||||
liftE $ testGHCVer (_tvVersion v) addMakeArgs
|
||||
liftE $ testGHCVer v addMakeArgs
|
||||
pure vi
|
||||
Just uri -> do
|
||||
runTestGHC s'{ settings = settings {noVerify = True}} $ do
|
||||
(v, vi) <- liftE $ fromVersion testVer GHC
|
||||
liftE $ testGHCBindist (DownloadInfo uri (Just $ RegexDir ".*/.*") "" Nothing Nothing) (_tvVersion v) addMakeArgs
|
||||
liftE $ testGHCBindist (DownloadInfo uri (Just $ RegexDir ".*/.*") "" Nothing Nothing) v addMakeArgs
|
||||
pure vi
|
||||
)
|
||||
>>= \case
|
||||
|
||||
@@ -181,13 +181,15 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
-- logger interpreter
|
||||
logfile <- runReaderT initGHCupFileLogging dirs
|
||||
no_color <- isJust <$> lookupEnv "NO_COLOR"
|
||||
liftIO $ hSetBuffering stderr LineBuffering
|
||||
liftIO $ hSetBuffering logfile LineBuffering
|
||||
let loggerConfig = LoggerConfig
|
||||
{ lcPrintDebug = verbose settings
|
||||
, consoleOutter = T.hPutStr stderr
|
||||
, fileOutter =
|
||||
case optCommand of
|
||||
Nuke -> \_ -> pure ()
|
||||
_ -> T.appendFile logfile
|
||||
_ -> T.hPutStr logfile
|
||||
, fancyColors = not no_color
|
||||
}
|
||||
let leanAppstate = LeanAppState settings dirs keybindings loggerConfig
|
||||
@@ -249,7 +251,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
case t of
|
||||
GHCup -> runLogger $
|
||||
logWarn ("New GHCup version available: "
|
||||
<> prettyVer l
|
||||
<> tVerToText l
|
||||
<> ". To upgrade, run 'ghcup upgrade'")
|
||||
_ -> runLogger $
|
||||
logWarn ("New "
|
||||
@@ -258,7 +260,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
<> "If you want to install this latest version, run 'ghcup install "
|
||||
<> T.pack (prettyShow t)
|
||||
<> " "
|
||||
<> prettyVer l
|
||||
<> tVerToText l
|
||||
<> "'")
|
||||
Just _ -> pure ()
|
||||
|
||||
@@ -332,7 +334,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
, MonadCatch m
|
||||
)
|
||||
=> Command
|
||||
-> (Tool, Version)
|
||||
-> (Tool, GHCTargetVersion)
|
||||
-> Excepts
|
||||
'[ TagNotFound
|
||||
, DayNotFound
|
||||
@@ -368,7 +370,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
)
|
||||
=> Tool
|
||||
-> Maybe ToolVersion
|
||||
-> Version
|
||||
-> GHCTargetVersion
|
||||
-> Excepts
|
||||
'[ TagNotFound
|
||||
, DayNotFound
|
||||
@@ -377,4 +379,4 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
] m Bool
|
||||
cmp' tool instVer ver = do
|
||||
(v, _) <- liftE $ fromVersion instVer tool
|
||||
pure (v == mkTVer ver)
|
||||
pure (v == ver)
|
||||
|
||||
Submodule data/metadata updated: 92efb732ac...c88802ea8c
@@ -37,8 +37,8 @@ RUN apk add --no-cache \
|
||||
xz-dev \
|
||||
ncurses-static
|
||||
|
||||
ARG GHCUP_VERSION=0.1.18.0
|
||||
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||
ARG GHCUP_VERSION=0.1.19.4
|
||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
|
||||
@@ -37,8 +37,9 @@ RUN apk add --no-cache \
|
||||
xz-dev \
|
||||
ncurses-static
|
||||
|
||||
ARG GHCUP_VERSION=0.1.18.0
|
||||
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||
ARG GHCUP_VERSION=0.1.19.4
|
||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
||||
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
|
||||
@@ -29,8 +29,8 @@ RUN apt-get update && \
|
||||
|
||||
RUN update_opt.sh 11 1
|
||||
|
||||
ARG GHCUP_VERSION=0.1.17.8
|
||||
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||
ARG GHCUP_VERSION=0.1.19.4
|
||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
|
||||
@@ -29,8 +29,8 @@ RUN apt-get update && \
|
||||
|
||||
RUN update_opt.sh 9 1
|
||||
|
||||
ARG GHCUP_VERSION=0.1.17.8
|
||||
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||
ARG GHCUP_VERSION=0.1.19.4
|
||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
|
||||
@@ -29,8 +29,8 @@ RUN apt-get update && \
|
||||
|
||||
RUN update_opt.sh 11 1
|
||||
|
||||
ARG GHCUP_VERSION=0.1.18.0
|
||||
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||
ARG GHCUP_VERSION=0.1.19.4
|
||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
|
||||
@@ -29,8 +29,8 @@ RUN apt-get update && \
|
||||
|
||||
RUN update_opt.sh 9 1
|
||||
|
||||
ARG GHCUP_VERSION=0.1.18.0
|
||||
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||
ARG GHCUP_VERSION=0.1.19.4
|
||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
|
||||
@@ -205,7 +205,7 @@ url-source:
|
||||
|
||||
### Nightlies
|
||||
|
||||
Nightlies are just a nother release channel. Currently, only GHC supports nightlies, which are binary releases
|
||||
Nightlies are just another release channel. Currently, only GHC supports nightlies, which are binary releases
|
||||
that are built every night from `master`.
|
||||
|
||||
To add the nightly channel, run:
|
||||
|
||||
@@ -318,6 +318,24 @@ export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
|
||||
|
||||
All set. You can run `cabal init` now in an empty directory to start a project.
|
||||
|
||||
## Esoteric distros
|
||||
|
||||
### Void Linux
|
||||
|
||||
Since void linux can be installed with glibc and musl, it's hard to support correctly with ghcup.
|
||||
One way to make ghcup work on **Void Linux musl** is to follow the [Overriding distro detection](../guide/#overriding-distro-detection)
|
||||
section and tell it to consider Alpine bindists only. E.g.:
|
||||
|
||||
```sh
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_MINIMAL=1 sh
|
||||
source ~/.ghcup/env
|
||||
ghcup config set platform-override '{ "arch": "A_64", "platform": { "contents": "Alpine", "tag": "Linux" }, "version": "3.17" }'
|
||||
ghcup install cabal --set latest
|
||||
ghcup install ghc --set latest
|
||||
ghcup install stack --set latest
|
||||
ghcup install hls --set latest
|
||||
```
|
||||
|
||||
## Vim integration
|
||||
|
||||
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).
|
||||
|
||||
@@ -328,7 +328,7 @@ see the [Cabal user guide](https://cabal.readthedocs.io/en/stable/getting-starte
|
||||
<a href="https://hackage.haskell.org/" class="btn btn-primary" role="button">Discover Haskell packages</a>
|
||||
<a href="https://hackage.haskell.org/package/base" class="btn btn-primary" role="button">The standard library</a>
|
||||
<a href="https://haskell-language-server.readthedocs.io/en/stable/installation.html" class="btn btn-primary" role="button">Editor setup with HLS</a>
|
||||
<a href="https://play-haskell.tomsmeding.com/play" class="btn btn-primary" role="button">Online playground</a>
|
||||
<a href="https://play.haskell.org/" class="btn btn-primary" role="button">Online playground</a>
|
||||
</div>
|
||||
|
||||
## How to learn Haskell proper
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
cabal-version: 2.4
|
||||
name: ghcup
|
||||
version: 0.1.19.3
|
||||
version: 0.1.19.5
|
||||
license: LGPL-3.0-only
|
||||
license-file: LICENSE
|
||||
copyright: Julian Ospald 2020
|
||||
|
||||
27
lib/GHCup.hs
27
lib/GHCup.hs
@@ -134,15 +134,24 @@ rmTool :: ( MonadReader env m
|
||||
=> ListResult
|
||||
-> Excepts '[NotInstalled, UninstallFailed] m ()
|
||||
rmTool ListResult {lVer, lTool, lCross} = do
|
||||
logInfo $ "removing " <> T.pack (show lTool) <> " version " <> prettyVer lVer
|
||||
let printRmTool = logInfo $ "removing " <> T.pack (show lTool) <> " version " <> prettyVer lVer
|
||||
case lTool of
|
||||
GHC ->
|
||||
GHC -> do
|
||||
let ghcTargetVersion = GHCTargetVersion lCross lVer
|
||||
in rmGHCVer ghcTargetVersion
|
||||
HLS -> rmHLSVer lVer
|
||||
Cabal -> liftE $ rmCabalVer lVer
|
||||
Stack -> liftE $ rmStackVer lVer
|
||||
GHCup -> lift rmGhcup
|
||||
logInfo $ "removing " <> T.pack (show lTool) <> " version " <> tVerToText ghcTargetVersion
|
||||
rmGHCVer ghcTargetVersion
|
||||
HLS -> do
|
||||
printRmTool
|
||||
rmHLSVer lVer
|
||||
Cabal -> do
|
||||
printRmTool
|
||||
liftE $ rmCabalVer lVer
|
||||
Stack -> do
|
||||
printRmTool
|
||||
liftE $ rmStackVer lVer
|
||||
GHCup -> do
|
||||
printRmTool
|
||||
lift rmGhcup
|
||||
|
||||
|
||||
rmGhcupDirs :: ( MonadReader env m
|
||||
@@ -303,7 +312,7 @@ upgradeGHCup mtarget force' fatal = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
|
||||
lift $ logInfo "Upgrading GHCup..."
|
||||
let latestVer = fst (fromJust (getLatest dls GHCup))
|
||||
let latestVer = _tvVersion $ fst (fromJust (getLatest dls GHCup))
|
||||
(Just ghcupPVPVer) <- pure $ pvpToVersion ghcUpVer ""
|
||||
when (not force' && (latestVer <= ghcupPVPVer)) $ throwE NoUpdate
|
||||
dli <- liftE $ getDownloadInfo GHCup latestVer
|
||||
@@ -492,7 +501,7 @@ rmOldGHC :: ( MonadReader env m
|
||||
=> Excepts '[NotInstalled, UninstallFailed] m ()
|
||||
rmOldGHC = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let oldGHCs = mkTVer <$> toListOf (ix GHC % getTagged Old % to fst) dls
|
||||
let oldGHCs = toListOf (ix GHC % getTagged Old % to fst) dls
|
||||
ghcs <- lift $ fmap rights getInstalledGHCs
|
||||
forM_ ghcs $ \ghc -> when (ghc `elem` oldGHCs) $ rmGHCVer ghc
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import Control.Monad.Trans.Resource
|
||||
hiding ( throwM )
|
||||
import Data.Either
|
||||
import Data.List
|
||||
import Data.Ord
|
||||
import Data.Maybe
|
||||
import Data.Versions hiding ( patch )
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
@@ -280,6 +281,6 @@ rmCabalVer ver = do
|
||||
|
||||
when (Just ver == cSet) $ do
|
||||
cVers <- lift $ fmap rights getInstalledCabals
|
||||
case headMay . reverse . sort $ cVers of
|
||||
case headMay . sortBy (comparing Down) $ cVers of
|
||||
Just latestver -> setCabal latestver
|
||||
Nothing -> lift $ rmLink (binDir </> "cabal" <> exeExt)
|
||||
|
||||
@@ -87,6 +87,8 @@ import qualified Data.Text.IO as T
|
||||
import qualified Data.Text.Encoding as E
|
||||
import qualified Data.Yaml.Aeson as Y
|
||||
|
||||
import qualified UnliftIO.Async as Async
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -111,6 +113,7 @@ getDownloadsF :: ( FromJSONKey Tool
|
||||
, MonadThrow m
|
||||
, MonadFail m
|
||||
, MonadMask m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Excepts
|
||||
'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError]
|
||||
@@ -121,12 +124,12 @@ getDownloadsF = do
|
||||
case urlSource of
|
||||
GHCupURL -> liftE $ getBase ghcupURL
|
||||
(OwnSource exts) -> do
|
||||
ext <- liftE $ mapM (either pure getBase) exts
|
||||
ext <- Async.mapConcurrently (either pure (liftE . getBase)) exts
|
||||
mergeGhcupInfo ext
|
||||
(OwnSpec av) -> pure av
|
||||
(AddSource exts) -> do
|
||||
base <- liftE $ getBase ghcupURL
|
||||
ext <- liftE $ mapM (either pure getBase) exts
|
||||
ext <- Async.mapConcurrently (either pure (liftE . getBase)) exts
|
||||
mergeGhcupInfo (base:ext)
|
||||
|
||||
where
|
||||
@@ -271,7 +274,6 @@ getBase uri = do
|
||||
|
||||
pure f
|
||||
|
||||
|
||||
getDownloadInfo :: ( MonadReader env m
|
||||
, HasPlatformReq env
|
||||
, HasGHCupInfo env
|
||||
@@ -283,8 +285,21 @@ getDownloadInfo :: ( MonadReader env m
|
||||
'[NoDownload]
|
||||
m
|
||||
DownloadInfo
|
||||
getDownloadInfo t v = do
|
||||
(PlatformRequest a p mv) <- lift getPlatformReq
|
||||
getDownloadInfo t v = getDownloadInfo' t (mkTVer v)
|
||||
|
||||
getDownloadInfo' :: ( MonadReader env m
|
||||
, HasPlatformReq env
|
||||
, HasGHCupInfo env
|
||||
)
|
||||
=> Tool
|
||||
-> GHCTargetVersion
|
||||
-- ^ tool version
|
||||
-> Excepts
|
||||
'[NoDownload]
|
||||
m
|
||||
DownloadInfo
|
||||
getDownloadInfo' t v = do
|
||||
pfreq@(PlatformRequest a p mv) <- lift getPlatformReq
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
|
||||
let distro_preview f g =
|
||||
@@ -305,7 +320,7 @@ getDownloadInfo t v = do
|
||||
without_distro = distro_preview (set _Linux UnknownLinux) (const Nothing)
|
||||
|
||||
maybe
|
||||
(throwE NoDownload)
|
||||
(throwE $ NoDownload v t (Just pfreq))
|
||||
pure
|
||||
(case p of
|
||||
-- non-musl won't work on alpine
|
||||
|
||||
@@ -206,12 +206,26 @@ instance HFErrorProject NoCompatiblePlatform where
|
||||
eDesc _ = "No compatible platform could be found"
|
||||
|
||||
-- | Unable to find a download for the requested version/distro.
|
||||
data NoDownload = NoDownload
|
||||
data NoDownload = NoDownload GHCTargetVersion Tool (Maybe PlatformRequest)
|
||||
| NoDownload' GlobalTool
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoDownload where
|
||||
pPrint NoDownload =
|
||||
text (eDesc (Proxy :: Proxy NoDownload))
|
||||
pPrint (NoDownload tver@(GHCTargetVersion mtarget vv) tool mpfreq)
|
||||
| (Just target) <- mtarget
|
||||
, target `elem` (T.pack . prettyShow <$> enumFromTo (minBound :: Tool) (maxBound :: Tool))
|
||||
= text $ "Unable to find a download for "
|
||||
<> show tool
|
||||
<> " version '"
|
||||
<> T.unpack (tVerToText tver)
|
||||
<> maybe "'\n" (\pfreq -> "' on detected platform " <> pfReqToString pfreq <> "\n") mpfreq
|
||||
<> "Perhaps you meant: 'ghcup <command> "
|
||||
<> T.unpack target
|
||||
<> " "
|
||||
<> T.unpack (prettyVer vv)
|
||||
<> "'"
|
||||
| otherwise = text $ "Unable to find a download for " <> T.unpack (tVerToText tver)
|
||||
pPrint (NoDownload' globalTool) = text $ "Unable to find a download for " <> prettyShow globalTool
|
||||
|
||||
instance HFErrorProject NoDownload where
|
||||
eBase _ = 10
|
||||
@@ -416,6 +430,8 @@ instance HFErrorProject JSONError where
|
||||
eBase _ = 160
|
||||
eDesc _ = "JSON decoding failed"
|
||||
|
||||
instance Exception JSONError
|
||||
|
||||
-- | A file that is supposed to exist does not exist
|
||||
-- (e.g. when we use file scheme to "download" something).
|
||||
data FileDoesNotExistError = FileDoesNotExistError FilePath
|
||||
@@ -429,6 +445,8 @@ instance HFErrorProject FileDoesNotExistError where
|
||||
eBase _ = 170
|
||||
eDesc _ = "A file that is supposed to exist does not exist (oops)"
|
||||
|
||||
instance Exception FileDoesNotExistError
|
||||
|
||||
-- | The file already exists
|
||||
-- (e.g. when we use isolated installs with the same path).
|
||||
-- (e.g. This is done to prevent any overwriting)
|
||||
@@ -468,6 +486,8 @@ instance HFErrorProject DigestError where
|
||||
eBase _ = 200
|
||||
eDesc _ = "File digest verification failed"
|
||||
|
||||
instance Exception DigestError
|
||||
|
||||
-- | File PGP verification failed.
|
||||
data GPGError = forall xs . (ToVariantMaybe DownloadFailed xs, PopVariant DownloadFailed xs, Show (V xs), Pretty (V xs)) => GPGError (V xs)
|
||||
|
||||
@@ -480,6 +500,8 @@ instance HFErrorProject GPGError where
|
||||
eBase _ = 210
|
||||
eDesc _ = "File PGP verification failed"
|
||||
|
||||
instance Exception GPGError
|
||||
|
||||
-- | Unexpected HTTP status.
|
||||
data HTTPStatusError = HTTPStatusError Int (M.Map (CI ByteString) ByteString)
|
||||
deriving Show
|
||||
@@ -693,6 +715,8 @@ instance HFErrorProject DownloadFailed where
|
||||
eNum (DownloadFailed xs) = 5000 + eNum xs
|
||||
eDesc _ = "A download failed."
|
||||
|
||||
instance Exception DownloadFailed
|
||||
|
||||
data InstallSetError = forall xs1 xs2 . (Show (V xs1), Pretty (V xs1), HFErrorProject (V xs1), Show (V xs2), Pretty (V xs2), HFErrorProject (V xs2)) => InstallSetError (V xs1) (V xs2)
|
||||
|
||||
instance Pretty InstallSetError where
|
||||
|
||||
308
lib/GHCup/GHC.hs
308
lib/GHCup/GHC.hs
@@ -80,9 +80,9 @@ import qualified Data.Text.Encoding as E
|
||||
import qualified Text.Megaparsec as MP
|
||||
|
||||
|
||||
data GHCVer v = SourceDist v
|
||||
| GitDist GitBranch
|
||||
| RemoteDist URI
|
||||
data GHCVer = SourceDist Version
|
||||
| GitDist GitBranch
|
||||
| RemoteDist URI
|
||||
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ testGHCVer :: ( MonadFail m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Version
|
||||
=> GHCTargetVersion
|
||||
-> [T.Text]
|
||||
-> Excepts
|
||||
'[ DigestError
|
||||
@@ -125,7 +125,7 @@ testGHCVer ver addMakeArgs = do
|
||||
|
||||
dlInfo <-
|
||||
preview (ix GHC % ix ver % viTestDL % _Just) dls
|
||||
?? NoDownload
|
||||
?? NoDownload ver GHC Nothing
|
||||
|
||||
liftE $ testGHCBindist dlInfo ver addMakeArgs
|
||||
|
||||
@@ -145,7 +145,7 @@ testGHCBindist :: ( MonadFail m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> DownloadInfo
|
||||
-> Version
|
||||
-> GHCTargetVersion
|
||||
-> [T.Text]
|
||||
-> Excepts
|
||||
'[ DigestError
|
||||
@@ -182,7 +182,7 @@ testPackedGHC :: ( MonadMask m
|
||||
)
|
||||
=> FilePath -- ^ Path to the packed GHC bindist
|
||||
-> Maybe TarDir -- ^ Subdir of the archive
|
||||
-> Version -- ^ The GHC version
|
||||
-> GHCTargetVersion -- ^ The GHC version
|
||||
-> [T.Text] -- ^ additional make args
|
||||
-> Excepts
|
||||
'[ ArchiveResult, UnknownArchive, TarDirDoesNotExist, TestFailed ] m ()
|
||||
@@ -208,19 +208,21 @@ testUnpackedGHC :: ( MonadReader env m
|
||||
, MonadIO m
|
||||
)
|
||||
=> GHCupPath -- ^ Path to the unpacked GHC bindist (where the make file resides)
|
||||
-> Version -- ^ The GHC version
|
||||
-> GHCTargetVersion -- ^ The GHC version
|
||||
-> [T.Text] -- ^ additional configure args for bindist
|
||||
-> Excepts '[ProcessError] m ()
|
||||
testUnpackedGHC path ver addMakeArgs = do
|
||||
lift $ logInfo $ "Testing GHC version " <> prettyVer ver <> "!"
|
||||
ghcDir <- lift $ ghcupGHCDir (mkTVer ver)
|
||||
testUnpackedGHC path tver addMakeArgs = do
|
||||
lift $ logInfo $ "Testing GHC version " <> tVerToText tver <> "!"
|
||||
ghcDir <- lift $ ghcupGHCDir tver
|
||||
let ghcBinDir = fromGHCupPath ghcDir </> "bin"
|
||||
env <- liftIO $ addToPath ghcBinDir False
|
||||
|
||||
lEM $ make' (fmap T.unpack addMakeArgs)
|
||||
(Just $ fromGHCupPath path)
|
||||
"ghc-test"
|
||||
(Just $ ("STAGE1_GHC", "ghc-" <> T.unpack (prettyVer ver)) : env)
|
||||
(Just $ ("STAGE1_GHC", maybe "" (T.unpack . (<> "-")) (_tvTarget tver)
|
||||
<> "ghc-"
|
||||
<> T.unpack (prettyVer $ _tvVersion tver)) : env)
|
||||
pure ()
|
||||
|
||||
|
||||
@@ -243,7 +245,7 @@ fetchGHCSrc :: ( MonadFail m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Version
|
||||
=> GHCTargetVersion
|
||||
-> Maybe FilePath
|
||||
-> Excepts
|
||||
'[ DigestError
|
||||
@@ -258,7 +260,7 @@ fetchGHCSrc v mfp = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
dlInfo <-
|
||||
preview (ix GHC % ix v % viSourceDL % _Just) dls
|
||||
?? NoDownload
|
||||
?? NoDownload v GHC Nothing
|
||||
liftE $ downloadCached' dlInfo Nothing mfp
|
||||
|
||||
|
||||
@@ -283,7 +285,7 @@ installGHCBindist :: ( MonadFail m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> DownloadInfo -- ^ where/how to download
|
||||
-> Version -- ^ the version to install
|
||||
-> GHCTargetVersion -- ^ the version to install
|
||||
-> InstallDir
|
||||
-> Bool -- ^ Force install
|
||||
-> [T.Text] -- ^ additional configure args for bindist
|
||||
@@ -306,10 +308,8 @@ installGHCBindist :: ( MonadFail m
|
||||
]
|
||||
m
|
||||
()
|
||||
installGHCBindist dlinfo ver installDir forceInstall addConfArgs = do
|
||||
let tver = mkTVer ver
|
||||
|
||||
lift $ logDebug $ "Requested to install GHC with " <> prettyVer ver
|
||||
installGHCBindist dlinfo tver installDir forceInstall addConfArgs = do
|
||||
lift $ logDebug $ "Requested to install GHC with " <> tVerToText tver
|
||||
|
||||
regularGHCInstalled <- lift $ ghcInstalled tver
|
||||
|
||||
@@ -317,7 +317,7 @@ installGHCBindist dlinfo ver installDir forceInstall addConfArgs = do
|
||||
| not forceInstall
|
||||
, regularGHCInstalled
|
||||
, GHCupInternal <- installDir -> do
|
||||
throwE $ AlreadyInstalled GHC ver
|
||||
throwE $ AlreadyInstalled GHC (_tvVersion tver)
|
||||
|
||||
| forceInstall
|
||||
, regularGHCInstalled
|
||||
@@ -336,12 +336,12 @@ installGHCBindist dlinfo ver installDir forceInstall addConfArgs = do
|
||||
case installDir of
|
||||
IsolateDir isoDir -> do -- isolated install
|
||||
lift $ logInfo $ "isolated installing GHC to " <> T.pack isoDir
|
||||
liftE $ installPackedGHC dl (view dlSubdir dlinfo) (IsolateDirResolved isoDir) ver forceInstall addConfArgs
|
||||
liftE $ installPackedGHC dl (view dlSubdir dlinfo) (IsolateDirResolved isoDir) tver forceInstall addConfArgs
|
||||
GHCupInternal -> do -- regular install
|
||||
-- prepare paths
|
||||
ghcdir <- lift $ ghcupGHCDir tver
|
||||
|
||||
liftE $ installPackedGHC dl (view dlSubdir dlinfo) (GHCupDir ghcdir) ver forceInstall addConfArgs
|
||||
liftE $ installPackedGHC dl (view dlSubdir dlinfo) (GHCupDir ghcdir) tver forceInstall addConfArgs
|
||||
|
||||
-- make symlinks & stuff when regular install,
|
||||
liftE $ postGHCInstall tver
|
||||
@@ -375,7 +375,7 @@ installPackedGHC :: ( MonadMask m
|
||||
=> FilePath -- ^ Path to the packed GHC bindist
|
||||
-> Maybe TarDir -- ^ Subdir of the archive
|
||||
-> InstallDirResolved
|
||||
-> Version -- ^ The GHC version
|
||||
-> GHCTargetVersion -- ^ The GHC version
|
||||
-> Bool -- ^ Force install
|
||||
-> [T.Text] -- ^ additional configure args for bindist
|
||||
-> Excepts
|
||||
@@ -423,26 +423,22 @@ installUnpackedGHC :: ( MonadReader env m
|
||||
)
|
||||
=> GHCupPath -- ^ Path to the unpacked GHC bindist (where the configure script resides)
|
||||
-> InstallDirResolved -- ^ Path to install to
|
||||
-> Version -- ^ The GHC version
|
||||
-> GHCTargetVersion -- ^ The GHC version
|
||||
-> Bool -- ^ Force install
|
||||
-> [T.Text] -- ^ additional configure args for bindist
|
||||
-> Excepts '[ProcessError, MergeFileTreeError] m ()
|
||||
installUnpackedGHC path inst ver forceInstall addConfArgs
|
||||
installUnpackedGHC path inst tver forceInstall addConfArgs
|
||||
| isWindows = do
|
||||
lift $ logInfo "Installing GHC (this may take a while)"
|
||||
-- Windows bindists are relocatable and don't need
|
||||
-- to run configure.
|
||||
-- We also must make sure to preserve mtime to not confuse ghc-pkg.
|
||||
liftE $ mergeFileTree path inst GHC (mkTVer ver) $ \source dest -> do
|
||||
mtime <- liftIO $ ifM (pathIsSymbolicLink source) (pure Nothing) (Just <$> getModificationTime source)
|
||||
when forceInstall $ hideError doesNotExistErrorType $ hideError InappropriateType $ recycleFile dest
|
||||
liftIO $ moveFilePortable source dest
|
||||
forM_ mtime $ liftIO . setModificationTime dest
|
||||
liftE $ mergeGHCFileTree path inst tver forceInstall
|
||||
| otherwise = do
|
||||
PlatformRequest {..} <- lift getPlatformReq
|
||||
|
||||
let ldOverride
|
||||
| ver >= [vver|8.2.2|]
|
||||
| _tvVersion tver >= [vver|8.2.2|]
|
||||
, _rPlatform `elem` [Linux Alpine, Darwin]
|
||||
= ["--disable-ld-override"]
|
||||
| otherwise
|
||||
@@ -451,7 +447,7 @@ installUnpackedGHC path inst ver forceInstall addConfArgs
|
||||
lift $ logInfo "Installing GHC (this may take a while)"
|
||||
lEM $ execLogged "sh"
|
||||
("./configure" : ("--prefix=" <> fromInstallDir inst)
|
||||
: (ldOverride <> (T.unpack <$> addConfArgs))
|
||||
: (maybe mempty (\x -> ["--target=" <> T.unpack x]) (_tvTarget tver) <> ldOverride <> (T.unpack <$> addConfArgs))
|
||||
)
|
||||
(Just $ fromGHCupPath path)
|
||||
"ghc-configure"
|
||||
@@ -459,17 +455,44 @@ installUnpackedGHC path inst ver forceInstall addConfArgs
|
||||
tmpInstallDest <- lift withGHCupTmpDir
|
||||
lEM $ make ["DESTDIR=" <> fromGHCupPath tmpInstallDest, "install"] (Just $ fromGHCupPath path)
|
||||
liftE $ catchWarn $ lEM @_ @'[ProcessError] $ darwinNotarization _rPlatform (fromGHCupPath tmpInstallDest)
|
||||
liftE $ mergeFileTree (tmpInstallDest `appendGHCupPath` dropDrive (fromInstallDir inst))
|
||||
liftE $ mergeGHCFileTree (tmpInstallDest `appendGHCupPath` dropDrive (fromInstallDir inst)) inst tver forceInstall
|
||||
pure ()
|
||||
|
||||
|
||||
mergeGHCFileTree :: ( MonadReader env m
|
||||
, HasPlatformReq env
|
||||
, HasDirs env
|
||||
, HasSettings env
|
||||
, MonadThrow m
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
, MonadMask m
|
||||
, MonadResource m
|
||||
, MonadFail m
|
||||
)
|
||||
=> GHCupPath -- ^ Path to the root of the tree
|
||||
-> InstallDirResolved -- ^ Path to install to
|
||||
-> GHCTargetVersion -- ^ The GHC version
|
||||
-> Bool -- ^ Force install
|
||||
-> Excepts '[MergeFileTreeError] m ()
|
||||
mergeGHCFileTree root inst tver forceInstall
|
||||
| isWindows = do
|
||||
liftE $ mergeFileTree root inst GHC tver $ \source dest -> do
|
||||
mtime <- liftIO $ ifM (pathIsSymbolicLink source) (pure Nothing) (Just <$> getModificationTime source)
|
||||
when forceInstall $ hideError doesNotExistErrorType $ hideError InappropriateType $ recycleFile dest
|
||||
liftIO $ moveFilePortable source dest
|
||||
forM_ mtime $ liftIO . setModificationTime dest
|
||||
| otherwise = do
|
||||
liftE $ mergeFileTree root
|
||||
inst
|
||||
GHC
|
||||
(mkTVer ver)
|
||||
tver
|
||||
(\f t -> liftIO $ do
|
||||
mtime <- ifM (pathIsSymbolicLink f) (pure Nothing) (Just <$> getModificationTime f)
|
||||
install f t (not forceInstall)
|
||||
forM_ mtime $ setModificationTime t)
|
||||
|
||||
pure ()
|
||||
|
||||
|
||||
-- | Installs GHC into @~\/.ghcup\/ghc/\<ver\>@ and places the
|
||||
-- following symlinks in @~\/.ghcup\/bin@:
|
||||
@@ -489,7 +512,7 @@ installGHCBin :: ( MonadFail m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Version -- ^ the version to install
|
||||
=> GHCTargetVersion -- ^ the version to install
|
||||
-> InstallDir
|
||||
-> Bool -- ^ force install
|
||||
-> [T.Text] -- ^ additional configure args for bindist
|
||||
@@ -512,9 +535,9 @@ installGHCBin :: ( MonadFail m
|
||||
]
|
||||
m
|
||||
()
|
||||
installGHCBin ver installDir forceInstall addConfArgs = do
|
||||
dlinfo <- liftE $ getDownloadInfo GHC ver
|
||||
liftE $ installGHCBindist dlinfo ver installDir forceInstall addConfArgs
|
||||
installGHCBin tver installDir forceInstall addConfArgs = do
|
||||
dlinfo <- liftE $ getDownloadInfo' GHC tver
|
||||
liftE $ installGHCBindist dlinfo tver installDir forceInstall addConfArgs
|
||||
|
||||
|
||||
|
||||
@@ -708,7 +731,7 @@ rmGHCVer ver = do
|
||||
Just files -> do
|
||||
lift $ logInfo $ "Removing files safely from: " <> T.pack dir
|
||||
forM_ files (lift . hideError NoSuchThing . recycleFile . (\f -> dir </> dropDrive f))
|
||||
removeEmptyDirsRecursive dir
|
||||
hideError UnsatisfiedConstraints $ removeEmptyDirsRecursive dir
|
||||
survivors <- liftIO $ hideErrorDef [doesNotExistErrorType] [] $ listDirectory dir
|
||||
f <- recordedInstallationFile GHC ver
|
||||
lift $ recycleFile f
|
||||
@@ -755,7 +778,8 @@ compileGHC :: ( MonadMask m
|
||||
, MonadUnliftIO m
|
||||
, MonadFail m
|
||||
)
|
||||
=> GHCVer GHCTargetVersion
|
||||
=> GHCVer
|
||||
-> Maybe Text -- ^ cross target
|
||||
-> Maybe Version -- ^ overwrite version
|
||||
-> Either Version FilePath -- ^ version to bootstrap with
|
||||
-> Maybe Int -- ^ jobs
|
||||
@@ -763,7 +787,7 @@ compileGHC :: ( MonadMask m
|
||||
-> Maybe (Either FilePath [URI]) -- ^ patches
|
||||
-> [Text] -- ^ additional args to ./configure
|
||||
-> Maybe String -- ^ build flavour
|
||||
-> Bool
|
||||
-> Maybe BuildSystem
|
||||
-> InstallDir
|
||||
-> Excepts
|
||||
'[ AlreadyInstalled
|
||||
@@ -792,20 +816,21 @@ compileGHC :: ( MonadMask m
|
||||
]
|
||||
m
|
||||
GHCTargetVersion
|
||||
compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadrian installDir
|
||||
compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs buildFlavour buildSystem installDir
|
||||
= do
|
||||
PlatformRequest { .. } <- lift getPlatformReq
|
||||
pfreq@PlatformRequest { .. } <- lift getPlatformReq
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
|
||||
(workdir, tmpUnpack, tver) <- case targetGhc of
|
||||
-- unpack from version tarball
|
||||
SourceDist tver -> do
|
||||
lift $ logDebug $ "Requested to compile: " <> tVerToText tver <> " with " <> either prettyVer T.pack bstrap
|
||||
SourceDist ver -> do
|
||||
lift $ logDebug $ "Requested to compile: " <> prettyVer ver <> " with " <> either prettyVer T.pack bstrap
|
||||
|
||||
-- download source tarball
|
||||
let tver = mkTVer ver
|
||||
dlInfo <-
|
||||
preview (ix GHC % ix (tver ^. tvVersion) % viSourceDL % _Just) dls
|
||||
?? NoDownload
|
||||
preview (ix GHC % ix tver % viSourceDL % _Just) dls
|
||||
?? NoDownload tver GHC (Just pfreq)
|
||||
dl <- liftE $ downloadCached dlInfo Nothing
|
||||
|
||||
-- unpack
|
||||
@@ -818,7 +843,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
(view dlSubdir dlInfo)
|
||||
liftE $ applyAnyPatch patches (fromGHCupPath workdir)
|
||||
|
||||
pure (workdir, tmpUnpack, Just tver)
|
||||
pure (workdir, tmpUnpack, Just (GHCTargetVersion crossTarget ver))
|
||||
|
||||
RemoteDist uri -> do
|
||||
lift $ logDebug $ "Requested to compile (from uri): " <> T.pack (show uri)
|
||||
@@ -842,7 +867,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
|
||||
let workdir = appendGHCupPath tmpUnpack (takeDirectory bf)
|
||||
|
||||
pure (workdir, tmpUnpack, mkTVer <$> tver)
|
||||
pure (workdir, tmpUnpack, GHCTargetVersion crossTarget <$> tver)
|
||||
|
||||
-- clone from git
|
||||
GitDist GitBranch{..} -> do
|
||||
@@ -899,12 +924,12 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
|
||||
pure tver
|
||||
|
||||
pure (tmpUnpack, tmpUnpack, mkTVer <$> tver)
|
||||
pure (tmpUnpack, tmpUnpack, GHCTargetVersion crossTarget <$> tver)
|
||||
-- the version that's installed may differ from the
|
||||
-- compiled version, so the user can overwrite it
|
||||
installVer <- if | Just ov' <- ov -> pure (mkTVer ov')
|
||||
installVer <- if | Just ov' <- ov -> pure (GHCTargetVersion crossTarget ov')
|
||||
| Just tver' <- tver -> pure tver'
|
||||
| otherwise -> fail "Newer GHCs don't support discovering the version in git. Complain to GHC devs: https://gitlab.haskell.org/ghc/ghc/-/issues/22322"
|
||||
| otherwise -> fail "No GHC version given and couldn't detect version. Giving up..."
|
||||
|
||||
alreadyInstalled <- lift $ ghcInstalled installVer
|
||||
alreadySet <- fmap (== Just installVer) $ lift $ ghcSet (_tvTarget installVer)
|
||||
@@ -923,16 +948,31 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
IsolateDir isoDir -> pure $ IsolateDirResolved isoDir
|
||||
GHCupInternal -> GHCupDir <$> lift (ghcupGHCDir installVer)
|
||||
|
||||
(mBindist, bmk) <- liftE $ runBuildAction
|
||||
mBindist <- liftE $ runBuildAction
|
||||
tmpUnpack
|
||||
(do
|
||||
b <- if hadrian
|
||||
-- prefer 'tver', because the real version carries out compatibility checks
|
||||
-- we don't want the user to do funny things with it
|
||||
then compileHadrianBindist (fromMaybe installVer tver) (fromGHCupPath workdir) ghcdir
|
||||
else compileMakeBindist (fromMaybe installVer tver) (fromGHCupPath workdir) ghcdir
|
||||
bmk <- liftIO $ handleIO (\_ -> pure "") $ B.readFile (build_mk $ fromGHCupPath workdir)
|
||||
pure (b, bmk)
|
||||
-- prefer 'tver', because the real version carries out compatibility checks
|
||||
-- we don't want the user to do funny things with it
|
||||
let doHadrian = compileHadrianBindist (fromMaybe installVer tver) (fromGHCupPath workdir) ghcdir
|
||||
doMake = compileMakeBindist (fromMaybe installVer tver) (fromGHCupPath workdir) ghcdir
|
||||
case buildSystem of
|
||||
Just Hadrian -> do
|
||||
lift $ logInfo "Requested to use Hadrian"
|
||||
liftE doHadrian
|
||||
Just Make -> do
|
||||
lift $ logInfo "Requested to use Make"
|
||||
doMake
|
||||
Nothing -> do
|
||||
supportsHadrian <- liftE $ catchE @HadrianNotFound @'[HadrianNotFound] @'[] (\_ -> return False)
|
||||
$ fmap (const True)
|
||||
$ findHadrianFile (fromGHCupPath workdir)
|
||||
if supportsHadrian
|
||||
then do
|
||||
lift $ logInfo "Detected Hadrian"
|
||||
liftE doHadrian
|
||||
else do
|
||||
lift $ logInfo "Detected Make"
|
||||
doMake
|
||||
)
|
||||
|
||||
case installDir of
|
||||
@@ -948,12 +988,10 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
liftE $ installPackedGHC bindist
|
||||
(Just $ RegexDir "ghc-.*")
|
||||
ghcdir
|
||||
(installVer ^. tvVersion)
|
||||
installVer
|
||||
False -- not a force install, since we already overwrite when compiling.
|
||||
[]
|
||||
|
||||
liftIO $ B.writeFile (fromInstallDir ghcdir </> ghcUpSrcBuiltFile) bmk
|
||||
|
||||
case installDir of
|
||||
-- set and make symlinks for regular (non-isolated) installs
|
||||
GHCupInternal -> do
|
||||
@@ -976,20 +1014,29 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
=> GHCupPath
|
||||
-> Excepts '[ProcessError, ParseError] m Version
|
||||
getGHCVer tmpUnpack = do
|
||||
lEM $ execWithGhcEnv "python3" ["./boot"] (Just $ fromGHCupPath tmpUnpack) "ghc-bootstrap"
|
||||
lEM $ execWithGhcEnv "sh" ["./configure"] (Just $ fromGHCupPath tmpUnpack) "ghc-bootstrap"
|
||||
CapturedProcess {..} <- lift $ makeOut
|
||||
["show!", "--quiet", "VALUE=ProjectVersion" ] (Just $ fromGHCupPath tmpUnpack)
|
||||
case _exitCode of
|
||||
ExitSuccess -> either (throwE . ParseError . show) pure . MP.parse ghcProjectVersion "" . T.pack . stripNewlineEnd . T.unpack . decUTF8Safe' $ _stdOut
|
||||
ExitFailure c -> throwE $ NonZeroExit c "make" ["show!", "--quiet", "VALUE=ProjectVersion" ]
|
||||
lEM $ execLogged "python3" ["./boot"] (Just $ fromGHCupPath tmpUnpack) "ghc-bootstrap" Nothing
|
||||
lEM $ configureWithGhcBoot Nothing [] (Just $ fromGHCupPath tmpUnpack) "ghc-bootstrap"
|
||||
let versionFile = fromGHCupPath tmpUnpack </> "VERSION"
|
||||
hasVersionFile <- liftIO $ doesFileExist versionFile
|
||||
if hasVersionFile
|
||||
then do
|
||||
lift $ logDebug "Detected VERSION file, trying to extract"
|
||||
contents <- liftIO $ readFile versionFile
|
||||
either (throwE . ParseError . show) pure . MP.parse version' "" . T.pack . stripNewlineEnd $ contents
|
||||
else do
|
||||
lift $ logDebug "Didn't detect VERSION file, trying to extract via legacy 'make'"
|
||||
CapturedProcess {..} <- lift $ makeOut
|
||||
["show!", "--quiet", "VALUE=ProjectVersion" ] (Just $ fromGHCupPath tmpUnpack)
|
||||
case _exitCode of
|
||||
ExitSuccess -> either (throwE . ParseError . show) pure . MP.parse ghcProjectVersion "" . T.pack . stripNewlineEnd . T.unpack . decUTF8Safe' $ _stdOut
|
||||
ExitFailure c -> throwE $ NonZeroExit c "make" ["show!", "--quiet", "VALUE=ProjectVersion" ]
|
||||
|
||||
defaultConf =
|
||||
let cross_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/cross" >> runIO (readFile "data/build_mk/cross")))
|
||||
default_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/default" >> runIO (readFile "data/build_mk/default")))
|
||||
in case targetGhc of
|
||||
SourceDist (GHCTargetVersion (Just _) _) -> cross_mk
|
||||
_ -> default_mk
|
||||
in case crossTarget of
|
||||
Just _ -> cross_mk
|
||||
_ -> default_mk
|
||||
|
||||
compileHadrianBindist :: ( MonadReader env m
|
||||
, HasDirs env
|
||||
@@ -1015,18 +1062,17 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
m
|
||||
(Maybe FilePath) -- ^ output path of bindist, None for cross
|
||||
compileHadrianBindist tver workdir ghcdir = do
|
||||
lEM $ execWithGhcEnv "python3" ["./boot"] (Just workdir) "ghc-bootstrap"
|
||||
|
||||
liftE $ configureBindist tver workdir ghcdir
|
||||
|
||||
lift $ logInfo "Building (this may take a while)..."
|
||||
hadrian_build <- liftE $ findHadrianFile workdir
|
||||
lEM $ execWithGhcEnv hadrian_build
|
||||
lEM $ execLogged hadrian_build
|
||||
( maybe [] (\j -> ["-j" <> show j] ) jobs
|
||||
++ maybe [] (\bf -> ["--flavour=" <> bf]) buildFlavour
|
||||
++ ["binary-dist"]
|
||||
)
|
||||
(Just workdir) "ghc-make"
|
||||
Nothing
|
||||
[tar] <- liftIO $ findFiles
|
||||
(workdir </> "_build" </> "bindist")
|
||||
(makeRegexOpts compExtended
|
||||
@@ -1059,6 +1105,9 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, MonadFail m
|
||||
, MonadMask m
|
||||
, MonadUnliftIO m
|
||||
, MonadResource m
|
||||
)
|
||||
=> GHCTargetVersion
|
||||
-> FilePath
|
||||
@@ -1070,6 +1119,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
, PatchFailed
|
||||
, ProcessError
|
||||
, NotFoundInPATH
|
||||
, MergeFileTreeError
|
||||
, CopyError]
|
||||
m
|
||||
(Maybe FilePath) -- ^ output path of bindist, None for cross
|
||||
@@ -1091,7 +1141,9 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
|
||||
if | isCross tver -> do
|
||||
lift $ logInfo "Installing cross toolchain..."
|
||||
lEM $ make ["install"] (Just workdir)
|
||||
tmpInstallDest <- lift withGHCupTmpDir
|
||||
lEM $ make ["DESTDIR=" <> fromGHCupPath tmpInstallDest, "install"] (Just workdir)
|
||||
liftE $ mergeGHCFileTree (tmpInstallDest `appendGHCupPath` dropDrive (fromInstallDir ghcdir)) ghcdir tver True
|
||||
pure Nothing
|
||||
| otherwise -> do
|
||||
lift $ logInfo "Creating bindist..."
|
||||
@@ -1164,8 +1216,8 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
let lines' = fmap T.strip . T.lines $ decUTF8Safe c
|
||||
|
||||
-- for cross, we need Stage1Only
|
||||
case targetGhc of
|
||||
SourceDist (GHCTargetVersion (Just _) _) -> when ("Stage1Only = YES" `notElem` lines') $ throwE
|
||||
case crossTarget of
|
||||
Just _ -> when ("Stage1Only = YES" `notElem` lines') $ throwE
|
||||
(InvalidBuildConfig
|
||||
[s|Cross compiling needs to be a Stage1 build, add "Stage1Only = YES" to your config!|]
|
||||
)
|
||||
@@ -1209,64 +1261,50 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
()
|
||||
configureBindist tver workdir (fromInstallDir -> ghcdir) = do
|
||||
lift $ logInfo [s|configuring build|]
|
||||
|
||||
if | _tvVersion tver >= [vver|8.8.0|] -> do
|
||||
lEM $ execWithGhcEnv
|
||||
"sh"
|
||||
("./configure" : maybe mempty
|
||||
(\x -> ["--target=" <> T.unpack x])
|
||||
(_tvTarget tver)
|
||||
++ ["--prefix=" <> ghcdir]
|
||||
++ (if isWindows then ["--enable-tarballs-autodownload"] else [])
|
||||
++ fmap T.unpack aargs
|
||||
)
|
||||
(Just workdir)
|
||||
"ghc-conf"
|
||||
| otherwise -> do
|
||||
lEM $ execLogged
|
||||
"sh"
|
||||
( [ "./configure", "--with-ghc=" <> either id id bghc
|
||||
]
|
||||
++ maybe mempty
|
||||
(\x -> ["--target=" <> T.unpack x])
|
||||
(_tvTarget tver)
|
||||
++ ["--prefix=" <> ghcdir]
|
||||
++ (if isWindows then ["--enable-tarballs-autodownload"] else [])
|
||||
++ fmap T.unpack aargs
|
||||
)
|
||||
(Just workdir)
|
||||
"ghc-conf"
|
||||
Nothing
|
||||
lEM $ configureWithGhcBoot (Just tver)
|
||||
(maybe mempty
|
||||
(\x -> ["--target=" <> T.unpack x])
|
||||
(_tvTarget tver)
|
||||
++ ["--prefix=" <> ghcdir]
|
||||
++ (if isWindows then ["--enable-tarballs-autodownload"] else [])
|
||||
++ fmap T.unpack aargs
|
||||
)
|
||||
(Just workdir)
|
||||
"ghc-conf"
|
||||
pure ()
|
||||
|
||||
execWithGhcEnv :: ( MonadReader env m
|
||||
, HasSettings env
|
||||
, HasDirs env
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, MonadThrow m)
|
||||
=> FilePath -- ^ thing to execute
|
||||
-> [String] -- ^ args for the thing
|
||||
-> Maybe FilePath -- ^ optionally chdir into this
|
||||
-> FilePath -- ^ log filename (opened in append mode)
|
||||
-> m (Either ProcessError ())
|
||||
execWithGhcEnv fp args dir logf = do
|
||||
env <- ghcEnv
|
||||
execLogged fp args dir logf (Just env)
|
||||
configureWithGhcBoot :: ( MonadReader env m
|
||||
, HasSettings env
|
||||
, HasDirs env
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, MonadThrow m)
|
||||
=> Maybe GHCTargetVersion
|
||||
-> [String] -- ^ args for configure
|
||||
-> Maybe FilePath -- ^ optionally chdir into this
|
||||
-> FilePath -- ^ log filename (opened in append mode)
|
||||
-> m (Either ProcessError ())
|
||||
configureWithGhcBoot mtver args dir logf = do
|
||||
let execNew = execLogged
|
||||
"sh"
|
||||
("./configure" : ("GHC=" <> bghc) : args)
|
||||
dir
|
||||
logf
|
||||
Nothing
|
||||
execOld = execLogged
|
||||
"sh"
|
||||
("./configure" : ("--with-ghc=" <> bghc) : args)
|
||||
dir
|
||||
logf
|
||||
Nothing
|
||||
if | Just tver <- mtver
|
||||
, _tvVersion tver >= [vver|8.8.0|] -> execNew
|
||||
| Nothing <- mtver -> execNew -- need some default for git checkouts where we don't know yet
|
||||
| otherwise -> execOld
|
||||
|
||||
bghc = case bstrap of
|
||||
Right g -> Right g
|
||||
Left bver -> Left ("ghc-" <> (T.unpack . prettyVer $ bver) <> exeExt)
|
||||
|
||||
ghcEnv :: (MonadThrow m, MonadIO m) => m [(String, String)]
|
||||
ghcEnv = do
|
||||
cEnv <- liftIO getEnvironment
|
||||
bghcPath <- case bghc of
|
||||
Right ghc' -> pure ghc'
|
||||
Left bver -> do
|
||||
spaths <- liftIO getSearchPath
|
||||
throwMaybeM (NotFoundInPATH bver) $ liftIO (searchPath spaths bver)
|
||||
pure (("GHC", bghcPath) : cEnv)
|
||||
Right g -> g
|
||||
Left bver -> "ghc-" <> (T.unpack . prettyVer $ bver) <> exeExt
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import Control.Monad.Trans.Resource
|
||||
import Data.ByteString ( ByteString )
|
||||
import Data.Either
|
||||
import Data.List
|
||||
import Data.Ord
|
||||
import Data.Maybe
|
||||
import Data.String ( fromString )
|
||||
import Data.Text ( Text )
|
||||
@@ -353,7 +354,7 @@ compileHLS :: ( MonadMask m
|
||||
, NotInstalled
|
||||
] m Version
|
||||
compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal updateCabal patches cabalArgs = do
|
||||
PlatformRequest { .. } <- lift getPlatformReq
|
||||
pfreq@PlatformRequest { .. } <- lift getPlatformReq
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
Dirs { .. } <- lift getDirs
|
||||
|
||||
@@ -368,8 +369,8 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal upda
|
||||
|
||||
-- download source tarball
|
||||
dlInfo <-
|
||||
preview (ix HLS % ix tver % viSourceDL % _Just) dls
|
||||
?? NoDownload
|
||||
preview (ix HLS % ix (mkTVer tver) % viSourceDL % _Just) dls
|
||||
?? NoDownload (mkTVer tver) HLS (Just pfreq)
|
||||
dl <- liftE $ downloadCached dlInfo Nothing
|
||||
|
||||
-- unpack
|
||||
@@ -704,7 +705,7 @@ rmHLSVer ver = do
|
||||
when (Just ver == isHlsSet) $ do
|
||||
-- set latest hls
|
||||
hlsVers <- lift $ fmap rights getInstalledHLSs
|
||||
case headMay . reverse . sort $ hlsVers of
|
||||
case headMay . sortBy (comparing Down) $ hlsVers of
|
||||
Just latestver -> liftE $ setHLS latestver SetHLSOnly Nothing
|
||||
Nothing -> pure ()
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ data ListResult = ListResult
|
||||
, lTag :: [Tag]
|
||||
, lInstalled :: Bool
|
||||
, lSet :: Bool -- ^ currently active version
|
||||
, fromSrc :: Bool -- ^ compiled from source
|
||||
, lStray :: Bool -- ^ not in download info
|
||||
, lNoBindist :: Bool -- ^ whether the version is available for this platform/arch
|
||||
, hlsPowered :: Bool
|
||||
@@ -86,7 +85,7 @@ data ListResult = ListResult
|
||||
|
||||
|
||||
-- | Extract all available tool versions and their tags.
|
||||
availableToolVersions :: GHCupDownloads -> Tool -> Map.Map Version VersionInfo
|
||||
availableToolVersions :: GHCupDownloads -> Tool -> Map.Map GHCTargetVersion VersionInfo
|
||||
availableToolVersions av tool = view
|
||||
(at tool % non Map.empty)
|
||||
av
|
||||
@@ -134,13 +133,13 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
slr <- strayGHCs avTools
|
||||
pure (sort (slr ++ lr))
|
||||
Cabal -> do
|
||||
slr <- strayCabals avTools cSet cabals
|
||||
slr <- strayCabals (Map.mapKeys _tvVersion avTools) cSet cabals
|
||||
pure (sort (slr ++ lr))
|
||||
HLS -> do
|
||||
slr <- strayHLS avTools hlsSet' hlses
|
||||
slr <- strayHLS (Map.mapKeys _tvVersion avTools) hlsSet' hlses
|
||||
pure (sort (slr ++ lr))
|
||||
Stack -> do
|
||||
slr <- strayStacks avTools sSet stacks
|
||||
slr <- strayStacks (Map.mapKeys _tvVersion avTools) sSet stacks
|
||||
pure (sort (slr ++ lr))
|
||||
GHCup -> do
|
||||
let cg = maybeToList $ currentGHCup avTools
|
||||
@@ -159,44 +158,28 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
)
|
||||
=> Map.Map Version VersionInfo
|
||||
=> Map.Map GHCTargetVersion VersionInfo
|
||||
-> m [ListResult]
|
||||
strayGHCs avTools = do
|
||||
ghcs <- getInstalledGHCs
|
||||
fmap catMaybes $ forM ghcs $ \case
|
||||
Right tver@GHCTargetVersion{ _tvTarget = Nothing, .. } -> do
|
||||
case Map.lookup _tvVersion avTools of
|
||||
Right tver@GHCTargetVersion{ .. } -> do
|
||||
case Map.lookup tver avTools of
|
||||
Just _ -> pure Nothing
|
||||
Nothing -> do
|
||||
lSet <- fmap (maybe False (\(GHCTargetVersion _ v ) -> v == _tvVersion)) $ ghcSet Nothing
|
||||
fromSrc <- ghcSrcInstalled tver
|
||||
lSet <- fmap (maybe False (\(GHCTargetVersion _ v ) -> v == _tvVersion)) $ ghcSet _tvTarget
|
||||
hlsPowered <- fmap (elem _tvVersion) hlsGHCVersions
|
||||
pure $ Just $ ListResult
|
||||
{ lTool = GHC
|
||||
, lVer = _tvVersion
|
||||
, lCross = Nothing
|
||||
, lCross = _tvTarget
|
||||
, lTag = []
|
||||
, lInstalled = True
|
||||
, lStray = isNothing (Map.lookup _tvVersion avTools)
|
||||
, lStray = isNothing (Map.lookup tver avTools)
|
||||
, lNoBindist = False
|
||||
, lReleaseDay = Nothing
|
||||
, ..
|
||||
}
|
||||
Right tver@GHCTargetVersion{ .. } -> do
|
||||
lSet <- fmap (maybe False (\(GHCTargetVersion _ v ) -> v == _tvVersion)) $ ghcSet _tvTarget
|
||||
fromSrc <- ghcSrcInstalled tver
|
||||
hlsPowered <- fmap (elem _tvVersion) hlsGHCVersions
|
||||
pure $ Just $ ListResult
|
||||
{ lTool = GHC
|
||||
, lVer = _tvVersion
|
||||
, lCross = _tvTarget
|
||||
, lTag = []
|
||||
, lInstalled = True
|
||||
, lStray = True -- NOTE: cross currently cannot be installed via bindist
|
||||
, lNoBindist = False
|
||||
, lReleaseDay = Nothing
|
||||
, ..
|
||||
}
|
||||
Left e -> do
|
||||
logWarn
|
||||
$ "Could not parse version of stray directory" <> T.pack e
|
||||
@@ -228,7 +211,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
, lInstalled = True
|
||||
, lStray = isNothing (Map.lookup ver avTools)
|
||||
, lNoBindist = False
|
||||
, fromSrc = False -- actually, we don't know :>
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = Nothing
|
||||
, ..
|
||||
@@ -263,7 +245,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
, lInstalled = True
|
||||
, lStray = isNothing (Map.lookup ver avTools)
|
||||
, lNoBindist = False
|
||||
, fromSrc = False -- actually, we don't know :>
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = Nothing
|
||||
, ..
|
||||
@@ -299,7 +280,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
, lInstalled = True
|
||||
, lStray = isNothing (Map.lookup ver avTools)
|
||||
, lNoBindist = False
|
||||
, fromSrc = False -- actually, we don't know :>
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = Nothing
|
||||
, ..
|
||||
@@ -309,19 +289,18 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
$ "Could not parse version of stray directory" <> T.pack e
|
||||
pure Nothing
|
||||
|
||||
currentGHCup :: Map.Map Version VersionInfo -> Maybe ListResult
|
||||
currentGHCup :: Map.Map GHCTargetVersion VersionInfo -> Maybe ListResult
|
||||
currentGHCup av =
|
||||
let currentVer = fromJust $ pvpToVersion ghcUpVer ""
|
||||
let currentVer = mkTVer $ fromJust $ pvpToVersion ghcUpVer ""
|
||||
listVer = Map.lookup currentVer av
|
||||
latestVer = fst <$> headOf (getTagged Latest) av
|
||||
recommendedVer = fst <$> headOf (getTagged Latest) av
|
||||
isOld = maybe True (> currentVer) latestVer && maybe True (> currentVer) recommendedVer
|
||||
in if | Map.member currentVer av -> Nothing
|
||||
| otherwise -> Just $ ListResult { lVer = currentVer
|
||||
| otherwise -> Just $ ListResult { lVer = _tvVersion currentVer
|
||||
, lTag = maybe (if isOld then [Old] else []) _viTags listVer
|
||||
, lCross = Nothing
|
||||
, lTool = GHCup
|
||||
, fromSrc = False
|
||||
, lStray = isNothing listVer
|
||||
, lSet = True
|
||||
, lInstalled = True
|
||||
@@ -346,18 +325,17 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
-> [Either FilePath Version]
|
||||
-> Maybe Version
|
||||
-> [Either FilePath Version]
|
||||
-> (Version, VersionInfo)
|
||||
-> (GHCTargetVersion, VersionInfo)
|
||||
-> m ListResult
|
||||
toListResult t cSet cabals hlsSet' hlses stackSet' stacks (v, VersionInfo{..}) = do
|
||||
toListResult t cSet cabals hlsSet' hlses stackSet' stacks (tver, VersionInfo{..}) = do
|
||||
let v = _tvVersion tver
|
||||
case t of
|
||||
GHC -> do
|
||||
lNoBindist <- fmap (isLeft . veitherToEither) $ runE @'[NoDownload] $ getDownloadInfo GHC v
|
||||
let tver = mkTVer v
|
||||
lSet <- fmap (maybe False (\(GHCTargetVersion _ v') -> v' == v)) $ ghcSet Nothing
|
||||
lNoBindist <- fmap (isLeft . veitherToEither) $ runE @'[NoDownload] $ getDownloadInfo' GHC tver
|
||||
lSet <- fmap (== Just tver) $ ghcSet (_tvTarget tver)
|
||||
lInstalled <- ghcInstalled tver
|
||||
fromSrc <- ghcSrcInstalled tver
|
||||
hlsPowered <- fmap (elem v) hlsGHCVersions
|
||||
pure ListResult { lVer = v, lCross = Nothing , lTag = _viTags, lTool = t, lStray = False, lReleaseDay = _viReleaseDay, .. }
|
||||
hlsPowered <- fmap (elem tver) (fmap mkTVer <$> hlsGHCVersions)
|
||||
pure ListResult { lVer = _tvVersion tver , lCross = _tvTarget tver , lTag = _viTags, lTool = t, lStray = False, lReleaseDay = _viReleaseDay, .. }
|
||||
Cabal -> do
|
||||
lNoBindist <- fmap (isLeft . veitherToEither) $ runE @'[NoDownload] $ getDownloadInfo Cabal v
|
||||
let lSet = cSet == Just v
|
||||
@@ -366,7 +344,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
, lCross = Nothing
|
||||
, lTag = _viTags
|
||||
, lTool = t
|
||||
, fromSrc = False
|
||||
, lStray = False
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = _viReleaseDay
|
||||
@@ -379,7 +356,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
, lTag = _viTags
|
||||
, lCross = Nothing
|
||||
, lTool = t
|
||||
, fromSrc = False
|
||||
, lStray = False
|
||||
, lNoBindist = False
|
||||
, hlsPowered = False
|
||||
@@ -394,7 +370,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
, lCross = Nothing
|
||||
, lTag = _viTags
|
||||
, lTool = t
|
||||
, fromSrc = False
|
||||
, lStray = False
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = _viReleaseDay
|
||||
@@ -408,7 +383,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
||||
, lCross = Nothing
|
||||
, lTag = _viTags
|
||||
, lTool = t
|
||||
, fromSrc = False
|
||||
, lStray = False
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = _viReleaseDay
|
||||
|
||||
@@ -34,6 +34,7 @@ import Control.Monad.IO.Class
|
||||
import Control.Monad.Reader
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.FilePath
|
||||
import System.IO
|
||||
import System.IO.Error
|
||||
import Text.Regex.Posix
|
||||
|
||||
@@ -45,7 +46,7 @@ initGHCupFileLogging :: ( MonadReader env m
|
||||
, HasDirs env
|
||||
, MonadIO m
|
||||
, MonadMask m
|
||||
) => m FilePath
|
||||
) => m Handle
|
||||
initGHCupFileLogging = do
|
||||
Dirs { logsDir } <- getDirs
|
||||
let logfile = fromGHCupPath logsDir </> "ghcup.log"
|
||||
@@ -58,4 +59,5 @@ initGHCupFileLogging = do
|
||||
forM_ logFiles $ hideError doesNotExistErrorType . recycleFile . (fromGHCupPath logsDir </>)
|
||||
|
||||
liftIO $ writeFile logfile ""
|
||||
pure logfile
|
||||
liftIO $ openFile logfile AppendMode
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import Control.Monad.Trans.Resource
|
||||
hiding ( throwM )
|
||||
import Data.Either
|
||||
import Data.List
|
||||
import Data.Ord
|
||||
import Data.Maybe
|
||||
import Data.Versions hiding ( patch )
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
@@ -279,6 +280,6 @@ rmStackVer ver = do
|
||||
|
||||
when (Just ver == sSet) $ do
|
||||
sVers <- lift $ fmap rights getInstalledStacks
|
||||
case headMay . reverse . sort $ sVers of
|
||||
case headMay . sortBy (comparing Down) $ sVers of
|
||||
Just latestver -> setStack latestver
|
||||
Nothing -> lift $ rmLink (binDir </> "stack" <> exeExt)
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE TypeOperators #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
|
||||
{-|
|
||||
Module : GHCup.Types
|
||||
@@ -28,13 +32,15 @@ module GHCup.Types
|
||||
|
||||
import {-# SOURCE #-} GHCup.Utils.Dirs ( fromGHCupPath, GHCupPath )
|
||||
|
||||
import Control.Monad
|
||||
import Control.Monad.Trans.Class ( lift )
|
||||
import Control.DeepSeq ( NFData, rnf )
|
||||
import Data.Map.Strict ( Map )
|
||||
import Data.List.NonEmpty ( NonEmpty (..) )
|
||||
import Data.Time.Calendar ( Day )
|
||||
import Data.Text ( Text )
|
||||
import Data.Versions
|
||||
import GHC.IO.Exception ( ExitCode )
|
||||
import GHC.IO.Exception ( ExitCode, IOException(..) )
|
||||
import Optics ( makeLenses )
|
||||
import Text.PrettyPrint.HughesPJClass (Pretty, pPrint, text)
|
||||
import URI.ByteString
|
||||
@@ -46,6 +52,12 @@ import qualified Data.ByteString.Lazy as BL
|
||||
import qualified Data.Text as T
|
||||
import qualified GHC.Generics as GHC
|
||||
|
||||
import Control.Monad.IO.Unlift
|
||||
import UnliftIO.Exception
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
import Haskus.Utils.Variant.VEither
|
||||
import Control.Monad.Except (ExceptT(..), runExceptT)
|
||||
|
||||
|
||||
#if !defined(BRICK)
|
||||
data Key = KEsc | KChar Char | KBS | KEnter
|
||||
@@ -104,7 +116,7 @@ instance NFData Requirements
|
||||
-- | Description of all binary and source downloads. This is a tree
|
||||
-- of nested maps.
|
||||
type GHCupDownloads = Map Tool ToolVersionSpec
|
||||
type ToolVersionSpec = Map Version VersionInfo
|
||||
type ToolVersionSpec = Map GHCTargetVersion VersionInfo
|
||||
type ArchitectureSpec = Map Architecture PlatformSpec
|
||||
type PlatformSpec = Map Platform PlatformVersionSpec
|
||||
type PlatformVersionSpec = Map (Maybe VersionRange) DownloadInfo
|
||||
@@ -132,6 +144,9 @@ data GlobalTool = ShimGen
|
||||
|
||||
instance NFData GlobalTool
|
||||
|
||||
instance Pretty GlobalTool where
|
||||
pPrint ShimGen = text "shimgen"
|
||||
|
||||
|
||||
-- | All necessary information of a tool version, including
|
||||
-- source download and per-architecture downloads.
|
||||
@@ -593,7 +608,9 @@ data GHCTargetVersion = GHCTargetVersion
|
||||
{ _tvTarget :: Maybe Text
|
||||
, _tvVersion :: Version
|
||||
}
|
||||
deriving (Ord, Eq, Show)
|
||||
deriving (Ord, Eq, Show, GHC.Generic)
|
||||
|
||||
instance NFData GHCTargetVersion
|
||||
|
||||
data GitBranch = GitBranch
|
||||
{ ref :: String
|
||||
@@ -717,4 +734,23 @@ instance Pretty ToolVersion where
|
||||
|
||||
|
||||
|
||||
data BuildSystem = Hadrian
|
||||
| Make
|
||||
deriving (Show, Eq)
|
||||
|
||||
instance forall es m . (MonadUnliftIO m, Exception (V es)) => MonadUnliftIO (Excepts es m) where
|
||||
withRunInIO exceptSToIO = Excepts $ fmap (either VLeft VRight) $ try $ do
|
||||
withRunInIO $ \runInIO ->
|
||||
exceptSToIO (runInIO . ((\case
|
||||
VLeft v -> liftIO $ throwIO $ toException v
|
||||
VRight a -> pure a) <=< runE))
|
||||
|
||||
|
||||
instance Exception (V '[]) where
|
||||
|
||||
instance
|
||||
( Exception x
|
||||
, Typeable xs
|
||||
, Exception (V xs)
|
||||
) => Exception (V (x ': xs))
|
||||
|
||||
|
||||
@@ -95,13 +95,29 @@ instance FromJSON URI where
|
||||
Right x -> pure x
|
||||
Left e -> fail . show $ e
|
||||
|
||||
instance ToJSON GHCTargetVersion where
|
||||
toJSON = toJSON . tVerToText
|
||||
|
||||
instance FromJSON GHCTargetVersion where
|
||||
parseJSON = withText "GHCTargetVersion" $ \t -> case MP.parse ghcTargetVerP "" t of
|
||||
Right x -> pure x
|
||||
Left e -> fail $ "Failure in GHCTargetVersion (FromJSON)" <> show e
|
||||
|
||||
instance ToJSONKey GHCTargetVersion where
|
||||
toJSONKey = toJSONKeyText $ \x -> tVerToText x
|
||||
|
||||
instance FromJSONKey GHCTargetVersion where
|
||||
fromJSONKey = FromJSONKeyTextParser $ \t -> case MP.parse ghcTargetVerP "" t of
|
||||
Right x -> pure x
|
||||
Left e -> fail $ "Failure in GHCTargetVersion (FromJSONKey)" <> show e
|
||||
|
||||
instance ToJSON Versioning where
|
||||
toJSON = toJSON . prettyV
|
||||
|
||||
instance FromJSON Versioning where
|
||||
parseJSON = withText "Versioning" $ \t -> case versioning t of
|
||||
Right x -> pure x
|
||||
Left e -> fail $ "Failure in Version (FromJSON)" <> show e
|
||||
Left e -> fail $ "Failure in GHCTargetVersion (FromJSON)" <> show e
|
||||
|
||||
instance ToJSONKey Versioning where
|
||||
toJSONKey = toJSONKeyText $ \x -> prettyV x
|
||||
|
||||
@@ -62,7 +62,6 @@ import Control.Monad.Trans.Resource
|
||||
hiding ( throwM )
|
||||
import Control.Monad.IO.Unlift ( MonadUnliftIO( withRunInIO ) )
|
||||
import Data.Char ( isHexDigit )
|
||||
import Data.Bifunctor ( first )
|
||||
import Data.ByteString ( ByteString )
|
||||
import Data.Either
|
||||
import Data.Foldable
|
||||
@@ -289,13 +288,6 @@ ghcInstalled ver = do
|
||||
liftIO $ doesDirectoryExist (fromGHCupPath ghcdir)
|
||||
|
||||
|
||||
-- | Whether the given GHC version is installed from source.
|
||||
ghcSrcInstalled :: (MonadIO m, MonadReader env m, HasDirs env, MonadThrow m) => GHCTargetVersion -> m Bool
|
||||
ghcSrcInstalled ver = do
|
||||
ghcdir <- ghcupGHCDir ver
|
||||
liftIO $ doesFileExist (fromGHCupPath ghcdir </> ghcUpSrcBuiltFile)
|
||||
|
||||
|
||||
-- | Whether the given GHC version is set as the current.
|
||||
ghcSet :: (MonadReader env m, HasDirs env, MonadThrow m, MonadIO m)
|
||||
=> Maybe Text -- ^ the target of the GHC version, if any
|
||||
@@ -774,13 +766,16 @@ getGHCForPVP' pvpIn ghcs' mt = do
|
||||
-- Just (PVP {_pComponents = 8 :| [8,4]})
|
||||
getLatestToolFor :: MonadThrow m
|
||||
=> Tool
|
||||
-> Maybe Text
|
||||
-> PVP
|
||||
-> GHCupDownloads
|
||||
-> m (Maybe (PVP, VersionInfo))
|
||||
getLatestToolFor tool pvpIn dls = do
|
||||
let ls = fromMaybe [] $ preview (ix tool % to Map.toDescList) dls
|
||||
let ps = catMaybes $ fmap (\(v, vi) -> (,vi) <$> versionToPVP v) ls
|
||||
pure . fmap (first fst) . headMay . filter (\((v, _), _) -> matchPVPrefix pvpIn v) $ ps
|
||||
-> m (Maybe (PVP, VersionInfo, Maybe Text))
|
||||
getLatestToolFor tool target pvpIn dls = do
|
||||
let ls :: [(GHCTargetVersion, VersionInfo)]
|
||||
ls = fromMaybe [] $ preview (ix tool % to Map.toDescList) dls
|
||||
let ps :: [((PVP, Text), VersionInfo, Maybe Text)]
|
||||
ps = catMaybes $ fmap (\(v, vi) -> (,vi, _tvTarget v) <$> versionToPVP (_tvVersion v)) ls
|
||||
pure . fmap (\((pv', _), vi, mt) -> (pv', vi, mt)) . headMay . filter (\((v, _), _, t) -> matchPVPrefix pvpIn v && t == target) $ ps
|
||||
|
||||
|
||||
|
||||
@@ -885,12 +880,12 @@ intoSubdir bdir tardir = case tardir of
|
||||
-- | Get the tool version that has this tag. If multiple have it,
|
||||
-- picks the greatest version.
|
||||
getTagged :: Tag
|
||||
-> Fold (Map.Map Version VersionInfo) (Version, VersionInfo)
|
||||
-> Fold (Map.Map GHCTargetVersion VersionInfo) (GHCTargetVersion, VersionInfo)
|
||||
getTagged tag =
|
||||
to (Map.toDescList . Map.filter (\VersionInfo {..} -> tag `elem` _viTags))
|
||||
% folding id
|
||||
|
||||
getByReleaseDay :: GHCupDownloads -> Tool -> Day -> Either (Maybe Day) (Version, VersionInfo)
|
||||
getByReleaseDay :: GHCupDownloads -> Tool -> Day -> Either (Maybe Day) (GHCTargetVersion, VersionInfo)
|
||||
getByReleaseDay av tool day = let mvv = fromMaybe mempty $ headOf (ix tool) av
|
||||
mdv = Map.foldrWithKey (\k vi@VersionInfo{..} m ->
|
||||
maybe m (\d -> let diff = diffDays d day
|
||||
@@ -902,24 +897,24 @@ getByReleaseDay av tool day = let mvv = fromMaybe mempty $ headOf (ix tool) av
|
||||
| absDiff == 0 -> Right (k, vi)
|
||||
| otherwise -> Left (Just (addDays diff day))
|
||||
|
||||
getByReleaseDayFold :: Day -> Fold (Map.Map Version VersionInfo) (Version, VersionInfo)
|
||||
getByReleaseDayFold :: Day -> Fold (Map.Map GHCTargetVersion VersionInfo) (GHCTargetVersion, VersionInfo)
|
||||
getByReleaseDayFold day = to (Map.toDescList . Map.filter (\VersionInfo {..} -> Just day == _viReleaseDay)) % folding id
|
||||
|
||||
getLatest :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
|
||||
getLatest :: GHCupDownloads -> Tool -> Maybe (GHCTargetVersion, VersionInfo)
|
||||
getLatest av tool = headOf (ix tool % getTagged Latest) av
|
||||
|
||||
getLatestPrerelease :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
|
||||
getLatestPrerelease :: GHCupDownloads -> Tool -> Maybe (GHCTargetVersion, VersionInfo)
|
||||
getLatestPrerelease av tool = headOf (ix tool % getTagged LatestPrerelease) av
|
||||
|
||||
getLatestNightly :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
|
||||
getLatestNightly :: GHCupDownloads -> Tool -> Maybe (GHCTargetVersion, VersionInfo)
|
||||
getLatestNightly av tool = headOf (ix tool % getTagged LatestNightly) av
|
||||
|
||||
getRecommended :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
|
||||
getRecommended :: GHCupDownloads -> Tool -> Maybe (GHCTargetVersion, VersionInfo)
|
||||
getRecommended av tool = headOf (ix tool % getTagged Recommended) av
|
||||
|
||||
|
||||
-- | Gets the latest GHC with a given base version.
|
||||
getLatestBaseVersion :: GHCupDownloads -> PVP -> Maybe (Version, VersionInfo)
|
||||
getLatestBaseVersion :: GHCupDownloads -> PVP -> Maybe (GHCTargetVersion, VersionInfo)
|
||||
getLatestBaseVersion av pvpVer =
|
||||
headOf (ix GHC % getTagged (Base pvpVer)) av
|
||||
|
||||
@@ -973,11 +968,6 @@ ghcToolFiles ver = do
|
||||
isNotAnyInfix xs t = foldr (\a b -> not (a `isInfixOf` t) && b) True xs
|
||||
|
||||
|
||||
-- | This file, when residing in @~\/.ghcup\/ghc\/\<ver\>\/@ signals that
|
||||
-- this GHC was built from source. It contains the build config.
|
||||
ghcUpSrcBuiltFile :: FilePath
|
||||
ghcUpSrcBuiltFile = ".ghcup_src_built"
|
||||
|
||||
|
||||
-- | Calls gmake if it exists in PATH, otherwise make.
|
||||
make :: ( MonadThrow m
|
||||
@@ -1101,9 +1091,9 @@ darwinNotarization _ _ = pure $ Right ()
|
||||
|
||||
|
||||
getChangeLog :: GHCupDownloads -> Tool -> ToolVersion -> Maybe URI
|
||||
getChangeLog dls tool (GHCVersion (_tvVersion -> v')) =
|
||||
getChangeLog dls tool (GHCVersion v') =
|
||||
preview (ix tool % ix v' % viChangeLog % _Just) dls
|
||||
getChangeLog dls tool (ToolVersion v') =
|
||||
getChangeLog dls tool (ToolVersion (mkTVer -> v')) =
|
||||
preview (ix tool % ix v' % viChangeLog % _Just) dls
|
||||
getChangeLog dls tool (ToolTag tag) =
|
||||
preview (ix tool % pre (getTagged tag) % to snd % viChangeLog % _Just) dls
|
||||
@@ -1192,7 +1182,7 @@ rmBDir dir = withRunInIO (\run -> run $
|
||||
$ rmPathForcibly dir)
|
||||
|
||||
|
||||
getVersionInfo :: Version
|
||||
getVersionInfo :: GHCTargetVersion
|
||||
-> Tool
|
||||
-> GHCupDownloads
|
||||
-> Maybe VersionInfo
|
||||
@@ -1222,7 +1212,7 @@ ensureGlobalTools
|
||||
(GHCupInfo _ _ gTools) <- lift getGHCupInfo
|
||||
dirs <- lift getDirs
|
||||
shimDownload <- liftE $ lE @_ @'[NoDownload]
|
||||
$ maybe (Left NoDownload) Right $ Map.lookup ShimGen gTools
|
||||
$ maybe (Left (NoDownload' ShimGen)) Right $ Map.lookup ShimGen gTools
|
||||
let dl = downloadCached' shimDownload (Just "gs.exe") Nothing
|
||||
void $ (\DigestError{} -> do
|
||||
lift $ logWarn "Digest doesn't match, redownloading gs.exe..."
|
||||
|
||||
@@ -52,7 +52,7 @@ versionCmp ver1 (VR_lteq ver2) = ver1 <= ver2
|
||||
versionCmp ver1 (VR_eq ver2) = ver1 == ver2
|
||||
|
||||
versionRange :: V.Versioning -> VersionRange -> Bool
|
||||
versionRange ver' (SimpleRange cmps) = and $ fmap (versionCmp ver') cmps
|
||||
versionRange ver' (SimpleRange cmps) = all (versionCmp ver') cmps
|
||||
versionRange ver' (OrRange cmps range) =
|
||||
versionRange ver' (SimpleRange cmps) || versionRange ver' range
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
plat="$(uname -s)"
|
||||
arch=$(uname -m)
|
||||
ghver="0.1.19.2"
|
||||
ghver="0.1.19.4"
|
||||
: "${GHCUP_BASE_URL:=https://downloads.haskell.org/~ghcup}"
|
||||
|
||||
export GHCUP_SKIP_UPDATE_CHECK=yes
|
||||
|
||||
@@ -40,10 +40,13 @@ param (
|
||||
# Whether to disable use of curl.exe
|
||||
[switch]$DisableCurl,
|
||||
# The Msys2 version to download (e.g. 20221216)
|
||||
[string]$Msys2Version
|
||||
[string]$Msys2Version,
|
||||
# The Msys2 sha256sum hash
|
||||
[string]$Msys2Hash
|
||||
)
|
||||
|
||||
$DefaultMsys2Version = "20221216"
|
||||
$DefaultMsys2Hash = "18370d32b0264915c97e3d7c618f7b32d48ad80858923883fde5145acd32ca0f"
|
||||
|
||||
$Silent = !$Interactive
|
||||
|
||||
@@ -430,9 +433,12 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
|
||||
if (!($Msys2Version)) {
|
||||
$Msys2Version = $DefaultMsys2Version
|
||||
}
|
||||
if (!($Msys2Hash)) {
|
||||
$Msys2Hash = $DefaultMsys2Hash
|
||||
}
|
||||
Print-Msg -msg ('Downloading Msys2 archive {0}...' -f $Msys2Version)
|
||||
$archive = ('msys2-base-x86_64-{0}.sfx.exe' -f $Msys2Version)
|
||||
$msysUrl = ('https://repo.msys2.org/distrib/x86_64/{0}' -f "$archive")
|
||||
$msysUrl = ('https://downloads.haskell.org/ghcup/msys2/{0}' -f "$archive")
|
||||
$archivePath = ('{0}\{1}' -f ([IO.Path]::GetTempPath()), "$archive")
|
||||
|
||||
if ((Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) -and !($DisableCurl)) {
|
||||
@@ -440,6 +446,11 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
|
||||
} else {
|
||||
Get-FileWCSynchronous -url "$msysUrl" -destinationFolder ([IO.Path]::GetTempPath()) -includeStats
|
||||
}
|
||||
$Msys2HashChecked = Get-FileHash -Algorithm SHA256 "${archivePath}"
|
||||
if (!($Msys2HashChecked.Hash -eq $Msys2Hash)) {
|
||||
Print-Msg -color Red -msg ("Hashes don't match, got {0}, but expected {1}" -f $Msys2HashChecked, $Msys2Hash)
|
||||
Exit 1
|
||||
}
|
||||
|
||||
Print-Msg -msg 'Extracting Msys2 archive...'
|
||||
$null = & "$archivePath" '-y' ('-o{0}' -f $GhcupDir) # Extract
|
||||
@@ -448,7 +459,7 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
|
||||
Print-Msg -msg 'Processing MSYS2 bash for first time use...'
|
||||
Exec "$Bash" '-lc' 'exit'
|
||||
|
||||
Exec "$env:windir\system32\taskkill.exe" /F /FI `"MODULES eq msys-2.0.dll`"
|
||||
Exec "$env:windir\system32\taskkill.exe" /F /FI "MODULES eq msys-2.0.dll"
|
||||
|
||||
Print-Msg -msg 'Upgrading full system...'
|
||||
Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu'
|
||||
|
||||
67
scripts/releasing/create-yaml-snippet.sh
Normal file
67
scripts/releasing/create-yaml-snippet.sh
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
RELEASE=$1
|
||||
|
||||
get_sha() {
|
||||
sha256sum "$1" | awk '{ print $1 }'
|
||||
}
|
||||
|
||||
cd "gh-release-artifacts/v${RELEASE}"
|
||||
|
||||
cat <<EOF > /dev/stdout
|
||||
GHCup:
|
||||
${RELEASE}:
|
||||
viTags:
|
||||
- Recommended
|
||||
- Latest
|
||||
viChangeLog: https://github.com/haskell/ghcup-hs/blob/master/CHANGELOG.md
|
||||
viSourceDL:
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/ghcup-${RELEASE}-src.tar.gz
|
||||
dlSubdir: ghcup-${RELEASE}
|
||||
dlHash: $(get_sha "ghcup-${RELEASE}-src.tar.gz")
|
||||
viArch:
|
||||
A_64:
|
||||
Linux_UnknownLinux:
|
||||
unknown_versioning: &ghcup-64
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/x86_64-linux-ghcup-${RELEASE}
|
||||
dlHash: $(get_sha "x86_64-linux-ghcup-${RELEASE}")
|
||||
Darwin:
|
||||
unknown_versioning:
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/x86_64-apple-darwin-ghcup-${RELEASE}
|
||||
dlHash: $(get_sha "x86_64-apple-darwin-ghcup-${RELEASE}")
|
||||
FreeBSD:
|
||||
unknown_versioning:
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/x86_64-portbld-freebsd-ghcup-${RELEASE}
|
||||
dlHash: $(get_sha "x86_64-portbld-freebsd-ghcup-${RELEASE}")
|
||||
Windows:
|
||||
unknown_versioning:
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/x86_64-mingw64-ghcup-${RELEASE}.exe
|
||||
dlHash: $(get_sha "x86_64-mingw64-ghcup-${RELEASE}.exe")
|
||||
Linux_Alpine:
|
||||
unknown_versioning: *ghcup-64
|
||||
A_32:
|
||||
Linux_UnknownLinux:
|
||||
unknown_versioning: &ghcup-32
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/i386-linux-ghcup-${RELEASE}
|
||||
dlHash: $(get_sha "i386-linux-ghcup-${RELEASE}")
|
||||
Linux_Alpine:
|
||||
unknown_versioning: *ghcup-32
|
||||
A_ARM64:
|
||||
Linux_UnknownLinux:
|
||||
unknown_versioning:
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/aarch64-linux-ghcup-${RELEASE}
|
||||
dlHash: $(get_sha "aarch64-linux-ghcup-${RELEASE}")
|
||||
Darwin:
|
||||
unknown_versioning:
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/aarch64-apple-darwin-ghcup-${RELEASE}
|
||||
dlHash: $(get_sha "aarch64-apple-darwin-ghcup-${RELEASE}")
|
||||
A_ARM:
|
||||
Linux_UnknownLinux:
|
||||
unknown_versioning:
|
||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/armv7-linux-ghcup-${RELEASE}
|
||||
dlHash: $(get_sha "armv7-linux-ghcup-${RELEASE}")
|
||||
EOF
|
||||
|
||||
@@ -29,7 +29,7 @@ gh release download "$RELEASE"
|
||||
|
||||
# cirrus
|
||||
curl -L -o "x86_64-portbld-freebsd-ghcup-${TAG}" \
|
||||
"https://api.cirrus-ci.com/v1/artifact/github/haskell/ghcup-hs/build/binaries/out/x86_64-portbld-freebsd-ghcup-${RELEASE}?branch=${RELEASE}"
|
||||
"https://api.cirrus-ci.com/v1/artifact/github/haskell/ghcup-hs/build/binaries/out/x86_64-portbld-freebsd-ghcup-${TAG}?branch=${RELEASE}"
|
||||
|
||||
sha256sum ./*-ghcup-* > SHA256SUMS
|
||||
gpg --detach-sign -u "${SIGNER}" SHA256SUMS
|
||||
|
||||
@@ -183,6 +183,10 @@ instance Arbitrary GHCupInfo where
|
||||
arbitrary = genericArbitrary
|
||||
shrink = genericShrink
|
||||
|
||||
instance Arbitrary GHCTargetVersion where
|
||||
arbitrary = GHCTargetVersion Nothing <$> arbitrary
|
||||
shrink = genericShrink
|
||||
|
||||
|
||||
-- our maps are nested... the default size easily blows up most ppls ram
|
||||
|
||||
|
||||
Reference in New Issue
Block a user