Compare commits
397 Commits
issue-367-
...
issue-982
| Author | SHA1 | Date | |
|---|---|---|---|
| 96f7aa5c62 | |||
| c2186bb33c | |||
| 1a9d43ea1a | |||
| 9de324d3c3 | |||
| b53acfe61f | |||
|
|
c92f71471d | ||
| 2a79c669a5 | |||
| 9b2d326c38 | |||
| 2bfca3760c | |||
| 0f7f5347d8 | |||
| 80703d7b29 | |||
| 942685f396 | |||
| 02744ff4a0 | |||
| c74409b9a5 | |||
| 1c32dbc88a | |||
| ab17270761 | |||
| d0538a50e0 | |||
| 318ac21e41 | |||
| 3e9bb7c369 | |||
| 2c64cd0f02 | |||
| 59e6b65249 | |||
| 91ef2c7666 | |||
| 935cb5541b | |||
| 9a7eb11c73 | |||
| 4b338ccfd8 | |||
| ca92b29ffe | |||
| ec4e69e89d | |||
| c225f2cfee | |||
| e325728f38 | |||
| c9a44d211e | |||
| 4b3ffd8570 | |||
| 3e9746cf0c | |||
| 950155cbe3 | |||
| dd978ff2fd | |||
| 4bbaffaa6f | |||
| 2a12362e75 | |||
| 411ac8dc31 | |||
| b837a93176 | |||
| 1c56e782d2 | |||
| c6c61ca486 | |||
| 6ae312c1f9 | |||
| f6cf4cb90c | |||
| 3ff65219e8 | |||
| e33f554838 | |||
| 2850f343b9 | |||
|
|
8d6445c632 | ||
|
|
de611e0d4e | ||
|
|
6fec9d4737 | ||
|
|
856e48aa14 | ||
|
|
2cafd9d2bc | ||
|
|
87ec8c756f | ||
| 2ece023c0f | |||
| 16e20ed474 | |||
| afd7e7dc4f | |||
| d46bdbf959 | |||
| cac3cec135 | |||
| 4e0efff4c4 | |||
| 71b7c96ddd | |||
| 5ff61cdf86 | |||
| 7d0ba7fc62 | |||
| bfe56aed1f | |||
| a1103c05a5 | |||
| 125125b9db | |||
| 4eec582f1b | |||
| e969489ca2 | |||
| ec4a657b42 | |||
| 55030d83da | |||
|
|
dfe213824f | ||
| c680a9f33b | |||
| df192ee18e | |||
|
|
008def2ff4 | ||
|
|
3976daddb7 | ||
| 524cdbbeb1 | |||
| a01c5acfe2 | |||
|
|
6689312ac5 | ||
| e214695a3e | |||
|
|
9d7f99bd00 | ||
| 3cea6ef97c | |||
| 3b0f131a65 | |||
|
|
e0a3020e34 | ||
|
|
0e46b9509a | ||
|
|
d3474d0cd9 | ||
|
|
5c3dad1bb9 | ||
|
|
987cdaf313 | ||
|
|
835352428a | ||
|
|
8f4246e716 | ||
|
|
1353a2fd20 | ||
|
|
aa9fbdbfc2 | ||
| 3a8cdf9967 | |||
| 2caf491e9d | |||
| d277e56121 | |||
| 335099ad19 | |||
| b1106985ec | |||
| cd8ce9aaa9 | |||
| 18f0cb086b | |||
| dee54445bf | |||
|
|
2df59fd1b3 | ||
| 2e5dee8e1a | |||
| c6aa5c3ed7 | |||
| 47ef380ebd | |||
| d6601b0353 | |||
| 0eba225723 | |||
| e7d91d138b | |||
| 0103e2771e | |||
| b6246734e4 | |||
| 6146c3494f | |||
| e5a7a2da70 | |||
| 6047614a16 | |||
| 6a86e9e77e | |||
| 4132447e04 | |||
| 9d223730de | |||
| ad9199568b | |||
| 0d91c2ac14 | |||
| 8644ca41e1 | |||
|
|
6051c0cfbc | ||
| 67d977ce39 | |||
| 8b6b3d2fbe | |||
| a5d228ba89 | |||
| a7be1e7068 | |||
| 30a10d871a | |||
| 90b0281c1c | |||
|
|
bba92baeb1 | ||
| e06a1c03d4 | |||
| 0171f2e870 | |||
| da078c7362 | |||
| 94b4b7c455 | |||
| 6aa486594a | |||
| 2c3148abcc | |||
| dde32fa72e | |||
| 675ab17fff | |||
| 9fcacbd96b | |||
| ba4c6e5b99 | |||
| f2b139b58b | |||
| a44bf5884d | |||
| 64c1d63d33 | |||
| 0300d8f2cc | |||
|
|
bb395b652d | ||
| 59bfdd9a30 | |||
| d85accb08e | |||
| c7439d3c89 | |||
| 38cd5ad8ed | |||
| 5fd0fa8d8e | |||
| 452ca8cca2 | |||
| 5f73320b29 | |||
| d14526059b | |||
| b1cde06bd0 | |||
| 0adb602a96 | |||
| f9a2b21cb0 | |||
| e73cf4033e | |||
| 5f0c6f60b8 | |||
| 29c9611152 | |||
| e90ca97441 | |||
| 1fb0387101 | |||
|
|
1981a12e67 | ||
|
|
eae197ccb3 | ||
|
|
15c6ed2b8d | ||
| fbb648d984 | |||
|
|
c914a284de | ||
| 9a17eaa32a | |||
| 480d6be02f | |||
| 3e907bd890 | |||
|
|
d999c3dfbf | ||
| 41d44b037d | |||
| 9d8d6e3293 | |||
|
|
8696a1c710 | ||
| 2f107197d4 | |||
| 486a1bac25 | |||
| a73ce186b5 | |||
| 76204aa366 | |||
| 502f0ea62f | |||
| e7e6663017 | |||
| e27fed09f3 | |||
| 9eeac00714 | |||
| c0ffb22d6a | |||
| f0b145d8dd | |||
| bb700281a3 | |||
|
|
fcdec4ba2c | ||
| 371eda962f | |||
| 50252d8613 | |||
| 78c393a16e | |||
| 9c3478075f | |||
| 7e7c11fda4 | |||
| bff14761ac | |||
| 99ddcc938f | |||
| e2301e2fa7 | |||
| c52096671e | |||
| 64f03a2f18 | |||
|
|
a72b78ef96 | ||
|
|
b17849c258 | ||
| d759535faa | |||
|
|
c25c07aa61 | ||
|
|
5f361e1e0b | ||
|
|
bcb498de20 | ||
|
|
fd6ff9f8ec | ||
|
|
69d311f0b4 | ||
|
|
fde0e712ac | ||
|
|
c60aa767ca | ||
|
|
78df858ba1 | ||
|
|
f1f4d5e836 | ||
|
|
2726e83235 | ||
|
|
f23631054a | ||
|
|
9189f9a65a | ||
|
|
7076472bde | ||
| a2a605ad89 | |||
|
|
8fae9a5083 | ||
|
|
6f07b6a343 | ||
|
|
dfebfc9504 | ||
|
|
36463ebf97 | ||
|
|
f400f43b8c | ||
| a3748507ca | |||
|
|
c92875882a | ||
|
|
2df2e3da40 | ||
|
|
cf1e8659b0 | ||
|
|
fb2e3f2740 | ||
| 578162f461 | |||
|
|
29bc40f65b | ||
|
|
aafb77df7c | ||
|
|
dc1a813305 | ||
|
|
16c7ecabe2 | ||
|
|
e1d8ba869a | ||
|
|
38db038953 | ||
|
|
bcdf2b23f1 | ||
|
|
83b82c328b | ||
| c149ee8d2b | |||
|
|
c10924274d | ||
|
|
e13c5a99af | ||
| 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 | |||
| 6e1380ef2e | |||
| 3e83a7fd83 | |||
| 34ac9cec4d | |||
| 513f7446b3 | |||
| aed478153d | |||
| 210816769a | |||
| 42bf21c86e | |||
| 4b34cddcda | |||
| 1ba2361fea | |||
| 278a3005d1 | |||
|
|
78d68e381a | ||
| 17ffc459db | |||
| afcb482866 | |||
|
c28de19faa
|
|||
|
7ae952c82e
|
|||
|
|
98098035c9 | ||
|
acdc0786ba
|
|||
|
7fa72a8892
|
|||
|
fa22920e51
|
|||
|
f084fbce43
|
|||
|
|
1850c00e9d | ||
|
c20deceaa8
|
|||
|
89e4145baf
|
|||
|
|
f5f7c26d8a | ||
|
784942ca58
|
|||
|
75de2a7bc1
|
|||
|
ea6c8d338c
|
|||
|
ae625b181c
|
|||
|
89ae54a083
|
|||
|
1bd73591ba
|
|||
|
f709f6e714
|
|||
|
3d7e07c371
|
|||
|
8bf17379ac
|
|||
|
4b1225ad71
|
|||
|
d628848af6
|
|||
|
48381be001
|
|||
|
b547324253
|
|||
|
2b1599c234
|
|||
|
7ac8989dfc
|
|||
|
cd6666ed30
|
|||
|
5b7478438a
|
|||
|
4a830d9fb7
|
|||
|
785fb895b4
|
|||
|
75e801e9e6
|
|||
|
6ffd5328a4
|
|||
|
ed509e482b
|
|||
|
420323f43b
|
|||
|
432962792c
|
|||
|
cb193f6069
|
|||
|
2f268b6a25
|
|||
|
580606af14
|
|||
|
faa1c3992b
|
|||
|
d17efef853
|
|||
|
179d4dd493
|
|||
|
e03c5ee4a1
|
|||
|
e57a8abd3d
|
|||
|
5fa10390a3
|
|||
|
e1e6f579d5
|
|||
|
72f8e53344
|
|||
|
9c464ec9fc
|
|||
|
1c9b296a5e
|
|||
|
|
275522584e | ||
|
|
804520c4bb | ||
|
|
9d25581f3c | ||
|
|
e798037d80 | ||
|
|
2afe5858cb | ||
|
f575dcdad6
|
|||
|
6cf9967e7c
|
|||
|
15a75d790a
|
|||
|
988672ea75
|
|||
|
6d3e8d65e1
|
|||
|
895e4b3f18
|
|||
|
20f0505120
|
|||
|
31e83cac5e
|
|||
|
|
9baba88f75 | ||
|
d3a1115b99
|
|||
|
6d46849fec
|
|||
|
53e324bfee
|
|||
|
2e39b7b603
|
|||
|
048932bf50
|
|||
|
69d325bf90
|
|||
|
3d1b8859cd
|
|||
|
db89ca9942
|
|||
|
bba009d98c
|
|||
|
9d954ea174
|
|||
|
da9c9049d2
|
|||
|
a4c00d2c56
|
|||
|
|
b30f565871 | ||
|
|
fa378a1d34 | ||
|
|
119efb1ff4 | ||
|
1fb4101b49
|
|||
|
ec8333b223
|
|||
|
54b979aa0b
|
|||
|
ba274307c0
|
|||
|
|
a623d0809d | ||
|
e00899d176
|
|||
|
a38ca1954b
|
|||
|
3f5a19c63e
|
|||
|
525e9672e8
|
|||
|
070c6e1cf1
|
|||
|
195fd00e0a
|
|||
|
733d014c19
|
|||
|
16039769d5
|
|||
|
5eeb8ca9fc
|
|||
|
317a06bbc3
|
|||
|
f693adcd7c
|
|||
|
ac88d2bd50
|
|||
|
a427146de5
|
|||
|
a16bcddeaa
|
|||
|
74edf1fc07
|
|||
|
1e32639873
|
|||
|
0704d2640a
|
|||
|
26a6368d79
|
|||
|
54af66d115
|
|||
|
850799c21a
|
|||
| d4834d7541 | |||
|
2895dd9d13
|
|||
|
eb9a0b66c4
|
|||
|
8d0432b961
|
|||
|
ab2c01d1c9
|
|||
|
fffaa65b7f
|
|||
|
703be0a706
|
|||
|
4be97ffd7c
|
|||
|
009f9211a9
|
|||
|
109187eb6f
|
|||
|
e881705323
|
|||
|
ea06c155a7
|
|||
|
d4732e15a7
|
|||
|
db6f784a1f
|
|||
|
24c36ef856
|
|||
|
2783b8f693
|
|||
|
d5a680e3c6
|
|||
|
e116a2392e
|
|||
|
7dd6f1f4a4
|
|||
|
4d82c37539
|
23
.cirrus.yml
23
.cirrus.yml
@@ -1,23 +0,0 @@
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-1
|
||||
|
||||
task:
|
||||
env:
|
||||
GHC_VER: 9.2.4
|
||||
CABAL_VER: 3.6.2.0
|
||||
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
||||
ARCH: 64
|
||||
RUNNER_OS: FreeBSD
|
||||
DISTRO: na
|
||||
GITHUB_WORKSPACE: ${CIRRUS_WORKING_DIR}
|
||||
JSON_VERSION: "0.0.7"
|
||||
CIRRUS_CLONE_SUBMODULES: true
|
||||
AWS_ACCESS_KEY_ID: ENCRYPTED[3e99c4ac040871f213abd616ec66952d954dc289cdd97772f88e58a74d08a2250133437780fe98b7aedf7ef1fb32f5eb]
|
||||
AWS_SECRET_ACCESS_KEY: ENCRYPTED[5910cfd77a922ff7fc06eeb6a6b9f79d4867863e541f06eb2c4cfecae0613650e3e0588373fa8d9249d295d76cf9cb3b]
|
||||
S3_HOST: ENCRYPTED[ce961780a33159f7d1d8046956b5ac6ebc3bfc8149428e5f538576cda51d9f3d0c35b79cdd1e325793639ff6e31f889d]
|
||||
install_script: pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake
|
||||
script:
|
||||
- bash .github/scripts/build.sh
|
||||
- bash .github/scripts/test.sh
|
||||
binaries_artifacts:
|
||||
path: "out/*"
|
||||
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@@ -0,0 +1,11 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = LF
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.hs]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
max_line_length = 80
|
||||
4
.github/scripts/bootstrap.sh
vendored
4
.github/scripts/bootstrap.sh
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
set -eux
|
||||
|
||||
. .github/scripts/prereq.sh
|
||||
. .github/scripts/env.sh
|
||||
|
||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||
|
||||
@@ -13,4 +13,6 @@ git describe --always
|
||||
./scripts/bootstrap/bootstrap-haskell
|
||||
|
||||
[ "$(ghc --numeric-version)" = "${BOOTSTRAP_HASKELL_GHC_VERSION}" ]
|
||||
# https://github.com/actions/runner-images/issues/7061
|
||||
[ "$(ghcup config | grep --color=never meta-mode)" = "meta-mode: Lax" ]
|
||||
|
||||
|
||||
27
.github/scripts/brew.sh
vendored
Normal file
27
.github/scripts/brew.sh
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
. .github/scripts/env.sh
|
||||
|
||||
if [ -e "$HOME/.brew" ] ; then
|
||||
(
|
||||
cd "$HOME/.brew"
|
||||
git fetch --depth 1
|
||||
git reset --hard origin/master
|
||||
)
|
||||
else
|
||||
git clone --depth=1 https://github.com/Homebrew/brew "$HOME/.brew"
|
||||
fi
|
||||
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH"
|
||||
|
||||
mkdir -p $CI_PROJECT_DIR/.brew_cache
|
||||
export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
||||
mkdir -p $CI_PROJECT_DIR/.brew_logs
|
||||
export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
||||
mkdir -p /private/tmp/.brew_tmp
|
||||
export HOMEBREW_TEMP=/private/tmp/.brew_tmp
|
||||
|
||||
brew update
|
||||
brew install ${1+"$@"}
|
||||
|
||||
77
.github/scripts/build.sh
vendored
77
.github/scripts/build.sh
vendored
@@ -2,75 +2,36 @@
|
||||
|
||||
set -eux
|
||||
|
||||
. .github/scripts/prereq.sh
|
||||
. .github/scripts/common.sh
|
||||
|
||||
|
||||
# ensure ghcup
|
||||
if ! command -v ghcup ; then
|
||||
install_ghcup
|
||||
fi
|
||||
|
||||
# ensure cabal-cache
|
||||
if ! cabal-cache version ; then
|
||||
download_cabal_cache "$HOME/.local/bin/cabal-cache"
|
||||
fi
|
||||
|
||||
# ensure ghc
|
||||
if [ "${RUNNER_OS}" != "FreeBSD" ] ; then
|
||||
if [ "${DISTRO}" != "Debian" ] ; then # ! armv7 or aarch64 linux
|
||||
if ! "ghc-${GHC_VER}" --numeric-version ; then
|
||||
ghcup -v install ghc --set --force "$GHC_VER"
|
||||
fi
|
||||
if [ "$(cabal --numeric-version || true)" != "${CABAL_VER}" ] ; then
|
||||
ghcup -v install cabal --force "$CABAL_VER"
|
||||
fi
|
||||
ghc --version
|
||||
cabal --version
|
||||
GHC="ghc-${GHC_VER}"
|
||||
else
|
||||
if [ "$(cabal --numeric-version || true)" != "${CABAL_VER}" ] ; then
|
||||
ghcup -v install cabal --force "$CABAL_VER"
|
||||
fi
|
||||
cabal --version
|
||||
GHC="ghc"
|
||||
fi
|
||||
else
|
||||
ghc --version
|
||||
cabal --version
|
||||
GHC="ghc"
|
||||
fi
|
||||
|
||||
git_describe
|
||||
|
||||
# ensure ghcup
|
||||
install_ghcup
|
||||
|
||||
# ensure cabal-cache
|
||||
download_cabal_cache "$HOME/.local/bin/cabal-cache"
|
||||
|
||||
# install toolchain (if necessary)
|
||||
ghcup -v install ghc --set --force "$GHC_VER"
|
||||
ghcup -v install cabal --force "$CABAL_VER"
|
||||
ghc --version
|
||||
cabal --version
|
||||
GHC="ghc-${GHC_VER}"
|
||||
|
||||
# build
|
||||
ecabal update
|
||||
|
||||
if [ "${RUNNER_OS}" = "Linux" ] ; then
|
||||
if [ "${ARCH}" = "32" ] ; then
|
||||
build_with_cache -w "${GHC}" --ghc-options='-split-sections -optl-static' -ftui --enable-tests
|
||||
elif [ "${ARCH}" = "64" ] ; then
|
||||
build_with_cache -w "${GHC}" --ghc-options='-split-sections -optl-static' -ftui --enable-tests
|
||||
else
|
||||
build_with_cache -w "${GHC}" -ftui --enable-tests
|
||||
fi
|
||||
elif [ "${RUNNER_OS}" = "FreeBSD" ] ; then
|
||||
build_with_cache -w "${GHC}" --ghc-options='-split-sections' --constraint="zlib +bundled-c-zlib" --constraint="zip +disable-zstd" -ftui --enable-tests
|
||||
elif [ "${RUNNER_OS}" = "Windows" ] ; then
|
||||
build_with_cache -w "${GHC}" --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" --enable-tests
|
||||
else
|
||||
build_with_cache -w "${GHC}" --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" -ftui --enable-tests
|
||||
fi
|
||||
|
||||
build_with_cache --project-file=cabal.project.release -w "${GHC}" --enable-tests
|
||||
|
||||
# set up artifacts
|
||||
mkdir -p out
|
||||
binary=$(cabal list-bin ghcup)
|
||||
binary_test=$(cabal list-bin ghcup-test)
|
||||
binary=$(cabal --project-file=cabal.project.release list-bin ghcup)
|
||||
binary_test=$(cabal --project-file=cabal.project.release list-bin ghcup-test)
|
||||
binary_opttest=$(cabal --project-file=cabal.project.release list-bin ghcup-optparse-test)
|
||||
ver=$("${binary}" --numeric-version)
|
||||
strip_binary "${binary}"
|
||||
cp "${binary}" "out/${ARTIFACT}-${ver}"
|
||||
cp "${binary_test}" "out/test-${ARTIFACT}-${ver}"
|
||||
cp "${binary}" "out/${ARTIFACT}-${ver}${ext}"
|
||||
cp "${binary_test}" "out/test-${ARTIFACT}-${ver}${ext}"
|
||||
cp "${binary_opttest}" "out/test-optparse-${ARTIFACT}-${ver}${ext}"
|
||||
cp ./dist-newstyle/cache/plan.json "out/${ARTIFACT}.plan.json"
|
||||
|
||||
|
||||
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)"
|
||||
|
||||
86
.github/scripts/common.sh
vendored
86
.github/scripts/common.sh
vendored
@@ -1,23 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${RUNNER_OS}" = "Windows" ] ; then
|
||||
ext=".exe"
|
||||
else
|
||||
ext=''
|
||||
fi
|
||||
. .github/scripts/env.sh
|
||||
|
||||
ecabal() {
|
||||
cabal "$@"
|
||||
}
|
||||
|
||||
sync_from_retry() {
|
||||
if [ "${RUNNER_OS}" != "Windows" ] ; then
|
||||
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
||||
else
|
||||
cabal_store_path="${CABAL_DIR}/store"
|
||||
fi
|
||||
|
||||
sync_from || { sleep 9 ; rm -rf "${cabal_store_path:?}"/* ; sync_from || { sleep 20 ; rm -rf "${cabal_store_path:?}"/* ; sync_from ; } }
|
||||
nonfatal() {
|
||||
"$@" || "$* failed"
|
||||
}
|
||||
|
||||
sync_from() {
|
||||
@@ -25,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 \
|
||||
@@ -34,16 +24,12 @@ sync_from() {
|
||||
--archive-uri "s3://ghcup-hs/${RUNNER_OS}-${ARCH}-${DISTRO}"
|
||||
}
|
||||
|
||||
sync_to_retry() {
|
||||
sync_to || { sleep 9 ; sync_to || { sleep 20 ; sync_to ; } }
|
||||
}
|
||||
|
||||
sync_to() {
|
||||
if [ "${RUNNER_OS}" != "Windows" ] ; then
|
||||
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 \
|
||||
@@ -58,7 +44,7 @@ raw_eghcup() {
|
||||
|
||||
eghcup() {
|
||||
if [ "${OS}" = "Windows" ] ; then
|
||||
"$GHCUP_BIN/ghcup${ext}" -c -s "file:/$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$@"
|
||||
"$GHCUP_BIN/ghcup${ext}" -c -s "file:${GITHUB_WORKSPACE//\\//}/data/metadata/ghcup-${JSON_VERSION}.yaml" "$@"
|
||||
else
|
||||
"$GHCUP_BIN/ghcup${ext}" -c -s "file://$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$@"
|
||||
fi
|
||||
@@ -81,6 +67,7 @@ git_describe() {
|
||||
download_cabal_cache() {
|
||||
(
|
||||
set -e
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
dest="$HOME/.local/bin/cabal-cache"
|
||||
url=""
|
||||
exe=""
|
||||
@@ -88,28 +75,28 @@ download_cabal_cache() {
|
||||
case "${RUNNER_OS}" in
|
||||
"Linux")
|
||||
case "${ARCH}" in
|
||||
"32") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental4/i386-linux-cabal-cache
|
||||
"32") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/i386-linux-cabal-cache
|
||||
;;
|
||||
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental4/x86_64-linux-cabal-cache
|
||||
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/x86_64-linux-cabal-cache
|
||||
;;
|
||||
"ARM64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental4/aarch64-linux-cabal-cache
|
||||
"ARM64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/aarch64-linux-cabal-cache
|
||||
;;
|
||||
"ARM") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental4/armv7-linux-cabal-cache
|
||||
"ARM") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/armv7-linux-cabal-cache
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"FreeBSD")
|
||||
url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental4/x86_64-portbld-freebsd-cabal-cache
|
||||
url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/x86_64-portbld-freebsd-cabal-cache
|
||||
;;
|
||||
"Windows")
|
||||
exe=".exe"
|
||||
url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental4/x86_64-mingw64-cabal-cache
|
||||
url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/x86_64-mingw64-cabal-cache
|
||||
;;
|
||||
"macOS")
|
||||
case "${ARCH}" in
|
||||
"ARM64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental4/aarch64-apple-darwin-cabal-cache
|
||||
"ARM64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/aarch64-apple-darwin-cabal-cache
|
||||
;;
|
||||
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental4/x86_64-apple-darwin-cabal-cache
|
||||
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/x86_64-apple-darwin-cabal-cache
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@@ -128,31 +115,46 @@ 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
|
||||
)
|
||||
}
|
||||
|
||||
build_with_cache() {
|
||||
ecabal configure "$@"
|
||||
ecabal build --dependencies-only "$@" --dry-run
|
||||
sync_from_retry
|
||||
ecabal build --dependencies-only "$@" || sync_to_retry
|
||||
sync_to_retry
|
||||
sync_from
|
||||
ecabal build --dependencies-only "$@" || sync_to
|
||||
sync_to
|
||||
ecabal build "$@"
|
||||
sync_to_retry
|
||||
sync_to
|
||||
}
|
||||
|
||||
install_ghcup() {
|
||||
find "$GHCUP_INSTALL_BASE_PREFIX"
|
||||
mkdir -p "$GHCUP_BIN"
|
||||
mkdir -p "$GHCUP_BIN"/../cache
|
||||
case "${RUNNER_OS}" in
|
||||
"Linux")
|
||||
case "${ARCH}" in
|
||||
"ARM"*)
|
||||
if command -v ghcup ; then
|
||||
mkdir -p "$GHCUP_BIN"
|
||||
cp "$(command -v ghcup)" "$GHCUP_BIN/ghcup${ext}"
|
||||
else
|
||||
install_ghcup_curl_sh
|
||||
fi
|
||||
;;
|
||||
*) install_ghcup_curl_sh
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*) install_ghcup_curl_sh
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ "${RUNNER_OS}" = "FreeBSD" ] ; then
|
||||
curl -o ghcup https://downloads.haskell.org/ghcup/tmp/x86_64-portbld-freebsd-ghcup-0.1.18.1
|
||||
chmod +x ghcup
|
||||
mv ghcup "$HOME/.local/bin/ghcup"
|
||||
else
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
|
||||
fi
|
||||
install_ghcup_curl_sh() {
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 BOOTSTRAP_HASKELL_INSTALL_NO_STACK=yes sh
|
||||
}
|
||||
|
||||
strip_binary() {
|
||||
|
||||
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 ]
|
||||
|
||||
34
.github/scripts/env.sh
vendored
Normal file
34
.github/scripts/env.sh
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${RUNNER_OS}" = "Windows" ] ; then
|
||||
ext=".exe"
|
||||
else
|
||||
ext=''
|
||||
fi
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export TZ=Asia/Singapore
|
||||
|
||||
if [ "${RUNNER_OS}" = "freebsd" ] ; then
|
||||
export RUNNER_OS=FreeBSD
|
||||
fi
|
||||
|
||||
export OS="$RUNNER_OS"
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
if [ "${RUNNER_OS}" = "Windows" ] ; then
|
||||
# on windows use pwd to get unix style path
|
||||
CI_PROJECT_DIR="$(pwd)"
|
||||
export CI_PROJECT_DIR
|
||||
export GHCUP_INSTALL_BASE_PREFIX="/c"
|
||||
export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin"
|
||||
export PATH="$GHCUP_BIN:$PATH"
|
||||
export CABAL_DIR="C:\\Users\\runneradmin\\AppData\\Roaming\\cabal"
|
||||
else
|
||||
export CI_PROJECT_DIR="${GITHUB_WORKSPACE}"
|
||||
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
||||
export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/.ghcup/bin"
|
||||
export PATH="$GHCUP_BIN:$PATH"
|
||||
export CABAL_DIR="$CI_PROJECT_DIR/cabal"
|
||||
export CABAL_CACHE="$CI_PROJECT_DIR/cabal-cache"
|
||||
fi
|
||||
7
.github/scripts/hls.sh
vendored
7
.github/scripts/hls.sh
vendored
@@ -2,7 +2,6 @@
|
||||
|
||||
set -eux
|
||||
|
||||
. .github/scripts/prereq.sh
|
||||
. .github/scripts/common.sh
|
||||
|
||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||
@@ -34,7 +33,7 @@ sha_sum "$(raw_eghcup --offline whereis ghcup)"
|
||||
git_describe
|
||||
|
||||
eghcup install ghc "${GHC_VERSION}"
|
||||
eghcup install cabal
|
||||
eghcup install cabal "${CABAL_VERSION}"
|
||||
|
||||
ecabal update
|
||||
|
||||
@@ -57,9 +56,9 @@ eghcup debug-info
|
||||
cd "haskell-language-server-${HLS_TARGET_VERSION}/"
|
||||
ecabal configure -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)"
|
||||
ecabal build --dependencies-only -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)" --dry-run
|
||||
sync_from_retry
|
||||
sync_from
|
||||
ecabal build --dependencies-only -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)" || sync_to
|
||||
sync_to_retry
|
||||
sync_to
|
||||
)
|
||||
|
||||
eghcup -v compile hls -j "$(nproc)" -g "${HLS_TARGET_VERSION}" --ghc "${GHC_VERSION}"
|
||||
|
||||
66
.github/scripts/prereq.sh
vendored
66
.github/scripts/prereq.sh
vendored
@@ -1,66 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
mkdir -p "$HOME"/.local/bin
|
||||
|
||||
export OS="$RUNNER_OS"
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
: "${APT_GET:=apt-get}"
|
||||
|
||||
if [ "${RUNNER_OS}" = "Windows" ] ; then
|
||||
# on windows use pwd to get unix style path
|
||||
CI_PROJECT_DIR="$(pwd)"
|
||||
export CI_PROJECT_DIR
|
||||
export GHCUP_INSTALL_BASE_PREFIX="/c"
|
||||
export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin"
|
||||
export PATH="$GHCUP_BIN:$PATH"
|
||||
export CABAL_DIR="C:\\Users\\runneradmin\\AppData\\Roaming\\cabal"
|
||||
else
|
||||
export CI_PROJECT_DIR="${GITHUB_WORKSPACE}"
|
||||
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
||||
export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/.ghcup/bin"
|
||||
export PATH="$GHCUP_BIN:$PATH"
|
||||
export CABAL_DIR="$CI_PROJECT_DIR/cabal"
|
||||
export CABAL_CACHE="$CI_PROJECT_DIR/cabal-cache"
|
||||
fi
|
||||
|
||||
if [ "${RUNNER_OS}" = "Linux" ] ; then
|
||||
if [ "${DISTRO}" = "Alpine" ] ; then
|
||||
:
|
||||
elif [ "${DISTRO}" = "Ubuntu" ] ; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export TZ=Asia/Singapore
|
||||
if [ "${ARCH}" = "ARM64" ] || [ "${ARCH}" = "ARM" ] ; then
|
||||
:
|
||||
else
|
||||
${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
|
||||
fi
|
||||
elif [ "${DISTRO}" = "Debian" ] ; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export TZ=Asia/Singapore
|
||||
${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 ghc gzip
|
||||
fi
|
||||
elif [ "${RUNNER_OS}" = "macOS" ] ; then
|
||||
if ! command -v brew ; then
|
||||
[ -e "$HOME/.brew" ] ||
|
||||
git clone --depth=1 https://github.com/Homebrew/brew "$HOME/.brew"
|
||||
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH"
|
||||
brew update
|
||||
fi
|
||||
if ! command -v git ; then
|
||||
brew install git
|
||||
fi
|
||||
if ! command -v realpath ; then
|
||||
brew install coreutils
|
||||
fi
|
||||
|
||||
if [ "${ARCH}" = "ARM64" ] ; then
|
||||
brew install llvm@11 autoconf automake
|
||||
export PATH="$HOME/.brew/opt/llvm@11/bin:$PATH"
|
||||
export CC="$HOME/.brew/opt/llvm@11/bin/clang"
|
||||
export CXX="$HOME/.brew/opt/llvm@11/bin/clang++"
|
||||
export LD=ld
|
||||
export AR="$HOME/.brew/opt/llvm@11/bin/llvm-ar"
|
||||
export RANLIB="$HOME/.brew/opt/llvm@11/bin/llvm-ranlib"
|
||||
fi
|
||||
fi
|
||||
|
||||
57
.github/scripts/test.sh
vendored
57
.github/scripts/test.sh
vendored
@@ -2,7 +2,6 @@
|
||||
|
||||
set -eux
|
||||
|
||||
. .github/scripts/prereq.sh
|
||||
. .github/scripts/common.sh
|
||||
|
||||
|
||||
@@ -12,6 +11,7 @@ else
|
||||
GHCUP_DIR="${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup
|
||||
fi
|
||||
|
||||
env
|
||||
git_describe
|
||||
|
||||
rm -rf "${GHCUP_DIR}"
|
||||
@@ -19,8 +19,10 @@ mkdir -p "${GHCUP_BIN}"
|
||||
|
||||
cp "out/${ARTIFACT}"-* "$GHCUP_BIN/ghcup${ext}"
|
||||
cp "out/test-${ARTIFACT}"-* "ghcup-test${ext}"
|
||||
cp "out/test-optparse-${ARTIFACT}"-* "ghcup-test-optparse${ext}"
|
||||
chmod +x "$GHCUP_BIN/ghcup${ext}"
|
||||
chmod +x "ghcup-test${ext}"
|
||||
chmod +x "ghcup-test-optparse${ext}"
|
||||
|
||||
"$GHCUP_BIN/ghcup${ext}" --version
|
||||
eghcup --version
|
||||
@@ -29,31 +31,38 @@ sha_sum "$(raw_eghcup --offline whereis ghcup)"
|
||||
|
||||
### Haskell test suite
|
||||
|
||||
./ghcup-test${ext}
|
||||
rm ghcup-test${ext}
|
||||
./"ghcup-test${ext}"
|
||||
./"ghcup-test-optparse${ext}"
|
||||
rm "ghcup-test${ext}" "ghcup-test-optparse${ext}"
|
||||
|
||||
### manual cli based testing
|
||||
|
||||
eghcup --numeric-version
|
||||
|
||||
eghcup install ghc ${GHC_VER}
|
||||
eghcup unset ghc ${GHC_VER}
|
||||
ls -lah "$(eghcup whereis -d ghc ${GHC_VER})"
|
||||
[ "`$(eghcup whereis ghc ${GHC_VER}) --numeric-version`" = "${GHC_VER}" ]
|
||||
[ "`eghcup run --ghc ${GHC_VER} -- ghc --numeric-version`" = "${GHC_VER}" ]
|
||||
[ "`ghcup run --ghc ${GHC_VER} -- ghc -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)'`" = "`$(ghcup whereis ghc ${GHC_VER}) -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)'`" ]
|
||||
eghcup set ghc ${GHC_VER}
|
||||
eghcup install cabal ${CABAL_VER}
|
||||
[ "`$(eghcup whereis cabal ${CABAL_VER}) --numeric-version`" = "${CABAL_VER}" ]
|
||||
# test PATH on windows wrt msys2
|
||||
# https://github.com/haskell/ghcup-hs/pull/992/checks
|
||||
if [ "${OS}" = "Windows" ] ; then
|
||||
eghcup run -m -- sh -c 'echo $PATH' | sed 's/:/\n/' | grep '^/mingw64/bin$'
|
||||
fi
|
||||
|
||||
eghcup install ghc "${GHC_VER}"
|
||||
eghcup unset ghc "${GHC_VER}"
|
||||
ls -lah "$(eghcup whereis -d ghc "${GHC_VER}")"
|
||||
[ "$($(eghcup whereis ghc "${GHC_VER}") --numeric-version)" = "${GHC_VER}" ]
|
||||
[ "$(eghcup run -q --ghc "${GHC_VER}" -- ghc --numeric-version)" = "${GHC_VER}" ]
|
||||
[ "$(ghcup run -q --ghc "${GHC_VER}" -- ghc -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)')" = "$($(ghcup whereis ghc "${GHC_VER}") -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)')" ]
|
||||
eghcup set ghc "${GHC_VER}"
|
||||
eghcup install cabal "${CABAL_VER}"
|
||||
[ "$($(eghcup whereis cabal "${CABAL_VER}") --numeric-version)" = "${CABAL_VER}" ]
|
||||
eghcup unset cabal
|
||||
"$GHCUP_BIN"/cabal --version && exit 1 || echo yes
|
||||
|
||||
# make sure no cabal is set when running 'ghcup run' to check that PATH propagages properly
|
||||
# https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
||||
[ "`eghcup run --cabal ${CABAL_VER} -- cabal --numeric-version`" = "${CABAL_VER}" ]
|
||||
eghcup set cabal ${CABAL_VER}
|
||||
[ "$(eghcup run -q --cabal "${CABAL_VER}" -- cabal --numeric-version)" = "${CABAL_VER}" ]
|
||||
eghcup set cabal "${CABAL_VER}"
|
||||
|
||||
[ "`$(eghcup whereis cabal ${CABAL_VER}) --numeric-version`" = "${CABAL_VER}" ]
|
||||
[ "$($(eghcup whereis cabal "${CABAL_VER}") --numeric-version)" = "${CABAL_VER}" ]
|
||||
|
||||
if [ "${OS}" != "FreeBSD" ] ; then
|
||||
if [ "${ARCH}" = "64" ] && [ "${DISTRO}" != "Alpine" ] ; then
|
||||
@@ -83,10 +92,10 @@ eghcup list -t cabal
|
||||
|
||||
ghc_ver=$(ghc --numeric-version)
|
||||
ghc --version
|
||||
ghc-${ghc_ver} --version
|
||||
"ghc-${ghc_ver}" --version
|
||||
if [ "${OS}" != "Windows" ] ; then
|
||||
ghci --version
|
||||
ghci-${ghc_ver} --version
|
||||
"ghci-${ghc_ver}" --version
|
||||
fi
|
||||
|
||||
|
||||
@@ -130,11 +139,11 @@ else
|
||||
eghcup --offline set 8.10.3
|
||||
eghcup set 8.10.3
|
||||
[ "$(ghc --numeric-version)" = "8.10.3" ]
|
||||
eghcup set ${GHC_VER}
|
||||
eghcup set "${GHC_VER}"
|
||||
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||
eghcup unset ghc
|
||||
"$GHCUP_BIN"/ghc --numeric-version && exit 1 || echo yes
|
||||
eghcup set ${GHC_VER}
|
||||
eghcup set "${GHC_VER}"
|
||||
eghcup --offline rm 8.10.3
|
||||
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||
|
||||
@@ -167,10 +176,10 @@ fi
|
||||
# check that lazy loading works for 'whereis'
|
||||
cp "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml.bak"
|
||||
echo '**' > "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml"
|
||||
eghcup whereis ghc $(ghc --numeric-version)
|
||||
eghcup whereis ghc "$(ghc --numeric-version)"
|
||||
mv -f "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml.bak" "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml"
|
||||
|
||||
eghcup rm $(ghc --numeric-version)
|
||||
eghcup rm "$(ghc --numeric-version)"
|
||||
|
||||
# https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/116
|
||||
if [ "${OS}" = "Linux" ] ; then
|
||||
@@ -184,14 +193,14 @@ eghcup gc -c
|
||||
|
||||
# test etags
|
||||
rm -f "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
||||
raw_eghcup -s https://www.haskell.org/ghcup/data/ghcup-${JSON_VERSION}.yaml list
|
||||
raw_eghcup -s "https://www.haskell.org/ghcup/data/ghcup-${JSON_VERSION}.yaml" list
|
||||
# snapshot yaml and etags file
|
||||
etag=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
||||
sha=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||
# invalidate access time timer, which is 5minutes, so we re-download
|
||||
touch -a -m -t '199901010101' "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
||||
# redownload same file with some newlines added
|
||||
raw_eghcup -s https://www.haskell.org/ghcup/exp/ghcup-${JSON_VERSION}.yaml list
|
||||
raw_eghcup -s https://raw.githubusercontent.com/haskell/ghcup-metadata/exp/ghcup-${JSON_VERSION}.yaml list
|
||||
# snapshot new yaml and etags file
|
||||
etag2=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
||||
sha2=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||
@@ -201,7 +210,7 @@ sha2=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||
# invalidate access time timer, which is 5minutes, but don't expect a re-download
|
||||
touch -a -m -t '199901010101' "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
||||
# this time, we expect the same hash and etag
|
||||
raw_eghcup -s https://www.haskell.org/ghcup/exp/ghcup-${JSON_VERSION}.yaml list
|
||||
raw_eghcup -s https://raw.githubusercontent.com/haskell/ghcup-metadata/exp/ghcup-${JSON_VERSION}.yaml list
|
||||
etag3=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
||||
sha3=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||
[ "${etag2}" = "${etag3}" ]
|
||||
|
||||
20
.github/workflows/bootstrap.yaml
vendored
20
.github/workflows/bootstrap.yaml
vendored
@@ -20,13 +20,12 @@ jobs:
|
||||
BOOTSTRAP_HASKELL_NONINTERACTIVE: yes
|
||||
ARCH: 64
|
||||
JSON_VERSION: "0.0.7"
|
||||
APT_GET: "sudo apt-get"
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
DISTRO: Ubuntu
|
||||
- os: macOS-10.15
|
||||
- os: macOS-11
|
||||
DISTRO: na
|
||||
- os: windows-latest
|
||||
DISTRO: na
|
||||
@@ -36,7 +35,15 @@ jobs:
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- if: runner.os != 'Windows'
|
||||
- if: runner.os == 'Linux'
|
||||
name: Run bootstrap
|
||||
run: |
|
||||
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
|
||||
sh ./.github/scripts/bootstrap.sh
|
||||
env:
|
||||
DISTRO: ${{ matrix.DISTRO }}
|
||||
|
||||
- if: runner.os == 'macOS'
|
||||
name: Run bootstrap
|
||||
run: sh ./.github/scripts/bootstrap.sh
|
||||
env:
|
||||
@@ -44,5 +51,10 @@ jobs:
|
||||
|
||||
- if: runner.os == 'Windows'
|
||||
name: Run bootstrap
|
||||
run: ./scripts/bootstrap/bootstrap-haskell.ps1 -InstallDir ${GITHUB_WORKSPACE} -BootstrapUrl ${GITHUB_WORKSPACE}/bootstrap-haskell -InBash
|
||||
run: |
|
||||
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
|
||||
$curDir = Get-Location
|
||||
Write-Host "Current Working Directory: $curDir"
|
||||
./scripts/bootstrap/bootstrap-haskell.ps1 -InstallDir ${GITHUB_WORKSPACE} -BootstrapUrl ("{0}/scripts/bootstrap/bootstrap-haskell" -f $curDir) -InBash -Msys2Env "MINGW64"
|
||||
shell: pwsh
|
||||
|
||||
|
||||
2
.github/workflows/cache.yaml
vendored
2
.github/workflows/cache.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
with:
|
||||
args: --recursive
|
||||
env:
|
||||
AWS_S3_ENDPOINT: ${{ secrets.S3_HOST }}
|
||||
AWS_S3_ENDPOINT: https://${{ secrets.S3_HOST }}
|
||||
AWS_S3_BUCKET: ghcup-hs
|
||||
AWS_REGION: us-west-2
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
|
||||
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: [self-hosted, Linux, X64, maerwald]
|
||||
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
|
||||
|
||||
83
.github/workflows/docker.yaml
vendored
83
.github/workflows/docker.yaml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
docker-alpine:
|
||||
docker-alpine32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -26,7 +26,24 @@ jobs:
|
||||
context: ./docker/alpine32
|
||||
push: true
|
||||
tags: hasufell/i386-alpine-haskell:3.12
|
||||
platforms: linux/i386
|
||||
platforms: |
|
||||
linux/i386
|
||||
linux/amd64
|
||||
|
||||
docker-alpine:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push (alpine 64bit)
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
@@ -35,34 +52,76 @@ jobs:
|
||||
tags: hasufell/alpine-haskell:3.12
|
||||
platforms: linux/amd64
|
||||
|
||||
docker-arm:
|
||||
runs-on: [self-hosted, Linux, aarch64]
|
||||
docker-arm32:
|
||||
runs-on: [self-hosted, Linux, ARM64]
|
||||
steps:
|
||||
- uses: docker://arm64v8/ubuntu:focal
|
||||
name: Cleanup
|
||||
name: Cleanup (aarch64 linux)
|
||||
continue-on-error: true
|
||||
with:
|
||||
args: rm -rf .ghcup/ cabal/ dist-newstyle/ out/
|
||||
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push (arm64v8)
|
||||
|
||||
- name: Build and push (debian buster)
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ./docker/arm64v8/
|
||||
context: ./docker/arm32v7/buster
|
||||
push: true
|
||||
tags: hasufell/arm64v8-ubuntu-haskell:focal
|
||||
platforms: linux/arm64
|
||||
- name: Build and push (arm32v7)
|
||||
tags: hasufell/arm32v7-debian-haskell:10
|
||||
platforms: linux/arm
|
||||
|
||||
- name: Build and push (ubuntu focal)
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ./docker/arm32v7
|
||||
context: ./docker/arm32v7/focal
|
||||
push: true
|
||||
tags: hasufell/arm32v7-ubuntu-haskell:focal
|
||||
platforms: linux/arm
|
||||
|
||||
docker-aarch:
|
||||
runs-on: [self-hosted, Linux, ARM64]
|
||||
steps:
|
||||
- uses: docker://arm64v8/ubuntu:focal
|
||||
name: Cleanup (aarch64 linux)
|
||||
continue-on-error: true
|
||||
with:
|
||||
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push (debian buster)
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ./docker/arm64v8/buster
|
||||
push: true
|
||||
tags: hasufell/arm64v8-debian-haskell:10
|
||||
platforms: linux/arm64
|
||||
|
||||
- name: Build and push (ubuntu focal)
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ./docker/arm64v8/focal
|
||||
push: true
|
||||
tags: hasufell/arm64v8-ubuntu-haskell:focal
|
||||
platforms: linux/arm64
|
||||
|
||||
243
.github/workflows/release.yaml
vendored
243
.github/workflows/release.yaml
vendored
@@ -12,13 +12,17 @@ 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.6.2.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
CABAL_VER: 3.10.2.0
|
||||
JSON_VERSION: "0.0.8"
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
S3_HOST: ${{ secrets.S3_HOST }}
|
||||
@@ -32,7 +36,7 @@ jobs:
|
||||
ARCH: 32
|
||||
- os: ubuntu-latest
|
||||
ARTIFACT: "x86_64-linux-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -82,7 +86,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
JSON_VERSION: "0.0.8"
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
S3_HOST: ${{ secrets.S3_HOST }}
|
||||
@@ -90,20 +94,15 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
include:
|
||||
- os: [self-hosted, Linux, aarch64]
|
||||
- os: [self-hosted, Linux, ARM64]
|
||||
ARTIFACT: "armv7-linux-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.2.8
|
||||
ARCH: ARM
|
||||
- os: [self-hosted, Linux, aarch64]
|
||||
- os: [self-hosted, Linux, ARM64]
|
||||
ARTIFACT: "aarch64-linux-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: ARM64
|
||||
steps:
|
||||
- uses: docker://arm64v8/ubuntu:focal
|
||||
name: Cleanup (aarch64 linux)
|
||||
with:
|
||||
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||
|
||||
- name: git config
|
||||
run: |
|
||||
git config --global --get-all safe.directory | grep '^\*$' || git config --global --add safe.directory "*"
|
||||
@@ -115,7 +114,7 @@ jobs:
|
||||
submodules: 'true'
|
||||
|
||||
- if: matrix.ARCH == 'ARM'
|
||||
uses: docker://hasufell/arm32v7-ubuntu-haskell:focal
|
||||
uses: docker://hasufell/arm32v7-debian-haskell:10
|
||||
name: Run build (armv7 linux)
|
||||
with:
|
||||
args: sh .github/scripts/build.sh
|
||||
@@ -129,7 +128,7 @@ jobs:
|
||||
S3_HOST: ${{ env.S3_HOST }}
|
||||
|
||||
- if: matrix.ARCH == 'ARM64'
|
||||
uses: docker://hasufell/arm64v8-ubuntu-haskell:focal
|
||||
uses: docker://hasufell/arm64v8-debian-haskell:10
|
||||
name: Run build (aarch64 linux)
|
||||
with:
|
||||
args: sh .github/scripts/build.sh
|
||||
@@ -154,9 +153,9 @@ jobs:
|
||||
name: Build binary (Mac/Win)
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
CABAL_VER: 3.10.2.0
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||
JSON_VERSION: "0.0.7"
|
||||
JSON_VERSION: "0.0.8"
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
S3_HOST: ${{ secrets.S3_HOST }}
|
||||
@@ -164,17 +163,17 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: [self-hosted, macOS, aarch64]
|
||||
- os: [self-hosted, macOS, ARM64]
|
||||
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
||||
GHC_VER: 9.2.5
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: ARM64
|
||||
- os: macOS-10.15
|
||||
- os: macOS-11
|
||||
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
||||
GHC_VER: 9.2.5
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
- os: windows-latest
|
||||
ARTIFACT: "x86_64-mingw64-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -182,8 +181,48 @@ jobs:
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- name: Run build (windows/mac)
|
||||
run: bash .github/scripts/build.sh
|
||||
- if: matrix.ARCH == 'ARM64' && runner.os == 'macOS'
|
||||
name: Run build
|
||||
run: |
|
||||
bash .github/scripts/brew.sh git coreutils llvm@13 autoconf automake
|
||||
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$HOME/.brew/opt/llvm@13/bin:$PATH"
|
||||
export CC="$HOME/.brew/opt/llvm@13/bin/clang"
|
||||
export CXX="$HOME/.brew/opt/llvm@13/bin/clang++"
|
||||
export LD=ld
|
||||
export AR="$HOME/.brew/opt/llvm@13/bin/llvm-ar"
|
||||
export RANLIB="$HOME/.brew/opt/llvm@13/bin/llvm-ranlib"
|
||||
bash .github/scripts/build.sh
|
||||
env:
|
||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||
ARCH: ${{ matrix.ARCH }}
|
||||
GHC_VER: ${{ matrix.GHC_VER }}
|
||||
DISTRO: na
|
||||
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||
S3_HOST: ${{ env.S3_HOST }}
|
||||
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
|
||||
|
||||
- if: matrix.ARCH == '64' && runner.os == 'macOS'
|
||||
name: Run build (windows/mac)
|
||||
run: |
|
||||
bash .github/scripts/brew.sh coreutils
|
||||
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH"
|
||||
bash .github/scripts/build.sh
|
||||
env:
|
||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||
ARCH: ${{ matrix.ARCH }}
|
||||
GHC_VER: ${{ matrix.GHC_VER }}
|
||||
DISTRO: na
|
||||
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||
S3_HOST: ${{ env.S3_HOST }}
|
||||
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
|
||||
|
||||
- if: runner.os == 'Windows'
|
||||
name: Run build (windows/mac)
|
||||
run: |
|
||||
bash .github/scripts/brew.sh git coreutils autoconf automake
|
||||
bash .github/scripts/build.sh
|
||||
env:
|
||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||
ARCH: ${{ matrix.ARCH }}
|
||||
@@ -202,14 +241,49 @@ jobs:
|
||||
path: |
|
||||
./out/*
|
||||
|
||||
build-freebsd:
|
||||
name: Build binary (FreeBSD)
|
||||
runs-on: [self-hosted, FreeBSD, X64]
|
||||
env:
|
||||
CABAL_VER: 3.10.2.0
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||
JSON_VERSION: "0.0.8"
|
||||
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-portbld-freebsd-ghcup"
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
DISTRO: na
|
||||
RUNNER_OS: FreeBSD
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- name: Run build
|
||||
run: |
|
||||
sed -i.bak -e 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
|
||||
pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake llvm14 libiconv
|
||||
tzsetup Etc/GMT
|
||||
adjkerntz -a
|
||||
bash .github/scripts/build.sh
|
||||
- if: always()
|
||||
name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: artifacts
|
||||
path: |
|
||||
./out/*
|
||||
|
||||
test-linux:
|
||||
name: Test linux
|
||||
needs: "build-linux"
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
CABAL_VER: 3.10.2.0
|
||||
JSON_VERSION: "0.0.8"
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -220,12 +294,12 @@ jobs:
|
||||
DISTRO: Alpine
|
||||
- os: ubuntu-latest
|
||||
ARTIFACT: "x86_64-linux-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
DISTRO: Alpine
|
||||
- os: ubuntu-latest
|
||||
ARTIFACT: "x86_64-linux-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
DISTRO: Ubuntu
|
||||
|
||||
@@ -264,13 +338,14 @@ jobs:
|
||||
|
||||
- if: matrix.DISTRO != 'Alpine'
|
||||
name: Run test (64 bit linux)
|
||||
run: sh .github/scripts/test.sh
|
||||
run: |
|
||||
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
|
||||
sh .github/scripts/test.sh
|
||||
env:
|
||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||
ARCH: ${{ matrix.ARCH }}
|
||||
GHC_VER: ${{ matrix.GHC_VER }}
|
||||
DISTRO: ${{ matrix.DISTRO }}
|
||||
APT_GET: "sudo apt-get"
|
||||
|
||||
- if: failure()
|
||||
name: Upload artifact
|
||||
@@ -278,7 +353,7 @@ jobs:
|
||||
with:
|
||||
name: testfiles
|
||||
path: |
|
||||
./test/golden/unix/GHCupInfo*json
|
||||
./test/ghcup-test/golden/unix/GHCupInfo*json
|
||||
|
||||
test-arm:
|
||||
name: Test ARM
|
||||
@@ -286,27 +361,22 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
JSON_VERSION: "0.0.7"
|
||||
JSON_VERSION: "0.0.8"
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: [self-hosted, Linux, aarch64]
|
||||
- os: [self-hosted, Linux, ARM64]
|
||||
ARTIFACT: "armv7-linux-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.2.8
|
||||
ARCH: ARM
|
||||
DISTRO: Ubuntu
|
||||
- os: [self-hosted, Linux, aarch64]
|
||||
- os: [self-hosted, Linux, ARM64]
|
||||
ARTIFACT: "aarch64-linux-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: ARM64
|
||||
DISTRO: Ubuntu
|
||||
|
||||
steps:
|
||||
- uses: docker://arm64v8/ubuntu:focal
|
||||
name: Cleanup (aarch64 linux)
|
||||
with:
|
||||
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -318,8 +388,8 @@ jobs:
|
||||
path: ./out
|
||||
|
||||
- if: matrix.ARCH == 'ARM'
|
||||
uses: docker://hasufell/arm32v7-ubuntu-haskell:focal
|
||||
name: Run build (armv7 linux)
|
||||
uses: docker://hasufell/arm32v7-debian-haskell:10
|
||||
name: Run test (armv7 linux)
|
||||
with:
|
||||
args: sh .github/scripts/test.sh
|
||||
env:
|
||||
@@ -329,8 +399,8 @@ jobs:
|
||||
DISTRO: Ubuntu
|
||||
|
||||
- if: matrix.ARCH == 'ARM64'
|
||||
uses: docker://hasufell/arm64v8-ubuntu-haskell:focal
|
||||
name: Run build (aarch64 linux)
|
||||
uses: docker://hasufell/arm64v8-debian-haskell:10
|
||||
name: Run test (aarch64 linux)
|
||||
with:
|
||||
args: sh .github/scripts/test.sh
|
||||
env:
|
||||
@@ -345,32 +415,32 @@ jobs:
|
||||
with:
|
||||
name: testfiles
|
||||
path: |
|
||||
./test/golden/unix/GHCupInfo*json
|
||||
./test/ghcup-test/golden/unix/GHCupInfo*json
|
||||
|
||||
test-macwin:
|
||||
name: Test Mac/Win
|
||||
needs: "build-macwin"
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CABAL_VER: 3.6.2.0
|
||||
CABAL_VER: 3.10.2.0
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||
JSON_VERSION: "0.0.7"
|
||||
JSON_VERSION: "0.0.8"
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: [self-hosted, macOS, aarch64]
|
||||
- os: [self-hosted, macOS, ARM64]
|
||||
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
||||
GHC_VER: 9.2.5
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: ARM64
|
||||
DISTRO: na
|
||||
- os: macOS-10.15
|
||||
- os: macOS-11
|
||||
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
||||
GHC_VER: 9.2.5
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
DISTRO: na
|
||||
- os: windows-latest
|
||||
ARTIFACT: "x86_64-mingw64-ghcup"
|
||||
GHC_VER: 8.10.7
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
DISTRO: na
|
||||
|
||||
@@ -385,7 +455,21 @@ jobs:
|
||||
name: artifacts
|
||||
path: ./out
|
||||
|
||||
- name: Run test (windows/mac)
|
||||
- if: runner.os == 'macOS'
|
||||
name: Run test
|
||||
run: |
|
||||
bash .github/scripts/brew.sh coreutils
|
||||
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH"
|
||||
bash .github/scripts/test.sh
|
||||
env:
|
||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||
ARCH: ${{ matrix.ARCH }}
|
||||
GHC_VER: ${{ matrix.GHC_VER }}
|
||||
DISTRO: ${{ matrix.DISTRO }}
|
||||
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
|
||||
|
||||
- if: runner.os != 'macOS'
|
||||
name: Run test
|
||||
run: bash .github/scripts/test.sh
|
||||
env:
|
||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||
@@ -400,7 +484,7 @@ jobs:
|
||||
with:
|
||||
name: testfiles
|
||||
path: |
|
||||
./test/golden/windows/GHCupInfo*json
|
||||
./test/ghcup-test/golden/windows/GHCupInfo*json
|
||||
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: Upload artifact
|
||||
@@ -408,7 +492,42 @@ jobs:
|
||||
with:
|
||||
name: testfiles
|
||||
path: |
|
||||
./test/golden/unix/GHCupInfo*json
|
||||
./test/ghcup-test/golden/unix/GHCupInfo*json
|
||||
test-freebsd:
|
||||
name: Test FreeBSD
|
||||
needs: "build-freebsd"
|
||||
runs-on: [self-hosted, FreeBSD, X64]
|
||||
env:
|
||||
CABAL_VER: 3.10.2.0
|
||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||
JSON_VERSION: "0.0.8"
|
||||
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: 64
|
||||
DISTRO: na
|
||||
RUNNER_OS: FreeBSD
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out
|
||||
|
||||
- name: Run test
|
||||
run: |
|
||||
bash .github/scripts/test.sh
|
||||
|
||||
- if: failure()
|
||||
name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: testfiles
|
||||
path: |
|
||||
./test/ghcup-test/golden/unix/GHCupInfo*json
|
||||
hls:
|
||||
name: hls
|
||||
needs: build-linux
|
||||
@@ -416,8 +535,8 @@ jobs:
|
||||
env:
|
||||
GHC_VERSION: "8.10.7"
|
||||
HLS_TARGET_VERSION: "1.8.0.0"
|
||||
CABAL_VERSION: "3.6.2.0"
|
||||
JSON_VERSION: "0.0.7"
|
||||
CABAL_VERSION: "3.8.1.0"
|
||||
JSON_VERSION: "0.0.8"
|
||||
ARTIFACT: "x86_64-linux-ghcup"
|
||||
DISTRO: Ubuntu
|
||||
ARCH: 64
|
||||
@@ -436,13 +555,13 @@ jobs:
|
||||
path: ./out
|
||||
|
||||
- name: Run hls build
|
||||
run: sh .github/scripts/hls.sh
|
||||
env:
|
||||
APT_GET: "sudo apt-get"
|
||||
run: |
|
||||
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
|
||||
sh .github/scripts/hls.sh
|
||||
|
||||
release:
|
||||
name: release
|
||||
needs: ["test-linux", "test-arm", "test-macwin", "hls"]
|
||||
needs: ["test-linux", "test-arm", "test-macwin", "test-freebsd", "hls"]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
steps:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ codex.tags
|
||||
dist-newstyle/
|
||||
cabal.project.local
|
||||
.stack-work/
|
||||
.hiefiles/
|
||||
bin/
|
||||
/*.prof
|
||||
/*.ps
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,4 +1,4 @@
|
||||
[submodule "data/metadata"]
|
||||
path = data/metadata
|
||||
url = https://github.com/haskell/ghcup-metadata.git
|
||||
branch = master
|
||||
branch = develop
|
||||
|
||||
25
.travis.yml
25
.travis.yml
@@ -1,25 +0,0 @@
|
||||
jobs:
|
||||
include:
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
language: generic
|
||||
env: ARTIFACT=x86_64-apple-darwin-10.13-ghcup
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode11.3
|
||||
language: generic
|
||||
env: ARTIFACT=x86_64-apple-darwin-10.14-ghcup
|
||||
|
||||
|
||||
script: ".travis/build.sh"
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: "hT2od8Iy04tdFVuonPSWv0NX5hZDmv4al8Q0GbIWmviUetROuM7c6/MCHUcgyiw6H2L3pmH4F24GBYWpKBT3ZMbxrKXhZOZ3KPLXzlnuRlm1qymKqqwsJs3466bMftaiBr16rx1VpAuditN4A32oSmTFcQAJc84Bxn2WZ4t8hk9muS8YPyLhqg3/NxT6ob8dzNp9eS2cA0WODMb/fMzaMruRtepSK8JvuXb/SnTvaDcl9plmPzEa+eW54jwVsDps8ZpQMQlTtGIjYHIwTQ36/iLH4LoAvD7OEnB7qf753LOzmI/bvlB75xYGsLxe1qgpzPMjuG3AK0jb2KGSZCzyAyrbBFSQMIyC1gNKMtab3CohnA9WdQqAT1xrzPzA9zNw516G5Fn/z+t9Ek1f6L2OYO2hJfweNhWh+ChAIsOags2QBpqc0qjkwUS4wqxCWBdyVfgPTUoGelvjCfjQgypgIyLEHFvXt9rlj+kd97FY7nG3vxZrsvWTKKKT551OqUYX5zWTyvGR71jKyNst/p93Pg3DkRy31gHrGnG9zfNgN5tWxJqDd/suR/BAFTp0VtkFb8fR3ct7WMVeJXtE2+bKqxO5Fnocs1VjEm8pKPk7glnp0muu08kaO0h54wiSOCbk1RvO1KZtHue4wKWrHcI18dwW2WtzoBQ4P1lOSkS81UY="
|
||||
file: $ARTIFACT
|
||||
on:
|
||||
repo: hasufell/ghcup-hs
|
||||
tags: true
|
||||
skip_cleanup: true
|
||||
draft: true
|
||||
61
CHANGELOG.md
61
CHANGELOG.md
@@ -1,5 +1,66 @@
|
||||
# Revision history for ghcup
|
||||
|
||||
## 0.1.20.0 -- 2023-11-10
|
||||
|
||||
### New features
|
||||
|
||||
* support TUI on windows thanks to the work from vty and brick maintainers (Chris Hackett, Timofey Zakrevskiy, Jonathan Daugherty, ...), wrt [#912](https://github.com/haskell/ghcup-hs/pull/912)
|
||||
* support JS and wasm cross compilers wrt [#838](https://github.com/haskell/ghcup-hs/issues/838), thanks to Sylvain Henry and IOG
|
||||
* Support stacks installation strategy and metadata wrt [#892](https://github.com/haskell/ghcup-hs/issues/892)
|
||||
- you can now enable stacks installation method via `ghcup config set url-source '["GHCupURL", "StackSetupURL"]'`... for more information, check the [documentation](https://www.haskell.org/ghcup/guide/#using-stacks-setup-info-metadata-to-install-ghc)
|
||||
|
||||
### Improvements and bug fixes
|
||||
|
||||
* fix segfault in TUI when hitting enter early wrt [#887](https://github.com/haskell/ghcup-hs/issues/887)
|
||||
* Improve key handling in TUI, fixes [#875](https://github.com/haskell/ghcup-hs/issues/875)
|
||||
* add explicit support for Void Linux and Rocky Linux (this requires a metadata version bump to `ghcup-0.0.8.yaml`)
|
||||
* optparse cli interface now has a test suite thanks to Lei Zhu, wrt [#862](https://github.com/haskell/ghcup-hs/pull/862)
|
||||
|
||||
## 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)
|
||||
* Fix GC with XDG dirs, fixes [#810](https://github.com/haskell/ghcup-hs/issues/810)
|
||||
|
||||
## 0.1.19.2 -- 2023-2-24
|
||||
|
||||
* Follow-up fix for JFS/ReiserFS and other filesystem that don't support `d_type`, fixes [#787](https://github.com/haskell/ghcup-hs/issues/787)
|
||||
- the previous release had a bug that invalidated that broke it
|
||||
* Implement 'latest-prerelease' tag wrt [#788](https://github.com/haskell/ghcup-hs/issues/788)
|
||||
* Fix 'Could not parse version of stray directory.DS_Store' warnings on macOs wrt [#797](https://github.com/haskell/ghcup-hs/issues/797)
|
||||
|
||||
## 0.1.19.1 -- 2023-2-19
|
||||
|
||||
* Fix GHCup on JFS/ReiserFS and other filesystem that don't support `d_type`, fixes [#766](https://github.com/haskell/ghcup-hs/issues/766)
|
||||
* Don't fail on setModificationTime, fixes [#784](https://github.com/haskell/ghcup-hs/issues/784) and many GitHub actions issues
|
||||
* Make armv7/aarch64 linux binaries more portable (built on Debian buster)
|
||||
* Improve usability on 'ghcup config add-release-channel', fixes [#751](https://github.com/haskell/ghcup-hs/issues/751)
|
||||
* Make version shortcuts work with 'ghcup set', fixes [#757](https://github.com/haskell/ghcup-hs/issues/757)
|
||||
* Don't implicitly smuggle in config options in `ghcup config set` wrt [#775](https://github.com/haskell/ghcup-hs/issues/775)
|
||||
* Fix build on unix with -ftui
|
||||
|
||||
## 0.1.19.0 -- 2023-1-13
|
||||
|
||||
* restore proper support for FreeBSD and Linux armv7
|
||||
* integrate with [errors.haskell.org](https://errors.haskell.org/index.html), wrt [#434](https://github.com/haskell/ghcup-hs/issues/434)
|
||||
* allow to overwrite distro detection via config wrt [#421](https://github.com/haskell/ghcup-hs/issues/421)
|
||||
- this is particularly useful for e.g. Ubuntu derivates, where ghcup doesn't pick the optimal bindist, also see the [GHCup documentation on overriding distro detection](https://www.haskell.org/ghcup/guide/#overriding-distro-detection)
|
||||
* Add proper support for mirrors wrt [#357](https://github.com/haskell/ghcup-hs/issues/357)
|
||||
* fix a (harmless) bug in `ghcup nuke` on windows
|
||||
* improvements to `ghcup add-release-channel` wrt [#708](https://github.com/haskell/ghcup-hs/issues/708)
|
||||
* fix building newer GHC from source wrt [#433](https://github.com/haskell/ghcup-hs/issues/433)
|
||||
* Fix `ghcup install hls -u` on windows
|
||||
* Fix failure with `--isolate=dir --force`
|
||||
* Add `--metadata-fetching-mode` arg, fixes [#440](https://github.com/haskell/ghcup-hs/issues/440)
|
||||
* Add content-length property to downloads
|
||||
* [Fix a grave bug on armv7](https://github.com/haskell/ghcup-hs/commit/78ee956df2618862f421178a565c82548ff7e578) during installation wrt [#415](https://github.com/haskell/ghcup-hs/issues/415)
|
||||
* improve many warning/error messages (contributions by @taylorfausak)
|
||||
* some minor optimization in `ghcup whereis ghcup`
|
||||
* improve `--keep=always` to not clean up directories in certain circumstances
|
||||
|
||||
## 0.1.18.1 -- 2022-08-06
|
||||
|
||||
* fix sdist and unbreak hackage, wrt [#399](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/399)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,7 +42,6 @@ import Data.Aeson.Encode.Pretty ( encodePretty )
|
||||
import Data.Either
|
||||
import Data.Functor
|
||||
import Data.Maybe
|
||||
import Data.Versions
|
||||
import GHC.IO.Encoding
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
import Language.Haskell.TH
|
||||
@@ -63,7 +62,7 @@ import qualified GHCup.Types as Types
|
||||
|
||||
|
||||
|
||||
toSettings :: Options -> IO (Settings, KeyBindings)
|
||||
toSettings :: Options -> IO (Settings, KeyBindings, UserSettings)
|
||||
toSettings options = do
|
||||
noColor <- isJust <$> lookupEnv "NO_COLOR"
|
||||
userConf <- runE @'[ JSONError ] ghcupConfigFile >>= \case
|
||||
@@ -73,21 +72,23 @@ toSettings options = do
|
||||
pure defaultUserSettings
|
||||
_ -> do
|
||||
die "Unexpected error!"
|
||||
pure $ mergeConf options userConf noColor
|
||||
pure $ (\(s', k) -> (s', k, userConf)) $ mergeConf options userConf noColor
|
||||
where
|
||||
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
||||
mergeConf Options{..} UserSettings{..} noColor =
|
||||
let cache = fromMaybe (fromMaybe (Types.cache defaultSettings) uCache) optCache
|
||||
metaCache = fromMaybe (fromMaybe (Types.metaCache defaultSettings) uMetaCache) optMetaCache
|
||||
metaMode = fromMaybe (fromMaybe (Types.metaMode defaultSettings) uMetaMode) optMetaMode
|
||||
noVerify = fromMaybe (fromMaybe (Types.noVerify defaultSettings) uNoVerify) optNoVerify
|
||||
verbose = fromMaybe (fromMaybe (Types.verbose defaultSettings) uVerbose) optVerbose
|
||||
keepDirs = fromMaybe (fromMaybe (Types.keepDirs defaultSettings) uKeepDirs) optKeepDirs
|
||||
downloader = fromMaybe (fromMaybe defaultDownloader uDownloader) optsDownloader
|
||||
keyBindings = maybe defaultKeyBindings mergeKeys uKeyBindings
|
||||
urlSource = maybe (fromMaybe (Types.urlSource defaultSettings) uUrlSource) (OwnSource . (:[]) . Right) optUrlSource
|
||||
urlSource = fromMaybe (fromMaybe (Types.urlSource defaultSettings) uUrlSource) optUrlSource
|
||||
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
|
||||
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
|
||||
platformOverride = optPlatform <|> (uPlatformOverride <|> Types.platformOverride defaultSettings)
|
||||
mirrors = fromMaybe (Types.mirrors defaultSettings) uMirrors
|
||||
in (Settings {..}, keyBindings)
|
||||
#if defined(INTERNAL_DOWNLOADER)
|
||||
defaultDownloader = Internal
|
||||
@@ -106,7 +107,6 @@ toSettings options = do
|
||||
, bSet = fromMaybe bSet kSet
|
||||
, bChangelog = fromMaybe bChangelog kChangelog
|
||||
, bShowAllVersions = fromMaybe bShowAllVersions kShowAll
|
||||
, bShowAllTools = fromMaybe bShowAllTools kShowAllTools
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
-- create ~/.ghcup dir
|
||||
ensureDirectories dirs
|
||||
|
||||
(settings, keybindings) <- toSettings opt
|
||||
(settings, keybindings, userConf) <- toSettings opt
|
||||
|
||||
-- logger interpreter
|
||||
logfile <- runReaderT initGHCupFileLogging dirs
|
||||
@@ -205,19 +205,18 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
VRight r -> pure r
|
||||
VLeft e -> do
|
||||
runLogger
|
||||
(logError $ T.pack $ prettyShow e)
|
||||
(logError $ T.pack $ prettyHFError e)
|
||||
exitWith (ExitFailure 2)
|
||||
|
||||
ghcupInfo <-
|
||||
( flip runReaderT leanAppstate
|
||||
. runE @'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed, FileDoesNotExistError]
|
||||
$ liftE getDownloadsF
|
||||
)
|
||||
( flip runReaderT leanAppstate . runE @'[ContentLengthError, DigestError, DistroNotFound, DownloadFailed, FileDoesNotExistError, GPGError, JSONError, NoCompatibleArch, NoCompatiblePlatform, NoDownload, GHCup.Errors.ParseError, ProcessError, UnsupportedSetupCombo, StackPlatformDetectError] $ do
|
||||
liftE $ getDownloadsF pfreq
|
||||
)
|
||||
>>= \case
|
||||
VRight r -> pure r
|
||||
VLeft e -> do
|
||||
runLogger
|
||||
(logError $ T.pack $ prettyShow e)
|
||||
(logError $ T.pack $ prettyHFError e)
|
||||
exitWith (ExitFailure 2)
|
||||
let s' = AppState settings dirs keybindings ghcupInfo pfreq loggerConfig
|
||||
|
||||
@@ -238,7 +237,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
_
|
||||
| Just False <- optVerbose -> pure ()
|
||||
| otherwise -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
||||
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
||||
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, DayNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
||||
newTools <- lift checkForUpdates
|
||||
forM_ newTools $ \newTool@(t, l) -> do
|
||||
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/283
|
||||
@@ -247,7 +246,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 "
|
||||
@@ -256,16 +255,16 @@ 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 ()
|
||||
|
||||
-- TODO: always run for windows
|
||||
siletRunLogger (flip runReaderT s' $ runE ensureGlobalTools) >>= \case
|
||||
siletRunLogger (flip runReaderT s' $ runE ensureShimGen) >>= \case
|
||||
VRight _ -> pure ()
|
||||
VLeft e -> do
|
||||
runLogger
|
||||
(logError $ T.pack $ prettyShow e)
|
||||
(logError $ T.pack $ prettyHFError e)
|
||||
exitWith (ExitFailure 30)
|
||||
pure s'
|
||||
|
||||
@@ -294,13 +293,14 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
#endif
|
||||
Install installCommand -> install installCommand settings appState runLogger
|
||||
InstallCabalLegacy iopts -> install (Left (InstallCabal iopts)) settings appState runLogger
|
||||
Test testCommand -> test testCommand settings appState runLogger
|
||||
Set setCommand -> set setCommand runAppState runLeanAppState runLogger
|
||||
UnSet unsetCommand -> unset unsetCommand runLeanAppState runLogger
|
||||
List lo -> list lo no_color runAppState
|
||||
Rm rmCommand -> rm rmCommand runAppState runLogger
|
||||
DInfo -> dinfo runAppState runLogger
|
||||
Compile compileCommand -> compile compileCommand settings dirs runAppState runLogger
|
||||
Config configCommand -> config configCommand settings keybindings runLogger
|
||||
Config configCommand -> config configCommand settings userConf keybindings runLogger
|
||||
Whereis whereisOptions
|
||||
whereisCommand -> whereis whereisCommand whereisOptions runAppState leanAppstate runLogger
|
||||
Upgrade uOpts force' fatal -> upgrade uOpts force' fatal dirs runAppState runLogger
|
||||
@@ -310,6 +310,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
Prefetch pfCom -> prefetch pfCom runAppState runLogger
|
||||
GC gcOpts -> gc gcOpts runAppState runLogger
|
||||
Run runCommand -> run runCommand appState leanAppstate runLogger
|
||||
PrintAppErrors -> putStrLn allHFError >> pure ExitSuccess
|
||||
|
||||
case res of
|
||||
ExitSuccess -> pure ()
|
||||
@@ -328,17 +329,18 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
, MonadCatch m
|
||||
)
|
||||
=> Command
|
||||
-> (Tool, Version)
|
||||
-> (Tool, GHCTargetVersion)
|
||||
-> Excepts
|
||||
'[ TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
] m Bool
|
||||
alreadyInstalling (Install (Right InstallOptions{..})) (GHC, ver) = cmp' GHC instVer ver
|
||||
alreadyInstalling (Install (Left (InstallGHC InstallOptions{..}))) (GHC, ver) = cmp' GHC instVer ver
|
||||
alreadyInstalling (Install (Left (InstallCabal InstallOptions{..}))) (Cabal, ver) = cmp' Cabal instVer ver
|
||||
alreadyInstalling (Install (Left (InstallHLS InstallOptions{..}))) (HLS, ver) = cmp' HLS instVer ver
|
||||
alreadyInstalling (Install (Left (InstallStack InstallOptions{..}))) (Stack, ver) = cmp' Stack instVer ver
|
||||
alreadyInstalling (Install (Left (InstallCabal InstallOptions{..}))) (Cabal, ver) = cmp' Cabal instVer ver
|
||||
alreadyInstalling (Install (Left (InstallHLS InstallOptions{..}))) (HLS, ver) = cmp' HLS instVer ver
|
||||
alreadyInstalling (Install (Left (InstallStack InstallOptions{..}))) (Stack, ver) = cmp' Stack instVer ver
|
||||
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ ovewrwiteVer = Just over }))
|
||||
(GHC, ver) = cmp' GHC (Just $ GHCVersion (mkTVer over)) ver
|
||||
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ targetGhc = GHC.SourceDist tver }))
|
||||
@@ -363,12 +365,14 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||
)
|
||||
=> Tool
|
||||
-> Maybe ToolVersion
|
||||
-> Version
|
||||
-> GHCTargetVersion
|
||||
-> Excepts
|
||||
'[ TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
] m Bool
|
||||
cmp' tool instVer ver = do
|
||||
(v, _) <- liftE $ fromVersion instVer tool
|
||||
pure (v == mkTVer ver)
|
||||
pure (v == ver)
|
||||
|
||||
|
||||
@@ -2,20 +2,34 @@ packages: ./ghcup.cabal
|
||||
|
||||
optional-packages: ./vendored/*/*.cabal
|
||||
|
||||
optimization: 2
|
||||
if impl(ghc < 9.0)
|
||||
package ghcup
|
||||
flags: +tui -tar
|
||||
else
|
||||
package ghcup
|
||||
flags: +tui +tar
|
||||
|
||||
package ghcup
|
||||
tests: True
|
||||
flags: +tui
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
|
||||
if os(mingw32)
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/bgamari/terminal-size.git
|
||||
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
|
||||
location: https://github.com/haskell/tar.git
|
||||
tag: d94a988be4311b830149a9f8fc16739927e5fc1c
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.Cabal ==3.6.2.0,
|
||||
any.aeson >= 2.0.1.0,
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/uri-bytestring.git
|
||||
tag: 4fb5ed14b500c192e6e7a97f6b2b1eb478806001
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/versions.git
|
||||
tag: 79e18fbc44fae3064d8957c550cc0229465db320
|
||||
|
||||
package libarchive
|
||||
flags: -system-libarchive
|
||||
@@ -32,6 +46,10 @@ package aeson
|
||||
package streamly
|
||||
flags: +use-unliftio
|
||||
|
||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||
package *
|
||||
test-show-details: direct
|
||||
|
||||
allow-newer: cabal-install-parsers:tar
|
||||
|
||||
|
||||
with-compiler: ghc-8.10.7
|
||||
|
||||
@@ -1,50 +1,57 @@
|
||||
active-repositories: hackage.haskell.org:merge
|
||||
constraints: any.Cabal ==3.6.2.0,
|
||||
constraints: any.Cabal ==3.6.3.0,
|
||||
Cabal -bundled-binary-generic,
|
||||
any.Cabal-syntax ==3.10.2.0,
|
||||
any.HUnit ==1.6.2.0,
|
||||
any.HsOpenSSL ==0.11.7.2,
|
||||
any.HsOpenSSL ==0.11.7.6,
|
||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||
any.OneTuple ==0.3.1,
|
||||
any.QuickCheck ==2.14.2,
|
||||
any.OneTuple ==0.4.1.1,
|
||||
any.QuickCheck ==2.14.3,
|
||||
QuickCheck -old-random +templatehaskell,
|
||||
any.StateVar ==1.2.2,
|
||||
any.abstract-deque ==0.3,
|
||||
abstract-deque -usecas,
|
||||
any.aeson ==2.0.3.0,
|
||||
any.aeson ==2.1.2.1,
|
||||
aeson -cffi +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.9,
|
||||
any.aeson-pretty ==0.8.10,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.2.7.1,
|
||||
any.ansi-terminal ==0.11.3,
|
||||
any.alex ==3.5.0.0,
|
||||
any.ansi-terminal ==1.0.2,
|
||||
ansi-terminal -example,
|
||||
any.ansi-terminal-types ==0.11.5,
|
||||
any.ansi-wl-pprint ==0.6.9,
|
||||
ansi-wl-pprint -example,
|
||||
any.array ==0.5.4.0,
|
||||
any.assoc ==1.0.2,
|
||||
any.async ==2.2.4,
|
||||
any.assoc ==1.1,
|
||||
assoc +tagged,
|
||||
any.async ==2.2.5,
|
||||
async -bench,
|
||||
any.atomic-primops ==0.8.4,
|
||||
atomic-primops -debug,
|
||||
any.attoparsec ==0.14.4,
|
||||
attoparsec -developer,
|
||||
any.base ==4.14.3.0,
|
||||
any.base-compat ==0.12.1,
|
||||
any.base-compat-batteries ==0.12.1,
|
||||
any.base-orphans ==0.8.6,
|
||||
any.base-compat ==0.13.1,
|
||||
any.base-compat-batteries ==0.13.1,
|
||||
any.base-orphans ==0.9.1,
|
||||
any.base16-bytestring ==1.0.2.0,
|
||||
any.base64-bytestring ==1.2.1.0,
|
||||
any.bifunctors ==5.5.12,
|
||||
bifunctors +semigroups +tagged,
|
||||
any.bifunctors ==5.6.1,
|
||||
bifunctors +tagged,
|
||||
any.bimap ==0.5.0,
|
||||
any.binary ==0.8.8.0,
|
||||
any.blaze-builder ==0.4.2.2,
|
||||
any.brick ==0.64.2,
|
||||
any.binary-instances ==1.0.4,
|
||||
any.binary-orphans ==1.0.4.1,
|
||||
any.blaze-builder ==0.4.2.3,
|
||||
any.brick ==2.1.1,
|
||||
brick -demos,
|
||||
any.bytestring ==0.10.12.0,
|
||||
any.bz2 ==1.0.1.0,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-plan ==0.7.2.1,
|
||||
any.cabal-install-parsers ==0.6.1,
|
||||
any.cabal-plan ==0.7.3.0,
|
||||
cabal-plan -_ -exe -license-report,
|
||||
any.call-stack ==0.4.0,
|
||||
any.case-insensitive ==1.2.1.0,
|
||||
@@ -52,14 +59,12 @@ constraints: any.Cabal ==3.6.2.0,
|
||||
any.chs-cabal ==0.1.1.1,
|
||||
any.chs-deps ==0.1.0.0,
|
||||
chs-deps -cross,
|
||||
any.clock ==0.8.3,
|
||||
clock -llvm,
|
||||
any.colour ==2.3.6,
|
||||
any.comonad ==5.0.8,
|
||||
comonad +containers +distributive +indexed-traversable,
|
||||
any.composition-prelude ==3.0.0.2,
|
||||
composition-prelude -development,
|
||||
any.config-ini ==0.2.4.0,
|
||||
any.config-ini ==0.2.7.0,
|
||||
config-ini -enable-doctests,
|
||||
any.containers ==0.6.5.1,
|
||||
any.contravariant ==1.5.5,
|
||||
@@ -69,6 +74,7 @@ constraints: any.Cabal ==3.6.2.0,
|
||||
any.cryptohash-sha1 ==0.11.101.0,
|
||||
any.cryptohash-sha256 ==0.11.102.1,
|
||||
cryptohash-sha256 -exe +use-cbits,
|
||||
any.data-array-byte ==0.1.0.1,
|
||||
any.data-clist ==0.2,
|
||||
any.data-fix ==0.3.2,
|
||||
any.deepseq ==1.4.4.0,
|
||||
@@ -79,160 +85,172 @@ constraints: any.Cabal ==3.6.2.0,
|
||||
any.dlist ==1.0,
|
||||
dlist -werror,
|
||||
any.exceptions ==0.10.4,
|
||||
any.file-uri ==0.1.0.0,
|
||||
any.filepath ==1.4.2.1,
|
||||
any.free ==5.1.8,
|
||||
any.foldable1-classes-compat ==0.1,
|
||||
foldable1-classes-compat +tagged,
|
||||
any.free ==5.2,
|
||||
any.fusion-plugin-types ==0.1.0,
|
||||
any.generic-arbitrary ==0.2.2,
|
||||
any.ghc ==8.10.7,
|
||||
any.ghc-boot ==8.10.7,
|
||||
any.generically ==0.1.1,
|
||||
any.ghc-boot-th ==8.10.7,
|
||||
any.ghc-byteorder ==4.11.0.0.10,
|
||||
any.ghc-heap ==8.10.7,
|
||||
any.ghc-prim ==0.6.1,
|
||||
any.ghci ==8.10.7,
|
||||
any.happy ==1.20.0,
|
||||
any.hashable ==1.4.0.2,
|
||||
hashable +containers +integer-gmp -random-initial-seed,
|
||||
any.happy ==1.20.1.1,
|
||||
any.hashable ==1.4.3.0,
|
||||
hashable +integer-gmp -random-initial-seed,
|
||||
any.haskell-lexer ==1.1.1,
|
||||
any.haskus-utils-data ==1.4,
|
||||
any.haskus-utils-types ==1.5.1,
|
||||
any.haskus-utils-variant ==3.2.1,
|
||||
any.haskus-utils-variant ==3.3,
|
||||
any.heaps ==0.4,
|
||||
any.hpc ==0.6.1.0,
|
||||
any.hsc2hs ==0.68.8,
|
||||
any.hsc2hs ==0.68.10,
|
||||
hsc2hs -in-ghc-tree,
|
||||
any.hspec ==2.9.7,
|
||||
any.hspec-core ==2.9.7,
|
||||
any.hspec-discover ==2.9.7,
|
||||
any.hspec ==2.10.10,
|
||||
any.hspec-core ==2.10.10,
|
||||
any.hspec-discover ==2.10.10,
|
||||
any.hspec-expectations ==0.8.2,
|
||||
any.hspec-golden-aeson ==0.9.0.0,
|
||||
any.http-io-streams ==0.1.6.1,
|
||||
any.http-io-streams ==0.1.6.3,
|
||||
http-io-streams -brotli +fast-xor,
|
||||
any.indexed-profunctors ==0.1.1,
|
||||
any.indexed-traversable ==0.1.2,
|
||||
any.indexed-traversable-instances ==0.1.1,
|
||||
any.indexed-profunctors ==0.1.1.1,
|
||||
any.indexed-traversable ==0.1.3,
|
||||
any.indexed-traversable-instances ==0.1.1.2,
|
||||
any.integer-gmp ==1.0.3.0,
|
||||
any.integer-logarithms ==1.0.3.1,
|
||||
integer-logarithms -check-bounds +integer-gmp,
|
||||
any.io-streams ==1.5.2.1,
|
||||
any.io-streams ==1.5.2.2,
|
||||
io-streams +network -nointeractivetests +zlib,
|
||||
any.language-c ==0.9.1,
|
||||
any.language-c ==0.9.2,
|
||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||
any.libarchive ==3.0.3.2,
|
||||
any.libarchive ==3.0.4.2,
|
||||
libarchive -cross -low-memory +no-exe -system-libarchive,
|
||||
any.libyaml-streamly ==0.2.1,
|
||||
any.libyaml-streamly ==0.2.2,
|
||||
libyaml-streamly -no-unicode -system-libyaml,
|
||||
any.lockfree-queue ==0.2.3.1,
|
||||
any.lzma-static ==5.2.5.4,
|
||||
any.lockfree-queue ==0.2.4,
|
||||
any.lukko ==0.1.1.3,
|
||||
lukko +ofd-locking,
|
||||
any.lzma-static ==5.2.5.5,
|
||||
any.megaparsec ==9.2.1,
|
||||
megaparsec -dev,
|
||||
any.microlens ==0.4.12.0,
|
||||
any.microlens-mtl ==0.2.0.2,
|
||||
any.microlens-th ==0.4.3.10,
|
||||
any.microlens ==0.4.13.1,
|
||||
any.microlens-mtl ==0.2.0.3,
|
||||
any.microlens-th ==0.4.3.14,
|
||||
any.mtl ==2.2.2,
|
||||
any.network ==3.1.2.7,
|
||||
any.mtl-compat ==0.2.2,
|
||||
mtl-compat -two-point-one -two-point-two,
|
||||
any.network ==3.1.4.0,
|
||||
network -devel,
|
||||
any.network-uri ==2.6.4.1,
|
||||
any.network-uri ==2.6.4.2,
|
||||
any.openssl-streams ==1.2.3.0,
|
||||
any.optics ==0.4.2,
|
||||
any.optics-core ==0.4.1,
|
||||
any.optics ==0.4.2.1,
|
||||
any.optics-core ==0.4.1.1,
|
||||
optics-core -explicit-generic-labels,
|
||||
any.optics-extra ==0.4.2.1,
|
||||
any.optics-th ==0.4.1,
|
||||
any.optparse-applicative ==0.17.0.0,
|
||||
any.optparse-applicative ==0.17.1.0,
|
||||
optparse-applicative +process,
|
||||
any.os-release ==1.0.2.1,
|
||||
os-release -devel,
|
||||
any.parallel ==3.2.2.0,
|
||||
any.parsec ==3.1.14.0,
|
||||
any.parsec ==3.1.17.0,
|
||||
any.parser-combinators ==1.3.0,
|
||||
parser-combinators -dev,
|
||||
any.polyparse ==1.13,
|
||||
any.pretty ==1.1.3.6,
|
||||
any.pretty-terminal ==0.1.0.0,
|
||||
any.primitive ==0.7.4.0,
|
||||
any.primitive ==0.8.0.0,
|
||||
any.process ==1.6.13.2,
|
||||
any.profunctors ==5.6.2,
|
||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||
any.quickcheck-io ==0.2.0,
|
||||
any.random ==1.2.1.1,
|
||||
any.recursion-schemes ==5.2.2.2,
|
||||
any.recursion-schemes ==5.2.2.5,
|
||||
recursion-schemes +template-haskell,
|
||||
any.regex-base ==0.94.0.2,
|
||||
any.regex-posix ==0.96.0.1,
|
||||
regex-posix -_regex-posix-clib,
|
||||
any.resourcet ==1.2.5,
|
||||
any.retry ==0.8.1.2,
|
||||
any.resourcet ==1.2.6,
|
||||
any.retry ==0.9.3.1,
|
||||
retry -lib-werror,
|
||||
any.rts ==1.0.1,
|
||||
any.safe ==0.3.19,
|
||||
any.safe-exceptions ==0.1.7.3,
|
||||
any.safe ==0.3.21,
|
||||
any.safe-exceptions ==0.1.7.4,
|
||||
any.scientific ==0.3.7.0,
|
||||
scientific -bytestring-builder -integer-simple,
|
||||
any.semialign ==1.2.0.1,
|
||||
any.semialign ==1.3,
|
||||
semialign +semigroupoids,
|
||||
any.semigroupoids ==5.3.7,
|
||||
any.semigroupoids ==6.0.0.1,
|
||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||
any.setenv ==0.1.1.3,
|
||||
any.split ==0.2.3.4,
|
||||
any.splitmix ==0.1.0.4,
|
||||
any.split ==0.2.5,
|
||||
any.splitmix ==0.1.0.5,
|
||||
splitmix -optimised-mixer,
|
||||
any.stm ==2.5.0.1,
|
||||
any.streamly ==0.8.2,
|
||||
any.streamly ==0.8.3,
|
||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -streamly-core -use-c-malloc +use-unliftio,
|
||||
any.strict ==0.4.0.1,
|
||||
strict +assoc,
|
||||
any.strict ==0.5,
|
||||
any.strict-base ==0.4.0.0,
|
||||
any.tagged ==0.8.6.1,
|
||||
any.tagged ==0.8.8,
|
||||
tagged +deepseq +transformers,
|
||||
any.tagsoup ==0.14.8,
|
||||
any.tar ==0.6.0.0,
|
||||
any.tasty ==1.5,
|
||||
tasty +unix,
|
||||
any.tasty-hunit ==0.10.1,
|
||||
any.template-haskell ==2.16.0.0,
|
||||
any.temporary ==1.3,
|
||||
any.terminal-progress-bar ==0.4.1,
|
||||
any.terminal-size ==0.3.2.1,
|
||||
any.terminal-progress-bar ==0.4.2,
|
||||
any.terminal-size ==0.3.4,
|
||||
any.terminfo ==0.4.1.4,
|
||||
any.text ==1.2.4.1,
|
||||
any.text ==2.0.2,
|
||||
text -developer +simdutf,
|
||||
any.text-binary ==0.2.1.1,
|
||||
any.text-short ==0.1.5,
|
||||
text-short -asserts,
|
||||
any.text-zipper ==0.11,
|
||||
any.text-zipper ==0.13,
|
||||
any.tf-random ==0.5,
|
||||
any.th-abstraction ==0.4.3.0,
|
||||
any.th-compat ==0.1.3,
|
||||
any.th-lift ==0.8.2,
|
||||
any.th-lift-instances ==0.1.19,
|
||||
any.these ==1.1.1.1,
|
||||
these +assoc,
|
||||
any.th-abstraction ==0.5.0.0,
|
||||
any.th-compat ==0.1.4,
|
||||
any.th-lift ==0.8.4,
|
||||
any.th-lift-instances ==0.1.20,
|
||||
any.these ==1.2,
|
||||
any.time ==1.9.3,
|
||||
any.time-compat ==1.9.6.1,
|
||||
time-compat -old-locale,
|
||||
any.transformers ==0.5.6.2,
|
||||
any.transformers-base ==0.4.6,
|
||||
transformers-base +orphaninstances,
|
||||
any.transformers-compat ==0.7.1,
|
||||
any.transformers-compat ==0.7.2,
|
||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||
any.unicode-data ==0.3.0,
|
||||
any.unicode-data ==0.3.1,
|
||||
unicode-data -ucd2haskell,
|
||||
any.unix ==2.7.2.2,
|
||||
any.unix-bytestring ==0.3.7.7,
|
||||
any.unix-compat ==0.6,
|
||||
any.unix-bytestring ==0.3.7.8,
|
||||
any.unix-compat ==0.7.1,
|
||||
unix-compat -old-time,
|
||||
any.unliftio-core ==0.2.0.1,
|
||||
any.unordered-containers ==0.2.19.1,
|
||||
any.unliftio-core ==0.2.1.0,
|
||||
any.unordered-containers ==0.2.20,
|
||||
unordered-containers -debug,
|
||||
any.uri-bytestring ==0.3.3.1,
|
||||
uri-bytestring -lib-werror,
|
||||
any.utf8-string ==1.0.2,
|
||||
any.uuid-types ==1.0.5,
|
||||
any.vector ==0.12.3.1,
|
||||
any.uuid-types ==1.0.5.1,
|
||||
any.vector ==0.13.1.0,
|
||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||
any.versions ==5.0.3,
|
||||
any.vty ==5.33,
|
||||
any.vector-binary-instances ==0.2.5.2,
|
||||
any.vector-stream ==0.1.0.1,
|
||||
any.versions ==6.0.4,
|
||||
any.vty ==6.0,
|
||||
any.vty-crossplatform ==0.2.0.0,
|
||||
vty-crossplatform -demos,
|
||||
any.vty-unix ==0.1.0.0,
|
||||
any.witherable ==0.4.2,
|
||||
any.word-wrap ==0.5,
|
||||
any.word8 ==0.1.3,
|
||||
any.xor ==0.0.1.1,
|
||||
any.yaml-streamly ==0.12.1,
|
||||
any.xor ==0.0.1.2,
|
||||
any.yaml-streamly ==0.12.4,
|
||||
yaml-streamly +no-examples +no-exe,
|
||||
any.zlib ==0.6.3.0,
|
||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||
any.zlib-bindings ==0.1.1.5
|
||||
index-state: hackage.haskell.org 2022-06-04T19:47:01Z
|
||||
index-state: hackage.haskell.org 2024-01-19T19:48:54Z
|
||||
|
||||
@@ -2,20 +2,34 @@ packages: ./ghcup.cabal
|
||||
|
||||
optional-packages: ./vendored/*/*.cabal
|
||||
|
||||
optimization: 2
|
||||
if impl(ghc < 9.0)
|
||||
package ghcup
|
||||
flags: +tui -tar
|
||||
else
|
||||
package ghcup
|
||||
flags: +tui +tar
|
||||
|
||||
package ghcup
|
||||
tests: True
|
||||
flags: +tui
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
|
||||
if os(mingw32)
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/bgamari/terminal-size.git
|
||||
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
|
||||
location: https://github.com/haskell/tar.git
|
||||
tag: d94a988be4311b830149a9f8fc16739927e5fc1c
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.Cabal ==3.6.2.0,
|
||||
any.aeson >= 2.0.1.0,
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/uri-bytestring.git
|
||||
tag: 4fb5ed14b500c192e6e7a97f6b2b1eb478806001
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/versions.git
|
||||
tag: 79e18fbc44fae3064d8957c550cc0229465db320
|
||||
|
||||
package libarchive
|
||||
flags: -system-libarchive
|
||||
@@ -32,6 +46,10 @@ package aeson
|
||||
package streamly
|
||||
flags: +use-unliftio
|
||||
|
||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||
package *
|
||||
test-show-details: direct
|
||||
|
||||
allow-newer: cabal-install-parsers:tar
|
||||
|
||||
|
||||
with-compiler: ghc-9.0.2
|
||||
|
||||
@@ -1,77 +1,88 @@
|
||||
active-repositories: hackage.haskell.org:merge
|
||||
constraints: any.Cabal ==3.6.2.0,
|
||||
constraints: any.Cabal ==3.6.3.0,
|
||||
Cabal -bundled-binary-generic,
|
||||
any.Cabal-syntax ==3.10.2.0,
|
||||
any.HUnit ==1.6.2.0,
|
||||
any.HsOpenSSL ==0.11.7.2,
|
||||
any.HsOpenSSL ==0.11.7.6,
|
||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||
any.OneTuple ==0.3.1,
|
||||
any.QuickCheck ==2.14.2,
|
||||
any.OneTuple ==0.4.1.1,
|
||||
any.QuickCheck ==2.14.3,
|
||||
QuickCheck -old-random +templatehaskell,
|
||||
any.StateVar ==1.2.2,
|
||||
any.abstract-deque ==0.3,
|
||||
abstract-deque -usecas,
|
||||
any.aeson ==2.0.3.0,
|
||||
any.aeson ==2.1.2.1,
|
||||
aeson -cffi +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.9,
|
||||
any.aeson-pretty ==0.8.10,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.2.7.1,
|
||||
any.ansi-terminal ==0.11.3,
|
||||
any.alex ==3.5.0.0,
|
||||
any.ansi-terminal ==1.0.2,
|
||||
ansi-terminal -example,
|
||||
any.ansi-terminal-types ==0.11.5,
|
||||
any.ansi-wl-pprint ==0.6.9,
|
||||
ansi-wl-pprint -example,
|
||||
any.array ==0.5.4.0,
|
||||
any.assoc ==1.0.2,
|
||||
any.async ==2.2.4,
|
||||
any.assoc ==1.1,
|
||||
assoc +tagged,
|
||||
any.async ==2.2.5,
|
||||
async -bench,
|
||||
any.atomic-primops ==0.8.4,
|
||||
atomic-primops -debug,
|
||||
any.attoparsec ==0.14.4,
|
||||
attoparsec -developer,
|
||||
any.base ==4.15.1.0,
|
||||
any.base-compat ==0.12.1,
|
||||
any.base-compat-batteries ==0.12.1,
|
||||
any.base-orphans ==0.8.6,
|
||||
any.base-compat ==0.13.1,
|
||||
any.base-compat-batteries ==0.13.1,
|
||||
any.base-orphans ==0.9.1,
|
||||
any.base16-bytestring ==1.0.2.0,
|
||||
any.base64-bytestring ==1.2.1.0,
|
||||
any.bifunctors ==5.5.12,
|
||||
bifunctors +semigroups +tagged,
|
||||
any.bifunctors ==5.6.1,
|
||||
bifunctors +tagged,
|
||||
any.bimap ==0.5.0,
|
||||
any.binary ==0.8.8.0,
|
||||
any.blaze-builder ==0.4.2.2,
|
||||
any.brick ==0.64.2,
|
||||
any.binary-instances ==1.0.4,
|
||||
any.binary-orphans ==1.0.4.1,
|
||||
any.bindings-DSL ==1.0.25,
|
||||
any.bitvec ==1.1.5.0,
|
||||
bitvec +simd,
|
||||
any.blaze-builder ==0.4.2.3,
|
||||
any.brick ==2.1.1,
|
||||
brick -demos,
|
||||
any.bytestring ==0.10.12.1,
|
||||
any.bz2 ==1.0.1.0,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.bzlib-conduit ==0.3.0.2,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-plan ==0.7.2.1,
|
||||
any.cabal-install-parsers ==0.6.1,
|
||||
any.cabal-plan ==0.7.3.0,
|
||||
cabal-plan -_ -exe -license-report,
|
||||
any.call-stack ==0.4.0,
|
||||
any.case-insensitive ==1.2.1.0,
|
||||
any.casing ==0.1.4.1,
|
||||
any.chs-cabal ==0.1.1.1,
|
||||
any.chs-deps ==0.1.0.0,
|
||||
chs-deps -cross,
|
||||
any.clock ==0.8.3,
|
||||
clock -llvm,
|
||||
any.cereal ==0.5.8.3,
|
||||
cereal -bytestring-builder,
|
||||
any.colour ==2.3.6,
|
||||
any.comonad ==5.0.8,
|
||||
comonad +containers +distributive +indexed-traversable,
|
||||
any.composition-prelude ==3.0.0.2,
|
||||
composition-prelude -development,
|
||||
any.config-ini ==0.2.4.0,
|
||||
any.conduit ==1.3.5,
|
||||
any.conduit-extra ==1.3.6,
|
||||
any.conduit-zstd ==0.0.2.0,
|
||||
any.config-ini ==0.2.7.0,
|
||||
config-ini -enable-doctests,
|
||||
any.containers ==0.6.4.1,
|
||||
any.contravariant ==1.5.5,
|
||||
contravariant +semigroups +statevar +tagged,
|
||||
any.cpphs ==1.20.9.1,
|
||||
cpphs -old-locale,
|
||||
any.cryptohash-sha1 ==0.11.101.0,
|
||||
any.cryptohash-sha256 ==0.11.102.1,
|
||||
cryptohash-sha256 -exe +use-cbits,
|
||||
any.data-array-byte ==0.1.0.1,
|
||||
any.data-clist ==0.2,
|
||||
any.data-default-class ==0.1.2.0,
|
||||
any.data-fix ==0.3.2,
|
||||
any.deepseq ==1.4.5.0,
|
||||
any.digest ==0.0.2.0,
|
||||
digest -have_arm64_crc32c -have_builtin_prefetch -have_mm_prefetch -have_sse42 -have_strong_getauxval -have_weak_getauxval +pkg-config,
|
||||
any.directory ==1.3.6.2,
|
||||
any.disk-free-space ==0.1.0.1,
|
||||
any.distributive ==0.6.2.1,
|
||||
@@ -79,160 +90,180 @@ constraints: any.Cabal ==3.6.2.0,
|
||||
any.dlist ==1.0,
|
||||
dlist -werror,
|
||||
any.exceptions ==0.10.4,
|
||||
any.file-uri ==0.1.0.0,
|
||||
any.filepath ==1.4.2.1,
|
||||
any.free ==5.1.8,
|
||||
any.foldable1-classes-compat ==0.1,
|
||||
foldable1-classes-compat +tagged,
|
||||
any.free ==5.2,
|
||||
any.fusion-plugin-types ==0.1.0,
|
||||
any.generic-arbitrary ==0.2.2,
|
||||
any.ghc ==9.0.2,
|
||||
any.generically ==0.1.1,
|
||||
any.ghc-bignum ==1.1,
|
||||
any.ghc-boot ==9.0.2,
|
||||
any.ghc-boot-th ==9.0.2,
|
||||
any.ghc-byteorder ==4.11.0.0.10,
|
||||
any.ghc-heap ==9.0.2,
|
||||
any.ghc-prim ==0.7.0,
|
||||
any.ghci ==9.0.2,
|
||||
any.happy ==1.20.0,
|
||||
any.hashable ==1.4.0.2,
|
||||
hashable +containers +integer-gmp -random-initial-seed,
|
||||
any.happy ==1.20.1.1,
|
||||
any.hashable ==1.4.3.0,
|
||||
hashable +integer-gmp -random-initial-seed,
|
||||
any.haskell-lexer ==1.1.1,
|
||||
any.haskus-utils-data ==1.4,
|
||||
any.haskus-utils-types ==1.5.1,
|
||||
any.haskus-utils-variant ==3.2.1,
|
||||
any.haskus-utils-variant ==3.3,
|
||||
any.heaps ==0.4,
|
||||
any.hpc ==0.6.1.0,
|
||||
any.hsc2hs ==0.68.8,
|
||||
any.hsc2hs ==0.68.10,
|
||||
hsc2hs -in-ghc-tree,
|
||||
any.hspec ==2.9.7,
|
||||
any.hspec-core ==2.9.7,
|
||||
any.hspec-discover ==2.9.7,
|
||||
any.hspec ==2.10.10,
|
||||
any.hspec-core ==2.10.10,
|
||||
any.hspec-discover ==2.10.10,
|
||||
any.hspec-expectations ==0.8.2,
|
||||
any.hspec-golden-aeson ==0.9.0.0,
|
||||
any.http-io-streams ==0.1.6.1,
|
||||
any.http-io-streams ==0.1.6.3,
|
||||
http-io-streams -brotli +fast-xor,
|
||||
any.indexed-profunctors ==0.1.1,
|
||||
any.indexed-traversable ==0.1.2,
|
||||
any.indexed-traversable-instances ==0.1.1,
|
||||
any.indexed-profunctors ==0.1.1.1,
|
||||
any.indexed-traversable ==0.1.3,
|
||||
any.indexed-traversable-instances ==0.1.1.2,
|
||||
any.integer-logarithms ==1.0.3.1,
|
||||
integer-logarithms -check-bounds +integer-gmp,
|
||||
any.io-streams ==1.5.2.1,
|
||||
any.io-streams ==1.5.2.2,
|
||||
io-streams +network -nointeractivetests +zlib,
|
||||
any.language-c ==0.9.1,
|
||||
any.language-c ==0.9.2,
|
||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||
any.libarchive ==3.0.3.2,
|
||||
libarchive -cross -low-memory +no-exe -system-libarchive,
|
||||
any.libyaml-streamly ==0.2.1,
|
||||
any.libyaml-streamly ==0.2.2,
|
||||
libyaml-streamly -no-unicode -system-libyaml,
|
||||
any.lockfree-queue ==0.2.3.1,
|
||||
any.lzma-static ==5.2.5.4,
|
||||
any.megaparsec ==9.2.1,
|
||||
any.lockfree-queue ==0.2.4,
|
||||
any.lukko ==0.1.1.3,
|
||||
lukko +ofd-locking,
|
||||
any.lzma-static ==5.2.5.5,
|
||||
any.megaparsec ==9.2.2,
|
||||
megaparsec -dev,
|
||||
any.microlens ==0.4.12.0,
|
||||
any.microlens-mtl ==0.2.0.2,
|
||||
any.microlens-th ==0.4.3.10,
|
||||
any.microlens ==0.4.13.1,
|
||||
any.microlens-mtl ==0.2.0.3,
|
||||
any.microlens-th ==0.4.3.14,
|
||||
any.monad-control ==1.0.3.1,
|
||||
any.mono-traversable ==1.0.15.3,
|
||||
any.mtl ==2.2.2,
|
||||
any.network ==3.1.2.7,
|
||||
any.mtl-compat ==0.2.2,
|
||||
mtl-compat -two-point-one -two-point-two,
|
||||
any.network ==3.1.4.0,
|
||||
network -devel,
|
||||
any.network-uri ==2.6.4.1,
|
||||
any.network-uri ==2.6.4.2,
|
||||
any.openssl-streams ==1.2.3.0,
|
||||
any.optics ==0.4.2,
|
||||
any.optics-core ==0.4.1,
|
||||
any.optics ==0.4.2.1,
|
||||
any.optics-core ==0.4.1.1,
|
||||
optics-core -explicit-generic-labels,
|
||||
any.optics-extra ==0.4.2.1,
|
||||
any.optics-th ==0.4.1,
|
||||
any.optparse-applicative ==0.17.0.0,
|
||||
any.optparse-applicative ==0.17.1.0,
|
||||
optparse-applicative +process,
|
||||
any.os-release ==1.0.2.1,
|
||||
os-release -devel,
|
||||
any.parallel ==3.2.2.0,
|
||||
any.parsec ==3.1.14.0,
|
||||
any.parsec ==3.1.17.0,
|
||||
any.parser-combinators ==1.3.0,
|
||||
parser-combinators -dev,
|
||||
any.polyparse ==1.13,
|
||||
any.pretty ==1.1.3.6,
|
||||
any.pretty-terminal ==0.1.0.0,
|
||||
any.primitive ==0.7.4.0,
|
||||
any.primitive ==0.8.0.0,
|
||||
any.process ==1.6.13.2,
|
||||
any.profunctors ==5.6.2,
|
||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||
any.quickcheck-io ==0.2.0,
|
||||
any.random ==1.2.1.1,
|
||||
any.recursion-schemes ==5.2.2.2,
|
||||
any.recursion-schemes ==5.2.2.5,
|
||||
recursion-schemes +template-haskell,
|
||||
any.regex-base ==0.94.0.2,
|
||||
any.regex-posix ==0.96.0.1,
|
||||
regex-posix -_regex-posix-clib,
|
||||
any.resourcet ==1.2.5,
|
||||
any.retry ==0.8.1.2,
|
||||
any.resourcet ==1.2.6,
|
||||
any.retry ==0.9.3.1,
|
||||
retry -lib-werror,
|
||||
any.rts ==1.0.2,
|
||||
any.safe ==0.3.19,
|
||||
any.safe-exceptions ==0.1.7.3,
|
||||
any.safe ==0.3.21,
|
||||
any.safe-exceptions ==0.1.7.4,
|
||||
any.scientific ==0.3.7.0,
|
||||
scientific -bytestring-builder -integer-simple,
|
||||
any.semialign ==1.2.0.1,
|
||||
any.semialign ==1.3,
|
||||
semialign +semigroupoids,
|
||||
any.semigroupoids ==5.3.7,
|
||||
any.semigroupoids ==6.0.0.1,
|
||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||
any.setenv ==0.1.1.3,
|
||||
any.split ==0.2.3.4,
|
||||
any.splitmix ==0.1.0.4,
|
||||
any.split ==0.2.5,
|
||||
any.splitmix ==0.1.0.5,
|
||||
splitmix -optimised-mixer,
|
||||
any.stm ==2.5.0.0,
|
||||
any.streamly ==0.8.2,
|
||||
any.streaming-commons ==0.2.2.6,
|
||||
streaming-commons -use-bytestring-builder,
|
||||
any.streamly ==0.8.3,
|
||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -streamly-core -use-c-malloc +use-unliftio,
|
||||
any.strict ==0.4.0.1,
|
||||
strict +assoc,
|
||||
any.strict ==0.5,
|
||||
any.strict-base ==0.4.0.0,
|
||||
any.tagged ==0.8.6.1,
|
||||
any.tagged ==0.8.8,
|
||||
tagged +deepseq +transformers,
|
||||
any.tagsoup ==0.14.8,
|
||||
any.tar ==0.6.0.0,
|
||||
any.tasty ==1.5,
|
||||
tasty +unix,
|
||||
any.tasty-hunit ==0.10.1,
|
||||
any.template-haskell ==2.17.0.0,
|
||||
any.temporary ==1.3,
|
||||
any.terminal-progress-bar ==0.4.1,
|
||||
any.terminal-size ==0.3.2.1,
|
||||
any.terminal-progress-bar ==0.4.2,
|
||||
any.terminal-size ==0.3.4,
|
||||
any.terminfo ==0.4.1.5,
|
||||
any.text ==1.2.5.0,
|
||||
any.text ==2.0.2,
|
||||
text -developer +simdutf,
|
||||
any.text-binary ==0.2.1.1,
|
||||
any.text-short ==0.1.5,
|
||||
text-short -asserts,
|
||||
any.text-zipper ==0.11,
|
||||
any.text-zipper ==0.13,
|
||||
any.tf-random ==0.5,
|
||||
any.th-abstraction ==0.4.3.0,
|
||||
any.th-compat ==0.1.3,
|
||||
any.th-lift ==0.8.2,
|
||||
any.th-lift-instances ==0.1.19,
|
||||
any.these ==1.1.1.1,
|
||||
these +assoc,
|
||||
any.th-abstraction ==0.5.0.0,
|
||||
any.th-compat ==0.1.4,
|
||||
any.th-lift ==0.8.4,
|
||||
any.th-lift-instances ==0.1.20,
|
||||
any.these ==1.2,
|
||||
any.time ==1.9.3,
|
||||
any.time-compat ==1.9.6.1,
|
||||
time-compat -old-locale,
|
||||
any.transformers ==0.5.6.2,
|
||||
any.transformers-base ==0.4.6,
|
||||
transformers-base +orphaninstances,
|
||||
any.transformers-compat ==0.7.1,
|
||||
any.transformers-compat ==0.7.2,
|
||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||
any.unicode-data ==0.3.0,
|
||||
any.typed-process ==0.2.11.1,
|
||||
any.unicode-data ==0.3.1,
|
||||
unicode-data -ucd2haskell,
|
||||
any.unix ==2.7.2.2,
|
||||
any.unix-bytestring ==0.3.7.7,
|
||||
any.unix-compat ==0.6,
|
||||
any.unix-bytestring ==0.3.7.8,
|
||||
any.unix-compat ==0.7.1,
|
||||
unix-compat -old-time,
|
||||
any.unliftio-core ==0.2.0.1,
|
||||
any.unordered-containers ==0.2.19.1,
|
||||
any.unliftio-core ==0.2.1.0,
|
||||
any.unordered-containers ==0.2.20,
|
||||
unordered-containers -debug,
|
||||
any.uri-bytestring ==0.3.3.1,
|
||||
uri-bytestring -lib-werror,
|
||||
any.utf8-string ==1.0.2,
|
||||
any.uuid-types ==1.0.5,
|
||||
any.vector ==0.12.3.1,
|
||||
any.uuid-types ==1.0.5.1,
|
||||
any.vector ==0.13.1.0,
|
||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||
any.versions ==5.0.3,
|
||||
any.vty ==5.33,
|
||||
any.vector-algorithms ==0.9.0.1,
|
||||
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
|
||||
any.vector-binary-instances ==0.2.5.2,
|
||||
any.vector-stream ==0.1.0.1,
|
||||
any.versions ==6.0.4,
|
||||
any.vty ==6.0,
|
||||
any.vty-crossplatform ==0.2.0.0,
|
||||
vty-crossplatform -demos,
|
||||
any.vty-unix ==0.1.0.0,
|
||||
any.witherable ==0.4.2,
|
||||
any.word-wrap ==0.5,
|
||||
any.word8 ==0.1.3,
|
||||
any.xor ==0.0.1.1,
|
||||
any.yaml-streamly ==0.12.1,
|
||||
any.xor ==0.0.1.2,
|
||||
any.yaml-streamly ==0.12.4,
|
||||
yaml-streamly +no-examples +no-exe,
|
||||
any.zip ==2.0.0,
|
||||
zip -dev -disable-bzip2 -disable-zstd,
|
||||
any.zlib ==0.6.3.0,
|
||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||
any.zlib-bindings ==0.1.1.5
|
||||
index-state: hackage.haskell.org 2022-06-04T19:47:01Z
|
||||
any.zlib-bindings ==0.1.1.5,
|
||||
any.zstd ==0.1.3.0,
|
||||
zstd +standalone
|
||||
index-state: hackage.haskell.org 2024-01-19T19:48:54Z
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
packages: ./ghcup.cabal
|
||||
|
||||
optional-packages: ./vendored/*/*.cabal
|
||||
|
||||
optimization: 2
|
||||
|
||||
package ghcup
|
||||
tests: True
|
||||
flags: +tui
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/bgamari/terminal-size.git
|
||||
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.Cabal ==3.6.2.0,
|
||||
any.aeson >= 2.0.1.0,
|
||||
|
||||
package libarchive
|
||||
flags: -system-libarchive
|
||||
|
||||
package aeson-pretty
|
||||
flags: +lib-only
|
||||
|
||||
package cabal-plan
|
||||
flags: -exe
|
||||
|
||||
package aeson
|
||||
flags: +ordered-keymap
|
||||
|
||||
package streamly
|
||||
flags: +use-unliftio
|
||||
|
||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||
|
||||
with-compiler: ghc-9.2.3
|
||||
@@ -1,233 +0,0 @@
|
||||
active-repositories: hackage.haskell.org:merge
|
||||
constraints: any.Cabal ==3.6.2.0,
|
||||
Cabal -bundled-binary-generic,
|
||||
any.HUnit ==1.6.2.0,
|
||||
any.HsOpenSSL ==0.11.7.2,
|
||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||
any.OneTuple ==0.3.1,
|
||||
any.QuickCheck ==2.14.2,
|
||||
QuickCheck -old-random +templatehaskell,
|
||||
any.StateVar ==1.2.2,
|
||||
any.abstract-deque ==0.3,
|
||||
abstract-deque -usecas,
|
||||
any.aeson ==2.0.3.0,
|
||||
aeson -cffi +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.9,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.2.7.1,
|
||||
any.ansi-terminal ==0.11.3,
|
||||
ansi-terminal -example,
|
||||
any.ansi-wl-pprint ==0.6.9,
|
||||
ansi-wl-pprint -example,
|
||||
any.array ==0.5.4.0,
|
||||
any.assoc ==1.0.2,
|
||||
any.async ==2.2.4,
|
||||
async -bench,
|
||||
any.atomic-primops ==0.8.4,
|
||||
atomic-primops -debug,
|
||||
any.attoparsec ==0.14.4,
|
||||
attoparsec -developer,
|
||||
any.base ==4.16.2.0,
|
||||
any.base-compat ==0.12.1,
|
||||
any.base-compat-batteries ==0.12.1,
|
||||
any.base-orphans ==0.8.6,
|
||||
any.base16-bytestring ==1.0.2.0,
|
||||
any.base64-bytestring ==1.2.1.0,
|
||||
any.bifunctors ==5.5.12,
|
||||
bifunctors +semigroups +tagged,
|
||||
any.binary ==0.8.9.0,
|
||||
any.blaze-builder ==0.4.2.2,
|
||||
any.brick ==0.64.2,
|
||||
brick -demos,
|
||||
any.bytestring ==0.11.3.1,
|
||||
any.bz2 ==1.0.1.0,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-plan ==0.7.2.1,
|
||||
cabal-plan -_ -exe -license-report,
|
||||
any.call-stack ==0.4.0,
|
||||
any.case-insensitive ==1.2.1.0,
|
||||
any.casing ==0.1.4.1,
|
||||
any.chs-cabal ==0.1.1.1,
|
||||
any.chs-deps ==0.1.0.0,
|
||||
chs-deps -cross,
|
||||
any.clock ==0.8.3,
|
||||
clock -llvm,
|
||||
any.colour ==2.3.6,
|
||||
any.comonad ==5.0.8,
|
||||
comonad +containers +distributive +indexed-traversable,
|
||||
any.composition-prelude ==3.0.0.2,
|
||||
composition-prelude -development,
|
||||
any.config-ini ==0.2.4.0,
|
||||
config-ini -enable-doctests,
|
||||
any.containers ==0.6.5.1,
|
||||
any.contravariant ==1.5.5,
|
||||
contravariant +semigroups +statevar +tagged,
|
||||
any.cpphs ==1.20.9.1,
|
||||
cpphs -old-locale,
|
||||
any.cryptohash-sha1 ==0.11.101.0,
|
||||
any.cryptohash-sha256 ==0.11.102.1,
|
||||
cryptohash-sha256 -exe +use-cbits,
|
||||
any.data-clist ==0.2,
|
||||
any.data-fix ==0.3.2,
|
||||
any.deepseq ==1.4.6.1,
|
||||
any.directory ==1.3.7.0,
|
||||
any.disk-free-space ==0.1.0.1,
|
||||
any.distributive ==0.6.2.1,
|
||||
distributive +semigroups +tagged,
|
||||
any.dlist ==1.0,
|
||||
dlist -werror,
|
||||
any.exceptions ==0.10.4,
|
||||
any.filepath ==1.4.2.2,
|
||||
any.free ==5.1.8,
|
||||
any.fusion-plugin-types ==0.1.0,
|
||||
any.generic-arbitrary ==0.2.2,
|
||||
any.ghc-bignum ==1.2,
|
||||
any.ghc-boot-th ==9.2.3,
|
||||
any.ghc-byteorder ==4.11.0.0.10,
|
||||
any.ghc-prim ==0.8.0,
|
||||
any.happy ==1.20.0,
|
||||
any.hashable ==1.4.0.2,
|
||||
hashable +containers +integer-gmp -random-initial-seed,
|
||||
any.haskus-utils-data ==1.4,
|
||||
any.haskus-utils-types ==1.5.1,
|
||||
any.haskus-utils-variant ==3.2.1,
|
||||
any.heaps ==0.4,
|
||||
any.hsc2hs ==0.68.8,
|
||||
hsc2hs -in-ghc-tree,
|
||||
any.hspec ==2.9.2,
|
||||
any.hspec-core ==2.9.2,
|
||||
any.hspec-discover ==2.9.2,
|
||||
any.hspec-expectations ==0.8.2,
|
||||
any.hspec-golden-aeson ==0.9.0.0,
|
||||
any.http-io-streams ==0.1.6.1,
|
||||
http-io-streams -brotli +fast-xor,
|
||||
any.indexed-profunctors ==0.1.1,
|
||||
any.indexed-traversable ==0.1.2,
|
||||
any.indexed-traversable-instances ==0.1.1,
|
||||
any.integer-logarithms ==1.0.3.1,
|
||||
integer-logarithms -check-bounds +integer-gmp,
|
||||
any.io-streams ==1.5.2.1,
|
||||
io-streams +network -nointeractivetests +zlib,
|
||||
any.language-c ==0.9.1,
|
||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||
any.libarchive ==3.0.3.2,
|
||||
libarchive -cross -low-memory +no-exe -system-libarchive,
|
||||
any.libyaml-streamly ==0.2.1,
|
||||
libyaml-streamly -no-unicode -system-libyaml,
|
||||
any.lockfree-queue ==0.2.3.1,
|
||||
any.lzma-static ==5.2.5.4,
|
||||
any.megaparsec ==9.2.1,
|
||||
megaparsec -dev,
|
||||
any.microlens ==0.4.12.0,
|
||||
any.microlens-mtl ==0.2.0.2,
|
||||
any.microlens-th ==0.4.3.10,
|
||||
any.mtl ==2.2.2,
|
||||
any.network ==3.1.2.7,
|
||||
network -devel,
|
||||
any.network-uri ==2.6.4.1,
|
||||
any.openssl-streams ==1.2.3.0,
|
||||
any.optics ==0.4.2,
|
||||
any.optics-core ==0.4.1,
|
||||
optics-core -explicit-generic-labels,
|
||||
any.optics-extra ==0.4.2.1,
|
||||
any.optics-th ==0.4.1,
|
||||
any.optparse-applicative ==0.17.0.0,
|
||||
optparse-applicative +process,
|
||||
any.os-release ==1.0.2.1,
|
||||
os-release -devel,
|
||||
any.parallel ==3.2.2.0,
|
||||
any.parsec ==3.1.15.0,
|
||||
any.parser-combinators ==1.3.0,
|
||||
parser-combinators -dev,
|
||||
any.polyparse ==1.13,
|
||||
any.pretty ==1.1.3.6,
|
||||
any.pretty-terminal ==0.1.0.0,
|
||||
any.primitive ==0.7.4.0,
|
||||
any.process ==1.6.14.0,
|
||||
any.profunctors ==5.6.2,
|
||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||
any.quickcheck-io ==0.2.0,
|
||||
any.random ==1.2.1.1,
|
||||
any.recursion-schemes ==5.2.2.2,
|
||||
recursion-schemes +template-haskell,
|
||||
any.regex-base ==0.94.0.2,
|
||||
any.regex-posix ==0.96.0.1,
|
||||
regex-posix -_regex-posix-clib,
|
||||
any.resourcet ==1.2.5,
|
||||
any.retry ==0.8.1.2,
|
||||
retry -lib-werror,
|
||||
any.rts ==1.0.2,
|
||||
any.safe ==0.3.19,
|
||||
any.safe-exceptions ==0.1.7.3,
|
||||
any.scientific ==0.3.7.0,
|
||||
scientific -bytestring-builder -integer-simple,
|
||||
any.semialign ==1.2.0.1,
|
||||
semialign +semigroupoids,
|
||||
any.semigroupoids ==5.3.7,
|
||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||
any.setenv ==0.1.1.3,
|
||||
any.split ==0.2.3.4,
|
||||
any.splitmix ==0.1.0.4,
|
||||
splitmix -optimised-mixer,
|
||||
any.stm ==2.5.0.2,
|
||||
any.streamly ==0.8.2,
|
||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -streamly-core -use-c-malloc +use-unliftio,
|
||||
any.strict ==0.4.0.1,
|
||||
strict +assoc,
|
||||
any.strict-base ==0.4.0.0,
|
||||
any.tagged ==0.8.6.1,
|
||||
tagged +deepseq +transformers,
|
||||
any.tagsoup ==0.14.8,
|
||||
any.template-haskell ==2.18.0.0,
|
||||
any.temporary ==1.3,
|
||||
any.terminal-progress-bar ==0.4.1,
|
||||
any.terminal-size ==0.3.2.1,
|
||||
any.terminfo ==0.4.1.5,
|
||||
any.text ==1.2.5.0,
|
||||
any.text-short ==0.1.5,
|
||||
text-short -asserts,
|
||||
any.text-zipper ==0.11,
|
||||
any.tf-random ==0.5,
|
||||
any.th-abstraction ==0.4.3.0,
|
||||
any.th-compat ==0.1.3,
|
||||
any.th-lift ==0.8.2,
|
||||
any.th-lift-instances ==0.1.19,
|
||||
any.these ==1.1.1.1,
|
||||
these +assoc,
|
||||
any.time ==1.9.3,
|
||||
any.time-compat ==1.9.6.1,
|
||||
time-compat -old-locale,
|
||||
any.transformers ==0.5.6.2,
|
||||
any.transformers-base ==0.4.6,
|
||||
transformers-base +orphaninstances,
|
||||
any.transformers-compat ==0.7.1,
|
||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||
any.unicode-data ==0.3.0,
|
||||
unicode-data -ucd2haskell,
|
||||
any.unix ==2.7.2.2,
|
||||
any.unix-bytestring ==0.3.7.7,
|
||||
any.unix-compat ==0.6,
|
||||
unix-compat -old-time,
|
||||
any.unliftio-core ==0.2.0.1,
|
||||
any.unordered-containers ==0.2.19.1,
|
||||
unordered-containers -debug,
|
||||
any.uri-bytestring ==0.3.3.1,
|
||||
uri-bytestring -lib-werror,
|
||||
any.utf8-string ==1.0.2,
|
||||
any.uuid-types ==1.0.5,
|
||||
any.vector ==0.12.3.1,
|
||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||
any.versions ==5.0.3,
|
||||
any.vty ==5.33,
|
||||
any.witherable ==0.4.2,
|
||||
any.word-wrap ==0.5,
|
||||
any.word8 ==0.1.3,
|
||||
any.xor ==0.0.1.1,
|
||||
any.yaml-streamly ==0.12.1,
|
||||
yaml-streamly +no-examples +no-exe,
|
||||
any.zlib ==0.6.3.0,
|
||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||
any.zlib-bindings ==0.1.1.5
|
||||
index-state: hackage.haskell.org 2022-06-04T19:47:01Z
|
||||
55
cabal.ghc928.project
Normal file
55
cabal.ghc928.project
Normal file
@@ -0,0 +1,55 @@
|
||||
packages: ./ghcup.cabal
|
||||
|
||||
optional-packages: ./vendored/*/*.cabal
|
||||
|
||||
if impl(ghc < 9.0)
|
||||
package ghcup
|
||||
flags: +tui -tar
|
||||
else
|
||||
package ghcup
|
||||
flags: +tui +tar
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
|
||||
if os(mingw32)
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/tar.git
|
||||
tag: d94a988be4311b830149a9f8fc16739927e5fc1c
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/uri-bytestring.git
|
||||
tag: 4fb5ed14b500c192e6e7a97f6b2b1eb478806001
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/versions.git
|
||||
tag: 79e18fbc44fae3064d8957c550cc0229465db320
|
||||
|
||||
package libarchive
|
||||
flags: -system-libarchive
|
||||
|
||||
package aeson-pretty
|
||||
flags: +lib-only
|
||||
|
||||
package cabal-plan
|
||||
flags: -exe
|
||||
|
||||
package aeson
|
||||
flags: +ordered-keymap
|
||||
|
||||
package streamly
|
||||
flags: +use-unliftio
|
||||
|
||||
package *
|
||||
test-show-details: direct
|
||||
|
||||
allow-newer: cabal-install-parsers:tar
|
||||
|
||||
|
||||
with-compiler: ghc-9.2.8
|
||||
269
cabal.ghc928.project.freeze
Normal file
269
cabal.ghc928.project.freeze
Normal file
@@ -0,0 +1,269 @@
|
||||
active-repositories: hackage.haskell.org:merge
|
||||
constraints: any.Cabal ==3.6.3.0,
|
||||
Cabal -bundled-binary-generic,
|
||||
any.Cabal-syntax ==3.10.2.0,
|
||||
any.HUnit ==1.6.2.0,
|
||||
any.HsOpenSSL ==0.11.7.6,
|
||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||
any.OneTuple ==0.4.1.1,
|
||||
any.QuickCheck ==2.14.3,
|
||||
QuickCheck -old-random +templatehaskell,
|
||||
any.StateVar ==1.2.2,
|
||||
any.abstract-deque ==0.3,
|
||||
abstract-deque -usecas,
|
||||
any.aeson ==2.1.2.1,
|
||||
aeson -cffi +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.10,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.5.0.0,
|
||||
any.ansi-terminal ==1.0.2,
|
||||
ansi-terminal -example,
|
||||
any.ansi-terminal-types ==0.11.5,
|
||||
any.ansi-wl-pprint ==0.6.9,
|
||||
ansi-wl-pprint -example,
|
||||
any.array ==0.5.4.0,
|
||||
any.assoc ==1.1,
|
||||
assoc +tagged,
|
||||
any.async ==2.2.5,
|
||||
async -bench,
|
||||
any.atomic-primops ==0.8.4,
|
||||
atomic-primops -debug,
|
||||
any.attoparsec ==0.14.4,
|
||||
attoparsec -developer,
|
||||
any.base ==4.16.4.0,
|
||||
any.base-compat ==0.13.1,
|
||||
any.base-compat-batteries ==0.13.1,
|
||||
any.base-orphans ==0.9.1,
|
||||
any.base16-bytestring ==1.0.2.0,
|
||||
any.base64-bytestring ==1.2.1.0,
|
||||
any.bifunctors ==5.6.1,
|
||||
bifunctors +tagged,
|
||||
any.bimap ==0.5.0,
|
||||
any.binary ==0.8.9.0,
|
||||
any.binary-instances ==1.0.4,
|
||||
any.binary-orphans ==1.0.4.1,
|
||||
any.bindings-DSL ==1.0.25,
|
||||
any.bitvec ==1.1.5.0,
|
||||
bitvec +simd,
|
||||
any.blaze-builder ==0.4.2.3,
|
||||
any.brick ==2.1.1,
|
||||
brick -demos,
|
||||
any.bytestring ==0.11.4.0,
|
||||
any.bz2 ==1.0.1.0,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.bzlib-conduit ==0.3.0.2,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-install-parsers ==0.6.1,
|
||||
any.cabal-plan ==0.7.3.0,
|
||||
cabal-plan -_ -exe -license-report,
|
||||
any.call-stack ==0.4.0,
|
||||
any.case-insensitive ==1.2.1.0,
|
||||
any.casing ==0.1.4.1,
|
||||
any.cereal ==0.5.8.3,
|
||||
cereal -bytestring-builder,
|
||||
any.colour ==2.3.6,
|
||||
any.comonad ==5.0.8,
|
||||
comonad +containers +distributive +indexed-traversable,
|
||||
any.conduit ==1.3.5,
|
||||
any.conduit-extra ==1.3.6,
|
||||
any.conduit-zstd ==0.0.2.0,
|
||||
any.config-ini ==0.2.7.0,
|
||||
config-ini -enable-doctests,
|
||||
any.containers ==0.6.5.1,
|
||||
any.contravariant ==1.5.5,
|
||||
contravariant +semigroups +statevar +tagged,
|
||||
any.cryptohash-sha1 ==0.11.101.0,
|
||||
any.cryptohash-sha256 ==0.11.102.1,
|
||||
cryptohash-sha256 -exe +use-cbits,
|
||||
any.data-array-byte ==0.1.0.1,
|
||||
any.data-clist ==0.2,
|
||||
any.data-default-class ==0.1.2.0,
|
||||
any.data-fix ==0.3.2,
|
||||
any.deepseq ==1.4.6.1,
|
||||
any.digest ==0.0.2.0,
|
||||
digest -have_arm64_crc32c -have_builtin_prefetch -have_mm_prefetch -have_sse42 -have_strong_getauxval -have_weak_getauxval +pkg-config,
|
||||
any.directory ==1.3.6.2,
|
||||
any.disk-free-space ==0.1.0.1,
|
||||
any.distributive ==0.6.2.1,
|
||||
distributive +semigroups +tagged,
|
||||
any.dlist ==1.0,
|
||||
dlist -werror,
|
||||
any.exceptions ==0.10.4,
|
||||
any.file-uri ==0.1.0.0,
|
||||
any.filepath ==1.4.2.2,
|
||||
any.foldable1-classes-compat ==0.1,
|
||||
foldable1-classes-compat +tagged,
|
||||
any.free ==5.2,
|
||||
any.fusion-plugin-types ==0.1.0,
|
||||
any.generic-arbitrary ==0.2.2,
|
||||
any.generically ==0.1.1,
|
||||
any.ghc-bignum ==1.2,
|
||||
any.ghc-boot-th ==9.2.8,
|
||||
any.ghc-byteorder ==4.11.0.0.10,
|
||||
any.ghc-prim ==0.8.0,
|
||||
any.happy ==1.20.1.1,
|
||||
any.hashable ==1.4.3.0,
|
||||
hashable +integer-gmp -random-initial-seed,
|
||||
any.haskell-lexer ==1.1.1,
|
||||
any.haskus-utils-data ==1.4,
|
||||
any.haskus-utils-types ==1.5.1,
|
||||
any.haskus-utils-variant ==3.3,
|
||||
any.heaps ==0.4,
|
||||
any.hsc2hs ==0.68.10,
|
||||
hsc2hs -in-ghc-tree,
|
||||
any.hspec ==2.10.10,
|
||||
any.hspec-core ==2.10.10,
|
||||
any.hspec-discover ==2.10.10,
|
||||
any.hspec-expectations ==0.8.2,
|
||||
any.hspec-golden-aeson ==0.9.0.0,
|
||||
any.http-io-streams ==0.1.6.3,
|
||||
http-io-streams -brotli +fast-xor,
|
||||
any.indexed-profunctors ==0.1.1.1,
|
||||
any.indexed-traversable ==0.1.3,
|
||||
any.indexed-traversable-instances ==0.1.1.2,
|
||||
any.integer-logarithms ==1.0.3.1,
|
||||
integer-logarithms -check-bounds +integer-gmp,
|
||||
any.io-streams ==1.5.2.2,
|
||||
io-streams +network -nointeractivetests +zlib,
|
||||
any.language-c ==0.9.2,
|
||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||
any.libyaml-streamly ==0.2.2,
|
||||
libyaml-streamly -no-unicode -system-libyaml,
|
||||
any.lockfree-queue ==0.2.4,
|
||||
any.lukko ==0.1.1.3,
|
||||
lukko +ofd-locking,
|
||||
any.lzma-static ==5.2.5.5,
|
||||
any.megaparsec ==9.2.2,
|
||||
megaparsec -dev,
|
||||
any.microlens ==0.4.13.1,
|
||||
any.microlens-mtl ==0.2.0.3,
|
||||
any.microlens-th ==0.4.3.14,
|
||||
any.monad-control ==1.0.3.1,
|
||||
any.mono-traversable ==1.0.15.3,
|
||||
any.mtl ==2.2.2,
|
||||
any.mtl-compat ==0.2.2,
|
||||
mtl-compat -two-point-one -two-point-two,
|
||||
any.network ==3.1.4.0,
|
||||
network -devel,
|
||||
any.network-uri ==2.6.4.2,
|
||||
any.openssl-streams ==1.2.3.0,
|
||||
any.optics ==0.4.2.1,
|
||||
any.optics-core ==0.4.1.1,
|
||||
optics-core -explicit-generic-labels,
|
||||
any.optics-extra ==0.4.2.1,
|
||||
any.optics-th ==0.4.1,
|
||||
any.optparse-applicative ==0.17.1.0,
|
||||
optparse-applicative +process,
|
||||
any.os-release ==1.0.2.1,
|
||||
os-release -devel,
|
||||
any.parsec ==3.1.17.0,
|
||||
any.parser-combinators ==1.3.0,
|
||||
parser-combinators -dev,
|
||||
any.pretty ==1.1.3.6,
|
||||
any.pretty-terminal ==0.1.0.0,
|
||||
any.primitive ==0.8.0.0,
|
||||
any.process ==1.6.16.0,
|
||||
any.profunctors ==5.6.2,
|
||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||
any.quickcheck-io ==0.2.0,
|
||||
any.random ==1.2.1.1,
|
||||
any.recursion-schemes ==5.2.2.5,
|
||||
recursion-schemes +template-haskell,
|
||||
any.regex-base ==0.94.0.2,
|
||||
any.regex-posix ==0.96.0.1,
|
||||
regex-posix -_regex-posix-clib,
|
||||
any.resourcet ==1.2.6,
|
||||
any.retry ==0.9.3.1,
|
||||
retry -lib-werror,
|
||||
any.rts ==1.0.2,
|
||||
any.safe ==0.3.21,
|
||||
any.safe-exceptions ==0.1.7.4,
|
||||
any.scientific ==0.3.7.0,
|
||||
scientific -bytestring-builder -integer-simple,
|
||||
any.semialign ==1.3,
|
||||
semialign +semigroupoids,
|
||||
any.semigroupoids ==6.0.0.1,
|
||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||
any.setenv ==0.1.1.3,
|
||||
any.split ==0.2.5,
|
||||
any.splitmix ==0.1.0.5,
|
||||
splitmix -optimised-mixer,
|
||||
any.stm ==2.5.0.2,
|
||||
any.streaming-commons ==0.2.2.6,
|
||||
streaming-commons -use-bytestring-builder,
|
||||
any.streamly ==0.8.3,
|
||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -streamly-core -use-c-malloc +use-unliftio,
|
||||
any.strict ==0.5,
|
||||
any.strict-base ==0.4.0.0,
|
||||
any.tagged ==0.8.8,
|
||||
tagged +deepseq +transformers,
|
||||
any.tagsoup ==0.14.8,
|
||||
any.tar ==0.6.0.0,
|
||||
any.tasty ==1.5,
|
||||
tasty +unix,
|
||||
any.tasty-hunit ==0.10.1,
|
||||
any.template-haskell ==2.18.0.0,
|
||||
any.temporary ==1.3,
|
||||
any.terminal-progress-bar ==0.4.2,
|
||||
any.terminal-size ==0.3.4,
|
||||
any.terminfo ==0.4.1.5,
|
||||
any.text ==2.0.2,
|
||||
text -developer +simdutf,
|
||||
any.text-binary ==0.2.1.1,
|
||||
any.text-short ==0.1.5,
|
||||
text-short -asserts,
|
||||
any.text-zipper ==0.13,
|
||||
any.tf-random ==0.5,
|
||||
any.th-abstraction ==0.5.0.0,
|
||||
any.th-compat ==0.1.4,
|
||||
any.th-lift ==0.8.4,
|
||||
any.th-lift-instances ==0.1.20,
|
||||
any.these ==1.2,
|
||||
any.time ==1.11.1.1,
|
||||
any.time-compat ==1.9.6.1,
|
||||
time-compat -old-locale,
|
||||
any.transformers ==0.5.6.2,
|
||||
any.transformers-base ==0.4.6,
|
||||
transformers-base +orphaninstances,
|
||||
any.transformers-compat ==0.7.2,
|
||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||
any.typed-process ==0.2.11.1,
|
||||
any.unicode-data ==0.3.1,
|
||||
unicode-data -ucd2haskell,
|
||||
any.unix ==2.7.2.2,
|
||||
any.unix-bytestring ==0.3.7.8,
|
||||
any.unix-compat ==0.7.1,
|
||||
unix-compat -old-time,
|
||||
any.unliftio-core ==0.2.1.0,
|
||||
any.unordered-containers ==0.2.20,
|
||||
unordered-containers -debug,
|
||||
any.uri-bytestring ==0.3.3.1,
|
||||
uri-bytestring -lib-werror,
|
||||
any.utf8-string ==1.0.2,
|
||||
any.uuid-types ==1.0.5.1,
|
||||
any.vector ==0.13.1.0,
|
||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||
any.vector-algorithms ==0.9.0.1,
|
||||
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
|
||||
any.vector-binary-instances ==0.2.5.2,
|
||||
any.vector-stream ==0.1.0.1,
|
||||
any.versions ==6.0.4,
|
||||
any.vty ==6.0,
|
||||
any.vty-crossplatform ==0.2.0.0,
|
||||
vty-crossplatform -demos,
|
||||
any.vty-unix ==0.1.0.0,
|
||||
any.witherable ==0.4.2,
|
||||
any.word-wrap ==0.5,
|
||||
any.word8 ==0.1.3,
|
||||
any.xor ==0.0.1.2,
|
||||
any.yaml-streamly ==0.12.4,
|
||||
yaml-streamly +no-examples +no-exe,
|
||||
any.zip ==2.0.0,
|
||||
zip -dev -disable-bzip2 -disable-zstd,
|
||||
any.zlib ==0.6.3.0,
|
||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||
any.zlib-bindings ==0.1.1.5,
|
||||
any.zstd ==0.1.3.0,
|
||||
zstd +standalone
|
||||
index-state: hackage.haskell.org 2024-01-19T19:48:54Z
|
||||
55
cabal.ghc948.project
Normal file
55
cabal.ghc948.project
Normal file
@@ -0,0 +1,55 @@
|
||||
packages: ./ghcup.cabal
|
||||
|
||||
optional-packages: ./vendored/*/*.cabal
|
||||
|
||||
if impl(ghc < 9.0)
|
||||
package ghcup
|
||||
flags: +tui -tar
|
||||
else
|
||||
package ghcup
|
||||
flags: +tui +tar
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
|
||||
if os(mingw32)
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/tar.git
|
||||
tag: d94a988be4311b830149a9f8fc16739927e5fc1c
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/uri-bytestring.git
|
||||
tag: 4fb5ed14b500c192e6e7a97f6b2b1eb478806001
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/versions.git
|
||||
tag: 79e18fbc44fae3064d8957c550cc0229465db320
|
||||
|
||||
package libarchive
|
||||
flags: -system-libarchive
|
||||
|
||||
package aeson-pretty
|
||||
flags: +lib-only
|
||||
|
||||
package cabal-plan
|
||||
flags: -exe
|
||||
|
||||
package aeson
|
||||
flags: +ordered-keymap
|
||||
|
||||
package streamly
|
||||
flags: +use-unliftio
|
||||
|
||||
package *
|
||||
test-show-details: direct
|
||||
|
||||
allow-newer: cabal-install-parsers:tar
|
||||
|
||||
|
||||
with-compiler: ghc-9.4.8
|
||||
267
cabal.ghc948.project.freeze
Normal file
267
cabal.ghc948.project.freeze
Normal file
@@ -0,0 +1,267 @@
|
||||
active-repositories: hackage.haskell.org:merge
|
||||
constraints: any.Cabal ==3.6.3.0 || ==3.8.1.0,
|
||||
Cabal -bundled-binary-generic,
|
||||
any.Cabal-syntax ==3.8.1.0 || ==3.10.2.0,
|
||||
any.HUnit ==1.6.2.0,
|
||||
any.HsOpenSSL ==0.11.7.6,
|
||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||
any.OneTuple ==0.4.1.1,
|
||||
any.QuickCheck ==2.14.3,
|
||||
QuickCheck -old-random +templatehaskell,
|
||||
any.StateVar ==1.2.2,
|
||||
any.abstract-deque ==0.3,
|
||||
abstract-deque -usecas,
|
||||
any.aeson ==2.1.2.1,
|
||||
aeson -cffi +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.10,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.5.0.0,
|
||||
any.ansi-terminal ==1.0.2,
|
||||
ansi-terminal -example,
|
||||
any.ansi-terminal-types ==0.11.5,
|
||||
any.ansi-wl-pprint ==0.6.9,
|
||||
ansi-wl-pprint -example,
|
||||
any.array ==0.5.4.0,
|
||||
any.assoc ==1.1,
|
||||
assoc +tagged,
|
||||
any.async ==2.2.5,
|
||||
async -bench,
|
||||
any.atomic-primops ==0.8.4,
|
||||
atomic-primops -debug,
|
||||
any.attoparsec ==0.14.4,
|
||||
attoparsec -developer,
|
||||
any.base ==4.17.2.1,
|
||||
any.base-compat ==0.13.1,
|
||||
any.base-compat-batteries ==0.13.1,
|
||||
any.base-orphans ==0.9.1,
|
||||
any.base16-bytestring ==1.0.2.0,
|
||||
any.base64-bytestring ==1.2.1.0,
|
||||
any.bifunctors ==5.6.1,
|
||||
bifunctors +tagged,
|
||||
any.bimap ==0.5.0,
|
||||
any.binary ==0.8.9.1,
|
||||
any.binary-instances ==1.0.4,
|
||||
any.binary-orphans ==1.0.4.1,
|
||||
any.bindings-DSL ==1.0.25,
|
||||
any.bitvec ==1.1.5.0,
|
||||
bitvec +simd,
|
||||
any.blaze-builder ==0.4.2.3,
|
||||
any.brick ==2.1.1,
|
||||
brick -demos,
|
||||
any.bytestring ==0.11.5.3,
|
||||
any.bz2 ==1.0.1.0,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.bzlib-conduit ==0.3.0.2,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-install-parsers ==0.6.1,
|
||||
any.cabal-plan ==0.7.3.0,
|
||||
cabal-plan -_ -exe -license-report,
|
||||
any.call-stack ==0.4.0,
|
||||
any.case-insensitive ==1.2.1.0,
|
||||
any.casing ==0.1.4.1,
|
||||
any.cereal ==0.5.8.3,
|
||||
cereal -bytestring-builder,
|
||||
any.colour ==2.3.6,
|
||||
any.comonad ==5.0.8,
|
||||
comonad +containers +distributive +indexed-traversable,
|
||||
any.conduit ==1.3.5,
|
||||
any.conduit-extra ==1.3.6,
|
||||
any.conduit-zstd ==0.0.2.0,
|
||||
any.config-ini ==0.2.7.0,
|
||||
config-ini -enable-doctests,
|
||||
any.containers ==0.6.7,
|
||||
any.contravariant ==1.5.5,
|
||||
contravariant +semigroups +statevar +tagged,
|
||||
any.cryptohash-sha1 ==0.11.101.0,
|
||||
any.cryptohash-sha256 ==0.11.102.1,
|
||||
cryptohash-sha256 -exe +use-cbits,
|
||||
any.data-clist ==0.2,
|
||||
any.data-default-class ==0.1.2.0,
|
||||
any.data-fix ==0.3.2,
|
||||
any.deepseq ==1.4.8.0,
|
||||
any.digest ==0.0.2.0,
|
||||
digest -have_arm64_crc32c -have_builtin_prefetch -have_mm_prefetch -have_sse42 -have_strong_getauxval -have_weak_getauxval +pkg-config,
|
||||
any.directory ==1.3.7.1,
|
||||
any.disk-free-space ==0.1.0.1,
|
||||
any.distributive ==0.6.2.1,
|
||||
distributive +semigroups +tagged,
|
||||
any.dlist ==1.0,
|
||||
dlist -werror,
|
||||
any.exceptions ==0.10.5,
|
||||
any.file-uri ==0.1.0.0,
|
||||
any.filepath ==1.4.2.2,
|
||||
any.foldable1-classes-compat ==0.1,
|
||||
foldable1-classes-compat +tagged,
|
||||
any.free ==5.2,
|
||||
any.fusion-plugin-types ==0.1.0,
|
||||
any.generic-arbitrary ==0.2.2,
|
||||
any.generically ==0.1.1,
|
||||
any.ghc-bignum ==1.3,
|
||||
any.ghc-boot-th ==9.4.8,
|
||||
any.ghc-byteorder ==4.11.0.0.10,
|
||||
any.ghc-prim ==0.9.1,
|
||||
any.happy ==1.20.1.1,
|
||||
any.hashable ==1.4.3.0,
|
||||
hashable +integer-gmp -random-initial-seed,
|
||||
any.haskell-lexer ==1.1.1,
|
||||
any.haskus-utils-data ==1.4,
|
||||
any.haskus-utils-types ==1.5.1,
|
||||
any.haskus-utils-variant ==3.3,
|
||||
any.heaps ==0.4,
|
||||
any.hsc2hs ==0.68.10,
|
||||
hsc2hs -in-ghc-tree,
|
||||
any.hspec ==2.10.10,
|
||||
any.hspec-core ==2.10.10,
|
||||
any.hspec-discover ==2.10.10,
|
||||
any.hspec-expectations ==0.8.2,
|
||||
any.hspec-golden-aeson ==0.9.0.0,
|
||||
any.http-io-streams ==0.1.6.3,
|
||||
http-io-streams -brotli +fast-xor,
|
||||
any.indexed-profunctors ==0.1.1.1,
|
||||
any.indexed-traversable ==0.1.3,
|
||||
any.indexed-traversable-instances ==0.1.1.2,
|
||||
any.integer-logarithms ==1.0.3.1,
|
||||
integer-logarithms -check-bounds +integer-gmp,
|
||||
any.io-streams ==1.5.2.2,
|
||||
io-streams +network -nointeractivetests +zlib,
|
||||
any.language-c ==0.9.2,
|
||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||
any.libyaml-streamly ==0.2.2,
|
||||
libyaml-streamly -no-unicode -system-libyaml,
|
||||
any.lockfree-queue ==0.2.4,
|
||||
any.lukko ==0.1.1.3,
|
||||
lukko +ofd-locking,
|
||||
any.lzma-static ==5.2.5.5,
|
||||
any.megaparsec ==9.2.2,
|
||||
megaparsec -dev,
|
||||
any.microlens ==0.4.13.1,
|
||||
any.microlens-mtl ==0.2.0.3,
|
||||
any.microlens-th ==0.4.3.14,
|
||||
any.monad-control ==1.0.3.1,
|
||||
any.mono-traversable ==1.0.15.3,
|
||||
any.mtl ==2.2.2,
|
||||
any.mtl-compat ==0.2.2,
|
||||
mtl-compat -two-point-one -two-point-two,
|
||||
any.network ==3.1.4.0,
|
||||
network -devel,
|
||||
any.network-uri ==2.6.4.2,
|
||||
any.openssl-streams ==1.2.3.0,
|
||||
any.optics ==0.4.2.1,
|
||||
any.optics-core ==0.4.1.1,
|
||||
optics-core -explicit-generic-labels,
|
||||
any.optics-extra ==0.4.2.1,
|
||||
any.optics-th ==0.4.1,
|
||||
any.optparse-applicative ==0.17.1.0,
|
||||
optparse-applicative +process,
|
||||
any.os-release ==1.0.2.1,
|
||||
os-release -devel,
|
||||
any.parsec ==3.1.16.1,
|
||||
any.parser-combinators ==1.3.0,
|
||||
parser-combinators -dev,
|
||||
any.pretty ==1.1.3.6,
|
||||
any.pretty-terminal ==0.1.0.0,
|
||||
any.primitive ==0.8.0.0,
|
||||
any.process ==1.6.18.0,
|
||||
any.profunctors ==5.6.2,
|
||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||
any.quickcheck-io ==0.2.0,
|
||||
any.random ==1.2.1.1,
|
||||
any.recursion-schemes ==5.2.2.5,
|
||||
recursion-schemes +template-haskell,
|
||||
any.regex-base ==0.94.0.2,
|
||||
any.regex-posix ==0.96.0.1,
|
||||
regex-posix -_regex-posix-clib,
|
||||
any.resourcet ==1.2.6,
|
||||
any.retry ==0.9.3.1,
|
||||
retry -lib-werror,
|
||||
any.rts ==1.0.2,
|
||||
any.safe ==0.3.21,
|
||||
any.safe-exceptions ==0.1.7.4,
|
||||
any.scientific ==0.3.7.0,
|
||||
scientific -bytestring-builder -integer-simple,
|
||||
any.semialign ==1.3,
|
||||
semialign +semigroupoids,
|
||||
any.semigroupoids ==6.0.0.1,
|
||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||
any.setenv ==0.1.1.3,
|
||||
any.split ==0.2.5,
|
||||
any.splitmix ==0.1.0.5,
|
||||
splitmix -optimised-mixer,
|
||||
any.stm ==2.5.1.0,
|
||||
any.streaming-commons ==0.2.2.6,
|
||||
streaming-commons -use-bytestring-builder,
|
||||
any.streamly ==0.8.3,
|
||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -streamly-core -use-c-malloc +use-unliftio,
|
||||
any.strict ==0.5,
|
||||
any.strict-base ==0.4.0.0,
|
||||
any.tagged ==0.8.8,
|
||||
tagged +deepseq +transformers,
|
||||
any.tagsoup ==0.14.8,
|
||||
any.tar ==0.6.0.0,
|
||||
any.tasty ==1.5,
|
||||
tasty +unix,
|
||||
any.tasty-hunit ==0.10.1,
|
||||
any.template-haskell ==2.19.0.0,
|
||||
any.temporary ==1.3,
|
||||
any.terminal-progress-bar ==0.4.2,
|
||||
any.terminal-size ==0.3.4,
|
||||
any.terminfo ==0.4.1.5,
|
||||
any.text ==2.0.2,
|
||||
any.text-binary ==0.2.1.1,
|
||||
any.text-short ==0.1.5,
|
||||
text-short -asserts,
|
||||
any.text-zipper ==0.13,
|
||||
any.tf-random ==0.5,
|
||||
any.th-abstraction ==0.5.0.0,
|
||||
any.th-compat ==0.1.4,
|
||||
any.th-lift ==0.8.4,
|
||||
any.th-lift-instances ==0.1.20,
|
||||
any.these ==1.2,
|
||||
any.time ==1.11.1.2 || ==1.12.2,
|
||||
any.time-compat ==1.9.6.1,
|
||||
time-compat -old-locale,
|
||||
any.transformers ==0.5.6.2,
|
||||
any.transformers-base ==0.4.6,
|
||||
transformers-base +orphaninstances,
|
||||
any.transformers-compat ==0.7.2,
|
||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||
any.typed-process ==0.2.11.1,
|
||||
any.unicode-data ==0.3.1,
|
||||
unicode-data -ucd2haskell,
|
||||
any.unix ==2.7.3,
|
||||
any.unix-bytestring ==0.3.7.8,
|
||||
any.unix-compat ==0.7.1,
|
||||
unix-compat -old-time,
|
||||
any.unliftio-core ==0.2.1.0,
|
||||
any.unordered-containers ==0.2.20,
|
||||
unordered-containers -debug,
|
||||
any.uri-bytestring ==0.3.3.1,
|
||||
uri-bytestring -lib-werror,
|
||||
any.utf8-string ==1.0.2,
|
||||
any.uuid-types ==1.0.5.1,
|
||||
any.vector ==0.13.1.0,
|
||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||
any.vector-algorithms ==0.9.0.1,
|
||||
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
|
||||
any.vector-binary-instances ==0.2.5.2,
|
||||
any.vector-stream ==0.1.0.1,
|
||||
any.versions ==6.0.4,
|
||||
any.vty ==6.0,
|
||||
any.vty-crossplatform ==0.2.0.0,
|
||||
vty-crossplatform -demos,
|
||||
any.vty-unix ==0.1.0.0,
|
||||
any.witherable ==0.4.2,
|
||||
any.word-wrap ==0.5,
|
||||
any.word8 ==0.1.3,
|
||||
any.xor ==0.0.1.2,
|
||||
any.yaml-streamly ==0.12.4,
|
||||
yaml-streamly +no-examples +no-exe,
|
||||
any.zip ==2.0.0,
|
||||
zip -dev -disable-bzip2 -disable-zstd,
|
||||
any.zlib ==0.6.3.0,
|
||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||
any.zlib-bindings ==0.1.1.5,
|
||||
any.zstd ==0.1.3.0,
|
||||
zstd +standalone
|
||||
index-state: hackage.haskell.org 2024-01-19T19:48:54Z
|
||||
@@ -2,19 +2,34 @@ packages: ./ghcup.cabal
|
||||
|
||||
optional-packages: ./vendored/*/*.cabal
|
||||
|
||||
optimization: 2
|
||||
if impl(ghc < 9.0)
|
||||
package ghcup
|
||||
flags: +tui -tar
|
||||
else
|
||||
package ghcup
|
||||
flags: +tui +tar
|
||||
|
||||
package ghcup
|
||||
flags: +tui
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
|
||||
if os(mingw32)
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/bgamari/terminal-size.git
|
||||
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
|
||||
location: https://github.com/haskell/tar.git
|
||||
tag: d94a988be4311b830149a9f8fc16739927e5fc1c
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.Cabal ==3.6.2.0,
|
||||
any.aeson >= 2.0.1.0,
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/uri-bytestring.git
|
||||
tag: 4fb5ed14b500c192e6e7a97f6b2b1eb478806001
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/versions.git
|
||||
tag: 79e18fbc44fae3064d8957c550cc0229465db320
|
||||
|
||||
package libarchive
|
||||
flags: -system-libarchive
|
||||
@@ -31,4 +46,8 @@ package aeson
|
||||
package streamly
|
||||
flags: +use-unliftio
|
||||
|
||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||
package *
|
||||
test-show-details: direct
|
||||
|
||||
allow-newer: cabal-install-parsers:tar
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
-- windows picks weird version
|
||||
constraints: any.hsc2hs ==0.68.7
|
||||
constraints: any.hsc2hs ==0.68.8
|
||||
|
||||
65
cabal.project.release
Normal file
65
cabal.project.release
Normal file
@@ -0,0 +1,65 @@
|
||||
packages: ./ghcup.cabal
|
||||
|
||||
optional-packages: ./vendored/*/*.cabal
|
||||
|
||||
optimization: 2
|
||||
|
||||
package ghcup
|
||||
flags: +tui -tar
|
||||
|
||||
if os(linux)
|
||||
if arch(x86_64) || arch(i386)
|
||||
package *
|
||||
ghc-options: -split-sections -optl-static
|
||||
elif os(darwin)
|
||||
constraints: zlib +bundled-c-zlib,
|
||||
lzma +static
|
||||
elif os(mingw32)
|
||||
constraints: zlib +bundled-c-zlib,
|
||||
lzma +static,
|
||||
text -simdutf,
|
||||
vty-windows >=0.1.0.3
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
elif os(freebsd)
|
||||
constraints: zlib +bundled-c-zlib,
|
||||
zip +disable-zstd
|
||||
package *
|
||||
ghc-options: -split-sections
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0,
|
||||
any.hsc2hs ==0.68.8
|
||||
|
||||
package libarchive
|
||||
flags: -system-libarchive
|
||||
|
||||
package aeson-pretty
|
||||
flags: +lib-only
|
||||
|
||||
package cabal-plan
|
||||
flags: -exe
|
||||
|
||||
package aeson
|
||||
flags: +ordered-keymap
|
||||
|
||||
package streamly
|
||||
flags: +use-unliftio
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/tar.git
|
||||
tag: d94a988be4311b830149a9f8fc16739927e5fc1c
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/uri-bytestring.git
|
||||
tag: 4fb5ed14b500c192e6e7a97f6b2b1eb478806001
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/hasufell/versions.git
|
||||
tag: 79e18fbc44fae3064d8957c550cc0229465db320
|
||||
|
||||
allow-newer: cabal-install-parsers:tar
|
||||
|
||||
104
data/config.yaml
104
data/config.yaml
@@ -16,6 +16,11 @@ gpg-setting: GPGNone # GPGStrict | GPGLax | GPGNone
|
||||
# TUI key bindings,
|
||||
# see https://hackage.haskell.org/package/vty-5.31/docs/Graphics-Vty-Input-Events.html#t:Key
|
||||
# for possible values.
|
||||
# It's also possible to define key+modifier, e.g.:
|
||||
# quit:
|
||||
# Key:
|
||||
# KChar: c
|
||||
# Mods: [MCtrl]
|
||||
key-bindings:
|
||||
up:
|
||||
KUp: []
|
||||
@@ -40,44 +45,54 @@ key-bindings:
|
||||
# of the file. These usually are in '~/.ghcup/cache/ghcup-<ver>.yaml'.
|
||||
meta-cache: 300 # in seconds
|
||||
|
||||
# Where to get GHC/cabal/hls download info/versions from. For more detailed explanation
|
||||
# check the 'URLSource' type in the code.
|
||||
# When trying to download ghcup metadata, this option decides what to do
|
||||
# when the download fails:
|
||||
# 1. Lax: use existing ~/.ghcup/cache/ghcup-<ver>.yaml as fallback (default)
|
||||
# 2. Strict: fail hard
|
||||
meta-mode: Lax # Strict | Lax
|
||||
|
||||
# Where to get GHC/cabal/hls download info/versions from. This is a list that performs
|
||||
# union over tool versions, preferring the later entries.
|
||||
url-source:
|
||||
## Use the internal download uri, this is the default
|
||||
GHCupURL: []
|
||||
- GHCupURL
|
||||
|
||||
## Example 1: Read download info from this location instead
|
||||
## Accepts file/http/https scheme
|
||||
## Can also be an array of URLs or an array of 'Either GHCupInfo URL', in
|
||||
## which case they are merged right-biased (overwriting duplicate versions).
|
||||
# OwnSource: "file:///home/jule/git/ghcup-hs/ghcup-0.0.3.yaml"
|
||||
## Prefer stack supplied metadata (will still use GHCup metadata for versions not existing in stack metadata)
|
||||
# - StackSetupURL
|
||||
|
||||
## Example 2: Add custom tarballs to the default downloads, overwriting duplicate versions.
|
||||
## Can also be an array of 'Either GHCupInfo URL', also see Example 3.
|
||||
# AddSource:
|
||||
# Left:
|
||||
# globalTools: {}
|
||||
# toolRequirements: {}
|
||||
# ghcupDownloads:
|
||||
# GHC:
|
||||
# 9.10.2:
|
||||
# viTags: []
|
||||
# viArch:
|
||||
# A_64:
|
||||
# Linux_UnknownLinux:
|
||||
# unknown_versioning:
|
||||
# dlUri: https://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-deb8-linux.tar.bz2
|
||||
# dlSubdir: ghc-7.10.3
|
||||
# dlHash: 01cfbad8dff1e8b34a5fdca8caeaf843b56e36af919e29cd68870d2588563db5
|
||||
## Add pre-release channel
|
||||
# - https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
|
||||
## Add nightly channel
|
||||
# - https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml
|
||||
## Add cross compiler channel
|
||||
# - https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml
|
||||
|
||||
## Example 3: Add multiple custom download files to the default downloads via right-biased merge (overwriting duplicate
|
||||
## versions).
|
||||
# AddSource:
|
||||
# - Right: "file:///home/jule/git/ghcup-hs/ghcup-prereleases.yaml"
|
||||
# - Right: "file:///home/jule/git/ghcup-hs/ghcup-custom.yaml"
|
||||
## Use dwarf bindist for 9.4.7 for ghcup metadata
|
||||
# - ghcup-info:
|
||||
# ghcupDownloads:
|
||||
# GHC:
|
||||
# 9.4.7:
|
||||
# viTags: []
|
||||
# viArch:
|
||||
# A_64:
|
||||
# Linux_UnknownLinux:
|
||||
# unknown_versioning:
|
||||
# dlUri: https://downloads.haskell.org/ghc/9.4.7/ghc-9.4.7-x86_64-deb10-linux-dwarf.tar.xz
|
||||
# dlSubdir:
|
||||
# RegexDir: "ghc-.*"
|
||||
# dlHash: b261b3438ba455e3cf757f9c8dc3a06fdc061ea8ec287a65b7809e25fe18bad4
|
||||
|
||||
## for stack metadata and the linux64-tinfo6 bindists, use static alpine for 9.8.1
|
||||
# - setup-info:
|
||||
# ghc:
|
||||
# linux64-tinfo6:
|
||||
# 9.8.1:
|
||||
# url: "https://downloads.haskell.org/~ghc/9.8.1/ghc-9.8.1-x86_64-alpine3_12-linux-static.tar.xz"
|
||||
# content-length: 229037440
|
||||
# sha256: b48f3d3a508d0c140d1c801e04afc65e80c0d25e7e939a8a41edb387b26b81b3
|
||||
|
||||
# This is a way to override platform detection, e.g. when you're running
|
||||
# a Ubuntu derivate based on 18.04, you could do:
|
||||
# a Ubuntu derivative based on 18.04, you could do:
|
||||
#
|
||||
# platform-override:
|
||||
# arch: A_64
|
||||
@@ -86,3 +101,30 @@ url-source:
|
||||
# tag: Linux
|
||||
# version: '18.04'
|
||||
platform-override: null
|
||||
|
||||
# Support for mirrors. Currently there are 3 hosts you can mirror:
|
||||
# - github.com (for stack and some older HLS versions)
|
||||
# - raw.githubusercontent.com (for the yaml metadata)
|
||||
# - downloads.haskell.org (for everything else)
|
||||
#
|
||||
# E.g. when we have 'https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml'
|
||||
# and the following mirror config
|
||||
#
|
||||
# "raw.githubusercontent.com":
|
||||
# authority:
|
||||
# host: "mirror.sjtu.edu.cn"
|
||||
# pathPrefix: "ghcup/yaml"
|
||||
#
|
||||
# Then the resulting url will be 'https://mirror.sjtu.edu.cn/ghcup/yaml/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml'
|
||||
mirrors:
|
||||
"github.com":
|
||||
authority:
|
||||
host: "mirror.sjtu.edu.cn"
|
||||
"raw.githubusercontent.com":
|
||||
authority:
|
||||
host: "mirror.sjtu.edu.cn"
|
||||
pathPrefix: "ghcup/yaml"
|
||||
"downloads.haskell.org":
|
||||
authority:
|
||||
host: "mirror.sjtu.edu.cn"
|
||||
|
||||
|
||||
Submodule data/metadata updated: 8f0e82ef06...7e1a50cfff
@@ -1,4 +1,4 @@
|
||||
FROM i386/alpine:3.12
|
||||
FROM --platform=linux/i386 i386/alpine:3.16
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
|
||||
@@ -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.20.0
|
||||
ARG GPG_KEY="7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C FFEB7CE81E16A36B3E2DED6F2DE04D4E97DB64AD 88B57FCF7DB53B4DB3BFA4B1588764FBE22D19C4 EAF2A9A722C0C96F2B431CA511AAD8CEDEE0CAEF"
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
@@ -51,9 +51,9 @@ RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
chmod +x /usr/bin/ghcup && \
|
||||
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||
|
||||
ARG GHC=8.10.7
|
||||
ARG CABAL_INSTALL=3.6.2.0
|
||||
ARG STACK=2.9.1
|
||||
ARG GHC=9.4.8
|
||||
ARG CABAL_INSTALL=3.10.2.0
|
||||
ARG STACK=2.13.1
|
||||
|
||||
ENV GHCUP_CURL_OPTS="--silent"
|
||||
ENV NO_COLOR=1
|
||||
@@ -63,7 +63,7 @@ RUN ghcup config set gpg-setting GPGStrict && \
|
||||
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||
find "/usr/lib/ghc-${GHC}/" \( -name "*_p.a" -o -name "*.p_hi" \) -type f -delete && \
|
||||
rm -r "/usr/share/doc/ghc-${GHC}" && \
|
||||
rm -rf "/usr/share/doc/ghc-${GHC}" && \
|
||||
rm -rf /tmp/ghcup* && \
|
||||
ghcup gc -p -s -c -t
|
||||
|
||||
|
||||
@@ -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.20.0
|
||||
ARG GPG_KEY="7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C FFEB7CE81E16A36B3E2DED6F2DE04D4E97DB64AD 88B57FCF7DB53B4DB3BFA4B1588764FBE22D19C4 EAF2A9A722C0C96F2B431CA511AAD8CEDEE0CAEF"
|
||||
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
@@ -51,9 +52,9 @@ RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
chmod +x /usr/bin/ghcup && \
|
||||
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||
|
||||
ARG GHC=8.10.7
|
||||
ARG CABAL_INSTALL=3.6.2.0
|
||||
ARG STACK=2.9.1
|
||||
ARG GHC=9.4.8
|
||||
ARG CABAL_INSTALL=3.10.2.0
|
||||
ARG STACK=2.13.1
|
||||
|
||||
ENV GHCUP_CURL_OPTS="--silent"
|
||||
ENV NO_COLOR=1
|
||||
@@ -63,7 +64,7 @@ RUN ghcup config set gpg-setting GPGStrict && \
|
||||
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||
find "/usr/lib/ghc-${GHC}/" \( -name "*_p.a" -o -name "*.p_hi" \) -type f -delete && \
|
||||
rm -r "/usr/share/doc/ghc-${GHC}" && \
|
||||
rm -rf "/usr/share/doc/ghc-${GHC}" && \
|
||||
rm -rf /tmp/ghcup* && \
|
||||
ghcup gc -p -s -c -t
|
||||
|
||||
|
||||
61
docker/arm32v7/buster/Dockerfile
Normal file
61
docker/arm32v7/buster/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
||||
FROM arm32v7/debian:10
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Asia/Singapore
|
||||
|
||||
COPY update_opt.sh /usr/bin/update_opt.sh
|
||||
RUN chmod +x /usr/bin/update_opt.sh
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
dirmngr \
|
||||
g++ \
|
||||
git \
|
||||
gnupg \
|
||||
libsqlite3-dev \
|
||||
libtinfo-dev \
|
||||
libgmp-dev \
|
||||
make \
|
||||
netbase \
|
||||
openssh-client \
|
||||
xz-utils \
|
||||
zlib1g-dev \
|
||||
libnuma-dev libgmp10 libssl-dev liblzma-dev libbz2-dev wget lsb-release software-properties-common apt-transport-https gcc autoconf automake build-essential gzip patchelf tree \
|
||||
llvm-11 clang-11 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN update_opt.sh 11 1
|
||||
|
||||
ARG GHCUP_VERSION=0.1.20.0
|
||||
ARG GPG_KEY="7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C FFEB7CE81E16A36B3E2DED6F2DE04D4E97DB64AD 88B57FCF7DB53B4DB3BFA4B1588764FBE22D19C4 EAF2A9A722C0C96F2B431CA511AAD8CEDEE0CAEF"
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/armv7-linux-ghcup-$GHCUP_VERSION && \
|
||||
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS && \
|
||||
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS.sig && \
|
||||
gpg --verify SHA256SUMS.sig SHA256SUMS && \
|
||||
sha256sum -c --ignore-missing SHA256SUMS && \
|
||||
mv armv7-linux-ghcup-$GHCUP_VERSION /usr/bin/ghcup && \
|
||||
chmod +x /usr/bin/ghcup && \
|
||||
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||
|
||||
ARG GHC=9.2.8
|
||||
ARG CABAL_INSTALL=3.6.2.0
|
||||
ARG STACK=2.13.1
|
||||
|
||||
ENV GHCUP_CURL_OPTS="--silent"
|
||||
ENV NO_COLOR=1
|
||||
|
||||
# install haskell toolchain
|
||||
RUN ghcup config set gpg-setting GPGStrict && \
|
||||
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||
ghcup gc -s -c -t
|
||||
|
||||
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||
|
||||
CMD ["ghci"]
|
||||
@@ -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 && \
|
||||
@@ -54,10 +54,7 @@ ENV NO_COLOR=1
|
||||
RUN ghcup config set gpg-setting GPGStrict && \
|
||||
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||
find "/usr/lib/ghc-${GHC}/" \( -name "*_p.a" -o -name "*.p_hi" \) -type f -delete && \
|
||||
rm -r "/usr/share/doc/ghc-${GHC}" && \
|
||||
rm -rf /tmp/ghcup* && \
|
||||
ghcup gc -p -s -c -t
|
||||
ghcup gc -s -c -t
|
||||
|
||||
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||
|
||||
61
docker/arm64v8/buster/Dockerfile
Normal file
61
docker/arm64v8/buster/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
||||
FROM arm64v8/debian:10
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Asia/Singapore
|
||||
|
||||
COPY update_opt.sh /usr/bin/update_opt.sh
|
||||
RUN chmod +x /usr/bin/update_opt.sh
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
dirmngr \
|
||||
g++ \
|
||||
git \
|
||||
gnupg \
|
||||
libsqlite3-dev \
|
||||
libtinfo-dev \
|
||||
libgmp-dev \
|
||||
make \
|
||||
netbase \
|
||||
openssh-client \
|
||||
xz-utils \
|
||||
zlib1g-dev \
|
||||
libnuma-dev libgmp10 libssl-dev liblzma-dev libbz2-dev wget lsb-release software-properties-common apt-transport-https gcc autoconf automake build-essential gzip patchelf tree \
|
||||
llvm-11 clang-11 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN update_opt.sh 11 1
|
||||
|
||||
ARG GHCUP_VERSION=0.1.20.0
|
||||
ARG GPG_KEY="7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C FFEB7CE81E16A36B3E2DED6F2DE04D4E97DB64AD 88B57FCF7DB53B4DB3BFA4B1588764FBE22D19C4 EAF2A9A722C0C96F2B431CA511AAD8CEDEE0CAEF"
|
||||
|
||||
# install ghcup
|
||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/aarch64-linux-ghcup-$GHCUP_VERSION && \
|
||||
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS && \
|
||||
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS.sig && \
|
||||
gpg --verify SHA256SUMS.sig SHA256SUMS && \
|
||||
sha256sum -c --ignore-missing SHA256SUMS && \
|
||||
mv aarch64-linux-ghcup-$GHCUP_VERSION /usr/bin/ghcup && \
|
||||
chmod +x /usr/bin/ghcup && \
|
||||
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||
|
||||
ARG GHC=9.4.8
|
||||
ARG CABAL_INSTALL=3.10.2.0
|
||||
ARG STACK=2.13.1
|
||||
|
||||
ENV GHCUP_CURL_OPTS="--silent"
|
||||
ENV NO_COLOR=1
|
||||
|
||||
# install haskell toolchain
|
||||
RUN ghcup config set gpg-setting GPGStrict && \
|
||||
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||
ghcup gc -s -c -t
|
||||
|
||||
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||
|
||||
CMD ["ghci"]
|
||||
36
docker/arm64v8/buster/update_opt.sh
Executable file
36
docker/arm64v8/buster/update_opt.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
# update_alternatives.sh
|
||||
|
||||
update_alternatives() {
|
||||
local version=${1}
|
||||
local priority=${2}
|
||||
local master=${3}
|
||||
local slaves=${4}
|
||||
local path=${5}
|
||||
local cmdln
|
||||
|
||||
cmdln="--verbose --install ${path}${master} ${master} ${path}${master}-${version} ${priority}"
|
||||
for slave in ${slaves}; do
|
||||
cmdln="${cmdln} --slave ${path}${slave} ${slave} ${path}${slave}-${version}"
|
||||
done
|
||||
update-alternatives ${cmdln}
|
||||
}
|
||||
|
||||
if [[ ${#} -ne 2 ]]; then
|
||||
echo usage: "${0}" clang_version priority
|
||||
exit 1
|
||||
fi
|
||||
|
||||
version=${1}
|
||||
priority=${2}
|
||||
path="/usr/bin/"
|
||||
|
||||
master="llvm-config"
|
||||
slaves="llvm-addr2line llvm-ar llvm-as llvm-bcanalyzer llvm-bitcode-strip llvm-cat llvm-cfi-verify llvm-cov llvm-c-test llvm-cvtres llvm-cxxdump llvm-cxxfilt llvm-cxxmap llvm-debuginfod llvm-debuginfod-find llvm-diff llvm-dis llvm-dlltool llvm-dwarfdump llvm-dwarfutil llvm-dwp llvm-exegesis llvm-extract llvm-gsymutil llvm-ifs llvm-install-name-tool llvm-jitlink llvm-jitlink-executor llvm-lib llvm-libtool-darwin llvm-link llvm-lipo llvm-lto llvm-lto2 llvm-mc llvm-mca llvm-ml llvm-modextract llvm-mt llvm-nm llvm-objcopy llvm-objdump llvm-omp-device-info llvm-opt-report llvm-otool llvm-pdbutil llvm-PerfectShuffle llvm-profdata llvm-profgen llvm-ranlib llvm-rc llvm-readelf llvm-readobj llvm-reduce llvm-remark-size-diff llvm-rtdyld llvm-sim llvm-size llvm-split llvm-stress llvm-strings llvm-strip llvm-symbolizer llvm-tapi-diff llvm-tblgen llvm-tli-checker llvm-undname llvm-windres llvm-xray"
|
||||
|
||||
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||
|
||||
master="clang"
|
||||
slaves="analyze-build asan_symbolize bugpoint c-index-test clang++ clang-apply-replacements clang-change-namespace clang-check clang-cl clang-cpp clangd clang-doc clang-extdef-mapping clang-format clang-format-diff clang-include-fixer clang-linker-wrapper clang-move clang-nvlink-wrapper clang-offload-bundler clang-offload-packager clang-offload-wrapper clang-pseudo clang-query clang-refactor clang-rename clang-reorder-fields clang-repl clang-scan-deps clang-tidy count diagtool dsymutil FileCheck find-all-symbols git-clang-format hmaptool hwasan_symbolize intercept-build ld64.lld ld.lld llc lld lldb lldb-argdumper lldb-instr lldb-server lldb-vscode lld-link lli lli-child-target modularize not obj2yaml opt pp-trace run-clang-tidy sancov sanstats scan-build scan-build-py scan-view split-file UnicodeNameMappingGenerator verify-uselistorder wasm-ld yaml2obj yaml-bench"
|
||||
|
||||
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||
@@ -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 && \
|
||||
@@ -54,10 +54,7 @@ ENV NO_COLOR=1
|
||||
RUN ghcup config set gpg-setting GPGStrict && \
|
||||
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||
find "/usr/lib/ghc-${GHC}/" \( -name "*_p.a" -o -name "*.p_hi" \) -type f -delete && \
|
||||
rm -r "/usr/share/doc/ghc-${GHC}" && \
|
||||
rm -rf /tmp/ghcup* && \
|
||||
ghcup gc -p -s -c -t
|
||||
ghcup gc -s -c -t
|
||||
|
||||
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||
|
||||
36
docker/arm64v8/focal/update_opt.sh
Executable file
36
docker/arm64v8/focal/update_opt.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
# update_alternatives.sh
|
||||
|
||||
update_alternatives() {
|
||||
local version=${1}
|
||||
local priority=${2}
|
||||
local master=${3}
|
||||
local slaves=${4}
|
||||
local path=${5}
|
||||
local cmdln
|
||||
|
||||
cmdln="--verbose --install ${path}${master} ${master} ${path}${master}-${version} ${priority}"
|
||||
for slave in ${slaves}; do
|
||||
cmdln="${cmdln} --slave ${path}${slave} ${slave} ${path}${slave}-${version}"
|
||||
done
|
||||
update-alternatives ${cmdln}
|
||||
}
|
||||
|
||||
if [[ ${#} -ne 2 ]]; then
|
||||
echo usage: "${0}" clang_version priority
|
||||
exit 1
|
||||
fi
|
||||
|
||||
version=${1}
|
||||
priority=${2}
|
||||
path="/usr/bin/"
|
||||
|
||||
master="llvm-config"
|
||||
slaves="llvm-addr2line llvm-ar llvm-as llvm-bcanalyzer llvm-bitcode-strip llvm-cat llvm-cfi-verify llvm-cov llvm-c-test llvm-cvtres llvm-cxxdump llvm-cxxfilt llvm-cxxmap llvm-debuginfod llvm-debuginfod-find llvm-diff llvm-dis llvm-dlltool llvm-dwarfdump llvm-dwarfutil llvm-dwp llvm-exegesis llvm-extract llvm-gsymutil llvm-ifs llvm-install-name-tool llvm-jitlink llvm-jitlink-executor llvm-lib llvm-libtool-darwin llvm-link llvm-lipo llvm-lto llvm-lto2 llvm-mc llvm-mca llvm-ml llvm-modextract llvm-mt llvm-nm llvm-objcopy llvm-objdump llvm-omp-device-info llvm-opt-report llvm-otool llvm-pdbutil llvm-PerfectShuffle llvm-profdata llvm-profgen llvm-ranlib llvm-rc llvm-readelf llvm-readobj llvm-reduce llvm-remark-size-diff llvm-rtdyld llvm-sim llvm-size llvm-split llvm-stress llvm-strings llvm-strip llvm-symbolizer llvm-tapi-diff llvm-tblgen llvm-tli-checker llvm-undname llvm-windres llvm-xray"
|
||||
|
||||
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||
|
||||
master="clang"
|
||||
slaves="analyze-build asan_symbolize bugpoint c-index-test clang++ clang-apply-replacements clang-change-namespace clang-check clang-cl clang-cpp clangd clang-doc clang-extdef-mapping clang-format clang-format-diff clang-include-fixer clang-linker-wrapper clang-move clang-nvlink-wrapper clang-offload-bundler clang-offload-packager clang-offload-wrapper clang-pseudo clang-query clang-refactor clang-rename clang-reorder-fields clang-repl clang-scan-deps clang-tidy count diagtool dsymutil FileCheck find-all-symbols git-clang-format hmaptool hwasan_symbolize intercept-build ld64.lld ld.lld llc lld lldb lldb-argdumper lldb-instr lldb-server lldb-vscode lld-link lli lli-child-target modularize not obj2yaml opt pp-trace run-clang-tidy sancov sanstats scan-build scan-build-py scan-view split-file UnicodeNameMappingGenerator verify-uselistorder wasm-ld yaml2obj yaml-bench"
|
||||
|
||||
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||
@@ -60,6 +60,29 @@ All you wanted to know about GHCup.
|
||||
3. handling cabal projects
|
||||
4. being a stack alternative
|
||||
|
||||
## Distribution policies
|
||||
|
||||
Like most Linux distros and other distribution channels, GHCup also
|
||||
follows certain policies. These are as follows:
|
||||
|
||||
1. The end-user experience is our primary concern
|
||||
- ghcup in CI systems as a use case is a first class citizen
|
||||
2. We strive to collaborate with all maintainers of all the tools we support and maintain a good relationship
|
||||
3. We may fix build system or other distribution bugs in upstream bindists
|
||||
- these are always communicated upstream
|
||||
4. We may even patch source code of supported tools in very rare cases if that is required to ensure that the end-user experience does not break
|
||||
- we'll first try to upstream any such required patch and request a new release to avoid downstream patching
|
||||
- patches will be communicated to the maintainers either way and we'll strive to get their review
|
||||
- they will also be communicated to the end-user
|
||||
- they will be uploaded along with the bindist
|
||||
- we will avoid maintaining long-running downstream patches (currently zero)
|
||||
5. We may add bindists for platforms that upstream does not support
|
||||
- this is currently the case for GHC for e.g. Alpine and possibly FreeBSD in the future
|
||||
- this is currently also the case for stack on darwin M1
|
||||
- we don't guarantee for unofficial bindists that the test suite passes at the moment (this may change in the future)
|
||||
6. We GPG sign all the GHCup metadata as well as the unofficial bindists
|
||||
- any trust issues relating to missing checksums or GPG signatures is a bug and given high priority
|
||||
|
||||
## How
|
||||
|
||||
Installs a specified GHC version into `~/.ghcup/ghc/<ver>`, and places `ghc-<ver>` symlinks in `~/.ghcup/bin/`.
|
||||
@@ -75,15 +98,15 @@ cabal-install/HLS/stack are installed in `~/.ghcup/bin/<tool>-<ver>` and have un
|
||||
## Known users
|
||||
|
||||
* CI:
|
||||
- [Github actions/virtual-environments](https://github.com/actions/virtual-environments)
|
||||
- [Github haskell/actions/setup](https://github.com/haskell/actions/tree/main/setup)
|
||||
- [haskell-ci](https://github.com/haskell-CI/haskell-ci)
|
||||
- [Github actions/virtual-environments](https://github.com/actions/virtual-environments)
|
||||
- [Github haskell/actions/setup](https://github.com/haskell/actions/tree/main/setup)
|
||||
- [haskell-ci](https://github.com/haskell-CI/haskell-ci)
|
||||
* mirrors:
|
||||
- [sjtug](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||
- [sjtug](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||
* tools:
|
||||
- [vscode-haskell](https://github.com/haskell/vscode-haskell)
|
||||
- [nvim-lsp-installer](https://github.com/williamboman/nvim-lsp-installer)
|
||||
- [vabal](https://github.com/Franciman/vabal)
|
||||
- [vscode-haskell](https://github.com/haskell/vscode-haskell)
|
||||
- [nvim-lsp-installer](https://github.com/williamboman/nvim-lsp-installer)
|
||||
- [vabal](https://github.com/Franciman/vabal)
|
||||
|
||||
## Known problems
|
||||
|
||||
|
||||
352
docs/guide.md
352
docs/guide.md
@@ -4,7 +4,7 @@ This is a more in-depth guide specific to GHCup. `ghcup --help` is your friend.
|
||||
|
||||
## Basic usage
|
||||
|
||||
For the simple, interactive, text-based user interface (TUI) (not available on windows), run:
|
||||
For the simple, interactive, text-based user interface (TUI), run:
|
||||
|
||||
```sh
|
||||
ghcup tui
|
||||
@@ -43,6 +43,12 @@ All of the following are valid arguments to `ghcup install ghc`:
|
||||
|
||||
If the argument is omitted, the default is `recommended`.
|
||||
|
||||
Other tags include:
|
||||
|
||||
- `prerelease`: a prerelease version
|
||||
- `latest-prerelease`: the latest prerelease version
|
||||
|
||||
|
||||
## Manpages
|
||||
|
||||
For man pages to work you need [man-db](http://man-db.nongnu.org/) as your `man` provider, then issue `man ghc`. Manpages only work for the currently set ghc.
|
||||
@@ -61,8 +67,7 @@ and make sure your bashrc sources the startup script
|
||||
|
||||
`ghcup` is very portable. There are a few exceptions though:
|
||||
|
||||
1. `ghcup tui` is only available on non-windows platforms
|
||||
2. legacy subcommands `ghcup install` (without a tool identifier) and `ghcup install-cabal` may be removed in the future
|
||||
1. legacy subcommands `ghcup install` (without a tool identifier) and `ghcup install-cabal` may be removed in the future
|
||||
|
||||
# Configuration
|
||||
|
||||
@@ -73,7 +78,7 @@ Partial configuration is fine. Command line options always override the config f
|
||||
|
||||
## Overriding distro detection
|
||||
|
||||
If you're running e.g. an Ubuntu derivate based on 18.04 and ghcup is picking bindists that
|
||||
If you're running e.g. an Ubuntu derivative based on 18.04 and ghcup is picking bindists that
|
||||
don't work well, you could do this in `config.yaml`:
|
||||
|
||||
```yml
|
||||
@@ -89,7 +94,7 @@ platform-override:
|
||||
|
||||
This is the complete list of env variables that change GHCup behavior:
|
||||
|
||||
* `GHCUP_USE_XDG_DIRS`: see [XDG support](#xdg-support) above
|
||||
* `GHCUP_USE_XDG_DIRS`: see [XDG support](#xdg-support) below
|
||||
* `GHCUP_INSTALL_BASE_PREFIX`: the base of ghcup (default: `$HOME`)
|
||||
* `GHCUP_CURL_OPTS`: additional options that can be passed to curl
|
||||
* `GHCUP_WGET_OPTS`: additional options that can be passed to wget
|
||||
@@ -100,6 +105,7 @@ This is the complete list of env variables that change GHCup behavior:
|
||||
On windows, there's additionally:
|
||||
|
||||
* `GHCUP_MSYS2`: Has to point to the root of an existing MSYS2 installation (when installed by GHCup, that's e.g. `C:\ghcup\msys64`). GHCup bootstrap takes care of this usually.
|
||||
* `GHCUP_MSYS2_ENV`: The [MSYS2 environment](https://www.msys2.org/docs/environments/) to use when executing e.g. `ghcup run --mingw-path`. Possible values are `MSYS`, `UCRT64`, `CLANG64`, `CLANGARM64`, `CLANG32`, `MINGW64`, `MINGW32`. Defaults to `MINGW64`, `MINGW32` or `CLANGARM64`, depending on the architecture. `MSYS` is always added as the last component. If you change this value after running the bootstrap script, you may need to make sure that the cabal config reflects this change, more specifically `extra-prog-path`, `extra-include-dirs` and `extra-lib-dirs`. (**NOTE: specifying anything other than the default is considered experimental**)
|
||||
|
||||
### XDG support
|
||||
|
||||
@@ -136,49 +142,29 @@ If you experience problems, consider clearing the cache via `ghcup gc --cache`.
|
||||
|
||||
## Metadata
|
||||
|
||||
The metadata are the files that describe tool versions, where to download them etc. and
|
||||
can be viewed here: [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata)
|
||||
Metadata files are also called release or distribution channels. They describe tool versions, where to download them etc. and
|
||||
can be viewed here: [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata).
|
||||
|
||||
### Mirrors
|
||||
See the [description](https://github.com/haskell/ghcup-metadata#metadata-variants-distribution-channels)
|
||||
of metadata files to understand their purpose. These can be combined.
|
||||
|
||||
GHCup allows to use custom mirrors/download-info hosted by yourself or 3rd parties.
|
||||
|
||||
To use a mirror, set the following option in `~/.ghcup/config.yaml`:
|
||||
|
||||
```yml
|
||||
url-source:
|
||||
# Accepts file/http/https scheme
|
||||
OwnSource: "https://some-url/ghcup-0.0.6.yaml"
|
||||
```
|
||||
|
||||
See [config.yaml](https://github.com/haskell/ghcup-hs/blob/master/data/config.yaml)
|
||||
for more options.
|
||||
|
||||
Alternatively you can do it via a cli switch:
|
||||
|
||||
```sh
|
||||
ghcup --url-source=https://some-url/ghcup-0.0.6.yaml list
|
||||
```
|
||||
|
||||
#### Known mirrors
|
||||
|
||||
1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||
|
||||
### (Pre-)Release channels
|
||||
|
||||
A release channel is basically just a metadata file location. You can add additional release
|
||||
channels that complement the default one, such as the **prerelease channel** like so:
|
||||
For example, if you want access to both prerelease and cross bindists, you'd do:
|
||||
|
||||
```sh
|
||||
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
|
||||
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml
|
||||
```
|
||||
|
||||
This will result in `~/.ghcup/config.yaml` to contain this record:
|
||||
This results in the following configuration in `~/.ghcup/config.yaml`:
|
||||
|
||||
```yml
|
||||
```yaml
|
||||
url-source:
|
||||
AddSource:
|
||||
- Right: https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
|
||||
# the base url that contains all the release bindists
|
||||
- GHCupURL
|
||||
# prereleases
|
||||
- https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.8.yaml
|
||||
# cross bindists
|
||||
- https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml
|
||||
```
|
||||
|
||||
You can add as many channels as you like. They are combined under *Last*, so versions from the prerelease channel
|
||||
@@ -188,18 +174,68 @@ To remove the channel, delete the entire `url-source` section or set it back to
|
||||
|
||||
```yml
|
||||
url-source:
|
||||
GHCupURL: []
|
||||
- GHCupURL
|
||||
```
|
||||
|
||||
If you want to combine your release channel with a mirror, you'd do it like so:
|
||||
Also see [config.yaml](https://github.com/haskell/ghcup-hs/blob/master/data/config.yaml)
|
||||
for more options.
|
||||
|
||||
You can also use an alternative metadata via one-shot cli option:
|
||||
|
||||
```sh
|
||||
ghcup --url-source=https://some-url/ghcup-0.0.8.yaml tui
|
||||
```
|
||||
|
||||
One main caveat of using URLs is that you might need to check whether there are new versions
|
||||
of the file (e.g. `ghcup-0.0.7.yaml` vs `ghcup-0.0.8.yaml`). Although old metadata files
|
||||
are supported for some time, they are not so indefinitely.
|
||||
|
||||
### Mirrors
|
||||
|
||||
Metadata files can also be used to operate 3rd party mirrors, in which case you want to use
|
||||
a URL instead of the `GHCupURL` alias. E.g. in `~/.ghcup/config.yaml`, you'd do:
|
||||
|
||||
```yml
|
||||
url-source:
|
||||
OwnSource:
|
||||
# base metadata
|
||||
- "https://mirror.sjtu.edu.cn/ghcup/yaml/ghcup/data/ghcup-0.0.6.yaml"
|
||||
# prerelease channel
|
||||
- "https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml"
|
||||
- https://mirror.sjtu.edu.cn/ghcup/yaml/ghcup/data/ghcup-0.0.6.yaml
|
||||
```
|
||||
|
||||
Note that later versions of GHCup allow more sophisticated mirror support, see [here](./#mirrors-proper).
|
||||
|
||||
#### Known mirrors
|
||||
|
||||
1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||
2. [https://mirrors.ustc.edu.cn/help/ghcup.html](https://mirrors.ustc.edu.cn/help/ghcup.html)
|
||||
|
||||
### Git based metadata config
|
||||
|
||||
If you don't like the way ghcup updates its metadata with caching and fetching via curl, you can also do as follows:
|
||||
|
||||
Clone the metadata git repo:
|
||||
|
||||
```sh
|
||||
mkdir -p /home/user/git/
|
||||
cd /home/user/git/
|
||||
git clone -b master https://github.com/haskell/ghcup-metadata.git
|
||||
```
|
||||
|
||||
Then tell ghcup to use file locations in `~/.ghcup/config.yaml`, e.g.:
|
||||
|
||||
```yaml
|
||||
url-source:
|
||||
- file:///home/user/git/ghcup-metadata/ghcup-0.0.8.yaml
|
||||
- file:///home/user/git/ghcup-metadata/ghcup-cross-0.0.8.yaml
|
||||
- file:///home/user/git/ghcup-metadata/ghcup-prereleases-0.0.8.yaml
|
||||
```
|
||||
|
||||
Now, if you invoke `ghcup tui`, it will open instantly without any download, since it just
|
||||
reads the metadata from local disk.
|
||||
|
||||
You'll have to update the metadata manually though, like so:
|
||||
|
||||
```sh
|
||||
cd /home/user/git/
|
||||
git pull --ff-only origin master
|
||||
```
|
||||
|
||||
## Stack integration
|
||||
@@ -207,17 +243,7 @@ url-source:
|
||||
Stack manages GHC versions internally by default. In order to make it use ghcup installed
|
||||
GHC versions there are two strategies.
|
||||
|
||||
### Strategy 1: System GHC (works on all stack versions)
|
||||
|
||||
You can instruct stack to use "system" GHC versions (whatever is in PATH). To do so,
|
||||
run the following commands:
|
||||
|
||||
```sh
|
||||
stack config set install-ghc false --global
|
||||
stack config set system-ghc true --global
|
||||
```
|
||||
|
||||
### Strategy 2: Stack hooks (new, recommended)
|
||||
### Strategy 1: Stack hooks (new, recommended)
|
||||
|
||||
Since stack 2.9.1 you can customize the installation logic of GHC completely, see [https://docs.haskellstack.org/en/stable/yaml_configuration/#ghc-installation-customisation](https://docs.haskellstack.org/en/stable/yaml_configuration/#ghc-installation-customisation).
|
||||
|
||||
@@ -239,6 +265,61 @@ stack config set system-ghc false --global
|
||||
By default, when the hook fails for whatever reason, stack will fall back to its own installation logic. To disable
|
||||
this, run `stack config set install-ghc false --global`.
|
||||
|
||||
### Strategy 2: System GHC (works on all stack versions)
|
||||
|
||||
You can instruct stack to use "system" GHC versions (whatever is in PATH). To do so,
|
||||
run the following commands:
|
||||
|
||||
```sh
|
||||
stack config set install-ghc false --global
|
||||
stack config set system-ghc true --global
|
||||
```
|
||||
|
||||
### Using stack's setup-info metadata to install GHC
|
||||
|
||||
You can now use stack's [setup-info metadata](https://github.com/commercialhaskell/stackage-content/blob/master/stack/stack-setup-2.yaml)
|
||||
to install GHC. For that, you can invoke ghcup like so as a shorthand:
|
||||
|
||||
```sh
|
||||
# ghcup will only see GHC now
|
||||
ghcup -s StackSetupURL install ghc 9.4.7
|
||||
# this combines both ghcup and stack metadata
|
||||
ghcup -s '["GHCupURL", "StackSetupURL"]' install ghc 9.4.7
|
||||
```
|
||||
|
||||
To make this permanent and combine it with the GHCup metadata, you can add the following to your `~/.ghcup/config.yaml`:
|
||||
|
||||
```yaml
|
||||
url-source:
|
||||
- GHCupURL
|
||||
# stack versions take precedence
|
||||
# you'll still have access to GHCup provided versions and tools in case they don't exist in stack metadata
|
||||
- StackSetupURL
|
||||
```
|
||||
|
||||
You can customize or add sections to the setup-info similar to how the [stack documentation](https://docs.haskellstack.org/en/stable/yaml_configuration/#setup-info) explains it. E.g. to change the 9.4.7 bindist, you might do:
|
||||
|
||||
```yaml
|
||||
url-source:
|
||||
- GHCupURL
|
||||
- StackSetupURL
|
||||
- setup-info:
|
||||
ghc:
|
||||
linux64-tinfo6:
|
||||
9.4.7:
|
||||
url: "https://downloads.haskell.org/~ghc/9.4.7/ghc-9.4.7-x86_64-fedora27-linux.tar.xz"
|
||||
content-length: 179117892
|
||||
sha256: 216b76b7c6383e6ad9ba82533f323f8550e52893a8b9fa33c7b9dc4201ac766a
|
||||
```
|
||||
|
||||
#### Caveats
|
||||
|
||||
The main caveat with using this method is that there's no guarantee that GHCup will pick a compatible HLS bindist
|
||||
when you try to install HLS.
|
||||
|
||||
Another potential usability issue is that the `latest` and `recommended` shorthands won't work anymore, since
|
||||
Stack metadata doesn't have a concept of those and we don't try to be smart when combining the metadatas.
|
||||
|
||||
### Windows
|
||||
|
||||
On windows, you may find the following config options useful too:
|
||||
@@ -246,6 +327,39 @@ On windows, you may find the following config options useful too:
|
||||
|
||||
Also check out: [https://docs.haskellstack.org/en/stable/yaml_configuration](https://docs.haskellstack.org/en/stable/yaml_configuration)
|
||||
|
||||
## Mirrors (proper)
|
||||
|
||||
Mirrors are now supported via configuration, instead of specifying alternative metadata files.
|
||||
|
||||
As an example, this would be a complete mirror configuration in `~/.ghcup/config.yaml`:
|
||||
|
||||
```yaml
|
||||
mirrors:
|
||||
# yaml download location, would result in:
|
||||
# https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-0.0.8.yaml
|
||||
# -> https://mirror.sjtu.edu.cn/ghcup/yaml/haskell/ghcup-metadata/master/ghcup-0.0.8.yaml
|
||||
"raw.githubusercontent.com":
|
||||
authority:
|
||||
host: "mirror.sjtu.edu.cn"
|
||||
pathPrefix: "ghcup/yaml"
|
||||
# for stack and some older HLS versions, would result in e.g.
|
||||
# https://github.com/haskell/haskell-language-server/releases/download/1.2.0/haskell-language-server-Windows-1.2.0.tar.gz
|
||||
# -> https://mirror.sjtu.edu.cn/ghcup/github/haskell/haskell-language-server/releases/download/1.2.0/haskell-language-server-Windows-1.2.0.tar.gz
|
||||
"github.com":
|
||||
authority:
|
||||
host: "mirror.sjtu.edu.cn"
|
||||
pathPrefix: "ghcup/github"
|
||||
# for all haskell.org hosted bindists, would result in e.g.
|
||||
# https://downloads.haskell.org/~ghc/9.8.1/ghc-9.8.1-x86_64-deb10-linux.tar.xz
|
||||
# -> https://mirror.sjtu.edu.cn/ghcup/haskell-downloads/~ghc/9.8.1/ghc-9.8.1-x86_64-deb10-linux.tar.xz
|
||||
"downloads.haskell.org":
|
||||
authority:
|
||||
host: "mirror.sjtu.edu.cn"
|
||||
pathPrefix: "downloads.haskell.org"
|
||||
```
|
||||
|
||||
The configuration depends on the host of the mirror and they have to provide the correct configuration.
|
||||
|
||||
# More on installation
|
||||
|
||||
## Customisation of the installation scripts
|
||||
@@ -382,9 +496,9 @@ ghcup compile hls --git-ref master --git-describe-version --ghc 8.10.7 --ghc 9.2
|
||||
|
||||
This however will create a new HLS version in ghcup, e.g. `1.7.0.0-105-gdc682ba1`, for both 8.10.7 and 9.2.4. If you want to switch back to the official bindists, run `ghcup set hls 1.7.0.0`.
|
||||
|
||||
### Cross support
|
||||
## Cross support
|
||||
|
||||
ghcup can compile and install a cross GHC for any target. However, this
|
||||
ghcup can compile a cross GHC for any target. However, this
|
||||
requires that the build host has a complete cross toolchain and various
|
||||
libraries installed for the target platform.
|
||||
|
||||
@@ -393,6 +507,76 @@ For distributions with non-standard locations of cross toolchain and
|
||||
libraries, this may need some tweaking of `build.mk` or configure args.
|
||||
See `ghcup compile ghc --help` for further information.
|
||||
|
||||
Since ghcup version 0.1.20.0, we provide cross bindists for GHC JS and WASM. These can be installed conveniently.
|
||||
However, these are intended as a developer preview only. By using these GHC variants, you are implicitly signing up to participate in GHC development!
|
||||
If you run into bugs or missing behavior, join the dev chat at https://matrix.to/#/#GHC:matrix.org.
|
||||
|
||||
First, add the cross release channel:
|
||||
|
||||
```sh
|
||||
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-cross-0.0.8.yaml
|
||||
```
|
||||
|
||||
The next sections explain how to install each cross bindist.
|
||||
|
||||
### GHC JS cross bindists (experimental)
|
||||
|
||||
You need the required emscripten JS toolchain:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/emscripten-core/emsdk.git
|
||||
cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
source ./emsdk_env.sh
|
||||
```
|
||||
|
||||
Instructions are also here: [Download and install — Emscripten 3.1.43-git (dev) documentation](https://emscripten.org/docs/getting_started/downloads.html).
|
||||
|
||||
To install we need to invoke ghcup like so:
|
||||
|
||||
```sh
|
||||
emconfigure ghcup install ghc --set javascript-unknown-ghcjs-9.6.2
|
||||
```
|
||||
|
||||
You'll now have the compiler `javascript-unknown-ghcjs-ghc`. To build a hello world, do e.g.:
|
||||
|
||||
```sh
|
||||
echo 'main = putStrLn "hello world"' > hello.hs
|
||||
javascript-unknown-ghcjs-ghc -fforce-recomp hello.hs
|
||||
./hello
|
||||
```
|
||||
|
||||
You can follow the instructions [here](https://gitlab.haskell.org/ghc/ghc/-/wikis/javascript-backend/building#compiling-hello-world).
|
||||
|
||||
### GHC WASM cross bindists (experimental)
|
||||
|
||||
You need the required wasm toolchain:
|
||||
|
||||
```sh
|
||||
git clone https://gitlab.haskell.org/ghc/ghc-wasm-meta.git
|
||||
cd ghc-wasm-meta/
|
||||
export SKIP_GHC=yes
|
||||
./setup.sh
|
||||
source ~/.ghc-wasm/env
|
||||
```
|
||||
|
||||
To install, we need to invoke ghcup like so also passing the `--host=<host>` flag (adjust as needed):
|
||||
|
||||
```sh
|
||||
ghcup install ghc --set wasm32-wasi-9.6.3.20230927 -- --host=x86_64-linux --with-intree-gmp --with-system-libffi
|
||||
```
|
||||
|
||||
Also check the documentation here: [Glasgow Haskell Compiler / ghc-wasm-meta](https://gitlab.haskell.org/ghc/ghc-wasm-meta).
|
||||
|
||||
You'll now have the compiler `wasm32-wasi-ghc`. To build a hello world, do e.g.:
|
||||
|
||||
```sh
|
||||
echo 'main = putStrLn "hello world"' > hello.hs
|
||||
wasm32-wasi-ghc hello.hs -o hello.wasm
|
||||
wasmtime ./hello.wasm
|
||||
```
|
||||
|
||||
## Isolated installs
|
||||
|
||||
**Before using isolated installs, make sure to have at least GHCup version 0.1.17.8!**
|
||||
@@ -427,7 +611,7 @@ Examples:
|
||||
## Continuous integration
|
||||
|
||||
On Windows, GHCup can be installed automatically on a CI runner
|
||||
non-interactively, as below. The paramaters to the PowerShell script are
|
||||
non-interactively, as below. The parameters to the PowerShell script are
|
||||
specified positionally, after `-ArgumentList`:
|
||||
|
||||
```ps
|
||||
@@ -449,8 +633,48 @@ variables and, in the case of Windows, parameters to tweak the script behavior.
|
||||
|
||||
### github workflows
|
||||
|
||||
On github workflows you can use [https://github.com/haskell/actions/](https://github.com/haskell/actions/).
|
||||
GHCup itself is also pre-installed on all platforms, but may use non-standard install locations.
|
||||
On github workflows GHCup itself is pre-installed on all platforms, but may use non-standard install locations.
|
||||
Here's an example workflow with a GHC matrix:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-22.04, macOS-latest]
|
||||
ghc: ['9.6', '9.4', '9.2', '9.0', '8.10', '8.8', '8.6']
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup toolchain
|
||||
run: |
|
||||
ghcup install cabal --set recommended
|
||||
ghcup install ghc --set ${{ matrix.ghc }}
|
||||
- name: Build
|
||||
run: |
|
||||
cabal update
|
||||
cabal test all --test-show-details=direct
|
||||
|
||||
i386:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: i386/ubuntu:bionic
|
||||
steps:
|
||||
- name: Install GHCup in container
|
||||
run: |
|
||||
apt-get update -y
|
||||
apt-get install -y autoconf build-essential zlib1g-dev libgmp-dev curl
|
||||
# we just go with recommended versions of cabal and GHC
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_INSTALL_NO_STACK=1 sh
|
||||
- uses: actions/checkout@v1
|
||||
- name: Test
|
||||
run: |
|
||||
# in containers we need to fix PATH
|
||||
source ~/.ghcup/env
|
||||
cabal update
|
||||
cabal test all --test-show-details=direct
|
||||
```
|
||||
|
||||
## GPG verification
|
||||
|
||||
@@ -460,8 +684,10 @@ this is cryptographically secure.
|
||||
First, obtain the gpg keys:
|
||||
|
||||
```sh
|
||||
gpg --batch --keyserver keys.openpgp.org --recv-keys 7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 88B57FCF7DB53B4DB3BFA4B1588764FBE22D19C4
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys EAF2A9A722C0C96F2B431CA511AAD8CEDEE0CAEF
|
||||
```
|
||||
|
||||
Then verify the gpg key in one of these ways:
|
||||
|
||||
@@ -4,10 +4,6 @@ hide:
|
||||
- toc
|
||||
---
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<script src="javascripts/extra.js"></script>
|
||||
|
||||
|
||||
<section class="index-ghcup-hero">
|
||||
<img alt="haskell logo" src="./haskell_logo.png" />
|
||||
<h1>GHCup</h1>
|
||||
@@ -35,7 +31,7 @@ hide:
|
||||
<span>
|
||||
</span>
|
||||
<div class="footer">
|
||||
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-install">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
||||
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-installation">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,7 +47,7 @@ hide:
|
||||
<button class="btn" onclick="copyToClipboardWin()" id="ghcup-windows-button"><i class="fa fa-copy"></i></button>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell.ps1" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-install">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
||||
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell.ps1" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-installation">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -84,9 +80,6 @@ hide:
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<script type="text/javascript" src="javascripts/ghcup.js"></script>
|
||||
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
188
docs/install.md
188
docs/install.md
@@ -1,7 +1,7 @@
|
||||
# Installation
|
||||
|
||||
GHCup makes it easy to install specific versions of GHC on GNU/Linux,
|
||||
macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh [Haskell developer environment](./install/#supported-tools) from scratch.
|
||||
macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh [Haskell developer environment](./#supported-tools) from scratch.
|
||||
It follows the UNIX philosophy of [do one thing and do it well](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well). Similar in scope to [rustup](https://github.com/rust-lang-nursery/rustup.rs), [pyenv](https://github.com/pyenv/pyenv) and [jenv](http://www.jenv.be).
|
||||
|
||||
## How to install
|
||||
@@ -24,7 +24,7 @@ Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager
|
||||
|
||||
There's also a [youtube video](https://www.youtube.com/watch?v=bB4fmQiUYPw) explaining installation on windows.
|
||||
|
||||
If you want to know what these scripts do, check out the [source code at the repository](https://github.com/haskell/ghcup-hs/tree/master/scripts/bootstrap). Advanced users may want to perform a [manual installation](#manual-install) and GPG verify the binaries.
|
||||
If you want to know what these scripts do, check out the [source code at the repository](https://github.com/haskell/ghcup-hs/tree/master/scripts/bootstrap). Advanced users may want to perform a [manual installation](#manual-installation) and GPG verify the binaries.
|
||||
|
||||
### Which versions get installed?
|
||||
|
||||
@@ -38,47 +38,85 @@ Also see [tags and shortcuts](../guide/#tags-and-shortcuts) for more information
|
||||
|
||||
### Linux Debian
|
||||
|
||||
#### Generic
|
||||
|
||||
The following distro packages are required: `build-essential curl libffi-dev libffi6 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5`
|
||||
|
||||
#### Version >= 11 && <= 12
|
||||
|
||||
The following distro packages are required: `build-essential curl libffi-dev libffi7 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5`
|
||||
|
||||
#### Version >= 12
|
||||
|
||||
The following distro packages are required: `build-essential curl libffi-dev libffi8 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5`
|
||||
|
||||
### Linux Ubuntu
|
||||
|
||||
#### Generic
|
||||
|
||||
The following distro packages are required: `build-essential curl libffi-dev libffi6 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5`
|
||||
|
||||
#### Version >= 20.04 && < 20.10
|
||||
|
||||
The following distro packages are required: `build-essential curl libffi-dev libffi7 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5`
|
||||
|
||||
#### Version >= 20.10 && < 23
|
||||
|
||||
The following distro packages are required: `build-essential curl libffi-dev libffi8ubuntu1 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5`
|
||||
|
||||
#### Version >= 23
|
||||
|
||||
The following distro packages are required: `build-essential curl libffi-dev libffi8ubuntu1 libgmp-dev libgmp10 libncurses-dev`
|
||||
|
||||
### Linux Fedora
|
||||
|
||||
#### Generic
|
||||
|
||||
The following distro packages are required: `gcc gcc-c++ gmp gmp-devel make ncurses ncurses-compat-libs xz perl`
|
||||
|
||||
### Linux Mageia
|
||||
|
||||
The following distro packages are required: `curl gcc gcc-c++ gmp libffi-devel libffi7 libgmp-devel libgmp10 make libncurses-devel libncurses5 xz perl`
|
||||
|
||||
### Linux CentOS
|
||||
|
||||
#### Generic
|
||||
|
||||
The following distro packages are required: `gcc gcc-c++ gmp gmp-devel make ncurses ncurses-compat-libs xz perl`
|
||||
|
||||
#### Version >= 7 && < 8
|
||||
|
||||
The following distro packages are required: `gcc gcc-c++ gmp gmp-devel make ncurses xz perl`
|
||||
|
||||
|
||||
### Linux Alpine
|
||||
|
||||
#### Generic
|
||||
|
||||
The following distro packages are required: `binutils-gold curl gcc g++ gmp-dev libc-dev libffi-dev make musl-dev ncurses-dev perl tar xz`
|
||||
|
||||
### Linux VoidLinux
|
||||
|
||||
The following distro packages are required: `gcc gmp curl coreutils xz ncurses make ncurses-libtinfo-libs perl tar`
|
||||
|
||||
### Linux (generic)
|
||||
|
||||
#### Generic
|
||||
|
||||
You need the following packages: curl g++ gcc gmp make ncurses realpath xz-utils. Consult your distro documentation on the exact names of those packages.
|
||||
|
||||
### Darwin
|
||||
|
||||
#### Generic
|
||||
|
||||
On OS X, in the course of running ghcup you will be given a dialog box to install the command line tools. Accept and the requirements will be installed for you. You will then need to run the command again.
|
||||
On Darwin M1 you might also need a working llvm installed (e.g. via brew) and have the toolchain exposed in PATH.
|
||||
|
||||
### FreeBSD
|
||||
|
||||
#### Generic
|
||||
|
||||
The following distro packages are required: `curl gcc gmp gmake ncurses perl5 libffi libiconv`
|
||||
|
||||
|
||||
### Windows
|
||||
|
||||
#### Generic
|
||||
|
||||
On Windows, msys2 should already have been set up during the installation, so most users should just proceed. If you are installing manually, make sure to have a working mingw64 toolchain and shell.
|
||||
|
||||
## Next steps
|
||||
@@ -102,10 +140,21 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
||||
<table>
|
||||
<thead><tr><th>GHC Version</th><th>Tags</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>9.4.3</td><td><span style="color:blue">latest</span>, base-4.17.0.0</td></tr>
|
||||
<tr><td>9.8.1</td><td><span style="color:blue">latest</span>, base-4.19.0.0</td></tr>
|
||||
<tr><td>9.6.3</td><td>base-4.18.1.0</td></tr>
|
||||
<tr><td>9.6.2</td><td>base-4.18.0.0</td></tr>
|
||||
<tr><td>9.6.1</td><td>base-4.18.0.0</td></tr>
|
||||
<tr><td>9.4.7</td><td><span style="color:green">recommended</span>, base-4.17.2.0</td></tr>
|
||||
<tr><td>9.4.6</td><td>base-4.17.2.0</td></tr>
|
||||
<tr><td>9.4.5</td><td>base-4.17.1.0</td></tr>
|
||||
<tr><td>9.4.4</td><td>base-4.17.0.0</td></tr>
|
||||
<tr><td>9.4.3</td><td>base-4.17.0.0</td></tr>
|
||||
<tr><td>9.4.2</td><td>base-4.17.0.0</td></tr>
|
||||
<tr><td>9.4.1</td><td>base-4.17.0.0</td></tr>
|
||||
<tr><td>9.2.5</td><td><span style="color:green">recommended</span>, base-4.16.4.0</td></tr>
|
||||
<tr><td>9.2.8</td><td>base-4.16.4.0</td></tr>
|
||||
<tr><td>9.2.7</td><td>base-4.16.4.0</td></tr>
|
||||
<tr><td>9.2.6</td><td>base-4.16.4.0</td></tr>
|
||||
<tr><td>9.2.5</td><td>base-4.16.4.0</td></tr>
|
||||
<tr><td>9.2.4</td><td>base-4.16.3.0</td></tr>
|
||||
<tr><td>9.2.3</td><td>base-4.16.2.0</td></tr>
|
||||
<tr><td>9.2.2</td><td>base-4.16.1.0</td></tr>
|
||||
@@ -143,7 +192,9 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
||||
<table>
|
||||
<thead><tr><th>Cabal Version</th><th>Tags</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>3.8.1.0</td><td><span style="color:blue">latest</span></td></tr>
|
||||
<tr><td>3.10.2.0</td><td><span style="color:blue">latest</span></td></tr>
|
||||
<tr><td>3.10.1.0</td><td></td></tr>
|
||||
<tr><td>3.8.1.0</td><td></td></tr>
|
||||
<tr><td>3.6.2.0</td><td><span style="color:green">recommended</span></td></tr>
|
||||
<tr><td>3.6.0.0</td><td></td></tr>
|
||||
<tr><td>3.4.1.0</td><td></td></tr>
|
||||
@@ -159,7 +210,16 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
||||
<table>
|
||||
<thead><tr><th>HLS Version</th><th>Tags</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>1.8.0.0</td><td><span style="color:blue">latest</span>, <span style="color:green">recommended</span></td></tr>
|
||||
<tr><td>2.4.0.0</td><td><span style="color:blue">latest</span>, <span style="color:green">recommended</span></td></tr>
|
||||
<tr><td>2.3.0.0</td><td></td></tr>
|
||||
<tr><td>2.2.0.0</td><td></td></tr>
|
||||
<tr><td>2.1.0.0</td><td></td></tr>
|
||||
<tr><td>2.0.0.1</td><td></td></tr>
|
||||
<tr><td>2.0.0.0</td><td></td></tr>
|
||||
<tr><td>1.10.0.0</td><td></td></tr>
|
||||
<tr><td>1.9.1.0</td><td></td></tr>
|
||||
<tr><td>1.9.0.0</td><td></td></tr>
|
||||
<tr><td>1.8.0.0</td><td></td></tr>
|
||||
<tr><td>1.7.0.0</td><td></td></tr>
|
||||
<tr><td>1.6.1.0</td><td></td></tr>
|
||||
<tr><td>1.6.0.0</td><td></td></tr>
|
||||
@@ -177,7 +237,10 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
||||
<table>
|
||||
<thead><tr><th>Stack Version</th><th>Tags</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>2.9.1</td><td><span style="color:blue">latest</span>, <span style="color:green">recommended</span></td></tr>
|
||||
<tr><td>2.13.1</td><td><span style="color:blue">latest</span></td></tr>
|
||||
<tr><td>2.11.1</td><td><span style="color:green">recommended</span></td></tr>
|
||||
<tr><td>2.9.3</td><td></td></tr>
|
||||
<tr><td>2.9.1</td><td></td></tr>
|
||||
<tr><td>2.7.5</td><td></td></tr>
|
||||
<tr><td>2.7.3</td><td></td></tr>
|
||||
<tr><td>2.7.1</td><td></td></tr>
|
||||
@@ -190,9 +253,9 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
||||
|
||||
This list may not be exhaustive and specifies support for bindists only.
|
||||
|
||||
| Platform | Architecture | ghcup | GHC | cabal | HLS | stack |
|
||||
| Platform | Architecture | ghcup | GHC | cabal | HLS | stack |
|
||||
| ------ | ------ | ------ | ------ | ------ | ------ | ------ |
|
||||
| Windows 7 | amd64 | ❔ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Windows 8.1 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Windows 10 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Windows Server 2016 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Windows Server 2019 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
@@ -208,12 +271,11 @@ This list may not be exhaustive and specifies support for bindists only.
|
||||
| Linux generic | aarch64 | ✅ | ⚠️ | ✅ | ⚠️ | ❌ |
|
||||
| Linux generic | armv7 | ✅ | ⚠️ | ✅ | ⚠️ | ❌ |
|
||||
|
||||
### Windows 7
|
||||
### Windows <8.1
|
||||
|
||||
May or may not work, several issues:
|
||||
|
||||
* [https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/140](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/140)
|
||||
* [https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/197](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/197)
|
||||
No longer supported for recent GHCs, according to manual testing of GHC 9.8.1 on Windows 7.
|
||||
According to [msys2 documentation](https://www.msys2.org/docs/windows_support), the minimum Windows
|
||||
version is now 8.1.
|
||||
|
||||
### WSL1
|
||||
|
||||
@@ -231,8 +293,9 @@ There are various issues with GHC itself.
|
||||
|
||||
### FreeBSD
|
||||
|
||||
Lacks some upstream bindists and may need compat libs, since most bindists are built on FreeBSD-12.
|
||||
Lacks some upstream bindists and may need compat libs (such as `misc/compat12x`).
|
||||
HLS bindists are experimental.
|
||||
Only latest FreeBSD is generally supported.
|
||||
|
||||
### Linux ARMv7/AARCH64
|
||||
|
||||
@@ -240,10 +303,19 @@ Lower availability of bindists. Stack and HLS binaries are experimental.
|
||||
|
||||
## Manual installation
|
||||
|
||||
### Unix
|
||||
|
||||
Download the binary for your platform at [https://downloads.haskell.org/~ghcup/](https://downloads.haskell.org/~ghcup/)
|
||||
and place it into your `PATH` anywhere.
|
||||
|
||||
If you want to GPG verify the binaries, import the following keys first: `7784930957807690A66EBDBE3786C5262ECB4A3F` and `FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01`.
|
||||
If you want to GPG verify the binaries, import the following keys first:
|
||||
|
||||
```sh
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 88B57FCF7DB53B4DB3BFA4B1588764FBE22D19C4
|
||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys EAF2A9A722C0C96F2B431CA511AAD8CEDEE0CAEF
|
||||
```
|
||||
|
||||
Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) like so:
|
||||
|
||||
@@ -251,6 +323,78 @@ Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) lik
|
||||
export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
1. Install ghcup binary
|
||||
- choose a base directory for installation, e.g. `C:\` that has sufficient space
|
||||
- then create the directory, e.g. `C:\ghcup\bin`
|
||||
- download the binary: https://downloads.haskell.org/~ghcup/x86_64-mingw64-ghcup.exe
|
||||
- place it as `ghcup.exe` into e.g. `C:\ghcup\bin`
|
||||
2. Install MSYS2
|
||||
- download https://repo.msys2.org/distrib/msys2-x86_64-latest.exe and execute it
|
||||
- remember the installation destination you choose (default is `C:\msys64`)
|
||||
- finish the installation
|
||||
* Add environment variables and update `Path`
|
||||
- open search bar and type in "Edit the system environment variables", then open it
|
||||
- click on "Environment Variables..." at the near bottom
|
||||
- in the upper half, select `Path` variable and double click on it
|
||||
- in the new window, click "New", type in `C:\ghcup\bin` (depending on step 1.) and press enter
|
||||
- click "OK" at the bottom
|
||||
- in the upper half, click on "New..."
|
||||
- enter `GHCUP_MSYS2` under "Variable name" and the installation destination from step 2. under "Variable value"
|
||||
- click "OK" at the bottom
|
||||
- in the upper half, click on "New..."
|
||||
- enter `GHCUP_INSTALL_BASE_PREFIX` under "Variable name" and based on the installation destination from step 1. enter the device directory (default `C:\`)
|
||||
- click "OK" at the bottom
|
||||
- in the upper half, click on "New..."
|
||||
- enter `CABAL_DIR` under "Variable name" and based on the installation destination from step 1. enter the device directory + `cabal` subdir (default `C:\cabal`)
|
||||
- click "OK" at the bottom
|
||||
- click "OK" at the bottom
|
||||
- click "OK" at the bottom
|
||||
3. Install tools
|
||||
- open powershell
|
||||
- run `ghcup install ghc --set recommended`
|
||||
- run `ghcup install cabal latest`
|
||||
- run `ghcup install stack latest`
|
||||
- run `ghcup install hls latest`
|
||||
- run `cabal update`
|
||||
4. Update msys2
|
||||
- run `ghcup run -m -- pacman --noconfirm -Syuu`
|
||||
- run `ghcup run -m -- pacman --noconfirm -Syuu`
|
||||
- run `ghcup run -m -- pacman --noconfirm -S --needed curl autoconf mingw-w64-x86_64-pkgconf`
|
||||
- run `ghcup run -m -- pacman --noconfirm -S ca-certificates`
|
||||
5. Update cabal config
|
||||
- go to e.g. `C:\cabal` (based on device you picked in 1.)
|
||||
- open file `config`
|
||||
- uncomment `extra-include-dirs` (the `-- `) and add the value (depending on installation destination you chose in 2.), e.g. `C:\msys64\mingw64\include`... so the final line should be `extra-include-dirs: C:\msys64\mingw64\include`
|
||||
- uncomment `extra-lib-dirs` and do the same, adding `C:\msys64\mingw64\lib`
|
||||
- uncomment `extra-prog-path` and set it to `C:\ghcup\bin, C:\cabal\bin, C:\msys64\mingw64\bin, C:\msys64\usr\bin`, depending on your install destinations from 1. and 2.
|
||||
6. Set up msys2 shell
|
||||
- run `ghcup run -m -- sed -i -e 's/db_home:.*$/db_home: windows/' /etc/nsswitch.conf` to make the HOME in your msys2 shell match the one from windows
|
||||
- make a desktop shortcut from `C:\msys64\msys2_shell.cmd`, which will allow you to start a proper msys2 shell
|
||||
- run `ghcup run -m -- sed -i -e 's/#MSYS2_PATH_TYPE=.*/MSYS2_PATH_TYPE=inherit/' /c/msys64/msys2.ini`
|
||||
- run `ghcup run -m -- sed -i -e 's/rem set MSYS2_PATH_TYPE=inherit/set MSYS2_PATH_TYPE=inherit/' /c/msys64/msys2_shell.cmd`
|
||||
|
||||
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).
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 27 KiB |
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 28 KiB |
@@ -1,201 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ config.theme.locale|default('en') }}">
|
||||
<head>
|
||||
{%- block site_meta %}
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{% if page and page.is_homepage %}<meta name="description" content="{{ config['site_description'] }}">{% endif %}
|
||||
{% if config.site_author %}<meta name="author" content="{{ config.site_author }}">{% endif %}
|
||||
{% if page and page.canonical_url %}<link rel="canonical" href="{{ page.canonical_url }}">{% endif %}
|
||||
{% if config.site_favicon %}<link rel="shortcut icon" href="{{ config.site_favicon|url }}">
|
||||
{% else %}<link rel="shortcut icon" href="{{ 'img/favicon.ico'|url }}">{% endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block htmltitle %}
|
||||
<title>{% if page and page.title and not page.is_homepage %}{{ page.title }} - {% endif %}{{ config.site_name }}</title>
|
||||
{%- endblock %}
|
||||
|
||||
{%- block styles %}
|
||||
<link href="{{ 'css/bootstrap.min.css'|url }}" rel="stylesheet">
|
||||
<link href="{{ 'css/font-awesome.min.css'|url }}" rel="stylesheet">
|
||||
<link href="{{ 'css/base.css'|url }}" rel="stylesheet">
|
||||
{%- if config.theme.highlightjs %}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/{{ config.theme.hljs_style }}.min.css">
|
||||
{%- endif %}
|
||||
{%- for path in extra_css %}
|
||||
<link href="{{ path }}" rel="stylesheet">
|
||||
{%- endfor %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block libs %}
|
||||
|
||||
<script src="{{ 'js/jquery-1.10.2.min.js'|url }}" defer></script>
|
||||
<script src="{{ 'js/bootstrap.min.js'|url }}" defer></script>
|
||||
{%- if config.theme.highlightjs %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
|
||||
{%- for lang in config.theme.hljs_languages %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/languages/{{lang}}.min.js"></script>
|
||||
{%- endfor %}
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block analytics %}
|
||||
{%- if config.theme.analytics.gtag %}
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id={{ config.theme.analytics.gtag }}"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', '{{ config.theme.analytics.gtag }}');
|
||||
</script>
|
||||
{%- elif config.google_analytics %}
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', '{{ config.google_analytics[0] }}', '{{ config.google_analytics[1] }}');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block extrahead %} {% endblock %}
|
||||
</head>
|
||||
|
||||
<body{% if page and page.is_homepage %} class="homepage"{% endif %}>
|
||||
<div class="navbar fixed-top navbar-expand-lg navbar-{% if config.theme.nav_style == "light" %}light{% else %}dark{% endif %} bg-{{ config.theme.nav_style }}">
|
||||
<div class="container">
|
||||
|
||||
{%- block site_name %}
|
||||
<a class="navbar-brand" href="{{ nav.homepage.url|url }}">{{ config.site_name }}</a>
|
||||
{%- endblock %}
|
||||
|
||||
{%- if nav|length>1 or (page and (page.next_page or page.previous_page)) or config.repo_url %}
|
||||
<!-- Expander button -->
|
||||
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
{%- endif %}
|
||||
|
||||
<!-- Expanded navigation -->
|
||||
<div id="navbar-collapse" class="navbar-collapse collapse">
|
||||
{%- block site_nav %}
|
||||
{%- if nav|length>1 %}
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
{%- for nav_item in nav %}
|
||||
{%- if nav_item.children %}
|
||||
<li class="dropdown{% if nav_item.active %} active{% endif %}">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">{{ nav_item.title }} <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
{%- for nav_item in nav_item.children %}
|
||||
{% include "nav-sub.html" %}
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{%- else %}
|
||||
<li class="navitem{% if nav_item.active %} active{% endif %}">
|
||||
<a href="{{ nav_item.url|url }}" class="nav-link">{{ nav_item.title }}</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
<ul class="nav navbar-nav ml-auto">
|
||||
{%- block search_button %}
|
||||
{%- if 'search' in config['plugins'] %}
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
|
||||
<i class="fa fa-search"></i> {% trans %}Search{% endtrans %}
|
||||
</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block next_prev %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block repo %}
|
||||
{%- if page and page.edit_url %}
|
||||
<li class="nav-item">
|
||||
<a href="{{ page.edit_url }}" class="nav-link">
|
||||
{%- if config.repo_name == 'GitHub' -%}
|
||||
<i class="fa fa-github"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
||||
{%- elif config.repo_name == 'Bitbucket' -%}
|
||||
<i class="fa fa-bitbucket"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
||||
{%- elif config.repo_name == 'GitLab' -%}
|
||||
<i class="fa fa-gitlab"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
||||
{%- else -%}
|
||||
{% trans repo_name=config.repo_name%}Edit on {{ repo_name }}{% endtrans %}
|
||||
{%- endif -%}
|
||||
</a>
|
||||
</li>
|
||||
{%- elif config.repo_url %}
|
||||
<li class="nav-item">
|
||||
<a href="{{ config.repo_url }}" class="nav-link">
|
||||
{%- if config.repo_name == 'GitHub' -%}
|
||||
<i class="fa fa-github"></i> {{ config.repo_name }}
|
||||
{%- elif config.repo_name == 'Bitbucket' -%}
|
||||
<i class="fa fa-bitbucket"></i> {{ config.repo_name }}
|
||||
{%- elif config.repo_name == 'GitLab' -%}
|
||||
<i class="fa fa-gitlab"></i> {{ config.repo_name }}
|
||||
{%- else -%}
|
||||
{{ config.repo_name }}
|
||||
{%- endif -%}
|
||||
</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{%- block content %}
|
||||
<div class="col-md-3">{% include "toc.html" %}</div>
|
||||
<div class="col-md-9" role="main">{% include "content.html" %}</div>
|
||||
{%- endblock %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="col-md-12">
|
||||
{%- block footer %}
|
||||
<hr>
|
||||
{%- if config.copyright %}
|
||||
<p>{{ config.copyright }}</p>
|
||||
{%- endif %}
|
||||
<p>{% trans mkdocs_link='<a href="https://www.mkdocs.org/">MkDocs</a>' %}Documentation built with {{ mkdocs_link }}.{% endtrans %}</p>
|
||||
{%- endblock %}
|
||||
</footer>
|
||||
|
||||
{%- block scripts %}
|
||||
<script>
|
||||
var base_url = {{ base_url | tojson }},
|
||||
shortcuts = {{ config.theme.shortcuts | tojson }};
|
||||
</script>
|
||||
<script src="{{ 'js/base.js'|url }}" defer></script>
|
||||
{%- for path in extra_javascript %}
|
||||
<script src="{{ path }}" defer></script>
|
||||
{%- endfor %}
|
||||
{%- endblock %}
|
||||
|
||||
{% if 'search' in config['plugins'] %}{%- include "search-modal.html" %}{% endif %}
|
||||
{%- include "keyboard-modal.html" %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
{% if page and page.is_homepage %}
|
||||
<!--
|
||||
MkDocs version : {{ mkdocs_version }}
|
||||
Build Date UTC : {{ build_date_utc }}
|
||||
-->
|
||||
{% endif %}
|
||||
BIN
docs/overrides/img/favicon.ico
Normal file
BIN
docs/overrides/img/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
4
docs/overrides/main.html
Normal file
4
docs/overrides/main.html
Normal file
@@ -0,0 +1,4 @@
|
||||
{% extends "base.html" %}
|
||||
<!-- Get rid of the next/prev buttons -->
|
||||
{% block next_prev %}
|
||||
{% endblock %}
|
||||
@@ -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
|
||||
|
||||
248
ghcup.cabal
248
ghcup.cabal
@@ -1,6 +1,6 @@
|
||||
cabal-version: 3.0
|
||||
cabal-version: 2.4
|
||||
name: ghcup
|
||||
version: 0.1.18.1
|
||||
version: 0.1.20.0
|
||||
license: LGPL-3.0-only
|
||||
license-file: LICENSE
|
||||
copyright: Julian Ospald 2020
|
||||
@@ -25,10 +25,15 @@ extra-source-files:
|
||||
cbits/dirutils.h
|
||||
data/build_mk/cross
|
||||
data/build_mk/default
|
||||
test/golden/unix/GHCupInfo.json
|
||||
test/golden/windows/GHCupInfo.json
|
||||
test/data/file
|
||||
test/data/dir/.keep
|
||||
test/ghcup-test/data/dir/.keep
|
||||
test/ghcup-test/data/file
|
||||
test/ghcup-test/golden/unix/GHCupInfo.json
|
||||
test/ghcup-test/golden/windows/GHCupInfo.json
|
||||
|
||||
tested-with: GHC==9.4.8
|
||||
, GHC==9.2.8
|
||||
, GHC==9.0.2
|
||||
, GHC==8.10.7
|
||||
|
||||
source-repository head
|
||||
type: git
|
||||
@@ -36,7 +41,7 @@ source-repository head
|
||||
|
||||
flag tui
|
||||
description:
|
||||
Build the brick powered tui (ghcup tui). This is disabled on windows.
|
||||
Build the brick powered tui (ghcup tui).
|
||||
|
||||
default: False
|
||||
manual: True
|
||||
@@ -53,6 +58,56 @@ flag no-exe
|
||||
default: False
|
||||
manual: True
|
||||
|
||||
flag tar
|
||||
description: Use haskell tar instead of libarchive.
|
||||
default: False
|
||||
manual: True
|
||||
|
||||
common app-common-depends
|
||||
build-depends:
|
||||
, aeson >=1.4
|
||||
, aeson-pretty ^>=0.8.8
|
||||
, async ^>=2.2.3
|
||||
, base >=4.12 && <5
|
||||
, bytestring >=0.10 && <0.12
|
||||
, cabal-install-parsers >=0.4.5
|
||||
, cabal-plan ^>=0.7.2
|
||||
, containers ^>=0.6
|
||||
, deepseq ^>=1.4
|
||||
, directory ^>=1.3.6.0
|
||||
, filepath ^>=1.4.2.1
|
||||
, haskus-utils-types ^>=1.5
|
||||
, haskus-utils-variant ^>=3.3
|
||||
, megaparsec >=8.0.0 && <9.3
|
||||
, mtl ^>=2.2
|
||||
, optparse-applicative >=0.15.1.0 && <0.18
|
||||
, pretty ^>=1.1.3.1
|
||||
, pretty-terminal ^>=0.1.0.0
|
||||
, process ^>=1.6.11.0
|
||||
, resourcet ^>=1.2.2
|
||||
, safe ^>=0.3.18
|
||||
, safe-exceptions ^>=0.1
|
||||
, tagsoup ^>=0.14
|
||||
, template-haskell >=2.7 && <2.22
|
||||
, temporary ^>=1.3
|
||||
, text ^>=2.0
|
||||
, time >=1.9.3 && <1.12
|
||||
, unordered-containers ^>=0.2
|
||||
, uri-bytestring ^>=0.3.2.2
|
||||
, utf8-string ^>=1.0
|
||||
, vector >=0.12 && <0.14
|
||||
, versions >=6.0.3 && <6.1
|
||||
, yaml-streamly ^>=0.12.0
|
||||
|
||||
if flag(tar)
|
||||
cpp-options: -DTAR
|
||||
build-depends:
|
||||
tar ^>=0.6.0.0
|
||||
, zip ^>=2.0.0
|
||||
|
||||
else
|
||||
build-depends: libarchive ^>=3.0.3.0
|
||||
|
||||
library
|
||||
exposed-modules:
|
||||
GHCup
|
||||
@@ -80,9 +135,14 @@ library
|
||||
GHCup.Types
|
||||
GHCup.Types.JSON
|
||||
GHCup.Types.JSON.Utils
|
||||
GHCup.Types.JSON.Versions
|
||||
GHCup.Types.Optics
|
||||
GHCup.Types.Stack
|
||||
GHCup.Utils
|
||||
GHCup.Utils.Dirs
|
||||
GHCup.Utils.Tar
|
||||
GHCup.Utils.Tar.Types
|
||||
GHCup.Utils.URI
|
||||
GHCup.Version
|
||||
|
||||
hs-source-dirs: lib
|
||||
@@ -125,9 +185,9 @@ library
|
||||
, disk-free-space ^>=0.1.0.1
|
||||
, exceptions ^>=0.10
|
||||
, filepath ^>=1.4.2.1
|
||||
, file-uri ^>=0.1.0.0
|
||||
, haskus-utils-types ^>=1.5
|
||||
, haskus-utils-variant ^>=3.2.1
|
||||
, libarchive ^>=3.0.3.0
|
||||
, haskus-utils-variant ^>=3.3
|
||||
, lzma-static ^>=5.2.5.3
|
||||
, megaparsec >=8.0.0 && <9.3
|
||||
, mtl ^>=2.2
|
||||
@@ -137,31 +197,40 @@ library
|
||||
, pretty-terminal ^>=0.1.0.0
|
||||
, regex-posix ^>=0.96
|
||||
, resourcet ^>=1.2.2
|
||||
, retry ^>=0.8.1.2
|
||||
, retry >=0.8.1.2 && <0.10
|
||||
, safe ^>=0.3.18
|
||||
, safe-exceptions ^>=0.1
|
||||
, split ^>=0.2.3.4
|
||||
, streamly ^>=0.8.2
|
||||
, strict-base ^>=0.4
|
||||
, template-haskell >=2.7 && <2.18
|
||||
, template-haskell >=2.7 && <2.22
|
||||
, temporary ^>=1.3
|
||||
, text ^>=1.2.4.0
|
||||
, time ^>=1.9.3
|
||||
, text ^>=2.0
|
||||
, time >=1.9.3 && <1.12
|
||||
, transformers ^>=0.5
|
||||
, unliftio-core ^>=0.2.0.1
|
||||
, unordered-containers ^>=0.2.10.0
|
||||
, uri-bytestring ^>=0.3.2.2
|
||||
, vector ^>=0.12
|
||||
, versions >=4.0.1 && <5.1
|
||||
, vector >=0.12 && <0.14
|
||||
, versions >=6.0.3 && <6.1
|
||||
, word8 ^>=0.1.3
|
||||
, yaml-streamly ^>=0.12.0
|
||||
, zlib ^>=0.6.2.2
|
||||
|
||||
if flag(tar)
|
||||
cpp-options: -DTAR
|
||||
build-depends:
|
||||
tar ^>=0.6.0.0
|
||||
, zip ^>=2.0.0
|
||||
|
||||
else
|
||||
build-depends: libarchive ^>=3.0.3.0
|
||||
|
||||
if (flag(internal-downloader) && !os(windows))
|
||||
exposed-modules: GHCup.Download.IOStreams
|
||||
cpp-options: -DINTERNAL_DOWNLOADER
|
||||
build-depends:
|
||||
, HsOpenSSL >=0.11.4.18
|
||||
, HsOpenSSL >=0.11.7.2
|
||||
, http-io-streams >=0.1.2.0
|
||||
, io-streams >=1.5.2.1
|
||||
, terminal-progress-bar >=0.4.1
|
||||
@@ -185,26 +254,25 @@ library
|
||||
GHCup.Prelude.File.Posix.Foreign
|
||||
GHCup.Prelude.Posix
|
||||
GHCup.Prelude.Process.Posix
|
||||
exposed-modules:
|
||||
GHCup.Prelude.File.Posix.Traversals
|
||||
|
||||
exposed-modules: GHCup.Prelude.File.Posix.Traversals
|
||||
include-dirs: cbits
|
||||
includes: dirutils.h
|
||||
install-includes: dirutils.h
|
||||
c-sources: cbits/dirutils.c
|
||||
build-depends:
|
||||
, bz2 >=0.5.0.5 && <1.1
|
||||
, terminal-size ^>=0.3.2.1
|
||||
, unix ^>=2.7
|
||||
, terminal-size ^>=0.3.3
|
||||
, unix ^>=2.7 || ^>=2.8
|
||||
, unix-bytestring ^>=0.3.7.3
|
||||
|
||||
if (flag(tui) && !os(windows))
|
||||
if flag(tui)
|
||||
cpp-options: -DBRICK
|
||||
build-depends: vty >=5.28.2 && <5.34
|
||||
build-depends: vty ^>=6.0
|
||||
|
||||
executable ghcup
|
||||
main-is: Main.hs
|
||||
other-modules:
|
||||
library ghcup-optparse
|
||||
import: app-common-depends
|
||||
exposed-modules:
|
||||
GHCup.OptParse
|
||||
GHCup.OptParse.ChangeLog
|
||||
GHCup.OptParse.Common
|
||||
@@ -219,11 +287,46 @@ executable ghcup
|
||||
GHCup.OptParse.Rm
|
||||
GHCup.OptParse.Run
|
||||
GHCup.OptParse.Set
|
||||
GHCup.OptParse.Test
|
||||
GHCup.OptParse.ToolRequirements
|
||||
GHCup.OptParse.UnSet
|
||||
GHCup.OptParse.Upgrade
|
||||
GHCup.OptParse.Whereis
|
||||
|
||||
hs-source-dirs: lib-opt
|
||||
default-language: Haskell2010
|
||||
default-extensions:
|
||||
LambdaCase
|
||||
MultiWayIf
|
||||
NamedFieldPuns
|
||||
PackageImports
|
||||
RecordWildCards
|
||||
ScopedTypeVariables
|
||||
StrictData
|
||||
TupleSections
|
||||
|
||||
ghc-options:
|
||||
-Wall -fwarn-tabs -fwarn-incomplete-uni-patterns
|
||||
-fwarn-incomplete-record-updates
|
||||
|
||||
build-depends: ghcup
|
||||
|
||||
if flag(internal-downloader)
|
||||
cpp-options: -DINTERNAL_DOWNLOADER
|
||||
|
||||
if flag(tui)
|
||||
cpp-options: -DBRICK
|
||||
|
||||
if os(windows)
|
||||
cpp-options: -DIS_WINDOWS
|
||||
|
||||
else
|
||||
build-depends: unix ^>=2.7 || ^>=2.8
|
||||
|
||||
executable ghcup
|
||||
import: app-common-depends
|
||||
main-is: Main.hs
|
||||
|
||||
hs-source-dirs: app/ghcup
|
||||
default-language: Haskell2010
|
||||
default-extensions:
|
||||
@@ -241,58 +344,25 @@ executable ghcup
|
||||
-fwarn-incomplete-record-updates -threaded
|
||||
|
||||
build-depends:
|
||||
, aeson >=1.4
|
||||
, aeson-pretty ^>=0.8.8
|
||||
, async ^>=2.2.3
|
||||
, base >=4.12 && <5
|
||||
, bytestring >=0.10 && <0.12
|
||||
, cabal-plan ^>=0.7.2
|
||||
, cabal-install-parsers >=0.4.5
|
||||
, containers ^>=0.6
|
||||
, deepseq ^>=1.4
|
||||
, directory ^>=1.3.6.0
|
||||
, filepath ^>=1.4.2.1
|
||||
, ghcup
|
||||
, haskus-utils-types ^>=1.5
|
||||
, haskus-utils-variant ^>=3.2.1
|
||||
, libarchive ^>=3.0.3.0
|
||||
, megaparsec >=8.0.0 && <9.3
|
||||
, mtl ^>=2.2
|
||||
, optparse-applicative >=0.15.1.0 && <0.18
|
||||
, pretty ^>=1.1.3.1
|
||||
, pretty-terminal ^>=0.1.0.0
|
||||
, process ^>=1.6.11.0
|
||||
, resourcet ^>=1.2.2
|
||||
, safe ^>=0.3.18
|
||||
, safe-exceptions ^>=0.1
|
||||
, tagsoup ^>=0.14
|
||||
, template-haskell >=2.7 && <2.18
|
||||
, temporary ^>=1.3
|
||||
, text ^>=1.2.4.0
|
||||
, unordered-containers ^>=0.2
|
||||
, uri-bytestring ^>=0.3.2.2
|
||||
, utf8-string ^>=1.0
|
||||
, vector ^>=0.12
|
||||
, versions >=4.0.1 && <5.1
|
||||
, yaml-streamly ^>=0.12.0
|
||||
, ghcup-optparse
|
||||
|
||||
if flag(internal-downloader)
|
||||
cpp-options: -DINTERNAL_DOWNLOADER
|
||||
|
||||
if (flag(tui) && !os(windows))
|
||||
if flag(tui)
|
||||
cpp-options: -DBRICK
|
||||
other-modules: BrickMain
|
||||
build-depends:
|
||||
, brick ^>=0.64
|
||||
, brick ^>=2.1
|
||||
, transformers ^>=0.5
|
||||
, unix ^>=2.7
|
||||
, vty >=5.28.2 && <5.34
|
||||
, vty ^>=6.0
|
||||
, optics ^>=0.4
|
||||
|
||||
if os(windows)
|
||||
cpp-options: -DIS_WINDOWS
|
||||
|
||||
else
|
||||
build-depends: unix ^>=2.7
|
||||
build-depends: unix ^>=2.7 || ^>=2.8
|
||||
|
||||
if flag(no-exe)
|
||||
buildable: False
|
||||
@@ -301,12 +371,12 @@ test-suite ghcup-test
|
||||
type: exitcode-stdio-1.0
|
||||
main-is: Main.hs
|
||||
build-tool-depends: hspec-discover:hspec-discover -any
|
||||
hs-source-dirs: test
|
||||
hs-source-dirs: test/ghcup-test
|
||||
other-modules:
|
||||
GHCup.ArbitraryTypes
|
||||
GHCup.Prelude.File.Posix.TraversalsSpec
|
||||
GHCup.Types.JSONSpec
|
||||
GHCup.Utils.FileSpec
|
||||
GHCup.Prelude.File.Posix.TraversalsSpec
|
||||
Spec
|
||||
|
||||
default-language: Haskell2010
|
||||
@@ -335,12 +405,50 @@ test-suite ghcup-test
|
||||
, QuickCheck ^>=2.14.1
|
||||
, quickcheck-arbitrary-adt ^>=0.3.1.0
|
||||
, streamly ^>=0.8.2
|
||||
, text ^>=1.2.4.0
|
||||
, text ^>=2.0
|
||||
, time >=1.9.3 && <1.12
|
||||
, uri-bytestring ^>=0.3.2.2
|
||||
, versions >=4.0.1 && <5.1
|
||||
, versions >=6.0.3 && <6.1
|
||||
|
||||
if os(windows)
|
||||
cpp-options: -DIS_WINDOWS
|
||||
|
||||
else
|
||||
build-depends:
|
||||
, unix ^>=2.7
|
||||
build-depends: unix ^>=2.7 || ^>=2.8
|
||||
|
||||
test-suite ghcup-optparse-test
|
||||
type: exitcode-stdio-1.0
|
||||
hs-source-dirs: test/optparse-test
|
||||
main-is: Main.hs
|
||||
other-modules:
|
||||
ChangeLogTest
|
||||
CompileTest
|
||||
ConfigTest
|
||||
GCTest
|
||||
InstallTest
|
||||
ListTest
|
||||
OtherCommandTest
|
||||
RmTest
|
||||
RunTest
|
||||
SetTest
|
||||
UnsetTest
|
||||
UpgradeTest
|
||||
Utils
|
||||
WhereisTest
|
||||
|
||||
if os(windows)
|
||||
cpp-options: -DIS_WINDOWS
|
||||
|
||||
default-language: Haskell2010
|
||||
ghc-options: -Wall
|
||||
build-depends:
|
||||
, base
|
||||
, ghcup
|
||||
, ghcup-optparse
|
||||
, optparse-applicative
|
||||
, tasty
|
||||
, tasty-hunit
|
||||
, template-haskell
|
||||
, text
|
||||
, uri-bytestring
|
||||
, versions
|
||||
|
||||
4
hie.yaml
4
hie.yaml
@@ -5,4 +5,6 @@ cradle:
|
||||
- component: "ghcup:exe:ghcup"
|
||||
path: ./app/ghcup
|
||||
- component: "ghcup:test:ghcup-test"
|
||||
path: ./test
|
||||
path: ./test/ghcup-test
|
||||
- component: "ghcup:test:ghcup-optparse-test"
|
||||
path: ./test/optparse-test
|
||||
@@ -8,6 +8,7 @@
|
||||
module GHCup.OptParse (
|
||||
module GHCup.OptParse.Common
|
||||
, module GHCup.OptParse.Install
|
||||
, module GHCup.OptParse.Test
|
||||
, module GHCup.OptParse.Set
|
||||
, module GHCup.OptParse.UnSet
|
||||
, module GHCup.OptParse.Rm
|
||||
@@ -31,6 +32,7 @@ module GHCup.OptParse (
|
||||
|
||||
import GHCup.OptParse.Common
|
||||
import GHCup.OptParse.Install
|
||||
import GHCup.OptParse.Test
|
||||
import GHCup.OptParse.Set
|
||||
import GHCup.OptParse.UnSet
|
||||
import GHCup.OptParse.Rm
|
||||
@@ -55,16 +57,12 @@ import GHCup.Types
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
#endif
|
||||
import Control.Monad.Reader
|
||||
import Data.Bifunctor
|
||||
import Data.Either
|
||||
import Data.Functor
|
||||
import Data.Maybe
|
||||
import Options.Applicative hiding ( style )
|
||||
import Options.Applicative.Help.Pretty ( text )
|
||||
import Prelude hiding ( appendFile )
|
||||
import URI.ByteString
|
||||
|
||||
import qualified Data.ByteString.UTF8 as UTF8
|
||||
|
||||
|
||||
|
||||
@@ -74,19 +72,22 @@ data Options = Options
|
||||
optVerbose :: Maybe Bool
|
||||
, optCache :: Maybe Bool
|
||||
, optMetaCache :: Maybe Integer
|
||||
, optMetaMode :: Maybe MetaMode
|
||||
, optPlatform :: Maybe PlatformRequest
|
||||
, optUrlSource :: Maybe URI
|
||||
, optUrlSource :: Maybe URLSource
|
||||
, optNoVerify :: Maybe Bool
|
||||
, optKeepDirs :: Maybe KeepDirs
|
||||
, optsDownloader :: Maybe Downloader
|
||||
, optNoNetwork :: Maybe Bool
|
||||
, optGpg :: Maybe GPGSetting
|
||||
, optStackSetup :: Maybe Bool
|
||||
-- commands
|
||||
, optCommand :: Command
|
||||
}
|
||||
|
||||
data Command
|
||||
= Install (Either InstallCommand InstallOptions)
|
||||
| Test TestCommand
|
||||
| InstallCabalLegacy InstallOptions
|
||||
| Set (Either SetCommand SetOptions)
|
||||
| UnSet UnsetCommand
|
||||
@@ -108,6 +109,7 @@ data Command
|
||||
| Prefetch PrefetchCommand
|
||||
| GC GCOptions
|
||||
| Run RunOptions
|
||||
| PrintAppErrors
|
||||
|
||||
|
||||
|
||||
@@ -116,7 +118,8 @@ opts =
|
||||
Options
|
||||
<$> invertableSwitch "verbose" (Just 'v') False (help "Enable verbosity (default: disabled)")
|
||||
<*> invertableSwitch "cache" (Just 'c') False (help "Cache downloads in ~/.ghcup/cache (default: disabled)")
|
||||
<*> optional (option auto (long "metadata-caching" <> help "How long the yaml metadata caching interval is (in seconds), 0 to disable" <> internal))
|
||||
<*> optional (option auto (long "metadata-caching" <> metavar "SEC" <> help "How long the yaml metadata caching interval is (in seconds), 0 to disable"))
|
||||
<*> optional (option auto (long "metadata-fetching-mode" <> metavar "<Strict|Lax>" <> help "Whether to fail on metadata download failure (Strict) or fall back to cached version (Lax (default))"))
|
||||
<*> optional
|
||||
(option
|
||||
(eitherReader platformParser)
|
||||
@@ -129,13 +132,13 @@ opts =
|
||||
)
|
||||
<*> optional
|
||||
(option
|
||||
(eitherReader parseUri)
|
||||
(eitherReader parseUrlSource)
|
||||
( short 's'
|
||||
<> long "url-source"
|
||||
<> metavar "URL"
|
||||
<> help "Alternative ghcup download info url"
|
||||
<> metavar "URL_SOURCE"
|
||||
<> help "Alternative ghcup download info"
|
||||
<> internal
|
||||
<> completer fileUri
|
||||
<> completer urlSourceCompleter
|
||||
)
|
||||
)
|
||||
<*> (fmap . fmap) not (invertableSwitch "verify" (Just 'n') True (help "Disable tarball checksum verification (default: enabled)"))
|
||||
@@ -173,10 +176,9 @@ opts =
|
||||
"GPG verification (default: none)"
|
||||
<> completer (listCompleter ["strict", "lax", "none"])
|
||||
))
|
||||
<*> invertableSwitch "stack-setup" (Just 's') False (help "Use stack's setup info for discovering and installing GHC versions")
|
||||
<*> com
|
||||
where
|
||||
parseUri s' =
|
||||
first show $ parseURI strictURIParserOptions (UTF8.fromString s')
|
||||
|
||||
|
||||
|
||||
com :: Parser Command
|
||||
@@ -203,6 +205,14 @@ com =
|
||||
<> footerDoc (Just $ text installToolFooter)
|
||||
)
|
||||
)
|
||||
<> command
|
||||
"test"
|
||||
(info
|
||||
(Test <$> testParser <**> helper)
|
||||
( progDesc "Run tests for a tool (if any) [EXPERIMENTAL!]"
|
||||
<> footerDoc (Just $ text testFooter)
|
||||
)
|
||||
)
|
||||
<> command
|
||||
"set"
|
||||
(info
|
||||
@@ -231,7 +241,8 @@ com =
|
||||
<> command
|
||||
"list"
|
||||
(info (List <$> listOpts <**> helper)
|
||||
(progDesc "Show available GHCs and other tools")
|
||||
(progDesc "Show available GHCs and other tools"
|
||||
<> footerDoc (Just $ text listToolFooter))
|
||||
)
|
||||
<> command
|
||||
"upgrade"
|
||||
@@ -340,3 +351,10 @@ com =
|
||||
<> commandGroup "Nuclear Commands:"
|
||||
<> hidden
|
||||
)
|
||||
<|> subparser
|
||||
(command
|
||||
"print-app-errors"
|
||||
(info (pure PrintAppErrors <**> helper)
|
||||
(progDesc ""))
|
||||
<> internal
|
||||
)
|
||||
@@ -12,6 +12,7 @@ module GHCup.OptParse.ChangeLog where
|
||||
|
||||
|
||||
import GHCup.Types
|
||||
import GHCup.Errors
|
||||
import GHCup.OptParse.Common
|
||||
import GHCup.Prelude
|
||||
import GHCup.Prelude.Logger
|
||||
@@ -28,13 +29,13 @@ import Data.Maybe
|
||||
import Options.Applicative hiding ( style )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import System.Process ( system )
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception.Safe (MonadMask)
|
||||
import GHCup.Types.Optics
|
||||
import GHCup.Utils
|
||||
import Data.Versions
|
||||
import URI.ByteString (serializeURIRef')
|
||||
import Data.Char (toLower)
|
||||
|
||||
@@ -49,7 +50,7 @@ data ChangeLogOptions = ChangeLogOptions
|
||||
{ clOpen :: Bool
|
||||
, clTool :: Maybe Tool
|
||||
, clToolVer :: Maybe ToolVersion
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -75,12 +76,12 @@ changelogP =
|
||||
e -> Left e
|
||||
)
|
||||
)
|
||||
(short 't' <> long "tool" <> metavar "<ghc|cabal|hls|ghcup>" <> help
|
||||
(short 't' <> long "tool" <> metavar "<ghc|cabal|hls|ghcup|stack>" <> help
|
||||
"Open changelog for given tool (default: ghc)"
|
||||
<> completer toolCompleter
|
||||
)
|
||||
)
|
||||
<*> optional (toolVersionTagArgument Nothing Nothing)
|
||||
<*> optional (toolVersionTagArgument [] Nothing)
|
||||
|
||||
|
||||
|
||||
@@ -114,40 +115,36 @@ changelog :: ( Monad m
|
||||
changelog ChangeLogOptions{..} runAppState runLogger = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- runAppState getGHCupInfo
|
||||
let tool = fromMaybe GHC clTool
|
||||
ver' = maybe
|
||||
(Right Latest)
|
||||
(\case
|
||||
GHCVersion tv -> Left (_tvVersion tv)
|
||||
ToolVersion tv -> Left tv
|
||||
ToolTag t -> Right t
|
||||
)
|
||||
ver' = fromMaybe
|
||||
(ToolTag Latest)
|
||||
clToolVer
|
||||
muri = getChangeLog dls tool ver'
|
||||
case muri of
|
||||
Nothing -> do
|
||||
runLogger
|
||||
(logWarn $
|
||||
"Could not find ChangeLog for " <> T.pack (prettyShow tool) <> ", version " <> either prettyVer (T.pack . show) ver'
|
||||
"Could not find ChangeLog for " <> T.pack (prettyShow tool) <> ", version " <> T.pack (prettyShow ver')
|
||||
)
|
||||
pure ExitSuccess
|
||||
Just uri -> do
|
||||
pfreq <- runAppState getPlatformReq
|
||||
let uri' = T.unpack . decUTF8Safe . serializeURIRef' $ uri
|
||||
cmd = case _rPlatform pfreq of
|
||||
Darwin -> "open"
|
||||
Linux _ -> "xdg-open"
|
||||
FreeBSD -> "xdg-open"
|
||||
Windows -> "start"
|
||||
|
||||
if clOpen
|
||||
then do
|
||||
runAppState $
|
||||
exec cmd
|
||||
[T.unpack $ decUTF8Safe $ serializeURIRef' uri]
|
||||
Nothing
|
||||
Nothing
|
||||
case _rPlatform pfreq of
|
||||
Darwin -> exec "open" [T.unpack $ decUTF8Safe $ serializeURIRef' uri] Nothing Nothing
|
||||
Linux _ -> exec "xdg-open" [T.unpack $ decUTF8Safe $ serializeURIRef' uri] Nothing Nothing
|
||||
FreeBSD -> exec "xdg-open" [T.unpack $ decUTF8Safe $ serializeURIRef' uri] Nothing Nothing
|
||||
Windows -> do
|
||||
let args = "start \"\" " ++ (T.unpack $ decUTF8Safe $ serializeURIRef' uri)
|
||||
c <- liftIO $ system $ args
|
||||
case c of
|
||||
(ExitFailure xi) -> pure $ Left $ NonZeroExit xi "cmd.exe" [args]
|
||||
ExitSuccess -> pure $ Right ()
|
||||
>>= \case
|
||||
Right _ -> pure ExitSuccess
|
||||
Left e -> logError (T.pack $ prettyShow e)
|
||||
Left e -> logError (T.pack $ prettyHFError e)
|
||||
>> pure (ExitFailure 13)
|
||||
else liftIO $ putStrLn uri' >> pure ExitSuccess
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE NumericUnderscores #-}
|
||||
{-# LANGUAGE ViewPatterns #-}
|
||||
|
||||
module GHCup.OptParse.Common where
|
||||
|
||||
@@ -16,6 +17,7 @@ import GHCup.Platform
|
||||
import GHCup.Types
|
||||
import GHCup.Types.Optics
|
||||
import GHCup.Utils
|
||||
import GHCup.Utils.URI
|
||||
import GHCup.Prelude
|
||||
import GHCup.Prelude.Process
|
||||
import GHCup.Prelude.Logger
|
||||
@@ -45,7 +47,9 @@ import Data.Functor
|
||||
import Data.List ( nub, sort, sortBy, isPrefixOf, stripPrefix )
|
||||
import Data.Maybe
|
||||
import Data.Text ( Text )
|
||||
import Data.Versions hiding ( str )
|
||||
import Data.Time.Calendar ( Day )
|
||||
import Data.Time.Format ( parseTimeM, defaultTimeLocale )
|
||||
import Data.Versions
|
||||
import Data.Void
|
||||
import qualified Data.Vector as V
|
||||
import GHC.IO.Exception
|
||||
@@ -56,11 +60,13 @@ import Safe
|
||||
import System.Process ( readProcess )
|
||||
import System.FilePath
|
||||
import Text.HTML.TagSoup hiding ( Tag )
|
||||
import URI.ByteString
|
||||
import URI.ByteString hiding (parseURI)
|
||||
|
||||
import qualified Data.ByteString.UTF8 as UTF8
|
||||
import qualified Data.Map.Strict as M
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Lazy.Encoding as LE
|
||||
import qualified Data.Text.Lazy as LT
|
||||
import qualified Text.Megaparsec as MP
|
||||
import qualified System.FilePath.Posix as FP
|
||||
import GHCup.Version
|
||||
@@ -72,26 +78,27 @@ import qualified Cabal.Config as CC
|
||||
--[ Types ]--
|
||||
-------------
|
||||
|
||||
data ToolVersion = GHCVersion GHCTargetVersion
|
||||
| ToolVersion Version
|
||||
| ToolTag Tag
|
||||
|
||||
-- a superset of ToolVersion
|
||||
data SetToolVersion = SetGHCVersion GHCTargetVersion
|
||||
| SetToolVersion Version
|
||||
| SetToolTag Tag
|
||||
| SetToolDay Day
|
||||
| SetRecommended
|
||||
| SetNext
|
||||
deriving (Eq, Show)
|
||||
|
||||
prettyToolVer :: ToolVersion -> String
|
||||
prettyToolVer (GHCVersion v') = T.unpack $ tVerToText v'
|
||||
prettyToolVer (GHCVersion v') = T.unpack $ tVerToText v'
|
||||
prettyToolVer (ToolVersion v') = T.unpack $ prettyVer v'
|
||||
prettyToolVer (ToolTag t) = show t
|
||||
prettyToolVer (ToolTag t) = show t
|
||||
prettyToolVer (ToolDay day) = show day
|
||||
|
||||
toSetToolVer :: Maybe ToolVersion -> SetToolVersion
|
||||
toSetToolVer (Just (GHCVersion v')) = SetGHCVersion v'
|
||||
toSetToolVer (Just (ToolVersion v')) = SetToolVersion v'
|
||||
toSetToolVer (Just (ToolTag t')) = SetToolTag t'
|
||||
toSetToolVer (Just (ToolDay d')) = SetToolDay d'
|
||||
toSetToolVer Nothing = SetRecommended
|
||||
|
||||
|
||||
@@ -102,28 +109,28 @@ toSetToolVer Nothing = SetRecommended
|
||||
--------------
|
||||
|
||||
|
||||
toolVersionTagArgument :: Maybe ListCriteria -> Maybe Tool -> Parser ToolVersion
|
||||
toolVersionTagArgument :: [ListCriteria] -> Maybe Tool -> Parser ToolVersion
|
||||
toolVersionTagArgument criteria tool =
|
||||
argument (eitherReader (parser tool))
|
||||
(metavar (mv tool)
|
||||
<> completer (tagCompleter (fromMaybe GHC tool) [])
|
||||
<> foldMap (completer . versionCompleter criteria) tool)
|
||||
where
|
||||
mv (Just GHC) = "GHC_VERSION|TAG"
|
||||
mv (Just HLS) = "HLS_VERSION|TAG"
|
||||
mv _ = "VERSION|TAG"
|
||||
mv (Just GHC) = "GHC_VERSION|TAG|RELEASE_DATE"
|
||||
mv (Just HLS) = "HLS_VERSION|TAG|RELEASE_DATE"
|
||||
mv _ = "VERSION|TAG|RELEASE_DATE"
|
||||
|
||||
parser (Just GHC) = ghcVersionTagEither
|
||||
parser Nothing = ghcVersionTagEither
|
||||
parser _ = toolVersionTagEither
|
||||
|
||||
|
||||
versionParser' :: Maybe ListCriteria -> Maybe Tool -> Parser Version
|
||||
versionParser' :: [ListCriteria] -> Maybe Tool -> Parser Version
|
||||
versionParser' criteria tool = argument
|
||||
(eitherReader (first show . version . T.pack))
|
||||
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
||||
|
||||
ghcVersionArgument :: Maybe ListCriteria -> Maybe Tool -> Parser GHCTargetVersion
|
||||
ghcVersionArgument :: [ListCriteria] -> Maybe Tool -> Parser GHCTargetVersion
|
||||
ghcVersionArgument criteria tool = argument (eitherReader ghcVersionEither)
|
||||
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
||||
|
||||
@@ -205,23 +212,11 @@ platformParser s' = case MP.parse (platformP <* MP.eof) "" (T.pack s') of
|
||||
)
|
||||
]
|
||||
distroP :: MP.Parsec Void Text LinuxDistro
|
||||
distroP = choice'
|
||||
[ MP.chunk "debian" $> Debian
|
||||
, MP.chunk "deb" $> Debian
|
||||
, MP.chunk "ubuntu" $> Ubuntu
|
||||
, MP.chunk "mint" $> Mint
|
||||
, MP.chunk "fedora" $> Fedora
|
||||
, MP.chunk "centos" $> CentOS
|
||||
, MP.chunk "redhat" $> RedHat
|
||||
, MP.chunk "alpine" $> Alpine
|
||||
, MP.chunk "gentoo" $> Gentoo
|
||||
, MP.chunk "exherbo" $> Exherbo
|
||||
, MP.chunk "unknown" $> UnknownLinux
|
||||
]
|
||||
distroP = choice' ((\d -> MP.chunk (T.pack $ distroToString d) $> d) <$> allDistros)
|
||||
|
||||
|
||||
uriParser :: String -> Either String URI
|
||||
uriParser = first show . parseURI strictURIParserOptions . UTF8.fromString
|
||||
uriParser = first show . parseURI . UTF8.fromString
|
||||
|
||||
|
||||
absolutePathParser :: FilePath -> Either String FilePath
|
||||
@@ -237,21 +232,23 @@ isolateParser f = case isValid f && isAbsolute f of
|
||||
-- this accepts cross prefix
|
||||
ghcVersionTagEither :: String -> Either String ToolVersion
|
||||
ghcVersionTagEither s' =
|
||||
second ToolTag (tagEither s') <|> second GHCVersion (ghcVersionEither s')
|
||||
second ToolDay (dayParser s') <|> second ToolTag (tagEither s') <|> second GHCVersion (ghcVersionEither s')
|
||||
|
||||
-- this ignores cross prefix
|
||||
toolVersionTagEither :: String -> Either String ToolVersion
|
||||
toolVersionTagEither s' =
|
||||
second ToolTag (tagEither s') <|> second ToolVersion (toolVersionEither s')
|
||||
second ToolDay (dayParser s') <|> second ToolTag (tagEither s') <|> second ToolVersion (toolVersionEither s')
|
||||
|
||||
tagEither :: String -> Either String Tag
|
||||
tagEither s' = case fmap toLower s' of
|
||||
"recommended" -> Right Recommended
|
||||
"latest" -> Right Latest
|
||||
"recommended" -> Right Recommended
|
||||
"latest" -> Right Latest
|
||||
"latest-prerelease" -> Right LatestPrerelease
|
||||
"latest-nightly" -> Right LatestNightly
|
||||
('b':'a':'s':'e':'-':ver') -> case pvp (T.pack ver') of
|
||||
Right x -> Right (Base x)
|
||||
Left _ -> Left $ "Invalid PVP version for base " <> ver'
|
||||
other -> Left $ "Unknown tag " <> other
|
||||
other -> Left $ "Unknown tag " <> other
|
||||
|
||||
|
||||
ghcVersionEither :: String -> Either String GHCTargetVersion
|
||||
@@ -260,7 +257,7 @@ ghcVersionEither =
|
||||
|
||||
toolVersionEither :: String -> Either String Version
|
||||
toolVersionEither =
|
||||
first (const "Not a valid version") . MP.parse version' "" . T.pack
|
||||
first (const "Not a valid version") . MP.parse (version' <* MP.eof) "" . T.pack
|
||||
|
||||
|
||||
toolParser :: String -> Either String Tool
|
||||
@@ -271,12 +268,22 @@ toolParser s' | t == T.pack "ghc" = Right GHC
|
||||
| otherwise = Left ("Unknown tool: " <> s')
|
||||
where t = T.toLower (T.pack s')
|
||||
|
||||
dayParser :: String -> Either String Day
|
||||
dayParser s = maybe (Left $ "Could not parse \"" <> s <> "\". Expected format is: YYYY-MM-DD") Right
|
||||
$ parseTimeM True defaultTimeLocale "%Y-%-m-%-d" s
|
||||
|
||||
|
||||
criteriaParser :: String -> Either String ListCriteria
|
||||
criteriaParser s' | t == T.pack "installed" = Right ListInstalled
|
||||
| t == T.pack "set" = Right ListSet
|
||||
| t == T.pack "available" = Right ListAvailable
|
||||
| otherwise = Left ("Unknown criteria: " <> s')
|
||||
criteriaParser s' | t == T.pack "installed" = Right $ ListInstalled True
|
||||
| t == T.pack "set" = Right $ ListSet True
|
||||
| t == T.pack "available" = Right $ ListAvailable True
|
||||
| t == T.pack "+installed" = Right $ ListInstalled True
|
||||
| t == T.pack "+set" = Right $ ListSet True
|
||||
| t == T.pack "+available" = Right $ ListAvailable True
|
||||
| t == T.pack "-installed" = Right $ ListInstalled False
|
||||
| t == T.pack "-set" = Right $ ListSet False
|
||||
| t == T.pack "-available" = Right $ ListAvailable False
|
||||
| otherwise = Left ("Unknown criteria: " <> s')
|
||||
where t = T.toLower (T.pack s')
|
||||
|
||||
|
||||
@@ -318,6 +325,15 @@ toolCompleter = listCompleter ["ghc", "cabal", "hls", "stack"]
|
||||
gitFileUri :: [String] -> Completer
|
||||
gitFileUri add = mkCompleter $ fileUri' (["git://"] <> add)
|
||||
|
||||
urlSourceCompleter :: Completer
|
||||
urlSourceCompleter = mkCompleter $ urlSourceCompleter' []
|
||||
|
||||
urlSourceCompleter' :: [String] -> String -> IO [String]
|
||||
urlSourceCompleter' add str' = do
|
||||
let static = ["GHCupURL", "StackSetupURL"]
|
||||
file <- fileUri' add str'
|
||||
pure $ static ++ file
|
||||
|
||||
fileUri :: Completer
|
||||
fileUri = mkCompleter $ fileUri' []
|
||||
|
||||
@@ -351,7 +367,7 @@ fileUri' add = \case
|
||||
-- We need to do this so bash doesn't expand out any ~ or other
|
||||
-- chars we want to complete on, or emit an end of line error
|
||||
-- when seeking the close to the quote.
|
||||
--
|
||||
--
|
||||
-- NOTE: copied from https://hackage.haskell.org/package/optparse-applicative-0.17.0.0/docs/src/Options.Applicative.Builder.Completer.html#requote
|
||||
requote :: String -> String
|
||||
requote s =
|
||||
@@ -446,18 +462,20 @@ tagCompleter tool add = listIOCompleter $ do
|
||||
defaultKeyBindings
|
||||
loggerConfig
|
||||
|
||||
mGhcUpInfo <- flip runReaderT appState . runE $ getDownloadsF
|
||||
case mGhcUpInfo of
|
||||
VRight ghcupInfo -> do
|
||||
let allTags = filter (/= Old)
|
||||
$ _viTags =<< M.elems (availableToolVersions (_ghcupDownloads ghcupInfo) tool)
|
||||
pure $ nub $ (add ++) $ fmap tagToString allTags
|
||||
VLeft _ -> pure (nub $ ["recommended", "latest"] ++ add)
|
||||
mpFreq <- flip runReaderT appState . runE $ platformRequest
|
||||
forFold mpFreq $ \pfreq -> do
|
||||
mGhcUpInfo <- flip runReaderT appState . runE $ getDownloadsF pfreq
|
||||
case mGhcUpInfo of
|
||||
VRight ghcupInfo -> do
|
||||
let allTags = filter (/= Old)
|
||||
$ _viTags =<< M.elems (availableToolVersions (_ghcupDownloads ghcupInfo) tool)
|
||||
pure $ nub $ (add ++) $ fmap tagToString allTags
|
||||
VLeft _ -> pure (nub $ ["recommended", "latest", "latest-prerelease"] ++ add)
|
||||
|
||||
versionCompleter :: Maybe ListCriteria -> Tool -> Completer
|
||||
versionCompleter :: [ListCriteria] -> Tool -> Completer
|
||||
versionCompleter criteria tool = versionCompleter' criteria tool (const True)
|
||||
|
||||
versionCompleter' :: Maybe ListCriteria -> Tool -> (Version -> Bool) -> Completer
|
||||
versionCompleter' :: [ListCriteria] -> Tool -> (Version -> Bool) -> Completer
|
||||
versionCompleter' criteria tool filter' = listIOCompleter $ do
|
||||
dirs' <- liftIO getAllDirs
|
||||
let loggerConfig = LoggerConfig
|
||||
@@ -473,8 +491,8 @@ versionCompleter' criteria tool filter' = listIOCompleter $ do
|
||||
defaultKeyBindings
|
||||
loggerConfig
|
||||
mpFreq <- flip runReaderT leanAppState . runE $ platformRequest
|
||||
mGhcUpInfo <- flip runReaderT leanAppState . runE $ getDownloadsF
|
||||
forFold mpFreq $ \pfreq -> do
|
||||
mGhcUpInfo <- flip runReaderT leanAppState . runE $ getDownloadsF pfreq
|
||||
forFold mGhcUpInfo $ \ghcupInfo -> do
|
||||
let appState = AppState
|
||||
settings
|
||||
@@ -486,7 +504,7 @@ versionCompleter' criteria tool filter' = listIOCompleter $ do
|
||||
|
||||
runEnv = flip runReaderT appState
|
||||
|
||||
installedVersions <- runEnv $ listVersions (Just tool) criteria
|
||||
installedVersions <- runEnv $ listVersions (Just tool) criteria False False (Nothing, Nothing)
|
||||
return $ fmap (T.unpack . prettyVer) . filter filter' . fmap lVer $ installedVersions
|
||||
|
||||
|
||||
@@ -654,6 +672,7 @@ fromVersion :: ( HasLog env
|
||||
-> Tool
|
||||
-> Excepts
|
||||
'[ TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
] m (GHCTargetVersion, Maybe VersionInfo)
|
||||
@@ -672,46 +691,58 @@ fromVersion' :: ( HasLog env
|
||||
-> Tool
|
||||
-> Excepts
|
||||
'[ TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
] 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 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 id Just <$> getLatestPrerelease dls tool ?? TagNotFound LatestPrerelease tool
|
||||
fromVersion' (SetToolTag LatestNightly) tool = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
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
|
||||
@@ -756,7 +787,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
|
||||
@@ -772,15 +803,15 @@ checkForUpdates :: ( MonadReader env m
|
||||
, MonadIO m
|
||||
, MonadFail m
|
||||
)
|
||||
=> m [(Tool, Version)]
|
||||
=> m [(Tool, GHCTargetVersion)]
|
||||
checkForUpdates = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
||||
lInstalled <- listVersions Nothing (Just ListInstalled)
|
||||
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
||||
lInstalled <- listVersions Nothing [ListInstalled True] False False (Nothing, Nothing)
|
||||
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
|
||||
@@ -795,8 +826,20 @@ checkForUpdates = do
|
||||
|
||||
logGHCPostRm :: (MonadReader env m, HasLog env, MonadIO m) => GHCTargetVersion -> m ()
|
||||
logGHCPostRm ghcVer = do
|
||||
cabalStore <- liftIO $ handleIO (\_ -> if isWindows then pure "C:\\cabal\\store" else pure "~/.cabal/store")
|
||||
cabalStore <- liftIO $ handleIO (\_ -> if isWindows then pure "C:\\cabal\\store" else pure "~/.cabal/store or ~/.local/state/cabal/store")
|
||||
(runIdentity . CC.cfgStoreDir <$> CC.readConfig)
|
||||
let storeGhcDir = cabalStore </> ("ghc-" <> T.unpack (prettyVer $ _tvVersion ghcVer))
|
||||
logInfo $ T.pack $ "After removing GHC you might also want to clean up your cabal store at: " <> storeGhcDir
|
||||
|
||||
parseUrlSource :: String -> Either String URLSource
|
||||
parseUrlSource "GHCupURL" = pure GHCupURL
|
||||
parseUrlSource "StackSetupURL" = pure StackSetupURL
|
||||
parseUrlSource s' = (eitherDecode . LE.encodeUtf8 . LT.pack $ s')
|
||||
<|> (fmap (OwnSource . (:[]) . Right) . first show . parseURI .UTF8.fromString $ s')
|
||||
|
||||
parseNewUrlSource :: String -> Either String NewURLSource
|
||||
parseNewUrlSource "GHCupURL" = pure NewGHCupURL
|
||||
parseNewUrlSource "StackSetupURL" = pure NewStackSetupURL
|
||||
parseNewUrlSource s' = (eitherDecode . LE.encodeUtf8 . LT.pack $ s')
|
||||
<|> (fmap NewURI . first show . parseURI .UTF8.fromString $ s')
|
||||
|
||||
@@ -25,7 +25,6 @@ import GHCup.OptParse.Common
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
#endif
|
||||
import Codec.Archive ( ArchiveResult )
|
||||
import Control.Concurrent (threadDelay)
|
||||
import Control.Monad.Reader
|
||||
import Control.Monad.Trans.Resource
|
||||
@@ -40,7 +39,6 @@ import Options.Applicative hiding ( style )
|
||||
import Options.Applicative.Help.Pretty ( text )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import URI.ByteString hiding ( uriParser )
|
||||
import qualified Data.Text as T
|
||||
@@ -58,6 +56,7 @@ import Text.Read (readEither)
|
||||
|
||||
data CompileCommand = CompileGHC GHCCompileOptions
|
||||
| CompileHLS HLSCompileOptions
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -67,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
|
||||
@@ -77,9 +76,9 @@ data GHCCompileOptions = GHCCompileOptions
|
||||
, setCompile :: Bool
|
||||
, ovewrwiteVer :: Maybe Version
|
||||
, buildFlavour :: Maybe String
|
||||
, hadrian :: Bool
|
||||
, buildSystem :: Maybe BuildSystem
|
||||
, isolateDir :: Maybe FilePath
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
data HLSCompileOptions = HLSCompileOptions
|
||||
@@ -94,7 +93,7 @@ data HLSCompileOptions = HLSCompileOptions
|
||||
, patches :: Maybe (Either FilePath [URI])
|
||||
, targetGHCs :: [ToolVersion]
|
||||
, cabalArgs :: [Text]
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -158,7 +157,7 @@ Examples:
|
||||
ghcup compile hls --version 1.7.0.0 --ghc 8.10.7 --cabal-update
|
||||
# compile from master for ghc 9.2.3 using 'git describe' to name the binary and ignore the pinned index state
|
||||
ghcup compile hls -g master --git-describe-version --ghc 9.2.3 -- --index-state=@(date '+%s')
|
||||
# compile a specific commit for ghc 9.2.3 and set a specifc version for the binary name
|
||||
# compile a specific commit for ghc 9.2.3 and set a specific version for the binary name
|
||||
ghcup compile hls -g a32db0b -o 1.7.0.0-p1 --ghc 9.2.3|]
|
||||
|
||||
|
||||
@@ -171,7 +170,7 @@ ghcCompileOpts =
|
||||
)
|
||||
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
||||
"The tool version to compile"
|
||||
<> (completer $ versionCompleter Nothing GHC)
|
||||
<> (completer $ versionCompleter [] GHC)
|
||||
)
|
||||
) <|>
|
||||
(GHC.GitDist <$> (GitBranch <$> option
|
||||
@@ -206,7 +205,7 @@ ghcCompileOpts =
|
||||
<> metavar "BOOTSTRAP_GHC"
|
||||
<> help
|
||||
"The GHC version (or full path) to bootstrap with (must be installed)"
|
||||
<> (completer $ versionCompleter Nothing GHC)
|
||||
<> (completer $ versionCompleter [] GHC)
|
||||
)
|
||||
<*> optional
|
||||
(option
|
||||
@@ -259,7 +258,7 @@ ghcCompileOpts =
|
||||
)
|
||||
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
||||
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
||||
<> (completer $ versionCompleter Nothing GHC)
|
||||
<> (completer $ versionCompleter [] GHC)
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
@@ -269,16 +268,22 @@ 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)
|
||||
( short 'i'
|
||||
<> long "isolate"
|
||||
<> metavar "DIR"
|
||||
<> help "install in an isolated directory instead of the default one, no symlinks to this installation will be made"
|
||||
<> help "install in an isolated absolute directory instead of the default one, no symlinks to this installation will be made"
|
||||
<> completer (bashCompleter "directory")
|
||||
)
|
||||
)
|
||||
@@ -292,7 +297,7 @@ hlsCompileOpts =
|
||||
)
|
||||
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
||||
"The version to compile (pulled from hackage)"
|
||||
<> (completer $ versionCompleter' Nothing HLS (either (const False) (const True) . V.pvp . V.prettyVer))
|
||||
<> (completer $ versionCompleter' [] HLS (either (const False) (const True) . V.pvp . V.prettyVer))
|
||||
)
|
||||
)
|
||||
<|>
|
||||
@@ -312,7 +317,7 @@ hlsCompileOpts =
|
||||
)
|
||||
(long "source-dist" <> metavar "VERSION" <> help
|
||||
"The version to compile (pulled from packaged git sources)"
|
||||
<> (completer $ versionCompleter Nothing HLS)
|
||||
<> (completer $ versionCompleter [] HLS)
|
||||
)
|
||||
))
|
||||
<|>
|
||||
@@ -344,7 +349,7 @@ hlsCompileOpts =
|
||||
)
|
||||
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
||||
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
||||
<> (completer $ versionCompleter Nothing HLS)
|
||||
<> (completer $ versionCompleter [] HLS)
|
||||
)
|
||||
)
|
||||
<|>
|
||||
@@ -361,7 +366,7 @@ hlsCompileOpts =
|
||||
( short 'i'
|
||||
<> long "isolate"
|
||||
<> metavar "DIR"
|
||||
<> help "install in an isolated directory instead of the default one, no symlinks to this installation will be made"
|
||||
<> help "install in an isolated absolute directory instead of the default one, no symlinks to this installation will be made"
|
||||
<> completer (bashCompleter "directory")
|
||||
)
|
||||
)
|
||||
@@ -404,7 +409,7 @@ hlsCompileOpts =
|
||||
option (eitherReader ghcVersionTagEither)
|
||||
( long "ghc" <> metavar "GHC_VERSION|TAG" <> help "For which GHC version to compile for (can be specified multiple times)"
|
||||
<> completer (tagCompleter GHC [])
|
||||
<> completer (versionCompleter Nothing GHC))
|
||||
<> completer (versionCompleter [] GHC))
|
||||
)
|
||||
<*> many (argument str (metavar "CABAL_ARGS" <> help "Additional arguments to cabal install, prefix with '-- ' (longopts)"))
|
||||
|
||||
@@ -454,6 +459,7 @@ type HLSEffects = '[ AlreadyInstalled
|
||||
, UnknownArchive
|
||||
, TarDirDoesNotExist
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
, NotInstalled
|
||||
@@ -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)
|
||||
@@ -546,24 +552,21 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
pure ExitSuccess
|
||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||
case keepDirs settings of
|
||||
Never -> runLogger $ logError $ T.pack $ prettyShow err
|
||||
_ -> runLogger (logError $ T.pack (prettyShow err) <> "\n" <>
|
||||
Never -> runLogger $ logError $ T.pack $ prettyHFError err
|
||||
_ -> runLogger (logError $ T.pack (prettyHFError err) <> "\n" <>
|
||||
"Check the logs at " <> T.pack (fromGHCupPath logsDir) <> " and the build directory "
|
||||
<> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||
pure $ ExitFailure 9
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
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)
|
||||
@@ -608,12 +609,12 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
pure $ ExitFailure 3
|
||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||
case keepDirs settings of
|
||||
Never -> runLogger $ logError $ T.pack $ prettyShow err
|
||||
_ -> runLogger (logError $ T.pack (prettyShow err) <> "\n" <>
|
||||
Never -> runLogger $ logError $ T.pack $ prettyHFError err
|
||||
_ -> runLogger (logError $ T.pack (prettyHFError err) <> "\n" <>
|
||||
"Check the logs at " <> T.pack (fromGHCupPath logsDir) <> " and the build directory "
|
||||
<> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||
pure $ ExitFailure 9
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 9
|
||||
@@ -32,7 +32,6 @@ import Options.Applicative hiding ( style, ParseError )
|
||||
import Options.Applicative.Help.Pretty ( text )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import URI.ByteString hiding ( uriParser )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.ByteString.UTF8 as UTF8
|
||||
@@ -51,7 +50,8 @@ data ConfigCommand
|
||||
= ShowConfig
|
||||
| SetConfig String (Maybe String)
|
||||
| InitConfig
|
||||
| AddReleaseChannel URI
|
||||
| AddReleaseChannel Bool NewURLSource
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ data ConfigCommand
|
||||
--[ Parsers ]--
|
||||
---------------
|
||||
|
||||
|
||||
|
||||
configP :: Parser ConfigCommand
|
||||
configP = subparser
|
||||
( command "init" initP
|
||||
@@ -67,15 +67,14 @@ configP = subparser
|
||||
<> command "show" showP
|
||||
<> command "add-release-channel" addP
|
||||
)
|
||||
<|> argsP -- add show for a single option
|
||||
<|> pure ShowConfig
|
||||
where
|
||||
initP = info (pure InitConfig) (progDesc "Write default config to ~/.ghcup/config.yaml")
|
||||
showP = info (pure ShowConfig) (progDesc "Show current config (default)")
|
||||
setP = info argsP (progDesc "Set config KEY to VALUE (or specify as single json value)" <> footerDoc (Just $ text configSetFooter))
|
||||
argsP = SetConfig <$> argument str (metavar "<JSON_VALUE | YAML_KEY>") <*> optional (argument str (metavar "YAML_VALUE"))
|
||||
addP = info (AddReleaseChannel <$> argument (eitherReader uriParser) (metavar "URI" <> completer fileUri))
|
||||
(progDesc "Add a release channel from a URI")
|
||||
addP = info (AddReleaseChannel <$> switch (long "force" <> help "Delete existing entry (if any) and append instead of failing") <*> argument (eitherReader parseNewUrlSource) (metavar "URL_SOURCE" <> completer urlSourceCompleter))
|
||||
(progDesc "Add a release channel, e.g. from a URI")
|
||||
|
||||
|
||||
|
||||
@@ -120,19 +119,37 @@ formatConfig :: UserSettings -> String
|
||||
formatConfig = UTF8.toString . Y.encode
|
||||
|
||||
|
||||
updateSettings :: UserSettings -> Settings -> Settings
|
||||
updateSettings UserSettings{..} Settings{..} =
|
||||
let cache' = fromMaybe cache uCache
|
||||
metaCache' = fromMaybe metaCache uMetaCache
|
||||
noVerify' = fromMaybe noVerify uNoVerify
|
||||
keepDirs' = fromMaybe keepDirs uKeepDirs
|
||||
downloader' = fromMaybe downloader uDownloader
|
||||
verbose' = fromMaybe verbose uVerbose
|
||||
urlSource' = fromMaybe urlSource uUrlSource
|
||||
noNetwork' = fromMaybe noNetwork uNoNetwork
|
||||
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
||||
platformOverride' = uPlatformOverride <|> platformOverride
|
||||
in Settings cache' metaCache' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor platformOverride'
|
||||
updateSettings :: UserSettings -> UserSettings -> UserSettings
|
||||
updateSettings usl usr =
|
||||
let cache' = uCache usl <|> uCache usr
|
||||
metaCache' = uMetaCache usl <|> uMetaCache usr
|
||||
metaMode' = uMetaMode usl <|> uMetaMode usr
|
||||
noVerify' = uNoVerify usl <|> uNoVerify usr
|
||||
verbose' = uVerbose usl <|> uVerbose usr
|
||||
keepDirs' = uKeepDirs usl <|> uKeepDirs usr
|
||||
downloader' = uDownloader usl <|> uDownloader usr
|
||||
urlSource' = uUrlSource usl <|> uUrlSource usr
|
||||
noNetwork' = uNoNetwork usl <|> uNoNetwork usr
|
||||
gpgSetting' = uGPGSetting usl <|> uGPGSetting usr
|
||||
platformOverride' = uPlatformOverride usl <|> uPlatformOverride usr
|
||||
mirrors' = uMirrors usl <|> uMirrors usr
|
||||
in UserSettings cache' metaCache' metaMode' noVerify' verbose' keepDirs' downloader' (updateKeyBindings (uKeyBindings usl) (uKeyBindings usr)) urlSource' noNetwork' gpgSetting' platformOverride' mirrors'
|
||||
where
|
||||
updateKeyBindings :: Maybe UserKeyBindings -> Maybe UserKeyBindings -> Maybe UserKeyBindings
|
||||
updateKeyBindings Nothing Nothing = Nothing
|
||||
updateKeyBindings (Just kbl) Nothing = Just kbl
|
||||
updateKeyBindings Nothing (Just kbr) = Just kbr
|
||||
updateKeyBindings (Just kbl) (Just kbr) =
|
||||
Just $ UserKeyBindings {
|
||||
kUp = kUp kbl <|> kUp kbr
|
||||
, kDown = kDown kbl <|> kDown kbr
|
||||
, kQuit = kQuit kbl <|> kQuit kbr
|
||||
, kInstall = kInstall kbl <|> kInstall kbr
|
||||
, kUninstall = kUninstall kbl <|> kUninstall kbr
|
||||
, kSet = kSet kbl <|> kSet kbr
|
||||
, kChangelog = kChangelog kbl <|> kChangelog kbr
|
||||
, kShowAll = kShowAll kbl <|> kShowAll kbr
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -140,6 +157,9 @@ updateSettings UserSettings{..} Settings{..} =
|
||||
--[ Entrypoint ]--
|
||||
------------------
|
||||
|
||||
data Duplicate = Duplicate -- ^ there is a duplicate somewhere in the middle
|
||||
| NoDuplicate -- ^ there is no duplicate
|
||||
| DuplicateLast -- ^ there's a duplicate, but it's the last element
|
||||
|
||||
|
||||
config :: forall m. ( Monad m
|
||||
@@ -149,10 +169,11 @@ config :: forall m. ( Monad m
|
||||
)
|
||||
=> ConfigCommand
|
||||
-> Settings
|
||||
-> UserSettings
|
||||
-> KeyBindings
|
||||
-> (ReaderT LeanAppState m () -> m ())
|
||||
-> m ExitCode
|
||||
config configCommand settings keybindings runLogger = case configCommand of
|
||||
config configCommand settings userConf keybindings runLogger = case configCommand of
|
||||
InitConfig -> do
|
||||
path <- getConfigFilePath
|
||||
liftIO $ writeFile path $ formatConfig $ fromSettings settings (Just keybindings)
|
||||
@@ -170,10 +191,14 @@ config configCommand settings keybindings runLogger = case configCommand of
|
||||
throwE $ ParseError "Empty values are not allowed"
|
||||
Nothing -> do
|
||||
usersettings <- decodeSettings k
|
||||
when (usersettings == defaultUserSettings)
|
||||
$ throwE $ ParseError ("Failed to parse setting (maybe typo?): " <> k)
|
||||
lift $ doConfig usersettings
|
||||
pure ()
|
||||
Just v -> do
|
||||
usersettings <- decodeSettings (k <> ": " <> v <> "\n")
|
||||
when (usersettings == defaultUserSettings)
|
||||
$ throwE $ ParseError ("Failed to parse key '" <> k <> "' with value '" <> v <> "' as user setting. Maybe typo?")
|
||||
lift $ doConfig usersettings
|
||||
pure ()
|
||||
case r of
|
||||
@@ -181,29 +206,38 @@ config configCommand settings keybindings runLogger = case configCommand of
|
||||
VLeft (V (JSONDecodeError e)) -> do
|
||||
runLogger $ logError $ "Error decoding config: " <> T.pack e
|
||||
pure $ ExitFailure 65
|
||||
VLeft _ -> pure $ ExitFailure 65
|
||||
VLeft e -> do
|
||||
runLogger (logError $ T.pack $ prettyHFError e)
|
||||
pure $ ExitFailure 65
|
||||
|
||||
AddReleaseChannel uri -> do
|
||||
case urlSource settings of
|
||||
AddSource xs -> do
|
||||
doConfig (defaultUserSettings { uUrlSource = Just $ AddSource (xs <> [Right uri]) })
|
||||
pure ExitSuccess
|
||||
GHCupURL -> do
|
||||
doConfig (defaultUserSettings { uUrlSource = Just $ AddSource [Right uri] })
|
||||
pure ExitSuccess
|
||||
OwnSource xs -> do
|
||||
doConfig (defaultUserSettings { uUrlSource = Just $ OwnSource (xs <> [Right uri]) })
|
||||
pure ExitSuccess
|
||||
OwnSpec spec -> do
|
||||
doConfig (defaultUserSettings { uUrlSource = Just $ OwnSource ([Left spec, Right uri]) })
|
||||
AddReleaseChannel force new -> do
|
||||
r <- runE @'[DuplicateReleaseChannel] $ do
|
||||
let oldSources = fromURLSource (urlSource settings)
|
||||
let merged = oldSources ++ [new]
|
||||
case checkDuplicate oldSources new of
|
||||
Duplicate
|
||||
| not force -> throwE (DuplicateReleaseChannel new)
|
||||
DuplicateLast -> pure ()
|
||||
_ -> lift $ doConfig (defaultUserSettings { uUrlSource = Just $ SimpleList merged })
|
||||
case r of
|
||||
VRight _ -> do
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 15
|
||||
|
||||
where
|
||||
checkDuplicate :: Eq a => [a] -> a -> Duplicate
|
||||
checkDuplicate xs a
|
||||
| last xs == a = DuplicateLast
|
||||
| a `elem` xs = Duplicate
|
||||
| otherwise = NoDuplicate
|
||||
|
||||
doConfig :: MonadIO m => UserSettings -> m ()
|
||||
doConfig usersettings = do
|
||||
let settings' = updateSettings usersettings settings
|
||||
let settings' = updateSettings usersettings userConf
|
||||
path <- liftIO getConfigFilePath
|
||||
liftIO $ writeFile path $ formatConfig $ fromSettings settings' (Just keybindings)
|
||||
liftIO $ writeFile path $ formatConfig $ settings'
|
||||
runLogger $ logDebug $ T.pack $ show settings'
|
||||
pure ()
|
||||
|
||||
@@ -115,5 +115,5 @@ dinfo runAppState runLogger = do
|
||||
liftIO $ putStrLn $ prettyDebugInfo di
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 8
|
||||
@@ -27,7 +27,6 @@ import Haskus.Utils.Variant.Excepts
|
||||
import Options.Applicative hiding ( style )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception.Safe (MonadMask)
|
||||
@@ -48,7 +47,7 @@ data GCOptions = GCOptions
|
||||
, gcHLSNoGHC :: Bool
|
||||
, gcCache :: Bool
|
||||
, gcTmp :: Bool
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -139,5 +138,5 @@ gc GCOptions{..} runAppState runLogger = runGC runAppState (do
|
||||
VRight _ -> do
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 27
|
||||
@@ -24,7 +24,6 @@ import GHCup.Prelude
|
||||
import GHCup.Prelude.Logger
|
||||
import GHCup.Prelude.String.QQ
|
||||
|
||||
import Codec.Archive
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
#endif
|
||||
@@ -38,7 +37,6 @@ import Options.Applicative hiding ( style )
|
||||
import Options.Applicative.Help.Pretty ( text )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
import URI.ByteString hiding ( uriParser )
|
||||
|
||||
import qualified Data.Text as T
|
||||
@@ -55,6 +53,7 @@ data InstallCommand = InstallGHC InstallOptions
|
||||
| InstallCabal InstallOptions
|
||||
| InstallHLS InstallOptions
|
||||
| InstallStack InstallOptions
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +62,6 @@ data InstallCommand = InstallGHC InstallOptions
|
||||
--[ Options ]--
|
||||
---------------
|
||||
|
||||
|
||||
data InstallOptions = InstallOptions
|
||||
{ instVer :: Maybe ToolVersion
|
||||
, instBindist :: Maybe URI
|
||||
@@ -71,7 +69,7 @@ data InstallOptions = InstallOptions
|
||||
, isolateDir :: Maybe FilePath
|
||||
, forceInstall :: Bool
|
||||
, addConfArgs :: [T.Text]
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -134,7 +132,7 @@ installParser =
|
||||
)
|
||||
)
|
||||
)
|
||||
<|> (Right <$> installOpts Nothing)
|
||||
<|> (Right <$> installOpts (Just GHC))
|
||||
where
|
||||
installHLSFooter :: String
|
||||
installHLSFooter = [s|Discussion:
|
||||
@@ -185,7 +183,7 @@ installOpts tool =
|
||||
<> completer (toolDlCompleter (fromMaybe GHC tool))
|
||||
)
|
||||
)
|
||||
<*> (Just <$> toolVersionTagArgument Nothing tool)
|
||||
<*> (Just <$> toolVersionTagArgument [] tool)
|
||||
)
|
||||
<|> pure (Nothing, Nothing)
|
||||
)
|
||||
@@ -197,7 +195,7 @@ installOpts tool =
|
||||
( short 'i'
|
||||
<> long "isolate"
|
||||
<> metavar "DIR"
|
||||
<> help "install in an isolated dir instead of the default one"
|
||||
<> help "install in an isolated absolute directory instead of the default one"
|
||||
<> completer (bashCompleter "directory")
|
||||
)
|
||||
)
|
||||
@@ -242,6 +240,7 @@ type InstallEffects = '[ AlreadyInstalled
|
||||
, NotInstalled
|
||||
, BuildFailed
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, DigestError
|
||||
, ContentLengthError
|
||||
, GPGError
|
||||
@@ -285,10 +284,16 @@ type InstallGHCEffects = '[ AlreadyInstalled
|
||||
, NotInstalled
|
||||
, ProcessError
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, TarDirDoesNotExist
|
||||
, UninstallFailed
|
||||
, UnknownArchive
|
||||
, InstallSetError
|
||||
, NoCompatiblePlatform
|
||||
, GHCup.Errors.ParseError
|
||||
, UnsupportedSetupCombo
|
||||
, DistroNotFound
|
||||
, NoCompatibleArch
|
||||
]
|
||||
|
||||
runInstGHC :: AppState
|
||||
@@ -308,13 +313,13 @@ runInstGHC appstate' =
|
||||
|
||||
install :: Either InstallCommand InstallOptions -> Settings -> IO AppState -> (ReaderT LeanAppState IO () -> IO ()) -> IO ExitCode
|
||||
install installCommand settings getAppState' runLogger = case installCommand of
|
||||
(Right iopts) -> do
|
||||
(Right iGHCopts) -> do
|
||||
runLogger (logWarn "This is an old-style command for installing GHC. Use 'ghcup install ghc' instead.")
|
||||
installGHC iopts
|
||||
(Left (InstallGHC iopts)) -> installGHC iopts
|
||||
(Left (InstallCabal iopts)) -> installCabal iopts
|
||||
(Left (InstallHLS iopts)) -> installHLS iopts
|
||||
(Left (InstallStack iopts)) -> installStack iopts
|
||||
installGHC iGHCopts
|
||||
(Left (InstallGHC iGHCopts)) -> installGHC iGHCopts
|
||||
(Left (InstallCabal iopts)) -> installCabal iopts
|
||||
(Left (InstallHLS iopts)) -> installHLS iopts
|
||||
(Left (InstallStack iopts)) -> installStack iopts
|
||||
where
|
||||
installGHC :: InstallOptions -> IO ExitCode
|
||||
installGHC InstallOptions{..} = do
|
||||
@@ -323,7 +328,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
|
||||
@@ -334,8 +339,8 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
runInstGHC s'{ settings = settings {noVerify = True}} $ do
|
||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||
liftE $ runBothE' (installGHCBindist
|
||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing)
|
||||
(_tvVersion v)
|
||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing Nothing)
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
forceInstall
|
||||
addConfArgs
|
||||
@@ -351,10 +356,10 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
pure ExitSuccess
|
||||
|
||||
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||
runLogger $ logWarn $ T.pack $ prettyShow e
|
||||
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||
pure ExitSuccess
|
||||
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||
runLogger $ logWarn $ T.pack $ prettyShow e
|
||||
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||
pure ExitSuccess
|
||||
|
||||
VLeft (V (DirNotEmpty fp)) -> do
|
||||
@@ -368,22 +373,22 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
|
||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||
case keepDirs settings of
|
||||
Never -> runLogger (logError $ T.pack $ prettyShow err)
|
||||
_ -> runLogger (logError $ T.pack (prettyShow err) <> "\n" <>
|
||||
Never -> runLogger (logError $ T.pack $ prettyHFError err)
|
||||
_ -> runLogger (logError $ T.pack (prettyHFError err) <> "\n" <>
|
||||
"Check the logs at " <> T.pack (fromGHCupPath logsDir) <> " and the build directory " <> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||
pure $ ExitFailure 3
|
||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||
case keepDirs settings of
|
||||
Never -> runLogger (logError $ T.pack $ prettyShow err)
|
||||
_ -> runLogger (logError $ T.pack (prettyShow err) <> "\n" <>
|
||||
Never -> runLogger (logError $ T.pack $ prettyHFError err)
|
||||
_ -> runLogger (logError $ T.pack (prettyHFError err) <> "\n" <>
|
||||
"Check the logs at " <> T.pack (fromGHCupPath logsDir) <> " and the build directory " <> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||
pure $ ExitFailure 3
|
||||
|
||||
VLeft e -> do
|
||||
runLogger $ do
|
||||
logError $ T.pack $ prettyShow e
|
||||
logError $ T.pack $ prettyHFError e
|
||||
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||
pure $ ExitFailure 3
|
||||
|
||||
@@ -404,7 +409,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Cabal
|
||||
liftE $ runBothE' (installCabalBindist
|
||||
(DownloadInfo uri Nothing "" Nothing)
|
||||
(DownloadInfo uri Nothing "" Nothing Nothing)
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
forceInstall
|
||||
@@ -418,14 +423,14 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
runLogger $ logInfo msg
|
||||
pure ExitSuccess
|
||||
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||
runLogger $ logWarn $ T.pack $ prettyShow e
|
||||
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||
pure ExitSuccess
|
||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||
runLogger $ logWarn $
|
||||
"File " <> T.pack fp <> " already exists. Use 'ghcup install cabal --isolate " <> T.pack fp <> " --force ..." <> "' if you want to overwrite."
|
||||
pure $ ExitFailure 3
|
||||
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||
runLogger $ logWarn $ T.pack $ prettyShow e
|
||||
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||
pure ExitSuccess
|
||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||
runLogger $ logWarn $
|
||||
@@ -433,7 +438,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
pure $ ExitFailure 3
|
||||
VLeft e -> do
|
||||
runLogger $ do
|
||||
logError $ T.pack $ prettyShow e
|
||||
logError $ T.pack $ prettyHFError e
|
||||
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||
pure $ ExitFailure 4
|
||||
|
||||
@@ -454,7 +459,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer HLS
|
||||
-- TODO: support legacy
|
||||
liftE $ runBothE' (installHLSBindist
|
||||
(DownloadInfo uri (Just $ RegexDir "haskell-language-server-*") "" Nothing)
|
||||
(DownloadInfo uri (if isWindows then Nothing else Just (RegexDir "haskell-language-server-*")) "" Nothing Nothing)
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
forceInstall
|
||||
@@ -468,14 +473,14 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
runLogger $ logInfo msg
|
||||
pure ExitSuccess
|
||||
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||
runLogger $ logWarn $ T.pack $ prettyShow e
|
||||
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||
pure ExitSuccess
|
||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||
runLogger $ logWarn $
|
||||
"File " <> T.pack fp <> " already exists. Use 'ghcup install hls --isolate " <> T.pack fp <> " --force ..." <> "' if you want to overwrite."
|
||||
pure $ ExitFailure 3
|
||||
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||
runLogger $ logWarn $ T.pack $ prettyShow e
|
||||
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||
pure ExitSuccess
|
||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||
runLogger $ logWarn $
|
||||
@@ -483,7 +488,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
pure $ ExitFailure 3
|
||||
VLeft e -> do
|
||||
runLogger $ do
|
||||
logError $ T.pack $ prettyShow e
|
||||
logError $ T.pack $ prettyHFError e
|
||||
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||
pure $ ExitFailure 4
|
||||
|
||||
@@ -503,7 +508,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Stack
|
||||
liftE $ runBothE' (installStackBindist
|
||||
(DownloadInfo uri Nothing "" Nothing)
|
||||
(DownloadInfo uri Nothing "" Nothing Nothing)
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
forceInstall
|
||||
@@ -517,14 +522,14 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
runLogger $ logInfo msg
|
||||
pure ExitSuccess
|
||||
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||
runLogger $ logWarn $ T.pack $ prettyShow e
|
||||
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||
pure ExitSuccess
|
||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||
runLogger $ logWarn $
|
||||
"File " <> T.pack fp <> " already exists. Use 'ghcup install stack --isolate " <> T.pack fp <> " --force ..." <> "' if you want to overwrite."
|
||||
pure $ ExitFailure 3
|
||||
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||
runLogger $ logWarn $ T.pack $ prettyShow e
|
||||
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||
pure ExitSuccess
|
||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||
runLogger $ logWarn $
|
||||
@@ -532,6 +537,6 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
pure $ ExitFailure 3
|
||||
VLeft e -> do
|
||||
runLogger $ do
|
||||
logError $ T.pack $ prettyShow e
|
||||
logError $ T.pack $ prettyHFError e
|
||||
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||
pure $ ExitFailure 4
|
||||
@@ -2,6 +2,7 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
|
||||
@@ -14,6 +15,7 @@ import GHCup
|
||||
import GHCup.Prelude
|
||||
import GHCup.Types
|
||||
import GHCup.OptParse.Common
|
||||
import GHCup.Prelude.String.QQ
|
||||
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
@@ -24,7 +26,8 @@ import Data.Char
|
||||
import Data.List ( intercalate, sort )
|
||||
import Data.Functor
|
||||
import Data.Maybe
|
||||
import Data.Versions hiding ( str )
|
||||
import Data.Time.Calendar ( Day )
|
||||
import Data.Versions
|
||||
import Data.Void
|
||||
import Options.Applicative hiding ( style )
|
||||
import Prelude hiding ( appendFile )
|
||||
@@ -50,8 +53,12 @@ import qualified Text.Megaparsec.Char as MPC
|
||||
data ListOptions = ListOptions
|
||||
{ loTool :: Maybe Tool
|
||||
, lCriteria :: Maybe ListCriteria
|
||||
, lFrom :: Maybe Day
|
||||
, lTo :: Maybe Day
|
||||
, lHideOld :: Bool
|
||||
, lShowNightly :: Bool
|
||||
, lRawFormat :: Bool
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -60,7 +67,6 @@ data ListOptions = ListOptions
|
||||
--[ Parsers ]--
|
||||
---------------
|
||||
|
||||
|
||||
listOpts :: Parser ListOptions
|
||||
listOpts =
|
||||
ListOptions
|
||||
@@ -69,7 +75,7 @@ listOpts =
|
||||
(eitherReader toolParser)
|
||||
(short 't' <> long "tool" <> metavar "<ghc|cabal|hls|stack>" <> help
|
||||
"Tool to list versions for. Default is all"
|
||||
<> completer (toolCompleter)
|
||||
<> completer toolCompleter
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
@@ -78,15 +84,53 @@ listOpts =
|
||||
( short 'c'
|
||||
<> long "show-criteria"
|
||||
<> metavar "<installed|set|available>"
|
||||
<> help "Show only installed/set/available tool versions"
|
||||
<> completer (listCompleter ["installed", "set", "available"])
|
||||
<> help "Apply filtering criteria, prefix with + or -"
|
||||
<> completer (listCompleter
|
||||
[ "+installed", "+set", "+available", "-installed", "-set", "-available"])
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
(option
|
||||
(eitherReader dayParser)
|
||||
(short 's' <> long "since" <> metavar "YYYY-MM-DD" <> help
|
||||
"List only tools with release date starting at YYYY-MM-DD or later"
|
||||
<> completer toolCompleter
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
(option
|
||||
(eitherReader dayParser)
|
||||
(short 'u' <> long "until" <> metavar "YYYY-MM-DD" <> help
|
||||
"List only tools with release date earlier than YYYY-MM-DD"
|
||||
<> completer toolCompleter
|
||||
)
|
||||
)
|
||||
<*> switch
|
||||
(short 'o' <> long "hide-old" <> help "Hide 'old' GHC versions (installed ones are always shown)"
|
||||
)
|
||||
<*> switch
|
||||
(short 'n' <> long "show-nightly" <> help "Show nightlies (installed ones are always shown)"
|
||||
)
|
||||
<*> switch
|
||||
(short 'r' <> long "raw-format" <> help "More machine-parsable format"
|
||||
)
|
||||
|
||||
|
||||
--------------
|
||||
--[ Footer ]--
|
||||
--------------
|
||||
|
||||
|
||||
listToolFooter :: String
|
||||
listToolFooter = [s|Discussion:
|
||||
Lists tool versions with optional criteria.
|
||||
Nightlies are by default hidden.
|
||||
|
||||
Examples:
|
||||
# query nightlies in a specific range
|
||||
ghcup list --show-nightly --since 2022-12-07 --until 2022-12-31
|
||||
# show all installed GHC versions
|
||||
ghcup list -t ghc -c installed|]
|
||||
|
||||
|
||||
-----------------
|
||||
@@ -105,8 +149,11 @@ printListResult no_color raw lr = do
|
||||
printTag Recommended = color Green "recommended"
|
||||
printTag Latest = color Yellow "latest"
|
||||
printTag Prerelease = color Red "prerelease"
|
||||
printTag Nightly = color Red "nightly"
|
||||
printTag (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
|
||||
printTag (UnknownTag t ) = t
|
||||
printTag LatestPrerelease = color Red "latest-prerelease"
|
||||
printTag LatestNightly = color Red "latest-nightly"
|
||||
printTag Old = ""
|
||||
|
||||
let
|
||||
@@ -133,8 +180,10 @@ 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
|
||||
Just d -> [color Blue (show d)])
|
||||
++ (if lNoBindist
|
||||
then [color Red "no-bindist"]
|
||||
else mempty
|
||||
@@ -259,7 +308,7 @@ list :: ( Monad m
|
||||
-> m ExitCode
|
||||
list ListOptions{..} no_color runAppState =
|
||||
runAppState (do
|
||||
l <- listVersions loTool lCriteria
|
||||
l <- listVersions loTool (maybeToList lCriteria) lHideOld lShowNightly (lFrom, lTo)
|
||||
liftIO $ printListResult no_color lRawFormat l
|
||||
pure ExitSuccess
|
||||
)
|
||||
@@ -26,7 +26,6 @@ import Haskus.Utils.Variant.Excepts
|
||||
import Options.Applicative hiding ( style )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception.Safe (MonadMask)
|
||||
@@ -77,8 +76,8 @@ nuke appState runLogger = do
|
||||
|
||||
lift $ logInfo "Initiating Nuclear Sequence 🚀🚀🚀"
|
||||
lift $ logInfo "Nuking in 3...2...1"
|
||||
|
||||
lInstalled <- lift $ listVersions Nothing (Just ListInstalled)
|
||||
|
||||
lInstalled <- lift $ listVersions Nothing [ListInstalled True] False True (Nothing, Nothing)
|
||||
|
||||
forM_ lInstalled (liftE . rmTool)
|
||||
|
||||
@@ -95,5 +94,5 @@ nuke appState runLogger = do
|
||||
pure ExitSuccess
|
||||
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 15
|
||||
@@ -14,6 +14,7 @@ module GHCup.OptParse.Prefetch where
|
||||
import GHCup
|
||||
import GHCup.Errors
|
||||
import GHCup.Types
|
||||
import GHCup.Types.Optics
|
||||
import GHCup.Prelude.File
|
||||
import GHCup.Prelude.Logger
|
||||
import GHCup.Prelude.String.QQ
|
||||
@@ -30,7 +31,6 @@ import Haskus.Utils.Variant.Excepts
|
||||
import Options.Applicative hiding ( style )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception.Safe (MonadMask)
|
||||
@@ -84,7 +84,7 @@ prefetchP = subparser
|
||||
<$> (PrefetchGHCOptions
|
||||
<$> ( switch (short 's' <> long "source" <> help "Download source tarball instead of bindist") <**> helper )
|
||||
<*> optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||
<*> optional (toolVersionTagArgument Nothing (Just GHC)) )
|
||||
<*> optional (toolVersionTagArgument [] (Just GHC)) )
|
||||
( progDesc "Download GHC assets for installation")
|
||||
)
|
||||
<>
|
||||
@@ -93,7 +93,7 @@ prefetchP = subparser
|
||||
(info
|
||||
(PrefetchCabal
|
||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||
<*> ( optional (toolVersionTagArgument Nothing (Just Cabal)) <**> helper ))
|
||||
<*> ( optional (toolVersionTagArgument [] (Just Cabal)) <**> helper ))
|
||||
( progDesc "Download cabal assets for installation")
|
||||
)
|
||||
<>
|
||||
@@ -102,7 +102,7 @@ prefetchP = subparser
|
||||
(info
|
||||
(PrefetchHLS
|
||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||
<*> ( optional (toolVersionTagArgument Nothing (Just HLS)) <**> helper ))
|
||||
<*> ( optional (toolVersionTagArgument [] (Just HLS)) <**> helper ))
|
||||
( progDesc "Download HLS assets for installation")
|
||||
)
|
||||
<>
|
||||
@@ -111,7 +111,7 @@ prefetchP = subparser
|
||||
(info
|
||||
(PrefetchStack
|
||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||
<*> ( optional (toolVersionTagArgument Nothing (Just Stack)) <**> helper ))
|
||||
<*> ( optional (toolVersionTagArgument [] (Just Stack)) <**> helper ))
|
||||
( progDesc "Download stack assets for installation")
|
||||
)
|
||||
<>
|
||||
@@ -149,6 +149,7 @@ Examples:
|
||||
|
||||
|
||||
type PrefetchEffects = '[ TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
, NoDownload
|
||||
@@ -157,7 +158,9 @@ type PrefetchEffects = '[ TagNotFound
|
||||
, GPGError
|
||||
, DownloadFailed
|
||||
, JSONError
|
||||
, FileDoesNotExistError ]
|
||||
, FileDoesNotExistError
|
||||
, StackPlatformDetectError
|
||||
]
|
||||
|
||||
|
||||
runPrefetch :: MonadUnliftIO m
|
||||
@@ -195,26 +198,27 @@ prefetch prefetchCommand runAppState runLogger =
|
||||
forM_ pfCacheDir (liftIO . createDirRecursive')
|
||||
(v, _) <- liftE $ fromVersion mt GHC
|
||||
if pfGHCSrc
|
||||
then liftE $ fetchGHCSrc (_tvVersion v) pfCacheDir
|
||||
else liftE $ fetchToolBindist (_tvVersion v) GHC pfCacheDir
|
||||
then liftE $ fetchGHCSrc v pfCacheDir
|
||||
else liftE $ fetchToolBindist v GHC pfCacheDir
|
||||
PrefetchCabal PrefetchOptions {pfCacheDir} mt -> do
|
||||
forM_ pfCacheDir (liftIO . createDirRecursive')
|
||||
(v, _) <- liftE $ fromVersion mt Cabal
|
||||
liftE $ fetchToolBindist (_tvVersion v) Cabal pfCacheDir
|
||||
liftE $ fetchToolBindist v Cabal pfCacheDir
|
||||
PrefetchHLS PrefetchOptions {pfCacheDir} mt -> do
|
||||
forM_ pfCacheDir (liftIO . createDirRecursive')
|
||||
(v, _) <- liftE $ fromVersion mt HLS
|
||||
liftE $ fetchToolBindist (_tvVersion v) HLS pfCacheDir
|
||||
liftE $ fetchToolBindist v HLS pfCacheDir
|
||||
PrefetchStack PrefetchOptions {pfCacheDir} mt -> do
|
||||
forM_ pfCacheDir (liftIO . createDirRecursive')
|
||||
(v, _) <- liftE $ fromVersion mt Stack
|
||||
liftE $ fetchToolBindist (_tvVersion v) Stack pfCacheDir
|
||||
liftE $ fetchToolBindist v Stack pfCacheDir
|
||||
PrefetchMetadata -> do
|
||||
_ <- liftE getDownloadsF
|
||||
pfreq <- lift getPlatformReq
|
||||
_ <- liftE $ getDownloadsF pfreq
|
||||
pure ""
|
||||
) >>= \case
|
||||
VRight _ -> do
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 15
|
||||
@@ -29,12 +29,11 @@ import Control.Monad.Reader
|
||||
import Control.Monad.Trans.Resource
|
||||
import Data.Functor
|
||||
import Data.Maybe
|
||||
import Data.Versions hiding ( str )
|
||||
import Data.Versions
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
import Options.Applicative hiding ( style )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception.Safe (MonadMask)
|
||||
@@ -51,6 +50,7 @@ data RmCommand = RmGHC RmOptions
|
||||
| RmCabal Version
|
||||
| RmHLS Version
|
||||
| RmStack Version
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ data RmCommand = RmGHC RmOptions
|
||||
|
||||
data RmOptions = RmOptions
|
||||
{ ghcVer :: GHCTargetVersion
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -81,19 +81,19 @@ rmParser =
|
||||
<> command
|
||||
"cabal"
|
||||
( RmCabal
|
||||
<$> info (versionParser' (Just ListInstalled) (Just Cabal) <**> helper)
|
||||
<$> info (versionParser' [ListInstalled True] (Just Cabal) <**> helper)
|
||||
(progDesc "Remove Cabal version")
|
||||
)
|
||||
<> command
|
||||
"hls"
|
||||
( RmHLS
|
||||
<$> info (versionParser' (Just ListInstalled) (Just HLS) <**> helper)
|
||||
<$> info (versionParser' [ListInstalled True] (Just HLS) <**> helper)
|
||||
(progDesc "Remove haskell-language-server version")
|
||||
)
|
||||
<> command
|
||||
"stack"
|
||||
( RmStack
|
||||
<$> info (versionParser' (Just ListInstalled) (Just Stack) <**> helper)
|
||||
<$> info (versionParser' [ListInstalled True] (Just Stack) <**> helper)
|
||||
(progDesc "Remove stack version")
|
||||
)
|
||||
)
|
||||
@@ -103,7 +103,7 @@ rmParser =
|
||||
|
||||
|
||||
rmOpts :: Maybe Tool -> Parser RmOptions
|
||||
rmOpts tool = RmOptions <$> ghcVersionArgument (Just ListInstalled) tool
|
||||
rmOpts tool = RmOptions <$> ghcVersionArgument [ListInstalled True] tool
|
||||
|
||||
|
||||
|
||||
@@ -171,7 +171,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
|
||||
@@ -179,7 +179,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
||||
postRmLog vi
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 7
|
||||
|
||||
rmCabal' tv =
|
||||
@@ -187,14 +187,14 @@ 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
|
||||
postRmLog vi
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 15
|
||||
|
||||
rmHLS' tv =
|
||||
@@ -202,14 +202,14 @@ 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
|
||||
postRmLog vi
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 15
|
||||
|
||||
rmStack' tv =
|
||||
@@ -217,14 +217,14 @@ 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
|
||||
postRmLog vi
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 15
|
||||
|
||||
postRmLog vi =
|
||||
@@ -28,7 +28,6 @@ import Control.Exception.Safe ( MonadMask, MonadCatch )
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
#endif
|
||||
import Codec.Archive
|
||||
import Control.Monad.Reader
|
||||
import Control.Monad.Trans.Resource
|
||||
import Data.Functor
|
||||
@@ -40,7 +39,6 @@ import Prelude hiding ( appendFile )
|
||||
import System.FilePath
|
||||
import System.Environment
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Text as T
|
||||
@@ -69,7 +67,7 @@ data RunOptions = RunOptions
|
||||
, runBinDir :: Maybe FilePath
|
||||
, runQuick :: Bool
|
||||
, runCOMMAND :: [String]
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -93,7 +91,7 @@ runOpts =
|
||||
(eitherReader ghcVersionTagEither)
|
||||
(metavar "GHC_VERSION" <> long "ghc" <> help "The ghc version"
|
||||
<> completer (tagCompleter GHC [])
|
||||
<> (completer $ versionCompleter Nothing GHC)
|
||||
<> (completer $ versionCompleter [] GHC)
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
@@ -101,7 +99,7 @@ runOpts =
|
||||
(eitherReader toolVersionTagEither)
|
||||
(metavar "CABAL_VERSION" <> long "cabal" <> help "The cabal version"
|
||||
<> completer (tagCompleter Cabal [])
|
||||
<> (completer $ versionCompleter Nothing Cabal)
|
||||
<> (completer $ versionCompleter [] Cabal)
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
@@ -109,7 +107,7 @@ runOpts =
|
||||
(eitherReader toolVersionTagEither)
|
||||
(metavar "HLS_VERSION" <> long "hls" <> help "The HLS version"
|
||||
<> completer (tagCompleter HLS [])
|
||||
<> (completer $ versionCompleter Nothing HLS)
|
||||
<> (completer $ versionCompleter [] HLS)
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
@@ -117,7 +115,7 @@ runOpts =
|
||||
(eitherReader toolVersionTagEither)
|
||||
(metavar "STACK_VERSION" <> long "stack" <> help "The stack version"
|
||||
<> completer (tagCompleter Stack [])
|
||||
<> (completer $ versionCompleter Nothing Stack)
|
||||
<> (completer $ versionCompleter [] Stack)
|
||||
)
|
||||
)
|
||||
<*> optional
|
||||
@@ -133,7 +131,7 @@ runOpts =
|
||||
<*> switch
|
||||
(short 'q' <> long "quick" <> help "Avoid any expensive work (such as downloads, version/tag resolution etc.). Disables --install.")
|
||||
<*> many (argument str (metavar "COMMAND" <> help "The command to run, with arguments (use longopts --). If omitted, just prints the created bin/ dir to stdout and exits."))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -176,6 +174,7 @@ type RunEffects = '[ AlreadyInstalled
|
||||
, NotInstalled
|
||||
, BuildFailed
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, DigestError
|
||||
, ContentLengthError
|
||||
, GPGError
|
||||
@@ -187,6 +186,11 @@ type RunEffects = '[ AlreadyInstalled
|
||||
, ProcessError
|
||||
, UninstallFailed
|
||||
, MergeFileTreeError
|
||||
, NoCompatiblePlatform
|
||||
, GHCup.Errors.ParseError
|
||||
, UnsupportedSetupCombo
|
||||
, DistroNotFound
|
||||
, NoCompatibleArch
|
||||
]
|
||||
|
||||
runLeanRUN :: (MonadUnliftIO m, MonadIO m)
|
||||
@@ -226,6 +230,7 @@ run :: forall m .
|
||||
, MonadCatch m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
, Alternative m
|
||||
)
|
||||
=> RunOptions
|
||||
-> IO AppState
|
||||
@@ -255,7 +260,9 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||
liftIO $ putStr tmp
|
||||
pure ExitSuccess
|
||||
(cmd:args) -> do
|
||||
newEnv <- liftIO $ addToPath tmp
|
||||
newEnv <- liftIO $ addToPath [tmp] runAppendPATH
|
||||
let pathVar = if isWindows then "Path" else "PATH"
|
||||
forM_ (Map.lookup pathVar . Map.fromList $ newEnv) $ liftIO . setEnv pathVar
|
||||
#ifndef IS_WINDOWS
|
||||
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
||||
pure ExitSuccess
|
||||
@@ -266,11 +273,11 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||
case r' of
|
||||
VRight _ -> pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 28
|
||||
#endif
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 27
|
||||
|
||||
where
|
||||
@@ -283,6 +290,7 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||
)
|
||||
=> Excepts
|
||||
'[ TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
] (ResourceT (ReaderT AppState m)) Toolchain
|
||||
@@ -328,11 +336,13 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||
, MonadThrow m
|
||||
, MonadIO m
|
||||
, MonadCatch m
|
||||
, Alternative m
|
||||
)
|
||||
=> Toolchain
|
||||
-> FilePath
|
||||
-> Excepts
|
||||
'[ TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
, UnknownArchive
|
||||
@@ -352,13 +362,18 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||
, CopyError
|
||||
, UninstallFailed
|
||||
, MergeFileTreeError
|
||||
, NoCompatiblePlatform
|
||||
, GHCup.Errors.ParseError
|
||||
, UnsupportedSetupCombo
|
||||
, DistroNotFound
|
||||
, NoCompatibleArch
|
||||
] (ResourceT (ReaderT AppState m)) ()
|
||||
installToolChainFull Toolchain{..} tmp = do
|
||||
case ghcVer of
|
||||
Just v -> do
|
||||
isInstalled <- lift $ checkIfToolInstalled' GHC v
|
||||
unless isInstalled $ when (runInstTool' && isNothing (_tvTarget v)) $ void $ liftE $ installGHCBin
|
||||
(_tvVersion v)
|
||||
v
|
||||
GHCupInternal
|
||||
False
|
||||
[]
|
||||
@@ -442,17 +457,6 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||
liftE $ setHLS v SetHLS_XYZ (Just tmp)
|
||||
liftE $ setHLS v SetHLSOnly (Just tmp)
|
||||
|
||||
addToPath path = do
|
||||
cEnv <- Map.fromList <$> getEnvironment
|
||||
let paths = ["PATH", "Path"]
|
||||
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
||||
newPath = intercalate [searchPathSeparator] (if runAppendPATH then (curPaths ++ [path]) else (path : curPaths))
|
||||
envWithoutPath = foldr (\x y -> Map.delete x y) cEnv paths
|
||||
pathVar = if isWindows then "Path" else "PATH"
|
||||
envWithNewPath = Map.toList $ Map.insert pathVar newPath envWithoutPath
|
||||
liftIO $ setEnv pathVar newPath
|
||||
return envWithNewPath
|
||||
|
||||
createTmpDir :: ( MonadUnliftIO m
|
||||
, MonadCatch m
|
||||
, MonadThrow m
|
||||
@@ -28,14 +28,13 @@ import Control.Monad.Trans.Resource
|
||||
import Data.Either
|
||||
import Data.Functor
|
||||
import Data.Maybe
|
||||
import Data.Versions hiding ( str )
|
||||
import Data.Versions
|
||||
import GHC.Unicode
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
import Options.Applicative hiding ( style )
|
||||
import Options.Applicative.Help.Pretty ( text )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Data.Bifunctor (second)
|
||||
@@ -54,6 +53,7 @@ data SetCommand = SetGHC SetOptions
|
||||
| SetCabal SetOptions
|
||||
| SetHLS SetOptions
|
||||
| SetStack SetOptions
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ data SetCommand = SetGHC SetOptions
|
||||
|
||||
data SetOptions = SetOptions
|
||||
{ sToolVer :: SetToolVersion
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -140,9 +140,9 @@ setParser =
|
||||
setOpts :: Tool -> Parser SetOptions
|
||||
setOpts tool = SetOptions <$>
|
||||
(fromMaybe SetRecommended <$>
|
||||
optional (setVersionArgument (Just ListInstalled) tool))
|
||||
optional (setVersionArgument [ListInstalled True] tool))
|
||||
|
||||
setVersionArgument :: Maybe ListCriteria -> Tool -> Parser SetToolVersion
|
||||
setVersionArgument :: [ListCriteria] -> Tool -> Parser SetToolVersion
|
||||
setVersionArgument criteria tool =
|
||||
argument (eitherReader setEither)
|
||||
(metavar "VERSION|TAG|next"
|
||||
@@ -185,6 +185,7 @@ setFooter = [s|Discussion:
|
||||
type SetGHCEffects = '[ FileDoesNotExistError
|
||||
, NotInstalled
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet]
|
||||
|
||||
@@ -199,6 +200,7 @@ runSetGHC runAppState =
|
||||
|
||||
type SetCabalEffects = '[ NotInstalled
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet]
|
||||
|
||||
@@ -213,6 +215,7 @@ runSetCabal runAppState =
|
||||
|
||||
type SetHLSEffects = '[ NotInstalled
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet]
|
||||
|
||||
@@ -227,6 +230,7 @@ runSetHLS runAppState =
|
||||
|
||||
type SetStackEffects = '[ NotInstalled
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet]
|
||||
|
||||
@@ -260,7 +264,7 @@ set :: forall m env.
|
||||
-> m (VEither eff GHCTargetVersion))
|
||||
-> (ReaderT LeanAppState m () -> m ())
|
||||
-> m ExitCode
|
||||
set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
||||
set setCommand runAppState _ runLogger = case setCommand of
|
||||
(Right sopts) -> do
|
||||
runLogger (logWarn "This is an old-style command for setting GHC. Use 'ghcup set ghc' instead.")
|
||||
setGHC' sopts
|
||||
@@ -272,10 +276,7 @@ set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
||||
where
|
||||
setGHC' :: SetOptions
|
||||
-> m ExitCode
|
||||
setGHC' SetOptions{ sToolVer } =
|
||||
case sToolVer of
|
||||
(SetGHCVersion v) -> runSetGHC runLeanAppState (liftE $ setGHC v SetGHCOnly Nothing >> pure v)
|
||||
_ -> runSetGHC runAppState (do
|
||||
setGHC' SetOptions{ sToolVer } = runSetGHC runAppState (do
|
||||
v <- liftE $ fst <$> fromVersion' sToolVer GHC
|
||||
liftE $ setGHC v SetGHCOnly Nothing
|
||||
)
|
||||
@@ -286,16 +287,13 @@ set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
||||
"GHC " <> prettyVer _tvVersion <> " successfully set as default version" <> maybe "" (" for cross target " <>) _tvTarget
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 5
|
||||
|
||||
|
||||
setCabal' :: SetOptions
|
||||
-> m ExitCode
|
||||
setCabal' SetOptions{ sToolVer } =
|
||||
case sToolVer of
|
||||
(SetToolVersion v) -> runSetCabal runLeanAppState (liftE $ setCabal v >> pure (mkTVer v))
|
||||
_ -> runSetCabal runAppState (do
|
||||
setCabal' SetOptions{ sToolVer } = runSetCabal runAppState (do
|
||||
v <- liftE $ fst <$> fromVersion' sToolVer Cabal
|
||||
liftE $ setCabal (_tvVersion v)
|
||||
pure v
|
||||
@@ -307,15 +305,12 @@ set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
||||
"Cabal " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 14
|
||||
|
||||
setHLS' :: SetOptions
|
||||
-> m ExitCode
|
||||
setHLS' SetOptions{ sToolVer } =
|
||||
case sToolVer of
|
||||
(SetToolVersion v) -> runSetHLS runLeanAppState (liftE $ setHLS v SetHLSOnly Nothing >> pure (mkTVer v))
|
||||
_ -> runSetHLS runAppState (do
|
||||
setHLS' SetOptions{ sToolVer } = runSetHLS runAppState (do
|
||||
v <- liftE $ fst <$> fromVersion' sToolVer HLS
|
||||
liftE $ setHLS (_tvVersion v) SetHLSOnly Nothing
|
||||
pure v
|
||||
@@ -327,16 +322,13 @@ set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
||||
"HLS " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 14
|
||||
|
||||
|
||||
setStack' :: SetOptions
|
||||
-> m ExitCode
|
||||
setStack' SetOptions{ sToolVer } =
|
||||
case sToolVer of
|
||||
(SetToolVersion v) -> runSetStack runLeanAppState (liftE $ setStack v >> pure (mkTVer v))
|
||||
_ -> runSetStack runAppState (do
|
||||
setStack' SetOptions{ sToolVer } = runSetStack runAppState (do
|
||||
v <- liftE $ fst <$> fromVersion' sToolVer Stack
|
||||
liftE $ setStack (_tvVersion v)
|
||||
pure v
|
||||
@@ -348,5 +340,5 @@ set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
||||
"Stack " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 14
|
||||
188
lib-opt/GHCup/OptParse/Test.hs
Normal file
188
lib-opt/GHCup/OptParse/Test.hs
Normal file
@@ -0,0 +1,188 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE ViewPatterns #-}
|
||||
{-# LANGUAGE TypeOperators #-}
|
||||
|
||||
module GHCup.OptParse.Test where
|
||||
|
||||
|
||||
|
||||
|
||||
import GHCup.OptParse.Common
|
||||
|
||||
import GHCup
|
||||
import GHCup.Errors
|
||||
import GHCup.Types
|
||||
import GHCup.Utils.Dirs
|
||||
import GHCup.Prelude.Logger
|
||||
import GHCup.Prelude.String.QQ
|
||||
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
#endif
|
||||
import Control.Monad.Reader
|
||||
import Control.Monad.Trans.Resource
|
||||
import Data.Functor
|
||||
import Data.Maybe
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
import Options.Applicative hiding ( style )
|
||||
import Options.Applicative.Help.Pretty ( text )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import URI.ByteString hiding ( uriParser )
|
||||
|
||||
import qualified Data.Text as T
|
||||
|
||||
|
||||
|
||||
|
||||
----------------
|
||||
--[ Commands ]--
|
||||
----------------
|
||||
|
||||
|
||||
data TestCommand = TestGHC TestOptions
|
||||
|
||||
|
||||
|
||||
|
||||
---------------
|
||||
--[ Options ]--
|
||||
---------------
|
||||
|
||||
|
||||
data TestOptions = TestOptions
|
||||
{ testVer :: Maybe ToolVersion
|
||||
, testBindist :: Maybe URI
|
||||
, addMakeArgs :: [T.Text]
|
||||
}
|
||||
|
||||
|
||||
|
||||
---------------
|
||||
--[ Footers ]--
|
||||
---------------
|
||||
|
||||
testFooter :: String
|
||||
testFooter = [s|Discussion:
|
||||
Runs test suites from the test bindist.|]
|
||||
|
||||
|
||||
|
||||
|
||||
---------------
|
||||
--[ Parsers ]--
|
||||
---------------
|
||||
|
||||
testParser :: Parser TestCommand
|
||||
testParser =
|
||||
subparser
|
||||
( command
|
||||
"ghc"
|
||||
( TestGHC
|
||||
<$> info
|
||||
(testOpts (Just GHC) <**> helper)
|
||||
( progDesc "Test GHC"
|
||||
<> footerDoc (Just $ text testGHCFooter)
|
||||
)
|
||||
)
|
||||
)
|
||||
where
|
||||
testGHCFooter :: String
|
||||
testGHCFooter = [s|Discussion:
|
||||
Runs the GHC test suite from the test bindist.|]
|
||||
|
||||
|
||||
testOpts :: Maybe Tool -> Parser TestOptions
|
||||
testOpts tool =
|
||||
(\(u, v) args -> TestOptions v u args)
|
||||
<$> ( ( (,)
|
||||
<$> optional
|
||||
(option
|
||||
(eitherReader uriParser)
|
||||
(short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
|
||||
"Install the specified version from this bindist"
|
||||
<> completer (toolDlCompleter (fromMaybe GHC tool))
|
||||
)
|
||||
)
|
||||
<*> (Just <$> toolVersionTagArgument [] tool)
|
||||
)
|
||||
<|> pure (Nothing, Nothing)
|
||||
)
|
||||
<*> many (argument str (metavar "MAKE_ARGS" <> help "Additional arguments to 'make', prefix with '-- ' (longopts)"))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---------------------------
|
||||
--[ Effect interpreters ]--
|
||||
---------------------------
|
||||
|
||||
|
||||
type TestGHCEffects = [ DigestError
|
||||
, ContentLengthError
|
||||
, GPGError
|
||||
, DownloadFailed
|
||||
, NoDownload
|
||||
, ArchiveResult
|
||||
, TarDirDoesNotExist
|
||||
, UnknownArchive
|
||||
, TestFailed
|
||||
, NextVerNotFound
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, NoToolVersionSet
|
||||
]
|
||||
|
||||
runTestGHC :: AppState
|
||||
-> Excepts TestGHCEffects (ResourceT (ReaderT AppState IO)) a
|
||||
-> IO (VEither TestGHCEffects a)
|
||||
runTestGHC appstate' =
|
||||
flip runReaderT appstate'
|
||||
. runResourceT
|
||||
. runE
|
||||
@TestGHCEffects
|
||||
|
||||
|
||||
-------------------
|
||||
--[ Entrypoints ]--
|
||||
-------------------
|
||||
|
||||
|
||||
test :: TestCommand -> Settings -> IO AppState -> (ReaderT LeanAppState IO () -> IO ()) -> IO ExitCode
|
||||
test testCommand settings getAppState' runLogger = case testCommand of
|
||||
(TestGHC iopts) -> go iopts
|
||||
where
|
||||
go :: TestOptions -> IO ExitCode
|
||||
go TestOptions{..} = do
|
||||
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
||||
(case testBindist of
|
||||
Nothing -> runTestGHC s' $ do
|
||||
(v, vi) <- liftE $ fromVersion testVer GHC
|
||||
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) v addMakeArgs
|
||||
pure vi
|
||||
)
|
||||
>>= \case
|
||||
VRight _ -> do
|
||||
runLogger $ logInfo "GHC test successful"
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ do
|
||||
logError $ T.pack $ prettyHFError e
|
||||
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||
pure $ ExitFailure 3
|
||||
|
||||
@@ -23,7 +23,6 @@ import Haskus.Utils.Variant.Excepts
|
||||
import Options.Applicative hiding ( style )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
@@ -118,5 +117,5 @@ toolRequirements ToolReqOpts{..} runAppState runLogger = runToolRequirements run
|
||||
>>= \case
|
||||
VRight _ -> pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 12
|
||||
@@ -31,7 +31,6 @@ import Options.Applicative hiding ( style )
|
||||
import Options.Applicative.Help.Pretty ( text )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception.Safe (MonadMask)
|
||||
@@ -49,6 +48,7 @@ data UnsetCommand = UnsetGHC UnsetOptions
|
||||
| UnsetCabal UnsetOptions
|
||||
| UnsetHLS UnsetOptions
|
||||
| UnsetStack UnsetOptions
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ data UnsetCommand = UnsetGHC UnsetOptions
|
||||
|
||||
data UnsetOptions = UnsetOptions
|
||||
{ sToolVer :: Maybe T.Text -- target platform triple
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ data UnsetOptions = UnsetOptions
|
||||
--[ Parsers ]--
|
||||
---------------
|
||||
|
||||
|
||||
|
||||
unsetParser :: Parser UnsetCommand
|
||||
unsetParser =
|
||||
subparser
|
||||
@@ -114,7 +114,14 @@ unsetParser =
|
||||
unsetGHCFooter :: String
|
||||
unsetGHCFooter = [s|Discussion:
|
||||
Unsets the the current GHC version. That means there won't
|
||||
be a ~/.ghcup/bin/ghc anymore.|]
|
||||
be a ~/.ghcup/bin/ghc anymore.
|
||||
|
||||
Examples:
|
||||
# unset ghc
|
||||
ghcup unset ghc
|
||||
|
||||
# unset ghc for the target version
|
||||
ghcup unset ghc armv7-unknown-linux-gnueabihf|]
|
||||
|
||||
unsetCabalFooter :: String
|
||||
unsetCabalFooter = [s|Discussion:
|
||||
@@ -189,7 +196,7 @@ unset unsetCommand runLeanAppState runLogger = case unsetCommand of
|
||||
runLogger $ logInfo "GHC successfully unset"
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 14
|
||||
(UnsetCabal (UnsetOptions _)) -> do
|
||||
void $ runLeanAppState (VRight <$> unsetCabal)
|
||||
@@ -28,7 +28,6 @@ import Haskus.Utils.Variant.Excepts
|
||||
import Options.Applicative hiding ( style )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception.Safe (MonadMask)
|
||||
@@ -36,7 +35,7 @@ import System.Environment
|
||||
import GHCup.Utils
|
||||
import System.FilePath
|
||||
import GHCup.Types.Optics
|
||||
import Data.Versions hiding (str)
|
||||
import Data.Versions
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +50,7 @@ import Data.Versions hiding (str)
|
||||
data UpgradeOpts = UpgradeInplace
|
||||
| UpgradeAt FilePath
|
||||
| UpgradeGHCupDir
|
||||
deriving Show
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -152,5 +151,5 @@ upgrade uOpts force' fatal Dirs{..} runAppState runLogger = do
|
||||
runLogger $ logWarn "No GHCup update available"
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 11
|
||||
@@ -34,7 +34,6 @@ import Options.Applicative.Help.Pretty ( text )
|
||||
import Prelude hiding ( appendFile )
|
||||
import System.Environment
|
||||
import System.Exit
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Control.Exception.Safe (MonadMask)
|
||||
@@ -55,6 +54,7 @@ data WhereisCommand = WhereisTool Tool (Maybe ToolVersion)
|
||||
| WhereisCacheDir
|
||||
| WhereisLogsDir
|
||||
| WhereisConfDir
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ data WhereisCommand = WhereisTool Tool (Maybe ToolVersion)
|
||||
|
||||
data WhereisOptions = WhereisOptions {
|
||||
directory :: Bool
|
||||
}
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ whereisP = subparser
|
||||
command
|
||||
"ghc"
|
||||
(WhereisTool GHC <$> info
|
||||
( optional (toolVersionTagArgument Nothing (Just GHC)) <**> helper )
|
||||
( optional (toolVersionTagArgument [] (Just GHC)) <**> helper )
|
||||
( progDesc "Get GHC location"
|
||||
<> footerDoc (Just $ text whereisGHCFooter ))
|
||||
)
|
||||
@@ -91,7 +91,7 @@ whereisP = subparser
|
||||
command
|
||||
"cabal"
|
||||
(WhereisTool Cabal <$> info
|
||||
( optional (toolVersionTagArgument Nothing (Just Cabal)) <**> helper )
|
||||
( optional (toolVersionTagArgument [] (Just Cabal)) <**> helper )
|
||||
( progDesc "Get cabal location"
|
||||
<> footerDoc (Just $ text whereisCabalFooter ))
|
||||
)
|
||||
@@ -99,7 +99,7 @@ whereisP = subparser
|
||||
command
|
||||
"hls"
|
||||
(WhereisTool HLS <$> info
|
||||
( optional (toolVersionTagArgument Nothing (Just HLS)) <**> helper )
|
||||
( optional (toolVersionTagArgument [] (Just HLS)) <**> helper )
|
||||
( progDesc "Get HLS location"
|
||||
<> footerDoc (Just $ text whereisHLSFooter ))
|
||||
)
|
||||
@@ -107,7 +107,7 @@ whereisP = subparser
|
||||
command
|
||||
"stack"
|
||||
(WhereisTool Stack <$> info
|
||||
( optional (toolVersionTagArgument Nothing (Just Stack)) <**> helper )
|
||||
( optional (toolVersionTagArgument [] (Just Stack)) <**> helper )
|
||||
( progDesc "Get stack location"
|
||||
<> footerDoc (Just $ text whereisStackFooter ))
|
||||
)
|
||||
@@ -223,6 +223,7 @@ type WhereisEffects = '[ NotInstalled
|
||||
, NoToolVersionSet
|
||||
, NextVerNotFound
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
]
|
||||
|
||||
|
||||
@@ -288,7 +289,7 @@ whereis whereisCommand whereisOptions runAppState leanAppstate runLogger = do
|
||||
liftIO $ putStr r
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 30
|
||||
(WhereisTool tool (Just (ToolVersion v)), WhereisOptions{..}) ->
|
||||
runLeanWhereIs leanAppstate (do
|
||||
@@ -302,7 +303,7 @@ whereis whereisCommand whereisOptions runAppState leanAppstate runLogger = do
|
||||
liftIO $ putStr r
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 30
|
||||
|
||||
(WhereisTool tool whereVer, WhereisOptions{..}) -> do
|
||||
@@ -318,7 +319,7 @@ whereis whereisCommand whereisOptions runAppState leanAppstate runLogger = do
|
||||
liftIO $ putStr r
|
||||
pure ExitSuccess
|
||||
VLeft e -> do
|
||||
runLogger $ logError $ T.pack $ prettyShow e
|
||||
runLogger $ logError $ T.pack $ prettyHFError e
|
||||
pure $ ExitFailure 30
|
||||
|
||||
(WhereisBaseDir, _) -> do
|
||||
34
lib/GHCup.hs
34
lib/GHCup.hs
@@ -78,7 +78,6 @@ import Text.Regex.Posix
|
||||
|
||||
import qualified Data.Text as T
|
||||
import qualified Streamly.Prelude as S
|
||||
import Text.PrettyPrint.HughesPJClass (prettyShow)
|
||||
|
||||
|
||||
|
||||
@@ -101,7 +100,7 @@ fetchToolBindist :: ( MonadFail m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Version
|
||||
=> GHCTargetVersion
|
||||
-> Tool
|
||||
-> Maybe FilePath
|
||||
-> Excepts
|
||||
@@ -114,7 +113,7 @@ fetchToolBindist :: ( MonadFail m
|
||||
m
|
||||
FilePath
|
||||
fetchToolBindist v t mfp = do
|
||||
dlinfo <- liftE $ getDownloadInfo t v
|
||||
dlinfo <- liftE $ getDownloadInfo' t v
|
||||
liftE $ downloadCached' dlinfo Nothing mfp
|
||||
|
||||
|
||||
@@ -135,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
|
||||
@@ -304,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
|
||||
@@ -328,7 +336,7 @@ upgradeGHCup mtarget force' fatal = do
|
||||
Just pa
|
||||
| fatal -> throwE (ToolShadowed GHCup pa destFile latestVer)
|
||||
| otherwise ->
|
||||
lift $ logWarn $ T.pack $ prettyShow (ToolShadowed GHCup pa destFile latestVer)
|
||||
lift $ logWarn $ T.pack $ prettyHFError (ToolShadowed GHCup pa destFile latestVer)
|
||||
|
||||
pure latestVer
|
||||
|
||||
@@ -493,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
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import GHCup.Prelude
|
||||
import GHCup.Prelude.File
|
||||
import GHCup.Prelude.Logger
|
||||
|
||||
import Codec.Archive ( ArchiveResult )
|
||||
import Control.Applicative
|
||||
import Control.Exception.Safe
|
||||
import Control.Monad
|
||||
@@ -38,6 +37,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
|
||||
@@ -50,7 +50,6 @@ import System.FilePath
|
||||
import System.IO.Error
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Text.PrettyPrint.HughesPJClass (prettyShow)
|
||||
|
||||
|
||||
|
||||
@@ -235,7 +234,7 @@ setCabal ver = do
|
||||
|
||||
liftIO (isShadowed cabalbin) >>= \case
|
||||
Nothing -> pure ()
|
||||
Just pa -> lift $ logWarn $ T.pack $ prettyShow (ToolShadowed Cabal pa cabalbin ver)
|
||||
Just pa -> lift $ logWarn $ T.pack $ prettyHFError (ToolShadowed Cabal pa cabalbin ver)
|
||||
|
||||
pure ()
|
||||
|
||||
@@ -281,6 +280,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)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
|
||||
|
||||
{-|
|
||||
Module : GHCup.Download
|
||||
Description : Downloading
|
||||
@@ -31,9 +30,12 @@ import GHCup.Download.Utils
|
||||
#endif
|
||||
import GHCup.Errors
|
||||
import GHCup.Types
|
||||
import qualified GHCup.Types.Stack as Stack
|
||||
import GHCup.Types.Optics
|
||||
import GHCup.Types.JSON ( )
|
||||
import GHCup.Utils.Dirs
|
||||
import GHCup.Utils.URI
|
||||
import GHCup.Platform
|
||||
import GHCup.Prelude
|
||||
import GHCup.Prelude.File
|
||||
import GHCup.Prelude.Logger.Internal
|
||||
@@ -55,6 +57,7 @@ import Data.ByteString ( ByteString )
|
||||
import Data.CaseInsensitive ( mk )
|
||||
#endif
|
||||
import Data.Maybe
|
||||
import Data.Either
|
||||
import Data.List
|
||||
import Data.Time.Clock
|
||||
import Data.Time.Clock.POSIX
|
||||
@@ -75,8 +78,7 @@ import System.Exit
|
||||
import System.FilePath
|
||||
import System.IO.Error
|
||||
import System.IO.Temp
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
import URI.ByteString
|
||||
import URI.ByteString hiding (parseURI)
|
||||
|
||||
import qualified Crypto.Hash.SHA256 as SHA256
|
||||
import qualified Data.ByteString as B
|
||||
@@ -113,33 +115,84 @@ getDownloadsF :: ( FromJSONKey Tool
|
||||
, MonadFail m
|
||||
, MonadMask m
|
||||
)
|
||||
=> Excepts
|
||||
'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError]
|
||||
=> PlatformRequest
|
||||
-> Excepts
|
||||
'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError, StackPlatformDetectError]
|
||||
m
|
||||
GHCupInfo
|
||||
getDownloadsF = do
|
||||
getDownloadsF pfreq@(PlatformRequest arch plat _) = do
|
||||
Settings { urlSource } <- lift getSettings
|
||||
case urlSource of
|
||||
GHCupURL -> liftE $ getBase ghcupURL
|
||||
(OwnSource exts) -> do
|
||||
ext <- liftE $ mapM (either pure getBase) exts
|
||||
mergeGhcupInfo ext
|
||||
(OwnSpec av) -> pure av
|
||||
(AddSource exts) -> do
|
||||
base <- liftE $ getBase ghcupURL
|
||||
ext <- liftE $ mapM (either pure getBase) exts
|
||||
mergeGhcupInfo (base:ext)
|
||||
|
||||
let newUrlSources = fromURLSource urlSource
|
||||
infos <- liftE $ mapM dl' newUrlSources
|
||||
keys <- if any isRight infos
|
||||
then liftE . reThrowAll @_ @_ @'[StackPlatformDetectError] StackPlatformDetectError $ getStackPlatformKey pfreq
|
||||
else pure []
|
||||
ghcupInfos <- fmap catMaybes $ forM infos $ \case
|
||||
Left gi -> pure (Just gi)
|
||||
Right si -> pure $ fromStackSetupInfo si keys
|
||||
mergeGhcupInfo ghcupInfos
|
||||
where
|
||||
|
||||
dl' :: ( FromJSONKey Tool
|
||||
, FromJSONKey Version
|
||||
, FromJSON VersionInfo
|
||||
, MonadReader env m
|
||||
, HasSettings env
|
||||
, HasDirs env
|
||||
, MonadIO m
|
||||
, MonadCatch m
|
||||
, HasLog env
|
||||
, MonadThrow m
|
||||
, MonadFail m
|
||||
, MonadMask m
|
||||
)
|
||||
=> NewURLSource
|
||||
-> Excepts
|
||||
'[DownloadFailed, GPGError, DigestError, ContentLengthError, JSONError, FileDoesNotExistError]
|
||||
m (Either GHCupInfo Stack.SetupInfo)
|
||||
dl' NewGHCupURL = fmap Left $ liftE (getBase ghcupURL) >>= liftE . decodeMetadata @GHCupInfo
|
||||
dl' NewStackSetupURL = fmap Right $ liftE (getBase stackSetupURL) >>= liftE . decodeMetadata @Stack.SetupInfo
|
||||
dl' (NewGHCupInfo gi) = pure (Left gi)
|
||||
dl' (NewSetupInfo si) = pure (Right si)
|
||||
dl' (NewURI uri) = do
|
||||
base <- liftE $ getBase uri
|
||||
catchE @JSONError (\(JSONDecodeError _) -> do
|
||||
logDebug $ "Couldn't decode " <> T.pack base <> " as GHCupInfo, trying as SetupInfo: "
|
||||
Right <$> decodeMetadata @Stack.SetupInfo base)
|
||||
$ fmap Left (decodeMetadata @GHCupInfo base >>= \gI -> warnOnMetadataUpdate uri gI >> pure gI)
|
||||
|
||||
fromStackSetupInfo :: MonadThrow m
|
||||
=> Stack.SetupInfo
|
||||
-> [String]
|
||||
-> m GHCupInfo
|
||||
fromStackSetupInfo (Stack.siGHCs -> ghcDli) keys = do
|
||||
let ghcVersionsPerKey = (`M.lookup` ghcDli) . T.pack <$> keys
|
||||
ghcVersions = fromMaybe mempty . listToMaybe . catMaybes $ ghcVersionsPerKey
|
||||
(ghcupInfo' :: M.Map GHCTargetVersion DownloadInfo) <-
|
||||
M.mapKeys mkTVer <$> M.traverseMaybeWithKey (\_ a -> pure $ fromStackDownloadInfo a) ghcVersions
|
||||
let ghcupDownloads' = M.singleton GHC (M.map fromDownloadInfo ghcupInfo')
|
||||
pure (GHCupInfo mempty ghcupDownloads' Nothing)
|
||||
where
|
||||
fromDownloadInfo :: DownloadInfo -> VersionInfo
|
||||
fromDownloadInfo dli = let aspec = M.singleton arch (M.singleton plat (M.singleton Nothing dli))
|
||||
in VersionInfo [] Nothing Nothing Nothing Nothing aspec Nothing Nothing Nothing
|
||||
|
||||
fromStackDownloadInfo :: MonadThrow m => Stack.GHCDownloadInfo -> m DownloadInfo
|
||||
fromStackDownloadInfo (Stack.GHCDownloadInfo { gdiDownloadInfo = Stack.DownloadInfo{..} }) = do
|
||||
url <- either (\e -> throwM $ ParseError (show e)) pure $ parseURI . E.encodeUtf8 $ downloadInfoUrl
|
||||
sha256 <- maybe (throwM $ DigestMissing url) (pure . E.decodeUtf8) downloadInfoSha256
|
||||
pure $ DownloadInfo url (Just $ RegexDir "ghc-.*") sha256 Nothing Nothing
|
||||
|
||||
|
||||
mergeGhcupInfo :: MonadFail m
|
||||
=> [GHCupInfo]
|
||||
-> m GHCupInfo
|
||||
mergeGhcupInfo [] = fail "mergeGhcupInfo: internal error: need at least one GHCupInfo"
|
||||
mergeGhcupInfo xs@(GHCupInfo{}: _) =
|
||||
let newDownloads = M.unionsWith (M.unionWith (\_ b2 -> b2)) (_ghcupDownloads <$> xs)
|
||||
newGlobalTools = M.unionsWith (\_ a2 -> a2 ) (_globalTools <$> xs)
|
||||
newToolReqs = M.unionsWith (M.unionWith (\_ b2 -> b2)) (_toolRequirements <$> xs)
|
||||
in pure $ GHCupInfo newToolReqs newDownloads newGlobalTools
|
||||
in pure $ GHCupInfo newToolReqs newDownloads Nothing
|
||||
|
||||
|
||||
|
||||
yamlFromCache :: (MonadReader env m, HasDirs env) => URI -> m FilePath
|
||||
@@ -152,7 +205,7 @@ etagsFile :: FilePath -> FilePath
|
||||
etagsFile = (<.> "etags")
|
||||
|
||||
|
||||
getBase :: ( MonadReader env m
|
||||
getBase :: forall m env . ( MonadReader env m
|
||||
, HasDirs env
|
||||
, HasSettings env
|
||||
, MonadFail m
|
||||
@@ -162,41 +215,28 @@ getBase :: ( MonadReader env m
|
||||
, MonadMask m
|
||||
)
|
||||
=> URI
|
||||
-> Excepts '[GPGError, DigestError, ContentLengthError, JSONError, FileDoesNotExistError] m GHCupInfo
|
||||
-> Excepts '[DownloadFailed, GPGError, DigestError, ContentLengthError] m FilePath
|
||||
getBase uri = do
|
||||
Settings { noNetwork, downloader } <- lift getSettings
|
||||
Settings { noNetwork, downloader, metaMode } <- lift getSettings
|
||||
|
||||
-- try to download yaml... usually this writes it into cache dir,
|
||||
-- but in some cases not (e.g. when using file://), so we honour
|
||||
-- the return filepath, if any
|
||||
mYaml <- if noNetwork && view (uriSchemeL' % schemeBSL') uri /= "file" -- for file://, let it fall through
|
||||
then pure Nothing
|
||||
else handleIO (\e -> lift (warnCache (displayException e) downloader) >> pure Nothing)
|
||||
. catchE @_ @_ @'[] (\e@(DownloadFailed _) -> lift (warnCache (prettyShow e) downloader) >> pure Nothing)
|
||||
else handleIO (\e -> case metaMode of
|
||||
Strict -> throwIO e
|
||||
Lax -> lift (warnCache (displayException e) downloader) >> pure Nothing)
|
||||
. catchE @_ @_ @'[DownloadFailed] (\e@(DownloadFailed _) -> case metaMode of
|
||||
Strict -> throwE e
|
||||
Lax -> lift (warnCache (prettyHFError e) downloader) >> pure Nothing)
|
||||
. fmap Just
|
||||
. smartDl
|
||||
$ uri
|
||||
|
||||
-- if we didn't get a filepath from the download, use the cached yaml
|
||||
actualYaml <- maybe (lift $ yamlFromCache uri) pure mYaml
|
||||
lift $ logDebug $ "Decoding yaml at: " <> T.pack actualYaml
|
||||
|
||||
liftE
|
||||
. onE_ (onError actualYaml)
|
||||
. lEM' @_ @_ @'[JSONError] (\(displayException -> e) -> JSONDecodeError $ unlines [e, "Consider removing " <> actualYaml <> " manually."])
|
||||
. liftIO
|
||||
. Y.decodeFileEither
|
||||
$ actualYaml
|
||||
maybe (lift $ yamlFromCache uri) pure mYaml
|
||||
where
|
||||
-- On error, remove the etags file and set access time to 0. This should ensure the next invocation
|
||||
-- may re-download and succeed.
|
||||
onError :: (MonadReader env m, HasLog env, MonadMask m, MonadCatch m, MonadIO m) => FilePath -> m ()
|
||||
onError fp = do
|
||||
let efp = etagsFile fp
|
||||
handleIO (\e -> logWarn $ "Couldn't remove file " <> T.pack efp <> ", error was: " <> T.pack (displayException e))
|
||||
(hideError doesNotExistErrorType $ rmFile efp)
|
||||
liftIO $ hideError doesNotExistErrorType $ setAccessTime fp (posixSecondsToUTCTime (fromIntegral @Int 0))
|
||||
|
||||
warnCache :: (MonadReader env m, HasLog env, MonadMask m, MonadCatch m, MonadIO m) => FilePath -> Downloader -> m ()
|
||||
warnCache s downloader' = do
|
||||
let tryDownloder = case downloader' of
|
||||
@@ -260,10 +300,76 @@ getBase uri = do
|
||||
dlWithMod modTime json_file = do
|
||||
let (dir, fn) = splitFileName json_file
|
||||
f <- liftE $ download uri' (Just $ over pathL' (<> ".sig") uri') Nothing Nothing dir (Just fn) True
|
||||
liftIO $ setModificationTime f modTime
|
||||
liftIO $ setAccessTime f modTime
|
||||
|
||||
-- make these failures non-fatal, also see:
|
||||
-- https://github.com/actions/runner-images/issues/7061
|
||||
handleIO (\e -> logWarn $ "setModificationTime failed with: " <> T.pack (displayException e)) $ liftIO $ setModificationTime f modTime
|
||||
handleIO (\e -> logWarn $ "setAccessTime failed with: " <> T.pack (displayException e)) $ liftIO $ setAccessTime f modTime
|
||||
|
||||
pure f
|
||||
|
||||
warnOnMetadataUpdate ::
|
||||
( MonadReader env m
|
||||
, MonadIO m
|
||||
, HasLog env
|
||||
, HasDirs env
|
||||
)
|
||||
=> URI
|
||||
-> GHCupInfo
|
||||
-> m ()
|
||||
warnOnMetadataUpdate uri (GHCupInfo { _metadataUpdate = Just newUri })
|
||||
| scheme' uri == "file"
|
||||
, urlBase' uri /= urlBase' newUri = do
|
||||
confFile <- getConfigFilePath'
|
||||
logWarn $ "New metadata version detected"
|
||||
<> "\n old URI: " <> (decUTF8Safe . serializeURIRef') uri
|
||||
<> "\n new URI: " <> (decUTF8Safe . serializeURIRef') newUri
|
||||
<> "\nYou might need to update your " <> T.pack confFile
|
||||
| scheme' uri /= "file"
|
||||
, uri /= newUri = do
|
||||
confFile <- getConfigFilePath'
|
||||
logWarn $ "New metadata version detected"
|
||||
<> "\n old URI: " <> (decUTF8Safe . serializeURIRef') uri
|
||||
<> "\n new URI: " <> (decUTF8Safe . serializeURIRef') newUri
|
||||
<> "\nYou might need to update your " <> T.pack confFile
|
||||
where
|
||||
scheme' = view (uriSchemeL' % schemeBSL')
|
||||
urlBase' = T.unpack . decUTF8Safe . urlBaseName . view pathL'
|
||||
warnOnMetadataUpdate _ _ = pure ()
|
||||
|
||||
|
||||
decodeMetadata :: forall j m env .
|
||||
( MonadReader env m
|
||||
, HasDirs env
|
||||
, HasSettings env
|
||||
, MonadFail m
|
||||
, MonadIO m
|
||||
, MonadCatch m
|
||||
, HasLog env
|
||||
, MonadMask m
|
||||
, FromJSON j
|
||||
)
|
||||
=> FilePath
|
||||
-> Excepts '[JSONError, FileDoesNotExistError] m j
|
||||
decodeMetadata actualYaml = do
|
||||
lift $ logDebug $ "Decoding yaml at: " <> T.pack actualYaml
|
||||
|
||||
liftE
|
||||
. onE_ (onError actualYaml)
|
||||
. lEM' @_ @_ @'[JSONError] (\(displayException -> e) -> JSONDecodeError $ unlines [e, "Consider removing " <> actualYaml <> " manually."])
|
||||
. liftIO
|
||||
. Y.decodeFileEither
|
||||
$ actualYaml
|
||||
where
|
||||
-- On error, remove the etags file and set access time to 0. This should ensure the next invocation
|
||||
-- may re-download and succeed.
|
||||
onError :: (MonadReader env m, HasLog env, MonadMask m, MonadCatch m, MonadIO m) => FilePath -> m ()
|
||||
onError fp = do
|
||||
let efp = etagsFile fp
|
||||
handleIO (\e -> logWarn $ "Couldn't remove file " <> T.pack efp <> ", error was: " <> T.pack (displayException e))
|
||||
(hideError doesNotExistErrorType $ rmFile efp)
|
||||
liftIO $ hideError doesNotExistErrorType $ setAccessTime fp (posixSecondsToUTCTime (fromIntegral @Int 0))
|
||||
|
||||
|
||||
getDownloadInfo :: ( MonadReader env m
|
||||
, HasPlatformReq env
|
||||
@@ -276,8 +382,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 =
|
||||
@@ -298,7 +417,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
|
||||
@@ -307,6 +426,7 @@ getDownloadInfo t v = do
|
||||
)
|
||||
|
||||
|
||||
|
||||
-- | Tries to download from the given http or https url
|
||||
-- and saves the result in continuous memory into a file.
|
||||
-- If the filename is not provided, then we:
|
||||
@@ -330,20 +450,21 @@ download :: ( MonadReader env m
|
||||
-> Maybe FilePath -- ^ optional filename
|
||||
-> Bool -- ^ whether to read an write etags
|
||||
-> Excepts '[DigestError, ContentLengthError, DownloadFailed, GPGError] m FilePath
|
||||
download uri gpgUri eDigest eCSize dest mfn etags
|
||||
download rawUri gpgUri eDigest eCSize dest mfn etags
|
||||
| scheme == "https" = liftE dl
|
||||
| scheme == "http" = liftE dl
|
||||
| scheme == "file" = do
|
||||
let destFile' = T.unpack . decUTF8Safe $ view pathL' uri
|
||||
let destFile' = T.unpack . decUTF8Safe $ view pathL' rawUri
|
||||
lift $ logDebug $ "using local file: " <> T.pack destFile'
|
||||
forM_ eCSize (liftE . flip checkCSize destFile')
|
||||
forM_ eDigest (liftE . flip checkDigest destFile')
|
||||
pure destFile'
|
||||
| otherwise = throwE $ DownloadFailed (variantFromValue UnsupportedScheme)
|
||||
|
||||
where
|
||||
scheme = view (uriSchemeL' % schemeBSL') uri
|
||||
scheme = view (uriSchemeL' % schemeBSL') rawUri
|
||||
dl = do
|
||||
Settings{ mirrors } <- lift getSettings
|
||||
let uri = applyMirrors mirrors rawUri
|
||||
baseDestFile <- liftE . reThrowAll @_ @_ @'[DownloadFailed] DownloadFailed $ getDestFile uri mfn
|
||||
lift $ logInfo $ "downloading: " <> (decUTF8Safe . serializeURIRef') uri <> " as file " <> T.pack baseDestFile
|
||||
|
||||
@@ -389,7 +510,7 @@ download uri gpgUri eDigest eCSize dest mfn etags
|
||||
liftE $ flip onException
|
||||
(lift $ hideError doesNotExistErrorType $ recycleFile (tmpFile gpgDestFile))
|
||||
$ catchAllE @_ @'[GPGError, ProcessError, UnsupportedScheme, DownloadFailed] @'[GPGError]
|
||||
(\e -> if gpgSetting == GPGStrict then throwE (GPGError e) else lift $ logWarn $ T.pack (prettyShow (GPGError e))
|
||||
(\e -> if gpgSetting == GPGStrict then throwE (GPGError e) else lift $ logWarn $ T.pack (prettyHFError (GPGError e))
|
||||
) $ do
|
||||
o' <- liftIO getGpgOpts
|
||||
lift $ logDebug $ "downloading: " <> (decUTF8Safe . serializeURIRef') gpgUri' <> " as file " <> T.pack gpgDestFile
|
||||
@@ -444,7 +565,6 @@ download uri gpgUri eDigest eCSize dest mfn etags
|
||||
liftE $ lEM @_ @'[ProcessError] $ exec "curl"
|
||||
(o' ++ (if etags then ["--dump-header", dh] else [])
|
||||
++ maybe [] (\t -> ["-H", "If-None-Match: " <> T.unpack t]) metag
|
||||
++ maybe [] (\s -> ["--max-file-size", show s]) eCSize
|
||||
++ ["-fL", "-o", destFileTemp, T.unpack uri']) Nothing Nothing
|
||||
headers <- liftIO $ T.readFile dh
|
||||
|
||||
@@ -484,7 +604,10 @@ download uri gpgUri eDigest eCSize dest mfn etags
|
||||
, MonadMask m
|
||||
, MonadIO m
|
||||
)
|
||||
=> [String] -> FilePath -> URI -> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
|
||||
=> [String]
|
||||
-> FilePath
|
||||
-> URI
|
||||
-> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
|
||||
wgetEtagsDL o' destFile (decUTF8Safe . serializeURIRef' -> uri') = do
|
||||
let destFileTemp = tmpFile destFile
|
||||
flip finally (try @_ @SomeException $ rmFile destFileTemp) $ do
|
||||
@@ -623,7 +746,9 @@ downloadCached dli mfn = do
|
||||
True -> downloadCached' dli mfn Nothing
|
||||
False -> do
|
||||
tmp <- lift withGHCupTmpDir
|
||||
liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) (fromGHCupPath tmp) mfn False
|
||||
liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) (fromGHCupPath tmp) outputFileName False
|
||||
where
|
||||
outputFileName = mfn <|> _dlOutput dli
|
||||
|
||||
|
||||
downloadCached' :: ( MonadReader env m
|
||||
@@ -642,7 +767,7 @@ downloadCached' :: ( MonadReader env m
|
||||
downloadCached' dli mfn mDestDir = do
|
||||
Dirs { cacheDir } <- lift getDirs
|
||||
let destDir = fromMaybe (fromGHCupPath cacheDir) mDestDir
|
||||
let fn = fromMaybe ((T.unpack . decUTF8Safe) $ urlBaseName $ view (dlUri % pathL') dli) mfn
|
||||
let fn = fromMaybe ((T.unpack . decUTF8Safe) $ urlBaseName $ view (dlUri % pathL') dli) outputFileName
|
||||
let cachfile = destDir </> fn
|
||||
fileExists <- liftIO $ doesFileExist cachfile
|
||||
if
|
||||
@@ -650,7 +775,9 @@ downloadCached' dli mfn mDestDir = do
|
||||
forM_ (view dlCSize dli) $ \s -> liftE $ checkCSize s cachfile
|
||||
liftE $ checkDigest (view dlHash dli) cachfile
|
||||
pure cachfile
|
||||
| otherwise -> liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) destDir mfn False
|
||||
| otherwise -> liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) destDir outputFileName False
|
||||
where
|
||||
outputFileName = mfn <|> _dlOutput dli
|
||||
|
||||
|
||||
|
||||
@@ -729,7 +856,7 @@ getGpgOpts =
|
||||
-- "baz"
|
||||
urlBaseName :: ByteString -- ^ the url path (without scheme and host)
|
||||
-> ByteString
|
||||
urlBaseName = snd . B.breakEnd (== _slash) . urlDecode False
|
||||
urlBaseName = snd . B.breakEnd (== _slash)
|
||||
|
||||
|
||||
-- | Curl saves all intermediate connect headers as well, not just the last one, so we make an effort to take the
|
||||
@@ -747,3 +874,17 @@ getLastHeader = T.unlines . lastDef [] . filter (\x -> not (null x)) . splitOn [
|
||||
|
||||
tmpFile :: FilePath -> FilePath
|
||||
tmpFile = (<.> "tmp")
|
||||
|
||||
|
||||
applyMirrors :: DownloadMirrors -> URI -> URI
|
||||
applyMirrors (DM ms) uri@(URI { uriAuthority = Just (Authority { authorityHost = Host host }) }) =
|
||||
case M.lookup (decUTF8Safe host) ms of
|
||||
Nothing -> uri
|
||||
Just (DownloadMirror auth (Just prefix)) ->
|
||||
uri { uriAuthority = Just auth
|
||||
, uriPath = E.encodeUtf8 $ T.pack ("/" <> T.unpack prefix <> (T.unpack . decUTF8Safe . uriPath $ uri))
|
||||
}
|
||||
Just (DownloadMirror auth Nothing) ->
|
||||
uri { uriAuthority = Just auth }
|
||||
applyMirrors _ uri = uri
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import GHCup.Download.Utils
|
||||
import GHCup.Errors
|
||||
import GHCup.Types.JSON ( )
|
||||
import GHCup.Prelude
|
||||
import GHCup.Utils.URI
|
||||
|
||||
import Control.Applicative
|
||||
import Control.Exception.Safe
|
||||
@@ -28,7 +29,7 @@ import Prelude hiding ( abs
|
||||
, writeFile
|
||||
)
|
||||
import System.ProgressBar
|
||||
import URI.ByteString
|
||||
import URI.ByteString hiding (parseURI)
|
||||
|
||||
import qualified Data.ByteString as BS
|
||||
import qualified Data.Map.Strict as M
|
||||
@@ -114,7 +115,7 @@ downloadInternal = go (5 :: Int)
|
||||
| otherwise -> throwE $ HTTPStatusError scode (getHeaderMap r)
|
||||
)
|
||||
|
||||
followRedirectURL bs = case parseURI strictURIParserOptions bs of
|
||||
followRedirectURL bs = case parseURI bs of
|
||||
Right uri' -> do
|
||||
(https', host', fullPath', port') <- liftE $ uriToQuadruple uri'
|
||||
go (redirs - 1) progressBar https' host' fullPath' port' consumer setup addHeaders eCSize
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
{-# LANGUAGE StandaloneDeriving #-}
|
||||
{-# LANGUAGE TypeOperators #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
|
||||
{-|
|
||||
Module : GHCup.Errors
|
||||
@@ -20,7 +21,6 @@ module GHCup.Errors where
|
||||
|
||||
import GHCup.Types
|
||||
|
||||
import Codec.Archive
|
||||
import Control.Exception.Safe
|
||||
import Data.ByteString ( ByteString )
|
||||
import Data.CaseInsensitive ( CI )
|
||||
@@ -34,9 +34,160 @@ import URI.ByteString
|
||||
|
||||
import qualified Data.Map.Strict as M
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as E
|
||||
import qualified Data.Text.Encoding.Error as E
|
||||
import Data.Data (Proxy(..))
|
||||
import Data.Time (Day)
|
||||
|
||||
|
||||
|
||||
allHFError :: String
|
||||
allHFError = unlines allErrors
|
||||
where
|
||||
format p = "GHCup-" <> show (eBase p) <> " " <> eDesc p
|
||||
format'' e p = "GHCup-" <> show (eNum e) <> " " <> eDesc p
|
||||
format' e _ = "GHCup-" <> show (eNum e) <> " " <> prettyShow e
|
||||
format''' e _ str' = "GHCup-" <> show (eNum e) <> " " <> str'
|
||||
allErrors =
|
||||
[ "# low level errors (1 to 500)"
|
||||
, let proxy = Proxy :: Proxy NoCompatiblePlatform in format proxy
|
||||
, let proxy = Proxy :: Proxy NoDownload in format proxy
|
||||
, let proxy = Proxy :: Proxy NoUpdate in format proxy
|
||||
, let proxy = Proxy :: Proxy DistroNotFound in format proxy
|
||||
, let proxy = Proxy :: Proxy UnknownArchive in format proxy
|
||||
, let proxy = Proxy :: Proxy UnsupportedScheme in format proxy
|
||||
, let proxy = Proxy :: Proxy CopyError in format proxy
|
||||
, let proxy = Proxy :: Proxy MergeFileTreeError in format proxy
|
||||
, let proxy = Proxy :: Proxy TagNotFound in format proxy
|
||||
, let proxy = Proxy :: Proxy DayNotFound in format proxy
|
||||
, let proxy = Proxy :: Proxy NextVerNotFound in format proxy
|
||||
, let proxy = Proxy :: Proxy AlreadyInstalled in format proxy
|
||||
, let proxy = Proxy :: Proxy DirNotEmpty in format proxy
|
||||
, let proxy = Proxy :: Proxy NotInstalled in format proxy
|
||||
, let proxy = Proxy :: Proxy UninstallFailed in format proxy
|
||||
, let proxy = Proxy :: Proxy NotFoundInPATH in format proxy
|
||||
, let proxy = Proxy :: Proxy JSONError in format proxy
|
||||
, let proxy = Proxy :: Proxy FileDoesNotExistError in format proxy
|
||||
, let proxy = Proxy :: Proxy FileAlreadyExistsError in format proxy
|
||||
, let proxy = Proxy :: Proxy TarDirDoesNotExist in format proxy
|
||||
, let proxy = Proxy :: Proxy DigestError in format proxy
|
||||
, let proxy = Proxy :: Proxy GPGError in format proxy
|
||||
, let proxy = Proxy :: Proxy HTTPStatusError in format proxy
|
||||
, let proxy = Proxy :: Proxy MalformedHeaders in format proxy
|
||||
, let proxy = Proxy :: Proxy HTTPNotModified in format proxy
|
||||
, let proxy = Proxy :: Proxy NoLocationHeader in format proxy
|
||||
, let proxy = Proxy :: Proxy TooManyRedirs in format proxy
|
||||
, let proxy = Proxy :: Proxy PatchFailed in format proxy
|
||||
, let proxy = Proxy :: Proxy NoToolRequirements in format proxy
|
||||
, let proxy = Proxy :: Proxy InvalidBuildConfig in format proxy
|
||||
, let proxy = Proxy :: Proxy NoToolVersionSet in format proxy
|
||||
, let proxy = Proxy :: Proxy NoNetwork in format proxy
|
||||
, let proxy = Proxy :: Proxy HadrianNotFound in format proxy
|
||||
, let proxy = Proxy :: Proxy ToolShadowed in format proxy
|
||||
, let proxy = Proxy :: Proxy ContentLengthError in format proxy
|
||||
, let proxy = Proxy :: Proxy DuplicateReleaseChannel in format proxy
|
||||
, let proxy = Proxy :: Proxy UnsupportedSetupCombo in format proxy
|
||||
, ""
|
||||
, "# high level errors (4000+)"
|
||||
, let proxy = Proxy :: Proxy DownloadFailed in format proxy
|
||||
, let proxy = Proxy :: Proxy InstallSetError in format proxy
|
||||
, let proxy = Proxy :: Proxy TestFailed in format proxy
|
||||
, let proxy = Proxy :: Proxy BuildFailed in format proxy
|
||||
, let proxy = Proxy :: Proxy GHCupSetError in format proxy
|
||||
, ""
|
||||
, "# true exceptions (500+)"
|
||||
, let proxy = Proxy :: Proxy ParseError in format proxy
|
||||
, let proxy = Proxy :: Proxy UnexpectedListLength in format proxy
|
||||
, let proxy = Proxy :: Proxy NoUrlBase in format proxy
|
||||
, let proxy = Proxy :: Proxy DigestMissing in format proxy
|
||||
, ""
|
||||
, "# orphans (800+)"
|
||||
, let proxy = Proxy :: Proxy URIParseError in format proxy
|
||||
, let proxy = Proxy :: Proxy URIParseError
|
||||
e = MalformedScheme MissingColon
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy URIParseError
|
||||
e = MalformedUserInfo
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy URIParseError
|
||||
e = MalformedQuery
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy URIParseError
|
||||
e = MalformedFragment
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy URIParseError
|
||||
e = MalformedHost
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy URIParseError
|
||||
e = MalformedPort
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy URIParseError
|
||||
e = MalformedPath
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy URIParseError
|
||||
e = OtherError ""
|
||||
in format'' e proxy
|
||||
, let proxy = Proxy :: Proxy ArchiveResult in format proxy
|
||||
, let proxy = Proxy :: Proxy ArchiveResult
|
||||
e = ArchiveFatal
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy ArchiveResult
|
||||
e = ArchiveFailed
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy ArchiveResult
|
||||
e = ArchiveWarn
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy ArchiveResult
|
||||
e = ArchiveRetry
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy ArchiveResult
|
||||
e = ArchiveOk
|
||||
in format' e proxy
|
||||
, let proxy = Proxy :: Proxy ArchiveResult
|
||||
e = ArchiveEOF
|
||||
in format' e proxy
|
||||
|
||||
, let proxy = Proxy :: Proxy ProcessError in format proxy
|
||||
, let proxy = Proxy :: Proxy ProcessError
|
||||
e = NonZeroExit 0 "" []
|
||||
in format''' e proxy "A process returned a non-zero exit code."
|
||||
, let proxy = Proxy :: Proxy ProcessError
|
||||
e = PTerminated "" []
|
||||
in format''' e proxy "A process terminated prematurely."
|
||||
, let proxy = Proxy :: Proxy ProcessError
|
||||
e = PStopped "" []
|
||||
in format''' e proxy "A process stopped prematurely."
|
||||
, let proxy = Proxy :: Proxy ProcessError
|
||||
e = NoSuchPid "" []
|
||||
in format''' e proxy "Could not find PID for this process."
|
||||
]
|
||||
|
||||
|
||||
prettyHFError :: (Pretty e, HFErrorProject e) => e -> String
|
||||
prettyHFError e =
|
||||
let errorCode = "GHCup-" <> padIntAndShow (eNum e)
|
||||
in ("[" <> linkEscapeCode errorCode (hfErrorLink errorCode) <> "] ") <> prettyShow e
|
||||
where
|
||||
hfErrorLink errorCode = "https://errors.haskell.org/messages/" <> errorCode
|
||||
padIntAndShow i
|
||||
| i < 10 = "0000" <> show i
|
||||
| i < 100 = "000" <> show i
|
||||
| i < 1000 = "00" <> show i
|
||||
| i < 10000 = "0" <> show i
|
||||
| otherwise = show i
|
||||
|
||||
class HFErrorProject a where
|
||||
eNum :: a -> Int
|
||||
eNum _ = eBase (Proxy :: Proxy a)
|
||||
|
||||
eBase :: Proxy a -> Int
|
||||
|
||||
eDesc :: Proxy a -> String
|
||||
|
||||
linkEscapeCode :: String -> String -> String
|
||||
linkEscapeCode linkText link = "\ESC]8;;" <> link <> "\ESC\\" <> linkText <> "\ESC]8;;\ESC\\"
|
||||
|
||||
|
||||
------------------------
|
||||
--[ Low-level errors ]--
|
||||
------------------------
|
||||
@@ -51,20 +202,46 @@ instance Pretty NoCompatiblePlatform where
|
||||
pPrint (NoCompatiblePlatform str') =
|
||||
text ("Could not find a compatible platform. Got: " ++ str')
|
||||
|
||||
instance HFErrorProject NoCompatiblePlatform where
|
||||
eBase _ = 1
|
||||
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)
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoDownload where
|
||||
pPrint NoDownload =
|
||||
text "Unable to find a download for the requested version/distro."
|
||||
pPrint (NoDownload tver@(GHCTargetVersion mtarget vv) tool mpfreq) =
|
||||
let helperMsg
|
||||
| (Just target) <- mtarget
|
||||
, target `elem` (T.pack . prettyShow <$> enumFromTo (minBound :: Tool) (maxBound :: Tool)) =
|
||||
"\nPerhaps you meant: 'ghcup <command> "
|
||||
<> T.unpack target
|
||||
<> " "
|
||||
<> T.unpack (prettyVer vv)
|
||||
<> "'"
|
||||
| otherwise = ""
|
||||
in text $ "Unable to find a download for "
|
||||
<> show tool
|
||||
<> " version "
|
||||
<> "'" <> T.unpack (tVerToText tver) <> "'"
|
||||
<> maybe "" (\pfreq -> " on detected platform " <> pfReqToString pfreq) mpfreq
|
||||
<> helperMsg
|
||||
|
||||
instance HFErrorProject NoDownload where
|
||||
eBase _ = 10
|
||||
eDesc _ = "Unable to find a download for the requested version/distro."
|
||||
|
||||
-- | No update available or necessary.
|
||||
data NoUpdate = NoUpdate
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoUpdate where
|
||||
pPrint NoUpdate = text "No update available or necessary."
|
||||
pPrint NoUpdate = text (eDesc (Proxy :: Proxy NoUpdate))
|
||||
|
||||
instance HFErrorProject NoUpdate where
|
||||
eBase _ = 20
|
||||
eDesc _ = "No update available or necessary."
|
||||
|
||||
-- | The Architecture is unknown and unsupported.
|
||||
data NoCompatibleArch = NoCompatibleArch String
|
||||
@@ -74,13 +251,21 @@ instance Pretty NoCompatibleArch where
|
||||
pPrint (NoCompatibleArch arch) =
|
||||
text ("The Architecture is unknown or unsupported. Got: " ++ arch)
|
||||
|
||||
instance HFErrorProject NoCompatibleArch where
|
||||
eBase _ = 30
|
||||
eDesc _ = "The Architecture is unknown and unsupported"
|
||||
|
||||
-- | Unable to figure out the distribution of the host.
|
||||
data DistroNotFound = DistroNotFound
|
||||
deriving Show
|
||||
|
||||
instance Pretty DistroNotFound where
|
||||
pPrint DistroNotFound =
|
||||
text "Unable to figure out the distribution of the host."
|
||||
text (eDesc (Proxy :: Proxy DistroNotFound))
|
||||
|
||||
instance HFErrorProject DistroNotFound where
|
||||
eBase _ = 40
|
||||
eDesc _ = "Unable to figure out the distribution of the host"
|
||||
|
||||
-- | The archive format is unknown. We don't know how to extract it.
|
||||
data UnknownArchive = UnknownArchive FilePath
|
||||
@@ -90,12 +275,21 @@ instance Pretty UnknownArchive where
|
||||
pPrint (UnknownArchive file) =
|
||||
text $ "The archive format is unknown. We don't know how to extract the file " <> file
|
||||
|
||||
instance HFErrorProject UnknownArchive where
|
||||
eBase _ = 50
|
||||
eDesc _ = "The archive format is unknown. We don't know how to extract it."
|
||||
|
||||
-- | The scheme is not supported (such as ftp).
|
||||
data UnsupportedScheme = UnsupportedScheme
|
||||
deriving Show
|
||||
|
||||
instance Pretty UnsupportedScheme where
|
||||
pPrint UnsupportedScheme = text "The scheme is not supported (such as ftp)."
|
||||
pPrint UnsupportedScheme =
|
||||
text (eDesc (Proxy :: Proxy UnsupportedScheme))
|
||||
|
||||
instance HFErrorProject UnsupportedScheme where
|
||||
eBase _ = 60
|
||||
eDesc _ = "The scheme is not supported (such as ftp)."
|
||||
|
||||
-- | Unable to copy a file.
|
||||
data CopyError = CopyError String
|
||||
@@ -105,6 +299,10 @@ instance Pretty CopyError where
|
||||
pPrint (CopyError reason) =
|
||||
text ("Unable to copy a file. Reason was: " ++ reason)
|
||||
|
||||
instance HFErrorProject CopyError where
|
||||
eBase _ = 70
|
||||
eDesc _ = "Unable to copy a file."
|
||||
|
||||
-- | Unable to merge file trees.
|
||||
data MergeFileTreeError = MergeFileTreeError IOException FilePath FilePath
|
||||
deriving Show
|
||||
@@ -114,6 +312,10 @@ instance Pretty MergeFileTreeError where
|
||||
text "Failed to merge file tree from" <+> text from <+> text "to" <+> text to <+> text "\nexception was:" <+> text (displayException e)
|
||||
<+> text "\n...you may need to delete" <+> text to <+> text "manually. Make sure it's gone."
|
||||
|
||||
instance HFErrorProject MergeFileTreeError where
|
||||
eBase _ = 80
|
||||
eDesc _ = "Unable to merge file trees during installation"
|
||||
|
||||
-- | Unable to find a tag of a tool.
|
||||
data TagNotFound = TagNotFound Tag Tool
|
||||
deriving Show
|
||||
@@ -122,6 +324,25 @@ instance Pretty TagNotFound where
|
||||
pPrint (TagNotFound tag tool) =
|
||||
text "Unable to find tag" <+> pPrint tag <+> text "of tool" <+> pPrint tool
|
||||
|
||||
instance HFErrorProject TagNotFound where
|
||||
eBase _ = 90
|
||||
eDesc _ = "Unable to find a tag of a tool"
|
||||
|
||||
-- | Unable to find a release day of a tool
|
||||
data DayNotFound = DayNotFound Day Tool (Maybe Day)
|
||||
deriving Show
|
||||
|
||||
instance Pretty DayNotFound where
|
||||
pPrint (DayNotFound day tool Nothing) =
|
||||
text "Unable to find release date" <+> text (show day) <+> text "of tool" <+> pPrint tool
|
||||
pPrint (DayNotFound day tool (Just alternateDay)) =
|
||||
text "Unable to find release date" <+> text (show day) <+> text "of tool" <+> pPrint tool <+>
|
||||
text "but found an alternative date" <+> text (show alternateDay)
|
||||
|
||||
instance HFErrorProject DayNotFound where
|
||||
eBase _ = 95
|
||||
eDesc _ = "Unable to find a release date of a tool"
|
||||
|
||||
-- | Unable to find the next version of a tool (the one after the currently
|
||||
-- set one).
|
||||
data NextVerNotFound = NextVerNotFound Tool
|
||||
@@ -131,6 +352,10 @@ instance Pretty NextVerNotFound where
|
||||
pPrint (NextVerNotFound tool) =
|
||||
text "Unable to find next (the one after the currently set one) version of tool" <+> pPrint tool
|
||||
|
||||
instance HFErrorProject NextVerNotFound where
|
||||
eBase _ = 100
|
||||
eDesc _ = "Unable to find the next version of a tool (the one after the currently set one)"
|
||||
|
||||
-- | The tool (such as GHC) is already installed with that version.
|
||||
data AlreadyInstalled = AlreadyInstalled Tool Version
|
||||
deriving Show
|
||||
@@ -140,6 +365,9 @@ instance Pretty AlreadyInstalled where
|
||||
(pPrint tool <> text "-" <> pPrint ver') <+> text "is already installed;"
|
||||
<+> text "if you really want to reinstall it, you may want to run 'ghcup install" <+> pPrint tool <+> text "--force" <+> (pPrint ver' <> text "'")
|
||||
|
||||
instance HFErrorProject AlreadyInstalled where
|
||||
eBase _ = 110
|
||||
eDesc _ = "The tool (such as GHC) is already installed with that version"
|
||||
|
||||
-- | The Directory is supposed to be empty, but wasn't.
|
||||
data DirNotEmpty = DirNotEmpty {path :: FilePath}
|
||||
@@ -149,6 +377,10 @@ instance Pretty DirNotEmpty where
|
||||
pPrint (DirNotEmpty path) = do
|
||||
text $ "The directory was expected to be empty, but isn't: " <> path
|
||||
|
||||
instance HFErrorProject DirNotEmpty where
|
||||
eBase _ = 120
|
||||
eDesc _ = "The Directory is supposed to be empty, but wasn't"
|
||||
|
||||
-- | The tool is not installed. Some operations rely on a tool
|
||||
-- to be installed (such as setting the current GHC version).
|
||||
data NotInstalled = NotInstalled Tool GHCTargetVersion
|
||||
@@ -156,7 +388,11 @@ data NotInstalled = NotInstalled Tool GHCTargetVersion
|
||||
|
||||
instance Pretty NotInstalled where
|
||||
pPrint (NotInstalled tool ver) =
|
||||
text "The version" <+> pPrint ver <+> text "of the tool" <+> pPrint tool <+> text "is not installed."
|
||||
text "The version" <+> (text "'" <> pPrint ver <> text "'") <+> text "of the tool" <+> pPrint tool <+> text "is not installed."
|
||||
|
||||
instance HFErrorProject NotInstalled where
|
||||
eBase _ = 130
|
||||
eDesc _ = "The required tool is not installed"
|
||||
|
||||
data UninstallFailed = UninstallFailed FilePath [FilePath]
|
||||
deriving Show
|
||||
@@ -165,6 +401,10 @@ instance Pretty UninstallFailed where
|
||||
pPrint (UninstallFailed dir files) =
|
||||
text "The following files survived uninstallation: " <+> pPrint files <+> text "...consider removing" <+> pPrint dir <+> text "manually."
|
||||
|
||||
instance HFErrorProject UninstallFailed where
|
||||
eBase _ = 140
|
||||
eDesc _ = "Uninstallation failed with leftover files"
|
||||
|
||||
-- | An executable was expected to be in PATH, but was not found.
|
||||
data NotFoundInPATH = NotFoundInPATH FilePath
|
||||
deriving Show
|
||||
@@ -175,6 +415,10 @@ instance Pretty NotFoundInPATH where
|
||||
pPrint (NotFoundInPATH exe) =
|
||||
text $ "The exe " <> exe <> " was not found in PATH."
|
||||
|
||||
instance HFErrorProject NotFoundInPATH where
|
||||
eBase _ = 150
|
||||
eDesc _ = "An executable was expected to be in PATH, but was not found"
|
||||
|
||||
-- | JSON decoding failed.
|
||||
data JSONError = JSONDecodeError String
|
||||
deriving Show
|
||||
@@ -183,6 +427,10 @@ instance Pretty JSONError where
|
||||
pPrint (JSONDecodeError err) =
|
||||
text $ "JSON decoding failed with: " <> err
|
||||
|
||||
instance HFErrorProject JSONError where
|
||||
eBase _ = 160
|
||||
eDesc _ = "JSON decoding failed"
|
||||
|
||||
-- | A file that is supposed to exist does not exist
|
||||
-- (e.g. when we use file scheme to "download" something).
|
||||
data FileDoesNotExistError = FileDoesNotExistError FilePath
|
||||
@@ -192,6 +440,10 @@ instance Pretty FileDoesNotExistError where
|
||||
pPrint (FileDoesNotExistError file) =
|
||||
text $ "File " <> file <> " does not exist."
|
||||
|
||||
instance HFErrorProject FileDoesNotExistError where
|
||||
eBase _ = 170
|
||||
eDesc _ = "A file that is supposed to exist does not exist (oops)"
|
||||
|
||||
-- | The file already exists
|
||||
-- (e.g. when we use isolated installs with the same path).
|
||||
-- (e.g. This is done to prevent any overwriting)
|
||||
@@ -202,6 +454,10 @@ instance Pretty FileAlreadyExistsError where
|
||||
pPrint (FileAlreadyExistsError file) =
|
||||
text $ "File " <> file <> " Already exists."
|
||||
|
||||
instance HFErrorProject FileAlreadyExistsError where
|
||||
eBase _ = 180
|
||||
eDesc _ = "A file already exists that wasn't expected to exist"
|
||||
|
||||
data TarDirDoesNotExist = TarDirDoesNotExist TarDir
|
||||
deriving Show
|
||||
|
||||
@@ -209,6 +465,10 @@ instance Pretty TarDirDoesNotExist where
|
||||
pPrint (TarDirDoesNotExist dir) =
|
||||
text "Tar directory does not exist:" <+> pPrint dir
|
||||
|
||||
instance HFErrorProject TarDirDoesNotExist where
|
||||
eBase _ = 190
|
||||
eDesc _ = "The tar directory (e.g. inside an archive) does not exist"
|
||||
|
||||
-- | File digest verification failed.
|
||||
data DigestError = DigestError FilePath Text Text
|
||||
deriving Show
|
||||
@@ -219,6 +479,175 @@ instance Pretty DigestError where
|
||||
<+> text (T.unpack expectedDigest) <+> text "but got" <+> pPrint currentDigest <+> text
|
||||
"\nConsider removing the file in case it's cached and try again."
|
||||
|
||||
instance HFErrorProject DigestError where
|
||||
eBase _ = 200
|
||||
eDesc _ = "File digest verification failed"
|
||||
|
||||
-- | File PGP verification failed.
|
||||
data GPGError = forall xs . (ToVariantMaybe DownloadFailed xs, PopVariant DownloadFailed xs, Show (V xs), Pretty (V xs)) => GPGError (V xs)
|
||||
|
||||
deriving instance Show GPGError
|
||||
|
||||
instance Pretty GPGError where
|
||||
pPrint (GPGError reason) = text "GPG verify failed:" <+> pPrint reason
|
||||
|
||||
instance HFErrorProject GPGError where
|
||||
eBase _ = 210
|
||||
eDesc _ = "File PGP verification failed"
|
||||
|
||||
-- | Unexpected HTTP status.
|
||||
data HTTPStatusError = HTTPStatusError Int (M.Map (CI ByteString) ByteString)
|
||||
deriving Show
|
||||
|
||||
instance Pretty HTTPStatusError where
|
||||
pPrint (HTTPStatusError status _) =
|
||||
text "Unexpected HTTP status:" <+> pPrint status
|
||||
|
||||
instance HFErrorProject HTTPStatusError where
|
||||
eBase _ = 220
|
||||
eDesc _ = "Unexpected HTTP status error (e.g. during downloads)"
|
||||
|
||||
-- | Malformed headers.
|
||||
data MalformedHeaders = MalformedHeaders Text
|
||||
deriving Show
|
||||
|
||||
instance Pretty MalformedHeaders where
|
||||
pPrint (MalformedHeaders h) =
|
||||
text "Headers are malformed: " <+> pPrint h
|
||||
|
||||
instance HFErrorProject MalformedHeaders where
|
||||
eBase _ = 230
|
||||
eDesc _ = "Malformed headers during download"
|
||||
|
||||
-- | Unexpected HTTP status.
|
||||
data HTTPNotModified = HTTPNotModified Text
|
||||
deriving Show
|
||||
|
||||
instance Pretty HTTPNotModified where
|
||||
pPrint (HTTPNotModified etag) =
|
||||
text "Remote resource not modified, etag was:" <+> pPrint etag
|
||||
|
||||
instance HFErrorProject HTTPNotModified where
|
||||
eBase _ = 240
|
||||
eDesc _ = "Not modified HTTP status error (e.g. during downloads)."
|
||||
|
||||
-- | The 'Location' header was expected during a 3xx redirect, but not found.
|
||||
data NoLocationHeader = NoLocationHeader
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoLocationHeader where
|
||||
pPrint NoLocationHeader =
|
||||
text (eDesc (Proxy :: Proxy NoLocationHeader))
|
||||
|
||||
instance HFErrorProject NoLocationHeader where
|
||||
eBase _ = 250
|
||||
eDesc _ = "The 'Location' header was expected during a 3xx redirect, but not found."
|
||||
|
||||
-- | Too many redirects.
|
||||
data TooManyRedirs = TooManyRedirs
|
||||
deriving Show
|
||||
|
||||
instance Pretty TooManyRedirs where
|
||||
pPrint TooManyRedirs =
|
||||
text (eDesc (Proxy :: Proxy TooManyRedirs))
|
||||
|
||||
instance HFErrorProject TooManyRedirs where
|
||||
eBase _ = 260
|
||||
eDesc _ = "Too many redirections."
|
||||
|
||||
-- | A patch could not be applied.
|
||||
data PatchFailed = PatchFailed
|
||||
deriving Show
|
||||
|
||||
instance Pretty PatchFailed where
|
||||
pPrint PatchFailed =
|
||||
text (eDesc (Proxy :: Proxy PatchFailed))
|
||||
|
||||
instance HFErrorProject PatchFailed where
|
||||
eBase _ = 270
|
||||
eDesc _ = "A patch could not be applied."
|
||||
|
||||
-- | The tool requirements could not be found.
|
||||
data NoToolRequirements = NoToolRequirements
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoToolRequirements where
|
||||
pPrint NoToolRequirements =
|
||||
text (eDesc (Proxy :: Proxy NoToolRequirements))
|
||||
|
||||
instance HFErrorProject NoToolRequirements where
|
||||
eBase _ = 280
|
||||
eDesc _ = "The Tool requirements could not be found."
|
||||
|
||||
data InvalidBuildConfig = InvalidBuildConfig Text
|
||||
deriving Show
|
||||
|
||||
instance Pretty InvalidBuildConfig where
|
||||
pPrint (InvalidBuildConfig reason) =
|
||||
text "The build config is invalid. Reason was:" <+> pPrint reason
|
||||
|
||||
instance HFErrorProject InvalidBuildConfig where
|
||||
eBase _ = 290
|
||||
eDesc _ = "The build config is invalid."
|
||||
|
||||
data NoToolVersionSet = NoToolVersionSet Tool
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoToolVersionSet where
|
||||
pPrint (NoToolVersionSet tool) =
|
||||
text "No version is set for tool" <+> pPrint tool <+> text "."
|
||||
|
||||
instance HFErrorProject NoToolVersionSet where
|
||||
eBase _ = 300
|
||||
eDesc _ = "No version is set for tool (but was expected)."
|
||||
|
||||
data NoNetwork = NoNetwork
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoNetwork where
|
||||
pPrint NoNetwork =
|
||||
text (eDesc (Proxy :: Proxy NoNetwork))
|
||||
|
||||
instance HFErrorProject NoNetwork where
|
||||
eBase _ = 310
|
||||
eDesc _ = "A download was required or requested, but '--offline' was specified."
|
||||
|
||||
data HadrianNotFound = HadrianNotFound
|
||||
deriving Show
|
||||
|
||||
instance Pretty HadrianNotFound where
|
||||
pPrint HadrianNotFound =
|
||||
text (eDesc (Proxy :: Proxy HadrianNotFound))
|
||||
|
||||
instance HFErrorProject HadrianNotFound where
|
||||
eBase _ = 320
|
||||
eDesc _ = "Could not find Hadrian build files. Does this GHC version support Hadrian builds?"
|
||||
|
||||
data ToolShadowed = ToolShadowed
|
||||
Tool
|
||||
FilePath -- shadow binary
|
||||
FilePath -- upgraded binary
|
||||
Version -- upgraded version
|
||||
deriving Show
|
||||
|
||||
instance Pretty ToolShadowed where
|
||||
pPrint (ToolShadowed tool sh up _) =
|
||||
text (prettyShow tool
|
||||
<> " is shadowed by "
|
||||
<> sh
|
||||
<> ".\nThe upgrade will not be in effect, unless you remove "
|
||||
<> sh
|
||||
<> "\nor make sure "
|
||||
<> takeDirectory up
|
||||
<> " comes before "
|
||||
<> takeDirectory sh
|
||||
<> " in PATH."
|
||||
)
|
||||
|
||||
instance HFErrorProject ToolShadowed where
|
||||
eBase _ = 330
|
||||
eDesc _ = "A tool is shadowed in PATH."
|
||||
|
||||
-- | File content length verification failed.
|
||||
data ContentLengthError = ContentLengthError (Maybe FilePath) (Maybe Integer) Integer
|
||||
deriving Show
|
||||
@@ -242,125 +671,40 @@ instance Pretty ContentLengthError where
|
||||
|
||||
instance Exception ContentLengthError
|
||||
|
||||
-- | File digest verification failed.
|
||||
data GPGError = forall xs . (ToVariantMaybe DownloadFailed xs, PopVariant DownloadFailed xs, Show (V xs), Pretty (V xs)) => GPGError (V xs)
|
||||
instance HFErrorProject ContentLengthError where
|
||||
eBase _ = 340
|
||||
eDesc _ = "File content length verification failed"
|
||||
|
||||
deriving instance Show GPGError
|
||||
|
||||
instance Pretty GPGError where
|
||||
pPrint (GPGError reason) = text "GPG verify failed:" <+> pPrint reason
|
||||
|
||||
-- | Unexpected HTTP status.
|
||||
data HTTPStatusError = HTTPStatusError Int (M.Map (CI ByteString) ByteString)
|
||||
data DuplicateReleaseChannel = DuplicateReleaseChannel NewURLSource
|
||||
deriving Show
|
||||
|
||||
instance Pretty HTTPStatusError where
|
||||
pPrint (HTTPStatusError status _) =
|
||||
text "Unexpected HTTP status:" <+> pPrint status
|
||||
instance HFErrorProject DuplicateReleaseChannel where
|
||||
eBase _ = 350
|
||||
eDesc _ = "Duplicate release channel detected when adding new source.\nGiving up. You can use '--force' to remove and append the duplicate source (this may change order/semantics)."
|
||||
|
||||
-- | Malformed headers.
|
||||
data MalformedHeaders = MalformedHeaders Text
|
||||
instance Pretty DuplicateReleaseChannel where
|
||||
pPrint (DuplicateReleaseChannel source) =
|
||||
text $ "Duplicate release channel detected when adding: \n "
|
||||
<> show source
|
||||
<> "\nGiving up. You can use '--force' to remove and append the duplicate source (this may change order/semantics)."
|
||||
|
||||
data UnsupportedSetupCombo = UnsupportedSetupCombo Architecture Platform
|
||||
deriving Show
|
||||
|
||||
instance Pretty MalformedHeaders where
|
||||
pPrint (MalformedHeaders h) =
|
||||
text "Headers are malformed: " <+> pPrint h
|
||||
instance Pretty UnsupportedSetupCombo where
|
||||
pPrint (UnsupportedSetupCombo arch plat) =
|
||||
text "Could not find a compatible setup combo for:" <+> pPrint arch <+> pPrint plat
|
||||
|
||||
-- | Unexpected HTTP status.
|
||||
data HTTPNotModified = HTTPNotModified Text
|
||||
deriving Show
|
||||
|
||||
instance Pretty HTTPNotModified where
|
||||
pPrint (HTTPNotModified etag) =
|
||||
text "Remote resource not modifed, etag was:" <+> pPrint etag
|
||||
|
||||
-- | The 'Location' header was expected during a 3xx redirect, but not found.
|
||||
data NoLocationHeader = NoLocationHeader
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoLocationHeader where
|
||||
pPrint NoLocationHeader =
|
||||
text "The 'Location' header was expected during a 3xx redirect, but not found."
|
||||
|
||||
-- | Too many redirects.
|
||||
data TooManyRedirs = TooManyRedirs
|
||||
deriving Show
|
||||
|
||||
instance Pretty TooManyRedirs where
|
||||
pPrint TooManyRedirs =
|
||||
text "Too many redirections."
|
||||
|
||||
-- | A patch could not be applied.
|
||||
data PatchFailed = PatchFailed
|
||||
deriving Show
|
||||
|
||||
instance Pretty PatchFailed where
|
||||
pPrint PatchFailed =
|
||||
text "A patch could not be applied."
|
||||
|
||||
-- | The tool requirements could not be found.
|
||||
data NoToolRequirements = NoToolRequirements
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoToolRequirements where
|
||||
pPrint NoToolRequirements =
|
||||
text "The Tool requirements could not be found."
|
||||
|
||||
data InvalidBuildConfig = InvalidBuildConfig Text
|
||||
deriving Show
|
||||
|
||||
instance Pretty InvalidBuildConfig where
|
||||
pPrint (InvalidBuildConfig reason) =
|
||||
text "The build config is invalid. Reason was:" <+> pPrint reason
|
||||
|
||||
data NoToolVersionSet = NoToolVersionSet Tool
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoToolVersionSet where
|
||||
pPrint (NoToolVersionSet tool) =
|
||||
text "No version is set for tool" <+> pPrint tool <+> text "."
|
||||
|
||||
data NoNetwork = NoNetwork
|
||||
deriving Show
|
||||
|
||||
instance Pretty NoNetwork where
|
||||
pPrint NoNetwork =
|
||||
text "A download was required or requested, but '--offline' was specified."
|
||||
|
||||
data HadrianNotFound = HadrianNotFound
|
||||
deriving Show
|
||||
|
||||
instance Pretty HadrianNotFound where
|
||||
pPrint HadrianNotFound =
|
||||
text "Could not find Hadrian build files. Does this GHC version support Hadrian builds?"
|
||||
|
||||
data ToolShadowed = ToolShadowed
|
||||
Tool
|
||||
FilePath -- shadow binary
|
||||
FilePath -- upgraded binary
|
||||
Version -- upgraded version
|
||||
deriving Show
|
||||
|
||||
instance Pretty ToolShadowed where
|
||||
pPrint (ToolShadowed tool sh up _) =
|
||||
text (prettyShow tool
|
||||
<> " is shadowed by "
|
||||
<> sh
|
||||
<> ".\nThe upgrade will not be in effect, unless you remove "
|
||||
<> sh
|
||||
<> "\nor make sure "
|
||||
<> takeDirectory up
|
||||
<> " comes before "
|
||||
<> takeDirectory sh
|
||||
<> " in PATH."
|
||||
)
|
||||
instance HFErrorProject UnsupportedSetupCombo where
|
||||
eBase _ = 360
|
||||
eDesc _ = "Could not find a compatible setup combo"
|
||||
|
||||
-------------------------
|
||||
--[ High-level errors ]--
|
||||
-------------------------
|
||||
|
||||
-- | A download failed. The underlying error is encapsulated.
|
||||
data DownloadFailed = forall xs . (ToVariantMaybe DownloadFailed xs, PopVariant DownloadFailed xs, Show (V xs), Pretty (V xs)) => DownloadFailed (V xs)
|
||||
data DownloadFailed = forall xs . (HFErrorProject (V xs), ToVariantMaybe DownloadFailed xs, PopVariant DownloadFailed xs, Show (V xs), Pretty (V xs)) => DownloadFailed (V xs)
|
||||
|
||||
instance Pretty DownloadFailed where
|
||||
pPrint (DownloadFailed reason) =
|
||||
@@ -370,20 +714,47 @@ instance Pretty DownloadFailed where
|
||||
|
||||
deriving instance Show DownloadFailed
|
||||
|
||||
data InstallSetError = forall xs1 xs2 . (Show (V xs1), Pretty (V xs1), Show (V xs2), Pretty (V xs2)) => InstallSetError (V xs1) (V xs2)
|
||||
instance HFErrorProject DownloadFailed where
|
||||
eBase _ = 5000
|
||||
eNum (DownloadFailed xs) = 5000 + eNum xs
|
||||
eDesc _ = "A download failed."
|
||||
|
||||
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
|
||||
pPrint (InstallSetError reason1 reason2) =
|
||||
text "Both installation and setting the tool failed. Install error was:"
|
||||
text "Both installation and setting the tool failed.\nInstall error was:"
|
||||
<+> pPrint reason1
|
||||
<+> text "\nSet error was:"
|
||||
<+> pPrint reason2
|
||||
|
||||
deriving instance Show InstallSetError
|
||||
|
||||
instance HFErrorProject InstallSetError where
|
||||
eBase _ = 7000
|
||||
-- will there be collisions?
|
||||
eNum (InstallSetError xs1 xs2) = 7000 + eNum xs1 + eNum xs2
|
||||
eDesc _ = "Installation or setting the tool failed."
|
||||
|
||||
|
||||
-- | A test failed.
|
||||
data TestFailed = forall es . (ToVariantMaybe TestFailed es, PopVariant TestFailed es, Pretty (V es), Show (V es), HFErrorProject (V es)) => TestFailed FilePath (V es)
|
||||
|
||||
instance Pretty TestFailed where
|
||||
pPrint (TestFailed path reason) =
|
||||
case reason of
|
||||
VMaybe (_ :: TestFailed) -> pPrint reason
|
||||
_ -> text ("The test failed. GHC test suite is fragile and non-portable. Please also check out the " <> linkEscapeCode "issue tracker" " https://gitlab.haskell.org/ghc/ghc/-/issues/?sort=updated_desc&state=opened&label_name%5B%5D=testsuite&label_name%5B%5D=packaging&first_page_size=20" <> ".\nBuild dir was:") <+> text path <+> text "\nReason was:" <+> pPrint reason
|
||||
|
||||
deriving instance Show TestFailed
|
||||
|
||||
instance HFErrorProject TestFailed where
|
||||
eBase _ = 4000
|
||||
eNum (TestFailed _ xs2) = 4000 + eNum xs2
|
||||
eDesc _ = "The test failed."
|
||||
|
||||
-- | A build failed.
|
||||
data BuildFailed = forall es . (ToVariantMaybe BuildFailed es, PopVariant BuildFailed es, Pretty (V es), Show (V es)) => BuildFailed FilePath (V es)
|
||||
data BuildFailed = forall es . (ToVariantMaybe BuildFailed es, PopVariant BuildFailed es, Pretty (V es), Show (V es), HFErrorProject (V es)) => BuildFailed FilePath (V es)
|
||||
|
||||
instance Pretty BuildFailed where
|
||||
pPrint (BuildFailed path reason) =
|
||||
@@ -393,18 +764,44 @@ instance Pretty BuildFailed where
|
||||
|
||||
deriving instance Show BuildFailed
|
||||
|
||||
instance HFErrorProject BuildFailed where
|
||||
eBase _ = 8000
|
||||
eNum (BuildFailed _ xs2) = 8000 + eNum xs2
|
||||
eDesc _ = "The build failed."
|
||||
|
||||
|
||||
-- | Setting the current GHC version failed.
|
||||
data GHCupSetError = forall es . (ToVariantMaybe GHCupSetError es, PopVariant GHCupSetError es, Show (V es), Pretty (V es)) => GHCupSetError (V es)
|
||||
data GHCupSetError = forall es . (ToVariantMaybe GHCupSetError es, PopVariant GHCupSetError es, Show (V es), Pretty (V es), HFErrorProject (V es)) => GHCupSetError (V es)
|
||||
|
||||
instance Pretty GHCupSetError where
|
||||
pPrint (GHCupSetError reason) =
|
||||
case reason of
|
||||
VMaybe (_ :: GHCupSetError) -> pPrint reason
|
||||
_ -> text "Setting the current GHC version failed:" <+> pPrint reason
|
||||
_ -> text "Setting the current version failed:" <+> pPrint reason
|
||||
|
||||
deriving instance Show GHCupSetError
|
||||
|
||||
instance HFErrorProject GHCupSetError where
|
||||
eBase _ = 9000
|
||||
eNum (GHCupSetError xs) = 9000 + eNum xs
|
||||
eDesc _ = "Setting the current version failed."
|
||||
|
||||
-- | Executing stacks platform detection failed.
|
||||
data StackPlatformDetectError = forall es . (ToVariantMaybe StackPlatformDetectError es, PopVariant StackPlatformDetectError es, Show (V es), Pretty (V es), HFErrorProject (V es)) => StackPlatformDetectError (V es)
|
||||
|
||||
instance Pretty StackPlatformDetectError where
|
||||
pPrint (StackPlatformDetectError reason) =
|
||||
case reason of
|
||||
VMaybe (_ :: StackPlatformDetectError) -> pPrint reason
|
||||
_ -> text "Running stack platform detection logic failed:" <+> pPrint reason
|
||||
|
||||
deriving instance Show StackPlatformDetectError
|
||||
|
||||
instance HFErrorProject StackPlatformDetectError where
|
||||
eBase _ = 6000
|
||||
eNum (StackPlatformDetectError xs) = 6000 + eNum xs
|
||||
eDesc _ = "Running stack platform detection logic failed."
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
--[ True Exceptions (e.g. for MonadThrow) ]--
|
||||
@@ -421,6 +818,10 @@ instance Pretty ParseError where
|
||||
|
||||
instance Exception ParseError
|
||||
|
||||
instance HFErrorProject ParseError where
|
||||
eBase _ = 500
|
||||
eDesc _ = "A parse error occurred."
|
||||
|
||||
|
||||
data UnexpectedListLength = UnexpectedListLength String
|
||||
deriving Show
|
||||
@@ -431,6 +832,10 @@ instance Pretty UnexpectedListLength where
|
||||
|
||||
instance Exception UnexpectedListLength
|
||||
|
||||
instance HFErrorProject UnexpectedListLength where
|
||||
eBase _ = 510
|
||||
eDesc _ = "A list had an unexpected length."
|
||||
|
||||
data NoUrlBase = NoUrlBase Text
|
||||
deriving Show
|
||||
|
||||
@@ -440,6 +845,22 @@ instance Pretty NoUrlBase where
|
||||
|
||||
instance Exception NoUrlBase
|
||||
|
||||
instance HFErrorProject NoUrlBase where
|
||||
eBase _ = 520
|
||||
eDesc _ = "URL does not have a base filename."
|
||||
|
||||
data DigestMissing = DigestMissing URI
|
||||
deriving Show
|
||||
|
||||
instance Pretty DigestMissing where
|
||||
pPrint (DigestMissing uri) =
|
||||
text "Digest missing for:" <+> (text . T.unpack . E.decodeUtf8With E.lenientDecode . serializeURIRef') uri
|
||||
|
||||
instance Exception DigestMissing
|
||||
|
||||
instance HFErrorProject DigestMissing where
|
||||
eBase _ = 530
|
||||
eDesc _ = "An expected digest is missing."
|
||||
|
||||
|
||||
------------------------
|
||||
@@ -459,6 +880,23 @@ instance
|
||||
Right x -> pPrint x
|
||||
Left xs -> pPrint xs
|
||||
|
||||
instance HFErrorProject (V '[]) where
|
||||
{-# INLINABLE eBase #-}
|
||||
eBase _ = undefined
|
||||
{-# INLINABLE eDesc #-}
|
||||
eDesc _ = undefined
|
||||
|
||||
instance
|
||||
( HFErrorProject x
|
||||
, HFErrorProject (V xs)
|
||||
) => HFErrorProject (V (x ': xs))
|
||||
where
|
||||
eNum v = case popVariantHead v of
|
||||
Right x -> eNum x
|
||||
Left xs -> eNum xs
|
||||
eDesc _ = undefined
|
||||
eBase _ = undefined
|
||||
|
||||
instance Pretty URIParseError where
|
||||
pPrint (MalformedScheme reason) =
|
||||
text "Failed to parse URI. Malformed scheme:" <+> text (show reason)
|
||||
@@ -477,6 +915,22 @@ instance Pretty URIParseError where
|
||||
pPrint (OtherError err) =
|
||||
text "Failed to parse URI:" <+> pPrint err
|
||||
|
||||
instance HFErrorProject URIParseError where
|
||||
eBase _ = 800
|
||||
|
||||
eNum (MalformedScheme NonAlphaLeading) = 801
|
||||
eNum (MalformedScheme InvalidChars) = 802
|
||||
eNum (MalformedScheme MissingColon) = 803
|
||||
eNum MalformedUserInfo = 804
|
||||
eNum MalformedQuery = 805
|
||||
eNum MalformedFragment = 806
|
||||
eNum MalformedHost = 807
|
||||
eNum MalformedPort = 808
|
||||
eNum MalformedPath = 809
|
||||
eNum (OtherError _) = 810
|
||||
|
||||
eDesc _ = "Failed to parse URI."
|
||||
|
||||
instance Pretty ArchiveResult where
|
||||
pPrint ArchiveFatal = text "Archive result: fatal"
|
||||
pPrint ArchiveFailed = text "Archive result: failed"
|
||||
@@ -485,5 +939,37 @@ instance Pretty ArchiveResult where
|
||||
pPrint ArchiveOk = text "Archive result: Ok"
|
||||
pPrint ArchiveEOF = text "Archive result: EOF"
|
||||
|
||||
instance HFErrorProject ArchiveResult where
|
||||
eBase _ = 820
|
||||
|
||||
eNum ArchiveFatal = 821
|
||||
eNum ArchiveFailed = 822
|
||||
eNum ArchiveWarn = 823
|
||||
eNum ArchiveRetry = 824
|
||||
eNum ArchiveOk = 825
|
||||
eNum ArchiveEOF = 826
|
||||
|
||||
eDesc _ = "Archive extraction result."
|
||||
|
||||
instance Pretty T.Text where
|
||||
pPrint = text . T.unpack
|
||||
|
||||
instance Pretty ProcessError where
|
||||
pPrint (NonZeroExit e exe args) =
|
||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "failed with exit code" <+> text (show e <> ".")
|
||||
pPrint (PTerminated exe args) =
|
||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "terminated."
|
||||
pPrint (PStopped exe args) =
|
||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "stopped."
|
||||
pPrint (NoSuchPid exe args) =
|
||||
text "Could not find PID for process running " <+> pPrint exe <+> text " with arguments " <+> text (show args) <+> text "."
|
||||
|
||||
instance HFErrorProject ProcessError where
|
||||
eBase _ = 840
|
||||
|
||||
eNum NonZeroExit{} = 841
|
||||
eNum (PTerminated _ _) = 842
|
||||
eNum (PStopped _ _) = 843
|
||||
eNum (NoSuchPid _ _) = 844
|
||||
|
||||
eDesc _ = "A process exited prematurely."
|
||||
|
||||
467
lib/GHCup/GHC.hs
467
lib/GHCup/GHC.hs
@@ -34,7 +34,6 @@ import GHCup.Prelude.String.QQ
|
||||
import GHCup.Prelude.Version.QQ
|
||||
import GHCup.Prelude.MegaParsec
|
||||
|
||||
import Codec.Archive ( ArchiveResult )
|
||||
import Control.Applicative
|
||||
import Control.Concurrent ( threadDelay )
|
||||
import Control.Exception.Safe
|
||||
@@ -74,18 +73,162 @@ import qualified Crypto.Hash.SHA256 as SHA256
|
||||
import qualified Data.ByteString.Base16 as B16
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.ByteString.Lazy as BL
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
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
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
--------------------
|
||||
--[ Tool testing ]--
|
||||
--------------------
|
||||
|
||||
|
||||
|
||||
testGHCVer :: ( MonadFail m
|
||||
, MonadMask m
|
||||
, MonadCatch m
|
||||
, MonadReader env m
|
||||
, HasDirs env
|
||||
, HasSettings env
|
||||
, HasPlatformReq env
|
||||
, HasGHCupInfo env
|
||||
, HasLog env
|
||||
, MonadResource m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> GHCTargetVersion
|
||||
-> [T.Text]
|
||||
-> Excepts
|
||||
'[ DigestError
|
||||
, ContentLengthError
|
||||
, GPGError
|
||||
, DownloadFailed
|
||||
, NoDownload
|
||||
, ArchiveResult
|
||||
, TarDirDoesNotExist
|
||||
, UnknownArchive
|
||||
, TestFailed
|
||||
]
|
||||
m
|
||||
()
|
||||
testGHCVer ver addMakeArgs = do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
|
||||
dlInfo <-
|
||||
preview (ix GHC % ix ver % viTestDL % _Just) dls
|
||||
?? NoDownload ver GHC Nothing
|
||||
|
||||
liftE $ testGHCBindist dlInfo ver addMakeArgs
|
||||
|
||||
|
||||
|
||||
testGHCBindist :: ( MonadFail m
|
||||
, MonadMask m
|
||||
, MonadCatch m
|
||||
, MonadReader env m
|
||||
, HasDirs env
|
||||
, HasSettings env
|
||||
, HasPlatformReq env
|
||||
, HasGHCupInfo env
|
||||
, HasLog env
|
||||
, MonadResource m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> DownloadInfo
|
||||
-> GHCTargetVersion
|
||||
-> [T.Text]
|
||||
-> Excepts
|
||||
'[ DigestError
|
||||
, ContentLengthError
|
||||
, GPGError
|
||||
, DownloadFailed
|
||||
, NoDownload
|
||||
, ArchiveResult
|
||||
, TarDirDoesNotExist
|
||||
, UnknownArchive
|
||||
, TestFailed
|
||||
]
|
||||
m
|
||||
()
|
||||
testGHCBindist dlinfo ver addMakeArgs = do
|
||||
-- download (or use cached version)
|
||||
dl <- liftE $ downloadCached dlinfo Nothing
|
||||
|
||||
liftE $ testPackedGHC dl (view dlSubdir dlinfo) ver addMakeArgs
|
||||
|
||||
|
||||
testPackedGHC :: ( MonadMask m
|
||||
, MonadCatch m
|
||||
, MonadReader env m
|
||||
, HasDirs env
|
||||
, HasPlatformReq env
|
||||
, HasSettings env
|
||||
, MonadThrow m
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
, MonadFail m
|
||||
, MonadResource m
|
||||
)
|
||||
=> FilePath -- ^ Path to the packed GHC bindist
|
||||
-> Maybe TarDir -- ^ Subdir of the archive
|
||||
-> GHCTargetVersion -- ^ The GHC version
|
||||
-> [T.Text] -- ^ additional make args
|
||||
-> Excepts
|
||||
'[ ArchiveResult, UnknownArchive, TarDirDoesNotExist, TestFailed ] m ()
|
||||
testPackedGHC dl msubdir ver addMakeArgs = do
|
||||
-- unpack
|
||||
tmpUnpack <- lift mkGhcupTmpDir
|
||||
liftE $ cleanUpOnError tmpUnpack (unpackToDir (fromGHCupPath tmpUnpack) dl)
|
||||
|
||||
-- the subdir of the archive where we do the work
|
||||
workdir <- maybe (pure tmpUnpack)
|
||||
(liftE . intoSubdir tmpUnpack)
|
||||
msubdir
|
||||
|
||||
reThrowAll @_ @'[ArchiveResult, UnknownArchive, TarDirDoesNotExist, ProcessError]
|
||||
(TestFailed (fromGHCupPath workdir)) $ liftE $ runBuildAction tmpUnpack
|
||||
(testUnpackedGHC workdir ver addMakeArgs)
|
||||
|
||||
testUnpackedGHC :: ( MonadReader env m
|
||||
, HasDirs env
|
||||
, HasSettings env
|
||||
, MonadThrow m
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
)
|
||||
=> GHCupPath -- ^ Path to the unpacked GHC bindist (where the make file resides)
|
||||
-> GHCTargetVersion -- ^ The GHC version
|
||||
-> [T.Text] -- ^ additional configure args for bindist
|
||||
-> Excepts '[ProcessError] m ()
|
||||
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
|
||||
let pathVar = if isWindows then "Path" else "PATH"
|
||||
forM_ (Map.lookup pathVar . Map.fromList $ env) $ liftIO . setEnv pathVar
|
||||
|
||||
lEM $ make' (fmap T.unpack addMakeArgs)
|
||||
(Just $ fromGHCupPath path)
|
||||
"ghc-test"
|
||||
(Just $ ("STAGE1_GHC", maybe "" (T.unpack . (<> "-")) (_tvTarget tver)
|
||||
<> "ghc-"
|
||||
<> T.unpack (prettyVer $ _tvVersion tver)) : env)
|
||||
pure ()
|
||||
|
||||
|
||||
---------------------
|
||||
--[ Tool fetching ]--
|
||||
---------------------
|
||||
@@ -105,7 +248,7 @@ fetchGHCSrc :: ( MonadFail m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Version
|
||||
=> GHCTargetVersion
|
||||
-> Maybe FilePath
|
||||
-> Excepts
|
||||
'[ DigestError
|
||||
@@ -120,7 +263,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
|
||||
|
||||
|
||||
@@ -145,7 +288,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
|
||||
@@ -168,10 +311,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
|
||||
|
||||
@@ -179,7 +320,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
|
||||
@@ -198,12 +339,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
|
||||
@@ -237,7 +378,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
|
||||
@@ -285,53 +426,93 @@ 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
|
||||
= []
|
||||
|
||||
lift $ logInfo "Installing GHC (this may take a while)"
|
||||
env <- case _rPlatform of
|
||||
-- https://github.com/haskell/ghcup-hs/issues/967
|
||||
Linux Alpine
|
||||
-- lets not touch LD for cross targets
|
||||
| Nothing <- _tvTarget tver -> do
|
||||
cEnv <- liftIO getEnvironment
|
||||
spaths <- liftIO getSearchPath
|
||||
has_ld_bfd <- isJust <$> liftIO (searchPath spaths "ld.bfd")
|
||||
let ldSet = isJust $ lookup "LD" cEnv
|
||||
-- only set LD if ld.bfd exists in PATH and LD is not set
|
||||
-- already
|
||||
if has_ld_bfd && not ldSet
|
||||
then do
|
||||
lift $ logInfo "Detected alpine linux... setting LD=ld.bfd"
|
||||
pure $ Just (("LD", "ld.bfd") : cEnv)
|
||||
else pure Nothing
|
||||
_ -> pure Nothing
|
||||
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"
|
||||
Nothing
|
||||
env
|
||||
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@:
|
||||
@@ -350,8 +531,9 @@ installGHCBin :: ( MonadFail m
|
||||
, MonadResource m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
, Alternative m
|
||||
)
|
||||
=> Version -- ^ the version to install
|
||||
=> GHCTargetVersion -- ^ the version to install
|
||||
-> InstallDir
|
||||
-> Bool -- ^ force install
|
||||
-> [T.Text] -- ^ additional configure args for bindist
|
||||
@@ -371,12 +553,17 @@ installGHCBin :: ( MonadFail m
|
||||
, ProcessError
|
||||
, UninstallFailed
|
||||
, MergeFileTreeError
|
||||
, NoCompatiblePlatform
|
||||
, ParseError
|
||||
, UnsupportedSetupCombo
|
||||
, DistroNotFound
|
||||
, NoCompatibleArch
|
||||
]
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -459,7 +646,7 @@ setGHC ver sghc mBinDir = do
|
||||
when (targetFile == "ghc") $
|
||||
liftIO (isShadowed fullF) >>= \case
|
||||
Nothing -> pure ()
|
||||
Just pa -> lift $ logWarn $ T.pack $ prettyShow (ToolShadowed GHC pa fullF (_tvVersion ver))
|
||||
Just pa -> lift $ logWarn $ T.pack $ prettyHFError (ToolShadowed GHC pa fullF (_tvVersion ver))
|
||||
|
||||
when (isNothing mBinDir) $ do
|
||||
-- create symlink for share dir
|
||||
@@ -570,7 +757,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
|
||||
@@ -592,7 +779,8 @@ rmGHCVer ver = do
|
||||
|
||||
Dirs {..} <- lift getDirs
|
||||
|
||||
lift $ hideError doesNotExistErrorType $ rmDirectoryLink (fromGHCupPath baseDir </> "share")
|
||||
when isSetGHC $ do
|
||||
lift $ hideError doesNotExistErrorType $ rmDirectoryLink (fromGHCupPath baseDir </> "share")
|
||||
|
||||
|
||||
|
||||
@@ -617,7 +805,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
|
||||
@@ -625,7 +814,7 @@ compileGHC :: ( MonadMask m
|
||||
-> Maybe (Either FilePath [URI]) -- ^ patches
|
||||
-> [Text] -- ^ additional args to ./configure
|
||||
-> Maybe String -- ^ build flavour
|
||||
-> Bool
|
||||
-> Maybe BuildSystem
|
||||
-> InstallDir
|
||||
-> Excepts
|
||||
'[ AlreadyInstalled
|
||||
@@ -654,20 +843,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
|
||||
@@ -680,7 +870,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)
|
||||
@@ -704,7 +894,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
|
||||
@@ -761,12 +951,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)
|
||||
@@ -785,16 +975,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
|
||||
@@ -810,12 +1015,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
|
||||
@@ -838,20 +1041,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
|
||||
@@ -877,18 +1089,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
|
||||
@@ -907,8 +1118,8 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
|
||||
let possible_files = if isWindows
|
||||
then ((workdir </> "hadrian") </>) <$> ["build.bat"]
|
||||
else ((workdir </> "hadrian") </>) <$> ["build", "build.sh"]
|
||||
exsists <- forM possible_files (\f -> liftIO (doesFileExist f) <&> (,f))
|
||||
case filter fst exsists of
|
||||
exists <- forM possible_files (\f -> liftIO (doesFileExist f) <&> (,f))
|
||||
case filter fst exists of
|
||||
[] -> throwE HadrianNotFound
|
||||
((_, x):_) -> pure x
|
||||
|
||||
@@ -921,6 +1132,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
|
||||
@@ -932,6 +1146,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
|
||||
@@ -953,7 +1168,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..."
|
||||
@@ -1026,8 +1243,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!|]
|
||||
)
|
||||
@@ -1071,64 +1288,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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import GHCup.Prelude.Logger
|
||||
import GHCup.Prelude.Process
|
||||
import GHCup.Prelude.String.QQ
|
||||
|
||||
import Codec.Archive ( ArchiveResult )
|
||||
import Control.Applicative
|
||||
import Control.Exception.Safe
|
||||
import Control.Monad
|
||||
@@ -43,6 +42,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 )
|
||||
@@ -68,13 +68,13 @@ import qualified Data.List.NonEmpty as NE
|
||||
import qualified Data.ByteString as B
|
||||
import qualified Data.Text as T
|
||||
import qualified Text.Megaparsec as MP
|
||||
import Text.PrettyPrint.HughesPJClass (prettyShow)
|
||||
|
||||
|
||||
data HLSVer = SourceDist Version
|
||||
| GitDist GitBranch
|
||||
| HackageDist Version
|
||||
| RemoteDist URI
|
||||
deriving (Eq, Show)
|
||||
|
||||
|
||||
|
||||
@@ -354,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
|
||||
|
||||
@@ -369,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
|
||||
@@ -634,7 +634,7 @@ setHLS ver shls mBinDir = do
|
||||
|
||||
liftIO (isShadowed wrapper) >>= \case
|
||||
Nothing -> pure ()
|
||||
Just pa -> lift $ logWarn $ T.pack $ prettyShow (ToolShadowed HLS pa wrapper ver)
|
||||
Just pa -> lift $ logWarn $ T.pack $ prettyHFError (ToolShadowed HLS pa wrapper ver)
|
||||
|
||||
|
||||
unsetHLS :: ( MonadMask m
|
||||
@@ -705,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 ()
|
||||
|
||||
@@ -716,8 +716,10 @@ getCabalVersion fp = do
|
||||
gpd <- case parseGenericPackageDescriptionMaybe contents of
|
||||
Nothing -> fail $ "could not parse cabal file: " <> fp
|
||||
Just r -> pure r
|
||||
let tver = (\c -> Version Nothing c [] Nothing)
|
||||
. NE.fromList . fmap (NE.fromList . (:[]) . digits . fromIntegral)
|
||||
let tver = (\c -> Version Nothing c Nothing Nothing)
|
||||
. Chunks
|
||||
. NE.fromList
|
||||
. fmap (Numeric . fromIntegral)
|
||||
. versionNumbers
|
||||
. pkgVersion
|
||||
. package
|
||||
|
||||
@@ -36,6 +36,7 @@ import Data.Either
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import Data.Text ( Text )
|
||||
import Data.Time.Calendar ( Day )
|
||||
import Data.Versions hiding ( patch )
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
import Optics
|
||||
@@ -61,10 +62,10 @@ import qualified Data.Text as T
|
||||
|
||||
|
||||
-- | Filter data type for 'listVersions'.
|
||||
data ListCriteria = ListInstalled
|
||||
| ListSet
|
||||
| ListAvailable
|
||||
deriving Show
|
||||
data ListCriteria = ListInstalled Bool
|
||||
| ListSet Bool
|
||||
| ListAvailable Bool
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | A list result describes a single tool version
|
||||
-- and various of its properties.
|
||||
@@ -75,16 +76,16 @@ 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
|
||||
, lReleaseDay :: Maybe Day
|
||||
}
|
||||
deriving (Eq, Ord, Show)
|
||||
|
||||
|
||||
-- | 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
|
||||
@@ -93,19 +94,22 @@ availableToolVersions av tool = view
|
||||
-- | List all versions from the download info, as well as stray
|
||||
-- versions.
|
||||
listVersions :: ( MonadCatch m
|
||||
, HasLog env
|
||||
, MonadThrow m
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, MonadReader env m
|
||||
, HasDirs env
|
||||
, HasPlatformReq env
|
||||
, HasGHCupInfo env
|
||||
)
|
||||
=> Maybe Tool
|
||||
-> Maybe ListCriteria
|
||||
-> m [ListResult]
|
||||
listVersions lt' criteria = do
|
||||
, HasLog env
|
||||
, MonadThrow m
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, MonadReader env m
|
||||
, HasDirs env
|
||||
, HasPlatformReq env
|
||||
, HasGHCupInfo env
|
||||
)
|
||||
=> Maybe Tool
|
||||
-> [ListCriteria]
|
||||
-> Bool
|
||||
-> Bool
|
||||
-> (Maybe Day, Maybe Day)
|
||||
-> m [ListResult]
|
||||
listVersions lt' criteria hideOld showNightly days = do
|
||||
-- some annoying work to avoid too much repeated IO
|
||||
cSet <- cabalSet
|
||||
cabals <- getInstalledCabals
|
||||
@@ -129,13 +133,13 @@ listVersions lt' criteria = 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
|
||||
@@ -154,42 +158,28 @@ listVersions lt' criteria = 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
|
||||
, ..
|
||||
}
|
||||
Left e -> do
|
||||
logWarn
|
||||
$ "Could not parse version of stray directory" <> T.pack e
|
||||
@@ -221,8 +211,8 @@ listVersions lt' criteria = do
|
||||
, lInstalled = True
|
||||
, lStray = isNothing (Map.lookup ver avTools)
|
||||
, lNoBindist = False
|
||||
, fromSrc = False -- actually, we don't know :>
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = Nothing
|
||||
, ..
|
||||
}
|
||||
Left e -> do
|
||||
@@ -255,8 +245,8 @@ listVersions lt' criteria = do
|
||||
, lInstalled = True
|
||||
, lStray = isNothing (Map.lookup ver avTools)
|
||||
, lNoBindist = False
|
||||
, fromSrc = False -- actually, we don't know :>
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = Nothing
|
||||
, ..
|
||||
}
|
||||
Left e -> do
|
||||
@@ -290,8 +280,8 @@ listVersions lt' criteria = do
|
||||
, lInstalled = True
|
||||
, lStray = isNothing (Map.lookup ver avTools)
|
||||
, lNoBindist = False
|
||||
, fromSrc = False -- actually, we don't know :>
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = Nothing
|
||||
, ..
|
||||
}
|
||||
Left e -> do
|
||||
@@ -299,24 +289,24 @@ listVersions lt' criteria = 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
|
||||
, lNoBindist = False
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = Nothing
|
||||
}
|
||||
|
||||
-- NOTE: this are not cross ones, because no bindists
|
||||
@@ -335,42 +325,41 @@ listVersions lt' criteria = do
|
||||
-> [Either FilePath Version]
|
||||
-> Maybe Version
|
||||
-> [Either FilePath Version]
|
||||
-> (Version, VersionInfo)
|
||||
-> (GHCTargetVersion, VersionInfo)
|
||||
-> m ListResult
|
||||
toListResult t cSet cabals hlsSet' hlses stackSet' stacks (v, _viTags -> tags) = 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 = tags, lTool = t, lStray = False, .. }
|
||||
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
|
||||
let lInstalled = elem v $ rights cabals
|
||||
pure ListResult { lVer = v
|
||||
, lCross = Nothing
|
||||
, lTag = tags
|
||||
, lTag = _viTags
|
||||
, lTool = t
|
||||
, fromSrc = False
|
||||
, lStray = False
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = _viReleaseDay
|
||||
, ..
|
||||
}
|
||||
GHCup -> do
|
||||
let lSet = prettyPVP ghcUpVer == prettyVer v
|
||||
let lInstalled = lSet
|
||||
pure ListResult { lVer = v
|
||||
, lTag = tags
|
||||
, lTag = _viTags
|
||||
, lCross = Nothing
|
||||
, lTool = t
|
||||
, fromSrc = False
|
||||
, lStray = False
|
||||
, lNoBindist = False
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = _viReleaseDay
|
||||
, ..
|
||||
}
|
||||
HLS -> do
|
||||
@@ -379,11 +368,11 @@ listVersions lt' criteria = do
|
||||
let lInstalled = elem v $ rights hlses
|
||||
pure ListResult { lVer = v
|
||||
, lCross = Nothing
|
||||
, lTag = tags
|
||||
, lTag = _viTags
|
||||
, lTool = t
|
||||
, fromSrc = False
|
||||
, lStray = False
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = _viReleaseDay
|
||||
, ..
|
||||
}
|
||||
Stack -> do
|
||||
@@ -392,19 +381,42 @@ listVersions lt' criteria = do
|
||||
let lInstalled = elem v $ rights stacks
|
||||
pure ListResult { lVer = v
|
||||
, lCross = Nothing
|
||||
, lTag = tags
|
||||
, lTag = _viTags
|
||||
, lTool = t
|
||||
, fromSrc = False
|
||||
, lStray = False
|
||||
, hlsPowered = False
|
||||
, lReleaseDay = _viReleaseDay
|
||||
, ..
|
||||
}
|
||||
|
||||
|
||||
filter' :: [ListResult] -> [ListResult]
|
||||
filter' lr = case criteria of
|
||||
Nothing -> lr
|
||||
Just ListInstalled -> filter (\ListResult {..} -> lInstalled) lr
|
||||
Just ListSet -> filter (\ListResult {..} -> lSet) lr
|
||||
Just ListAvailable -> filter (\ListResult {..} -> not lNoBindist) lr
|
||||
filter' = filterNightly . filterOld . filter (\lr -> foldr (\a b -> fromCriteria a lr && b) True criteria) . filterDays
|
||||
|
||||
filterDays :: [ListResult] -> [ListResult]
|
||||
filterDays lrs = case days of
|
||||
(Nothing, Nothing) -> lrs
|
||||
(Just from, Just to') -> filter (\ListResult{..} -> maybe False (\d -> d >= from && d <= to') lReleaseDay) lrs
|
||||
(Nothing, Just to') -> filter (\ListResult{..} -> maybe False (<= to') lReleaseDay) lrs
|
||||
(Just from, Nothing) -> filter (\ListResult{..} -> maybe False (>= from) lReleaseDay) lrs
|
||||
|
||||
fromCriteria :: ListCriteria -> ListResult -> Bool
|
||||
fromCriteria lc ListResult{..} = case lc of
|
||||
ListInstalled b -> f b lInstalled
|
||||
ListSet b -> f b lSet
|
||||
ListAvailable b -> f b $ not lNoBindist
|
||||
where
|
||||
f b
|
||||
| b = id
|
||||
| otherwise = not
|
||||
|
||||
filterOld :: [ListResult] -> [ListResult]
|
||||
filterOld lr
|
||||
| hideOld = filter (\ListResult {..} -> lInstalled || Old `notElem` lTag) lr
|
||||
| otherwise = lr
|
||||
|
||||
filterNightly :: [ListResult] -> [ListResult]
|
||||
filterNightly lr
|
||||
| showNightly = lr
|
||||
| otherwise = filter (\ListResult {..} -> lInstalled || (Nightly `notElem` lTag && LatestNightly `notElem` lTag)) lr
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
{-|
|
||||
Module : GHCup.Plaform
|
||||
Module : GHCup.Platform
|
||||
Description : Retrieving platform information
|
||||
Copyright : (c) Julian Ospald, 2020
|
||||
License : LGPL-3.0
|
||||
@@ -28,6 +28,8 @@ import GHCup.Prelude
|
||||
import GHCup.Prelude.Logger
|
||||
import GHCup.Prelude.Process
|
||||
import GHCup.Prelude.String.QQ
|
||||
import GHCup.Prelude.Version.QQ
|
||||
import GHCup.Prelude.MegaParsec
|
||||
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
@@ -48,11 +50,18 @@ import Prelude hiding ( abs
|
||||
)
|
||||
import System.Info
|
||||
import System.OsRelease
|
||||
import System.Exit
|
||||
import System.FilePath
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||
import Text.Regex.Posix
|
||||
|
||||
import qualified Text.Megaparsec as MP
|
||||
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Data.Void
|
||||
import qualified Data.List as L
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -143,6 +152,9 @@ getLinuxDistro = do
|
||||
| hasWord name ["exherbo"] -> Exherbo
|
||||
| hasWord name ["gentoo"] -> Gentoo
|
||||
| hasWord name ["amazonlinux", "Amazon Linux"] -> AmazonLinux
|
||||
| hasWord name ["rocky", "Rocky Linux"] -> Rocky
|
||||
-- https://github.com/void-linux/void-packages/blob/master/srcpkgs/base-files/files/os-release
|
||||
| hasWord name ["void", "Void Linux"] -> Void
|
||||
| otherwise -> UnknownLinux
|
||||
pure (distro, parsedVer)
|
||||
where
|
||||
@@ -197,3 +209,155 @@ getLinuxDistro = do
|
||||
try_debian_version = do
|
||||
ver <- T.readFile debian_version
|
||||
pure (T.pack "debian", Just ver)
|
||||
|
||||
|
||||
getStackGhcBuilds :: (MonadReader env m, HasLog env, MonadIO m)
|
||||
=> PlatformResult
|
||||
-> Excepts '[ParseError, NoCompatiblePlatform, DistroNotFound, ProcessError] m [String]
|
||||
getStackGhcBuilds PlatformResult{..} = do
|
||||
case _platform of
|
||||
Linux _ -> do
|
||||
-- Some systems don't have ldconfig in the PATH, so make sure to look in
|
||||
-- /sbin and /usr/sbin as well
|
||||
sbinEnv <- liftIO $ addToPath sbinDirs False
|
||||
ldConfig <- lift $ executeOut' "ldconfig" ["-p"] Nothing (Just sbinEnv)
|
||||
firstWords <- case ldConfig of
|
||||
CapturedProcess ExitSuccess so _ ->
|
||||
pure . mapMaybe (listToMaybe . T.words) . T.lines . T.pack . stripNewlineEnd . T.unpack . decUTF8Safe' $ so
|
||||
CapturedProcess (ExitFailure _) _ _ ->
|
||||
-- throwE $ NonZeroExit c "ldconfig" ["-p" ]
|
||||
pure []
|
||||
let checkLib :: (MonadReader env m, HasLog env, MonadIO m) => String -> m Bool
|
||||
checkLib lib
|
||||
| libT `elem` firstWords = do
|
||||
logDebug $ "Found shared library " <> libT <> " in 'ldconfig -p' output"
|
||||
pure True
|
||||
| isWindows =
|
||||
-- Cannot parse /usr/lib on Windows
|
||||
pure False
|
||||
| otherwise = hasMatches lib usrLibDirs
|
||||
-- This is a workaround for the fact that libtinfo.so.x doesn't
|
||||
-- appear in the 'ldconfig -p' output on Arch or Slackware even
|
||||
-- when it exists. There doesn't seem to be an easy way to get the
|
||||
-- true list of directories to scan for shared libs, but this
|
||||
-- works for our particular cases.
|
||||
where
|
||||
libT = T.pack lib
|
||||
|
||||
hasMatches :: (MonadReader env m, HasLog env, MonadIO m) => String -> [FilePath] -> m Bool
|
||||
hasMatches lib dirs = do
|
||||
matches <- filterM (liftIO . doesFileExist . (</> lib)) dirs
|
||||
case matches of
|
||||
[] -> logDebug ("Did not find shared library " <> libT) >> pure False
|
||||
(path:_) -> logDebug ("Found shared library " <> libT <> " in " <> T.pack path) >> pure True
|
||||
where
|
||||
libT = T.pack lib
|
||||
|
||||
getLibc6Version :: MonadIO m
|
||||
=> Excepts '[ParseError, ProcessError] m Version
|
||||
getLibc6Version = do
|
||||
CapturedProcess{..} <- lift $ executeOut "ldd" ["--version"] Nothing
|
||||
case _exitCode of
|
||||
ExitSuccess -> either (throwE . ParseError . show) pure
|
||||
. MP.parse lddVersion "" . T.pack . stripNewlineEnd . T.unpack . decUTF8Safe' $ _stdOut
|
||||
ExitFailure c -> throwE $ NonZeroExit c "ldd" ["--version" ]
|
||||
|
||||
-- Assumes the first line of ldd has the format:
|
||||
--
|
||||
-- ldd (...) nn.nn
|
||||
--
|
||||
-- where nn.nn corresponds to the version of libc6.
|
||||
lddVersion :: MP.Parsec Void Text Version
|
||||
lddVersion = do
|
||||
skipWhile (/= ')')
|
||||
skip (== ')')
|
||||
skipSpace
|
||||
version'
|
||||
|
||||
hasMusl <- hasMatches relFileLibcMuslx86_64So1 libDirs
|
||||
mLibc6Version <- veitherToEither <$> runE getLibc6Version
|
||||
case mLibc6Version of
|
||||
Right libc6Version -> logDebug $ "Found shared library libc6 in version: " <> prettyVer libc6Version
|
||||
Left _ -> logDebug "Did not find a version of shared library libc6."
|
||||
let hasLibc6_2_32 = either (const False) (>= [vver|2.32|]) mLibc6Version
|
||||
hastinfo5 <- checkLib relFileLibtinfoSo5
|
||||
hastinfo6 <- checkLib relFileLibtinfoSo6
|
||||
hasncurses6 <- checkLib relFileLibncurseswSo6
|
||||
hasgmp5 <- checkLib relFileLibgmpSo10
|
||||
hasgmp4 <- checkLib relFileLibgmpSo3
|
||||
let libComponents = if hasMusl
|
||||
then
|
||||
[ ["musl"] ]
|
||||
else
|
||||
concat
|
||||
[ if hastinfo6 && hasgmp5
|
||||
then
|
||||
if hasLibc6_2_32
|
||||
then [["tinfo6"]]
|
||||
else [["tinfo6-libc6-pre232"]]
|
||||
else [[]]
|
||||
, [ [] | hastinfo5 && hasgmp5 ]
|
||||
, [ ["ncurses6"] | hasncurses6 && hasgmp5 ]
|
||||
, [ ["gmp4"] | hasgmp4 ]
|
||||
]
|
||||
pure $ map
|
||||
(\c -> case c of
|
||||
[] -> []
|
||||
_ -> L.intercalate "-" c)
|
||||
libComponents
|
||||
FreeBSD ->
|
||||
case _distroVersion of
|
||||
Just fVer
|
||||
| fVer >= [vers|12|] -> pure []
|
||||
_ -> pure ["ino64"]
|
||||
Darwin -> pure []
|
||||
Windows -> pure []
|
||||
where
|
||||
|
||||
relFileLibcMuslx86_64So1 :: FilePath
|
||||
relFileLibcMuslx86_64So1 = "libc.musl-x86_64.so.1"
|
||||
libDirs :: [FilePath]
|
||||
libDirs = ["/lib", "/lib64"]
|
||||
usrLibDirs :: [FilePath]
|
||||
usrLibDirs = ["/usr/lib", "/usr/lib64"]
|
||||
sbinDirs :: [FilePath]
|
||||
sbinDirs = ["/sbin", "/usr/sbin"]
|
||||
relFileLibtinfoSo5 :: FilePath
|
||||
relFileLibtinfoSo5 = "libtinfo.so.5"
|
||||
relFileLibtinfoSo6 :: FilePath
|
||||
relFileLibtinfoSo6 = "libtinfo.so.6"
|
||||
relFileLibncurseswSo6 :: FilePath
|
||||
relFileLibncurseswSo6 = "libncursesw.so.6"
|
||||
relFileLibgmpSo10 :: FilePath
|
||||
relFileLibgmpSo10 = "libgmp.so.10"
|
||||
relFileLibgmpSo3 :: FilePath
|
||||
relFileLibgmpSo3 = "libgmp.so.3"
|
||||
|
||||
getStackOSKey :: Monad m => PlatformRequest -> Excepts '[UnsupportedSetupCombo] m String
|
||||
getStackOSKey PlatformRequest { .. } =
|
||||
case (_rArch, _rPlatform) of
|
||||
(A_32 , Linux _) -> pure "linux32"
|
||||
(A_64 , Linux _) -> pure "linux64"
|
||||
(A_32 , Darwin ) -> pure "macosx"
|
||||
(A_64 , Darwin ) -> pure "macosx"
|
||||
(A_32 , FreeBSD) -> pure "freebsd32"
|
||||
(A_64 , FreeBSD) -> pure "freebsd64"
|
||||
(A_32 , Windows) -> pure "windows32"
|
||||
(A_64 , Windows) -> pure "windows64"
|
||||
(A_ARM , Linux _) -> pure "linux-armv7"
|
||||
(A_ARM64, Linux _) -> pure "linux-aarch64"
|
||||
(A_Sparc, Linux _) -> pure "linux-sparc"
|
||||
(A_ARM64, Darwin ) -> pure "macosx-aarch64"
|
||||
(A_ARM64, FreeBSD) -> pure "freebsd-aarch64"
|
||||
(arch', os') -> throwE $ UnsupportedSetupCombo arch' os'
|
||||
|
||||
getStackPlatformKey :: (MonadReader env m, MonadFail m, HasLog env, MonadCatch m, MonadIO m)
|
||||
=> PlatformRequest
|
||||
-> Excepts '[UnsupportedSetupCombo, ParseError, NoCompatiblePlatform, NoCompatibleArch, DistroNotFound, ProcessError] m [String]
|
||||
getStackPlatformKey pfreq@PlatformRequest{..} = do
|
||||
osKey <- liftE $ getStackOSKey pfreq
|
||||
builds <- liftE $ getStackGhcBuilds (PlatformResult _rPlatform _rVersion)
|
||||
let builds' = (\build -> if null build then osKey else osKey <> "-" <> build) <$> builds
|
||||
logDebug $ "Potential GHC builds: " <> mconcat (L.intersperse ", " $ fmap T.pack builds')
|
||||
pure builds'
|
||||
|
||||
|
||||
@@ -41,24 +41,30 @@ import GHCup.Prelude.Posix
|
||||
import Control.Monad.IO.Class
|
||||
import Control.Monad.Reader
|
||||
import Haskus.Utils.Variant.Excepts
|
||||
import Text.PrettyPrint.HughesPJClass ( prettyShow, Pretty )
|
||||
import Text.PrettyPrint.HughesPJClass ( Pretty )
|
||||
import qualified Data.Text as T
|
||||
import System.Environment (getEnvironment)
|
||||
import qualified Data.Map.Strict as Map
|
||||
import System.FilePath
|
||||
import Data.List (intercalate)
|
||||
|
||||
|
||||
|
||||
-- for some obscure reason... this won't type-check if we move it to a different module
|
||||
catchWarn :: forall es m env . ( Pretty (V es)
|
||||
, HFErrorProject (V es)
|
||||
, MonadReader env m
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, Monad m) => Excepts es m () -> Excepts '[] m ()
|
||||
catchWarn = catchAllE @_ @es (\v -> lift $ logWarn (T.pack . prettyShow $ v))
|
||||
catchWarn = catchAllE @_ @es (\v -> lift $ logWarn (T.pack . prettyHFError $ v))
|
||||
|
||||
|
||||
runBothE' :: forall e m a b .
|
||||
( Monad m
|
||||
, Show (V e)
|
||||
, Pretty (V e)
|
||||
, HFErrorProject (V e)
|
||||
, PopVariant InstallSetError e
|
||||
, LiftVariant' e (InstallSetError ': e)
|
||||
, e :<< (InstallSetError ': e)
|
||||
@@ -75,8 +81,36 @@ runBothE' a1 a2 = do
|
||||
(_ , VLeft e ) -> throwSomeE e
|
||||
(VRight _, VRight _) -> pure ()
|
||||
|
||||
-- "throwSomeE" function has been upstreamed in haskus-utils-variant-3.3
|
||||
-- So, only conditionally include this shim if
|
||||
-- haskus-utils-variant version is < 3.3
|
||||
|
||||
#if MIN_VERSION_haskus_utils_variant(3,3,0)
|
||||
#else
|
||||
-- | Throw some exception
|
||||
throwSomeE :: forall es' es a m. (Monad m, LiftVariant es' es) => V es' -> Excepts es m a
|
||||
{-# INLINABLE throwSomeE #-}
|
||||
throwSomeE = Excepts . pure . VLeft . liftVariant
|
||||
#endif
|
||||
|
||||
addToPath :: [FilePath]
|
||||
-> Bool -- ^ if False will prepend
|
||||
-> IO [(String, String)]
|
||||
addToPath paths append = do
|
||||
cEnv <- getEnvironment
|
||||
return $ addToPath' cEnv paths append
|
||||
|
||||
addToPath' :: [(String, String)]
|
||||
-> [FilePath]
|
||||
-> Bool -- ^ if False will prepend
|
||||
-> [(String, String)]
|
||||
addToPath' cEnv' newPaths append =
|
||||
let cEnv = Map.fromList cEnv'
|
||||
paths = ["PATH", "Path"]
|
||||
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
||||
{- HLINT ignore "Redundant bracket" -}
|
||||
newPath = intercalate [searchPathSeparator] (if append then (curPaths ++ newPaths) else (newPaths ++ curPaths))
|
||||
envWithoutPath = foldr (\x y -> Map.delete x y) cEnv paths
|
||||
pathVar = if isWindows then "Path" else "PATH"
|
||||
envWithNewPath = Map.toList $ Map.insert pathVar newPath envWithoutPath
|
||||
in envWithNewPath
|
||||
|
||||
@@ -387,7 +387,7 @@ rmLink fp
|
||||
--
|
||||
-- This overwrites previously existing files.
|
||||
--
|
||||
-- On windows, this requires that 'ensureGlobalTools' was run beforehand.
|
||||
-- On windows, this requires that 'ensureShimGen' was run beforehand.
|
||||
createLink :: ( MonadMask m
|
||||
, MonadThrow m
|
||||
, HasLog env
|
||||
|
||||
@@ -48,6 +48,7 @@ import Streamly.Internal.Data.Unfold.Type
|
||||
import qualified Streamly.Internal.Data.Unfold as U
|
||||
import Streamly.Internal.Control.Concurrent ( withRunInIO )
|
||||
import Streamly.Internal.Data.IOFinalizer ( newIOFinalizer, runIOFinalizer )
|
||||
import GHC.IO.Exception (IOException(ioe_type), IOErrorType (..))
|
||||
|
||||
|
||||
-- | On unix, we can use symlinks, so we just get the
|
||||
@@ -116,8 +117,18 @@ copyFile from to fail' = do
|
||||
let dflags = [ FD.oNofollow
|
||||
, if fail' then FD.oExcl else FD.oTrunc
|
||||
]
|
||||
let openFdHandle' = openFdHandle to SPI.WriteOnly dflags $ Just sourceFileMode
|
||||
bracket
|
||||
(openFdHandle to SPI.WriteOnly dflags $ Just sourceFileMode)
|
||||
(handleIO (\e -> if
|
||||
-- if we copy from regular file to symlink, we need
|
||||
-- to delete the symlink
|
||||
| ioe_type e == InvalidArgument
|
||||
, not fail' -> do
|
||||
removeLink to
|
||||
openFdHandle'
|
||||
| otherwise -> throwIO e
|
||||
)
|
||||
openFdHandle')
|
||||
(hClose . snd)
|
||||
$ \(_, tH) -> do
|
||||
hSetBinaryMode fH True
|
||||
@@ -229,7 +240,7 @@ recreateSymlink symsource newsym fail' = do
|
||||
createSymbolicLink sympoint newsym
|
||||
|
||||
|
||||
-- copys files, recreates symlinks, fails on all other types
|
||||
-- copies files, recreates symlinks, fails on all other types
|
||||
install :: FilePath -> FilePath -> Bool -> IO ()
|
||||
install from to fail' = do
|
||||
fs <- PF.getSymbolicLinkStatus from
|
||||
@@ -268,11 +279,11 @@ removeEmptyDirectory = PD.removeDirectory
|
||||
|
||||
-- | Create an 'Unfold' of directory contents.
|
||||
unfoldDirContents :: (MonadMask m, MonadIO m, S.MonadAsync m) => Unfold m FilePath (FD.DirType, FilePath)
|
||||
unfoldDirContents = U.bracket (liftIO . openDirStream) (liftIO . closeDirStream) (Unfold step return)
|
||||
unfoldDirContents = U.bracket (liftIO . openDirStreamPortable) (liftIO . closeDirStreamPortable) (Unfold step return)
|
||||
where
|
||||
{-# INLINE [0] step #-}
|
||||
step dirstream = do
|
||||
(typ, e) <- liftIO $ readDirEnt dirstream
|
||||
(typ, e) <- liftIO $ readDirEntPortable dirstream
|
||||
return $ if
|
||||
| null e -> D.Stop
|
||||
| "." == e -> D.Skip dirstream
|
||||
@@ -297,8 +308,8 @@ getDirectoryContentsRecursiveUnfold = Unfold step (\s -> return (s, Nothing, [""
|
||||
step (_, Nothing, []) = return D.Stop
|
||||
|
||||
step (topdir, Just (cdir, dirstream, finalizer), dirs) = flip onException (runIOFinalizer finalizer) $ do
|
||||
(dt, f) <- liftIO $ readDirEnt dirstream
|
||||
if | FD.dtUnknown == dt -> do
|
||||
(dt, f) <- liftIO $ readDirEntPortable dirstream
|
||||
if | f == "" -> do
|
||||
runIOFinalizer finalizer
|
||||
return $ D.Skip (topdir, Nothing, dirs)
|
||||
| f == "." || f == ".."
|
||||
@@ -312,8 +323,8 @@ getDirectoryContentsRecursiveUnfold = Unfold step (\s -> return (s, Nothing, [""
|
||||
|
||||
acquire dir =
|
||||
withRunInIO $ \run -> mask_ $ run $ do
|
||||
dirstream <- liftIO $ openDirStream dir
|
||||
ref <- newIOFinalizer (liftIO $ closeDirStream dirstream)
|
||||
dirstream <- liftIO $ openDirStreamPortable dir
|
||||
ref <- newIOFinalizer (liftIO $ closeDirStreamPortable dirstream)
|
||||
return (dirstream, ref)
|
||||
|
||||
getDirectoryContentsRecursiveBFSUnsafe :: (MonadMask m, MonadIO m, S.MonadAsync m)
|
||||
|
||||
@@ -10,9 +10,20 @@
|
||||
module GHCup.Prelude.File.Posix.Traversals (
|
||||
-- lower-level stuff
|
||||
readDirEnt
|
||||
, readDirEntPortable
|
||||
, openDirStreamPortable
|
||||
, closeDirStreamPortable
|
||||
, unpackDirStream
|
||||
, DirStreamPortable
|
||||
) where
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
#if __GLASGOW_HASKELL__ < 710
|
||||
import Control.Applicative ((<$>))
|
||||
@@ -28,6 +39,7 @@ import Foreign.Storable
|
||||
import System.Posix
|
||||
import Foreign (alloca)
|
||||
import System.Posix.Internals (peekFilePath)
|
||||
import System.FilePath
|
||||
|
||||
|
||||
|
||||
@@ -90,3 +102,38 @@ readDirEnt (unpackDirStream -> dirp) =
|
||||
then return (dtUnknown, mempty)
|
||||
else throwErrno "readDirEnt"
|
||||
|
||||
|
||||
newtype DirStreamPortable = DirStreamPortable (FilePath, DirStream)
|
||||
|
||||
openDirStreamPortable :: FilePath -> IO DirStreamPortable
|
||||
openDirStreamPortable fp = do
|
||||
dirs <- openDirStream fp
|
||||
pure $ DirStreamPortable (fp, dirs)
|
||||
|
||||
closeDirStreamPortable :: DirStreamPortable -> IO ()
|
||||
closeDirStreamPortable (DirStreamPortable (_, dirs)) = closeDirStream dirs
|
||||
|
||||
readDirEntPortable :: DirStreamPortable -> IO (DirType, FilePath)
|
||||
readDirEntPortable (DirStreamPortable (basedir, dirs)) = do
|
||||
(dt, fp) <- readDirEnt dirs
|
||||
case (dt, fp) of
|
||||
(DirType #{const DT_BLK}, _) -> pure (dt, fp)
|
||||
(DirType #{const DT_CHR}, _) -> pure (dt, fp)
|
||||
(DirType #{const DT_DIR}, _) -> pure (dt, fp)
|
||||
(DirType #{const DT_FIFO}, _) -> pure (dt, fp)
|
||||
(DirType #{const DT_LNK}, _) -> pure (dt, fp)
|
||||
(DirType #{const DT_REG}, _) -> pure (dt, fp)
|
||||
(DirType #{const DT_SOCK}, _) -> pure (dt, fp)
|
||||
(_, _)
|
||||
| fp /= "" -> do
|
||||
stat <- getSymbolicLinkStatus (basedir </> fp)
|
||||
pure $ (, fp) $ if | isBlockDevice stat -> DirType #{const DT_BLK}
|
||||
| isCharacterDevice stat -> DirType #{const DT_CHR}
|
||||
| isDirectory stat -> DirType #{const DT_DIR}
|
||||
| isNamedPipe stat -> DirType #{const DT_FIFO}
|
||||
| isSymbolicLink stat -> DirType #{const DT_LNK}
|
||||
| isRegularFile stat -> DirType #{const DT_REG}
|
||||
| isSocket stat -> DirType #{const DT_SOCK}
|
||||
| otherwise -> DirType #{const DT_UNKNOWN}
|
||||
| otherwise -> pure (dt, fp)
|
||||
|
||||
@@ -80,7 +80,7 @@ logInternal logLevel msg = do
|
||||
Info -> style' "[ Info ]"
|
||||
Warn -> style' "[ Warn ]"
|
||||
Error -> style' "[ Error ]"
|
||||
let strs = T.split (== '\n') msg
|
||||
let strs = T.split (== '\n') . T.dropWhileEnd (`elem` ("\n\r" :: String)) $ msg
|
||||
let out = case strs of
|
||||
[] -> T.empty
|
||||
(x:xs) ->
|
||||
|
||||
@@ -91,18 +91,16 @@ ghcTargetVerP =
|
||||
verP' :: MP.Parsec Void Text Text
|
||||
verP' = do
|
||||
v <- version'
|
||||
let startsWithDigists =
|
||||
let startsWithDigits =
|
||||
and
|
||||
. take 3
|
||||
. concatMap
|
||||
(map
|
||||
(\case
|
||||
(Digits _) -> True
|
||||
(Str _) -> False
|
||||
) . NE.toList)
|
||||
. map (\case
|
||||
Numeric _ -> True
|
||||
Alphanum _ -> False)
|
||||
. NE.toList
|
||||
. (\(Chunks nec) -> nec)
|
||||
$ _vChunks v
|
||||
if startsWithDigists && isNothing (_vEpoch v)
|
||||
if startsWithDigits && isNothing (_vEpoch v)
|
||||
then pure $ prettyVer v
|
||||
else fail "Oh"
|
||||
|
||||
@@ -122,3 +120,17 @@ verP suffix = do
|
||||
|
||||
pathSep :: MP.Parsec Void Text Char
|
||||
pathSep = MP.oneOf pathSeparators
|
||||
|
||||
skipWhile :: (Char -> Bool) -> MP.Parsec Void Text ()
|
||||
skipWhile f = void $ MP.takeWhileP Nothing f
|
||||
|
||||
skip :: (Char -> Bool) -> MP.Parsec Void Text ()
|
||||
skip f = void $ MP.satisfy f
|
||||
|
||||
skipSpace :: MP.Parsec Void Text ()
|
||||
skipSpace = void $ MP.satisfy isSpace
|
||||
|
||||
isSpace :: Char -> Bool
|
||||
isSpace c = (c == ' ') || ('\t' <= c && c <= '\r')
|
||||
{-# INLINE isSpace #-}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ Portability : portable
|
||||
-}
|
||||
module GHCup.Prelude.Process (
|
||||
executeOut,
|
||||
executeOut',
|
||||
execLogged,
|
||||
exec,
|
||||
toProcessError,
|
||||
|
||||
@@ -70,6 +70,16 @@ executeOut path args chdir = liftIO $ captureOutStreams $ do
|
||||
maybe (pure ()) changeWorkingDirectory chdir
|
||||
SPP.executeFile path True args Nothing
|
||||
|
||||
executeOut' :: MonadIO m
|
||||
=> FilePath -- ^ command as filename, e.g. 'ls'
|
||||
-> [String] -- ^ arguments to the command
|
||||
-> Maybe FilePath -- ^ chdir to this path
|
||||
-> Maybe [(String, String)]
|
||||
-> m CapturedProcess
|
||||
executeOut' path args chdir env = liftIO $ captureOutStreams $ do
|
||||
maybe (pure ()) changeWorkingDirectory chdir
|
||||
SPP.executeFile path True args env
|
||||
|
||||
|
||||
execLogged :: ( MonadReader env m
|
||||
, HasSettings env
|
||||
@@ -138,7 +148,7 @@ execLogged exe args chdir lfile env = do
|
||||
void $ SPIB.fdWrite fileFd (bs' <> "\n")
|
||||
void $ SPIB.fdWrite stdOutput (bs' <> "\n")
|
||||
|
||||
-- Reads fdIn and logs the output in a continous scrolling area
|
||||
-- Reads fdIn and logs the output in a continuous scrolling area
|
||||
-- of 'size' terminal lines. Also writes to a log file.
|
||||
printToRegion :: Fd -> Fd -> Int -> MVar Bool -> Bool -> IO ()
|
||||
printToRegion fileFd fdIn size pState no_color = do
|
||||
@@ -169,7 +179,7 @@ execLogged exe args chdir lfile env = do
|
||||
overwriteNthLine n str = pos1 <> moveLineUp n <> clearLine <> str <> moveLineDown n <> pos1
|
||||
|
||||
blue :: ByteString -> ByteString
|
||||
blue bs
|
||||
blue bs
|
||||
| no_color = bs
|
||||
| otherwise = "\x1b[0;34m" <> bs <> "\x1b[0m"
|
||||
|
||||
|
||||
@@ -140,8 +140,16 @@ executeOut :: MonadIO m
|
||||
-> [String] -- ^ arguments to the command
|
||||
-> Maybe FilePath -- ^ chdir to this path
|
||||
-> m CapturedProcess
|
||||
executeOut path args chdir = do
|
||||
cp <- createProcessWithMingwPath ((proc path args){ cwd = chdir })
|
||||
executeOut path args chdir = executeOut' path args chdir Nothing
|
||||
|
||||
executeOut' :: MonadIO m
|
||||
=> FilePath -- ^ command as filename, e.g. 'ls'
|
||||
-> [String] -- ^ arguments to the command
|
||||
-> Maybe FilePath -- ^ chdir to this path
|
||||
-> Maybe [(String, String)]
|
||||
-> m CapturedProcess
|
||||
executeOut' path args chdir env' = do
|
||||
cp <- createProcessWithMingwPath ((proc path args){ cwd = chdir, env = env' })
|
||||
(exit, out, err) <- liftIO $ readCreateProcessWithExitCodeBS cp ""
|
||||
pure $ CapturedProcess exit out err
|
||||
|
||||
@@ -255,12 +263,9 @@ createProcessWithMingwPath :: MonadIO m
|
||||
=> CreateProcess
|
||||
-> m CreateProcess
|
||||
createProcessWithMingwPath cp = do
|
||||
msys2Dir <- liftIO ghcupMsys2Dir
|
||||
cEnv <- Map.fromList <$> maybe (liftIO getEnvironment) pure (env cp)
|
||||
let mingWPaths = [msys2Dir </> "mingw64" </> "bin"
|
||||
,msys2Dir </> "usr" </> "bin"
|
||||
]
|
||||
paths = ["PATH", "Path"]
|
||||
mingWPaths <- liftIO ghcupMsys2BinDirs'
|
||||
let paths = ["PATH", "Path"]
|
||||
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
||||
newPath = intercalate [searchPathSeparator] (mingWPaths ++ curPaths)
|
||||
envWithoutPath = foldr (\x y -> Map.delete x y) cEnv paths
|
||||
@@ -268,11 +273,4 @@ createProcessWithMingwPath cp = do
|
||||
liftIO $ setEnv "Path" newPath
|
||||
pure $ cp { env = Just $ Map.toList envWithNewPath }
|
||||
|
||||
ghcupMsys2Dir :: IO FilePath
|
||||
ghcupMsys2Dir =
|
||||
lookupEnv "GHCUP_MSYS2" >>= \case
|
||||
Just fp -> pure fp
|
||||
Nothing -> do
|
||||
baseDir <- liftIO ghcupBaseDir
|
||||
pure (fromGHCupPath baseDir </> "msys64")
|
||||
|
||||
|
||||
@@ -26,36 +26,14 @@ import GHC.Base
|
||||
#endif
|
||||
import Language.Haskell.TH
|
||||
import Language.Haskell.TH.Quote ( QuasiQuoter(..) )
|
||||
import Language.Haskell.TH.Syntax ( Lift
|
||||
, dataToExpQ
|
||||
)
|
||||
import Language.Haskell.TH.Syntax ( dataToExpQ )
|
||||
import qualified Data.Text as T
|
||||
import qualified Language.Haskell.TH.Syntax as TH
|
||||
|
||||
|
||||
|
||||
deriving instance Data Versioning
|
||||
deriving instance Lift Versioning
|
||||
deriving instance Data Version
|
||||
deriving instance Lift Version
|
||||
deriving instance Data SemVer
|
||||
deriving instance Lift SemVer
|
||||
deriving instance Data Mess
|
||||
deriving instance Lift Mess
|
||||
deriving instance Data MChunk
|
||||
deriving instance Lift MChunk
|
||||
deriving instance Data PVP
|
||||
deriving instance Lift PVP
|
||||
deriving instance Lift VSep
|
||||
deriving instance Data VSep
|
||||
deriving instance Lift VUnit
|
||||
deriving instance Data VUnit
|
||||
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
deriving instance Lift (NonEmpty Word)
|
||||
deriving instance Lift (NonEmpty VChunk)
|
||||
deriving instance Lift (NonEmpty MChunk)
|
||||
deriving instance Lift (NonEmpty VUnit)
|
||||
#endif
|
||||
|
||||
qq :: (Text -> Q Exp) -> QuasiQuoter
|
||||
|
||||
@@ -26,7 +26,6 @@ import GHCup.Prelude
|
||||
import GHCup.Prelude.File
|
||||
import GHCup.Prelude.Logger
|
||||
|
||||
import Codec.Archive ( ArchiveResult )
|
||||
import Control.Applicative
|
||||
import Control.Exception.Safe
|
||||
import Control.Monad
|
||||
@@ -38,6 +37,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
|
||||
@@ -50,7 +50,6 @@ import System.FilePath
|
||||
import System.IO.Error
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Text.PrettyPrint.HughesPJClass (prettyShow)
|
||||
|
||||
|
||||
|
||||
@@ -234,7 +233,7 @@ setStack ver = do
|
||||
|
||||
liftIO (isShadowed stackbin) >>= \case
|
||||
Nothing -> pure ()
|
||||
Just pa -> lift $ logWarn $ T.pack $ prettyShow (ToolShadowed Cabal pa stackbin ver)
|
||||
Just pa -> lift $ logWarn $ T.pack $ prettyHFError (ToolShadowed Stack pa stackbin ver)
|
||||
|
||||
pure ()
|
||||
|
||||
@@ -280,6 +279,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)
|
||||
|
||||
@@ -22,29 +22,34 @@ module GHCup.Types
|
||||
( module GHCup.Types
|
||||
#if defined(BRICK)
|
||||
, Key(..)
|
||||
, Modifier(..)
|
||||
#endif
|
||||
, ArchiveResult(..)
|
||||
)
|
||||
where
|
||||
|
||||
import GHCup.Types.Stack ( SetupInfo )
|
||||
import GHCup.Utils.Tar.Types ( ArchiveResult(..) )
|
||||
import {-# SOURCE #-} GHCup.Utils.Dirs ( fromGHCupPath, GHCupPath )
|
||||
|
||||
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 Optics ( makeLenses )
|
||||
import Text.PrettyPrint.HughesPJClass (Pretty, pPrint, text, (<+>))
|
||||
import Text.PrettyPrint.HughesPJClass (Pretty, pPrint, text)
|
||||
import URI.ByteString
|
||||
#if defined(BRICK)
|
||||
import Graphics.Vty ( Key(..) )
|
||||
import Graphics.Vty ( Key(..), Modifier(..) )
|
||||
#endif
|
||||
|
||||
import qualified Data.ByteString.Lazy as BL
|
||||
import qualified Data.Text as T
|
||||
import qualified GHC.Generics as GHC
|
||||
|
||||
import qualified Data.List.NonEmpty as NE
|
||||
|
||||
#if !defined(BRICK)
|
||||
data Key = KEsc | KChar Char | KBS | KEnter
|
||||
@@ -53,8 +58,15 @@ data Key = KEsc | KChar Char | KBS | KEnter
|
||||
| KFun Int | KBackTab | KPrtScr | KPause | KIns
|
||||
| KHome | KPageUp | KDel | KEnd | KPageDown | KBegin | KMenu
|
||||
deriving (Eq,Show,Read,Ord,GHC.Generic)
|
||||
|
||||
data Modifier = MShift | MCtrl | MMeta | MAlt
|
||||
deriving (Eq,Show,Read,Ord,GHC.Generic)
|
||||
#endif
|
||||
|
||||
data KeyCombination = KeyCombination { key :: Key, mods :: [Modifier] }
|
||||
deriving (Eq,Show,Read,Ord,GHC.Generic)
|
||||
|
||||
|
||||
|
||||
--------------------
|
||||
--[ GHCInfo Tree ]--
|
||||
@@ -64,9 +76,9 @@ data Key = KEsc | KChar Char | KBS | KEnter
|
||||
data GHCupInfo = GHCupInfo
|
||||
{ _toolRequirements :: ToolRequirements
|
||||
, _ghcupDownloads :: GHCupDownloads
|
||||
, _globalTools :: Map GlobalTool DownloadInfo
|
||||
, _metadataUpdate :: Maybe URI
|
||||
}
|
||||
deriving (Show, GHC.Generic)
|
||||
deriving (Show, GHC.Generic, Eq)
|
||||
|
||||
instance NFData GHCupInfo
|
||||
|
||||
@@ -87,7 +99,7 @@ data Requirements = Requirements
|
||||
{ _distroPKGs :: [Text]
|
||||
, _notes :: Text
|
||||
}
|
||||
deriving (Show, GHC.Generic)
|
||||
deriving (Show, GHC.Generic, Eq)
|
||||
|
||||
instance NFData Requirements
|
||||
|
||||
@@ -103,7 +115,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
|
||||
@@ -126,18 +138,15 @@ instance Pretty Tool where
|
||||
|
||||
instance NFData Tool
|
||||
|
||||
data GlobalTool = ShimGen
|
||||
deriving (Eq, GHC.Generic, Ord, Show, Enum, Bounded)
|
||||
|
||||
instance NFData GlobalTool
|
||||
|
||||
|
||||
-- | All necessary information of a tool version, including
|
||||
-- source download and per-architecture downloads.
|
||||
data VersionInfo = VersionInfo
|
||||
{ _viTags :: [Tag] -- ^ version specific tag
|
||||
, _viReleaseDay :: Maybe Day
|
||||
, _viChangeLog :: Maybe URI
|
||||
, _viSourceDL :: Maybe DownloadInfo -- ^ source tarball
|
||||
, _viTestDL :: Maybe DownloadInfo -- ^ test tarball
|
||||
, _viArch :: ArchitectureSpec -- ^ descend for binary downloads per arch
|
||||
-- informative messages
|
||||
, _viPostInstall :: Maybe Text
|
||||
@@ -150,10 +159,17 @@ instance NFData VersionInfo
|
||||
|
||||
|
||||
-- | A tag. These are currently attached to a version of a tool.
|
||||
data Tag = Latest
|
||||
| Recommended
|
||||
| Prerelease
|
||||
| Base PVP
|
||||
data Tag = Latest -- ^ the latest version of a tool (unique per tool)
|
||||
| Recommended -- ^ the recommended version of a tool (unique per tool)
|
||||
| Prerelease -- ^ denotes a prerelease version
|
||||
-- (a version should either be 'Prerelease' or
|
||||
-- 'LatestPrerelease', but not both)
|
||||
| LatestPrerelease -- ^ the latest prerelease (unique per tool)
|
||||
| Nightly -- ^ denotes a nightly version
|
||||
-- (a version should either be 'Nightly' or
|
||||
-- 'LatestNightly', but not both)
|
||||
| LatestNightly -- ^ the latest nightly (unique per tool)
|
||||
| Base PVP -- ^ the base version shipped with GHC
|
||||
| Old -- ^ old versions are hidden by default in TUI
|
||||
| UnknownTag String -- ^ used for upwardscompat
|
||||
deriving (Ord, Eq, GHC.Generic, Show) -- FIXME: manual JSON instance
|
||||
@@ -164,16 +180,22 @@ tagToString :: Tag -> String
|
||||
tagToString Recommended = "recommended"
|
||||
tagToString Latest = "latest"
|
||||
tagToString Prerelease = "prerelease"
|
||||
tagToString Nightly = "nightly"
|
||||
tagToString (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
|
||||
tagToString (UnknownTag t ) = t
|
||||
tagToString LatestPrerelease = "latest-prerelease"
|
||||
tagToString LatestNightly = "latest-nightly"
|
||||
tagToString Old = ""
|
||||
|
||||
instance Pretty Tag where
|
||||
pPrint Recommended = text "recommended"
|
||||
pPrint Latest = text "latest"
|
||||
pPrint Prerelease = text "prerelease"
|
||||
pPrint Nightly = text "nightly"
|
||||
pPrint (Base pvp'') = text ("base-" ++ T.unpack (prettyPVP pvp''))
|
||||
pPrint (UnknownTag t ) = text t
|
||||
pPrint LatestPrerelease = text "latest-prerelease"
|
||||
pPrint LatestNightly = text "latest-prerelease"
|
||||
pPrint Old = mempty
|
||||
|
||||
data Architecture = A_64
|
||||
@@ -229,13 +251,18 @@ data LinuxDistro = Debian
|
||||
| RedHat
|
||||
| Alpine
|
||||
| AmazonLinux
|
||||
| Rocky
|
||||
| Void
|
||||
-- rolling
|
||||
| Gentoo
|
||||
| Exherbo
|
||||
-- not known
|
||||
| UnknownLinux
|
||||
-- ^ must exit
|
||||
deriving (Eq, GHC.Generic, Ord, Show)
|
||||
deriving (Eq, GHC.Generic, Ord, Show, Enum, Bounded)
|
||||
|
||||
allDistros :: [LinuxDistro]
|
||||
allDistros = enumFromTo minBound maxBound
|
||||
|
||||
instance NFData LinuxDistro
|
||||
|
||||
@@ -248,6 +275,8 @@ distroToString CentOS = "centos"
|
||||
distroToString RedHat = "redhat"
|
||||
distroToString Alpine = "alpine"
|
||||
distroToString AmazonLinux = "amazon"
|
||||
distroToString Rocky = "rocky"
|
||||
distroToString Void = "void"
|
||||
distroToString Gentoo = "gentoo"
|
||||
distroToString Exherbo = "exherbo"
|
||||
distroToString UnknownLinux = "unknown"
|
||||
@@ -263,6 +292,7 @@ data DownloadInfo = DownloadInfo
|
||||
, _dlSubdir :: Maybe TarDir
|
||||
, _dlHash :: Text
|
||||
, _dlCSize :: Maybe Integer
|
||||
, _dlOutput :: Maybe FilePath
|
||||
}
|
||||
deriving (Eq, Ord, GHC.Generic, Show)
|
||||
|
||||
@@ -274,6 +304,23 @@ instance NFData DownloadInfo
|
||||
--[ Others ]--
|
||||
--------------
|
||||
|
||||
data DownloadMirror = DownloadMirror {
|
||||
authority :: Authority
|
||||
, pathPrefix :: Maybe Text
|
||||
} deriving (Eq, Ord, GHC.Generic, Show)
|
||||
|
||||
instance NFData DownloadMirror
|
||||
|
||||
newtype DownloadMirrors = DM (Map Text DownloadMirror)
|
||||
deriving (Eq, Ord, GHC.Generic, Show)
|
||||
|
||||
instance NFData DownloadMirrors
|
||||
|
||||
instance NFData UserInfo
|
||||
instance NFData Host
|
||||
instance NFData Port
|
||||
instance NFData Authority
|
||||
|
||||
|
||||
-- | How to descend into a tar archive.
|
||||
data TarDir = RealDir FilePath
|
||||
@@ -289,19 +336,51 @@ instance Pretty TarDir where
|
||||
|
||||
-- | Where to fetch GHCupDownloads from.
|
||||
data URLSource = GHCupURL
|
||||
| OwnSource [Either GHCupInfo URI] -- ^ complete source list
|
||||
| OwnSpec GHCupInfo
|
||||
| AddSource [Either GHCupInfo URI] -- ^ merge with GHCupURL
|
||||
deriving (GHC.Generic, Show)
|
||||
| StackSetupURL
|
||||
| OwnSource [Either (Either GHCupInfo SetupInfo) URI] -- ^ complete source list
|
||||
| OwnSpec (Either GHCupInfo SetupInfo)
|
||||
| AddSource [Either (Either GHCupInfo SetupInfo) URI] -- ^ merge with GHCupURL
|
||||
| SimpleList [NewURLSource]
|
||||
deriving (Eq, GHC.Generic, Show)
|
||||
|
||||
data NewURLSource = NewGHCupURL
|
||||
| NewStackSetupURL
|
||||
| NewGHCupInfo GHCupInfo
|
||||
| NewSetupInfo SetupInfo
|
||||
| NewURI URI
|
||||
deriving (Eq, GHC.Generic, Show)
|
||||
|
||||
instance NFData NewURLSource
|
||||
|
||||
fromURLSource :: URLSource -> [NewURLSource]
|
||||
fromURLSource GHCupURL = [NewGHCupURL]
|
||||
fromURLSource StackSetupURL = [NewStackSetupURL]
|
||||
fromURLSource (OwnSource arr) = convert' <$> arr
|
||||
fromURLSource (AddSource arr) = NewGHCupURL:(convert' <$> arr)
|
||||
fromURLSource (SimpleList arr) = arr
|
||||
fromURLSource (OwnSpec (Left gi)) = [NewGHCupInfo gi]
|
||||
fromURLSource (OwnSpec (Right si)) = [NewSetupInfo si]
|
||||
|
||||
convert' :: Either (Either GHCupInfo SetupInfo) URI -> NewURLSource
|
||||
convert' (Left (Left gi)) = NewGHCupInfo gi
|
||||
convert' (Left (Right si)) = NewSetupInfo si
|
||||
convert' (Right uri) = NewURI uri
|
||||
|
||||
instance NFData URLSource
|
||||
instance NFData (URIRef Absolute) where
|
||||
rnf (URI !_ !_ !_ !_ !_) = ()
|
||||
|
||||
|
||||
data MetaMode = Strict
|
||||
| Lax
|
||||
deriving (Show, Read, Eq, GHC.Generic)
|
||||
|
||||
instance NFData MetaMode
|
||||
|
||||
data UserSettings = UserSettings
|
||||
{ uCache :: Maybe Bool
|
||||
, uMetaCache :: Maybe Integer
|
||||
, uMetaMode :: Maybe MetaMode
|
||||
, uNoVerify :: Maybe Bool
|
||||
, uVerbose :: Maybe Bool
|
||||
, uKeepDirs :: Maybe KeepDirs
|
||||
@@ -310,18 +389,20 @@ data UserSettings = UserSettings
|
||||
, uUrlSource :: Maybe URLSource
|
||||
, uNoNetwork :: Maybe Bool
|
||||
, uGPGSetting :: Maybe GPGSetting
|
||||
, uPlatformOverride :: Maybe PlatformRequest
|
||||
, uPlatformOverride :: Maybe PlatformRequest
|
||||
, uMirrors :: Maybe DownloadMirrors
|
||||
}
|
||||
deriving (Show, GHC.Generic)
|
||||
deriving (Show, GHC.Generic, Eq)
|
||||
|
||||
defaultUserSettings :: UserSettings
|
||||
defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
||||
defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
||||
|
||||
fromSettings :: Settings -> Maybe KeyBindings -> UserSettings
|
||||
fromSettings Settings{..} Nothing =
|
||||
UserSettings {
|
||||
uCache = Just cache
|
||||
, uMetaCache = Just metaCache
|
||||
, uMetaMode = Just metaMode
|
||||
, uNoVerify = Just noVerify
|
||||
, uVerbose = Just verbose
|
||||
, uKeepDirs = Just keepDirs
|
||||
@@ -331,6 +412,7 @@ fromSettings Settings{..} Nothing =
|
||||
, uUrlSource = Just urlSource
|
||||
, uGPGSetting = Just gpgSetting
|
||||
, uPlatformOverride = platformOverride
|
||||
, uMirrors = Just mirrors
|
||||
}
|
||||
fromSettings Settings{..} (Just KeyBindings{..}) =
|
||||
let ukb = UserKeyBindings
|
||||
@@ -342,11 +424,11 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
|
||||
, kSet = Just bSet
|
||||
, kChangelog = Just bChangelog
|
||||
, kShowAll = Just bShowAllVersions
|
||||
, kShowAllTools = Just bShowAllTools
|
||||
}
|
||||
in UserSettings {
|
||||
uCache = Just cache
|
||||
, uMetaCache = Just metaCache
|
||||
, uMetaMode = Just metaMode
|
||||
, uNoVerify = Just noVerify
|
||||
, uVerbose = Just verbose
|
||||
, uKeepDirs = Just keepDirs
|
||||
@@ -356,48 +438,52 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
|
||||
, uUrlSource = Just urlSource
|
||||
, uGPGSetting = Just gpgSetting
|
||||
, uPlatformOverride = platformOverride
|
||||
, uMirrors = Just mirrors
|
||||
}
|
||||
|
||||
data UserKeyBindings = UserKeyBindings
|
||||
{ kUp :: Maybe Key
|
||||
, kDown :: Maybe Key
|
||||
, kQuit :: Maybe Key
|
||||
, kInstall :: Maybe Key
|
||||
, kUninstall :: Maybe Key
|
||||
, kSet :: Maybe Key
|
||||
, kChangelog :: Maybe Key
|
||||
, kShowAll :: Maybe Key
|
||||
, kShowAllTools :: Maybe Key
|
||||
{ kUp :: Maybe KeyCombination
|
||||
, kDown :: Maybe KeyCombination
|
||||
, kQuit :: Maybe KeyCombination
|
||||
, kInstall :: Maybe KeyCombination
|
||||
, kUninstall :: Maybe KeyCombination
|
||||
, kSet :: Maybe KeyCombination
|
||||
, kChangelog :: Maybe KeyCombination
|
||||
, kShowAll :: Maybe KeyCombination
|
||||
}
|
||||
deriving (Show, GHC.Generic)
|
||||
deriving (Show, GHC.Generic, Eq)
|
||||
|
||||
data KeyBindings = KeyBindings
|
||||
{ bUp :: Key
|
||||
, bDown :: Key
|
||||
, bQuit :: Key
|
||||
, bInstall :: Key
|
||||
, bUninstall :: Key
|
||||
, bSet :: Key
|
||||
, bChangelog :: Key
|
||||
, bShowAllVersions :: Key
|
||||
, bShowAllTools :: Key
|
||||
{ bUp :: KeyCombination
|
||||
, bDown :: KeyCombination
|
||||
, bQuit :: KeyCombination
|
||||
, bInstall :: KeyCombination
|
||||
, bUninstall :: KeyCombination
|
||||
, bSet :: KeyCombination
|
||||
, bChangelog :: KeyCombination
|
||||
, bShowAllVersions :: KeyCombination
|
||||
}
|
||||
deriving (Show, GHC.Generic)
|
||||
|
||||
instance NFData KeyBindings
|
||||
#if !defined(BRICK)
|
||||
instance NFData Key
|
||||
|
||||
instance NFData Modifier
|
||||
|
||||
#endif
|
||||
instance NFData KeyCombination
|
||||
|
||||
defaultKeyBindings :: KeyBindings
|
||||
defaultKeyBindings = KeyBindings
|
||||
{ bUp = KUp
|
||||
, bDown = KDown
|
||||
, bQuit = KChar 'q'
|
||||
, bInstall = KChar 'i'
|
||||
, bUninstall = KChar 'u'
|
||||
, bSet = KChar 's'
|
||||
, bChangelog = KChar 'c'
|
||||
, bShowAllVersions = KChar 'a'
|
||||
, bShowAllTools = KChar 't'
|
||||
{ bUp = KeyCombination { key = KUp , mods = [] }
|
||||
, bDown = KeyCombination { key = KDown , mods = [] }
|
||||
, bQuit = KeyCombination { key = KChar 'q', mods = [] }
|
||||
, bInstall = KeyCombination { key = KChar 'i', mods = [] }
|
||||
, bUninstall = KeyCombination { key = KChar 'u', mods = [] }
|
||||
, bSet = KeyCombination { key = KChar 's', mods = [] }
|
||||
, bChangelog = KeyCombination { key = KChar 'c', mods = [] }
|
||||
, bShowAllVersions = KeyCombination { key = KChar 'a', mods = [] }
|
||||
}
|
||||
|
||||
data AppState = AppState
|
||||
@@ -427,6 +513,7 @@ instance NFData LeanAppState
|
||||
data Settings = Settings
|
||||
{ cache :: Bool
|
||||
, metaCache :: Integer
|
||||
, metaMode :: MetaMode
|
||||
, noVerify :: Bool
|
||||
, keepDirs :: KeepDirs
|
||||
, downloader :: Downloader
|
||||
@@ -436,6 +523,7 @@ data Settings = Settings
|
||||
, gpgSetting :: GPGSetting
|
||||
, noColor :: Bool -- this also exists in LoggerConfig
|
||||
, platformOverride :: Maybe PlatformRequest
|
||||
, mirrors :: DownloadMirrors
|
||||
}
|
||||
deriving (Show, GHC.Generic)
|
||||
|
||||
@@ -443,7 +531,7 @@ defaultMetaCache :: Integer
|
||||
defaultMetaCache = 300 -- 5 minutes
|
||||
|
||||
defaultSettings :: Settings
|
||||
defaultSettings = Settings False defaultMetaCache False Never Curl False GHCupURL False GPGNone False Nothing
|
||||
defaultSettings = Settings False defaultMetaCache Lax False Never Curl False GHCupURL False GPGNone False Nothing (DM mempty)
|
||||
|
||||
instance NFData Settings
|
||||
|
||||
@@ -456,11 +544,23 @@ data Dirs = Dirs
|
||||
, dbDir :: GHCupPath
|
||||
, recycleDir :: GHCupPath -- mainly used on windows
|
||||
, tmpDir :: GHCupPath
|
||||
, msys2Dir :: FilePath
|
||||
}
|
||||
deriving (Show, GHC.Generic)
|
||||
|
||||
instance NFData Dirs
|
||||
|
||||
data MSYS2Env = MSYS
|
||||
| UCRT64
|
||||
| CLANG64
|
||||
| CLANGARM64
|
||||
| CLANG32
|
||||
| MINGW64
|
||||
| MINGW32
|
||||
deriving (Eq, Show, Ord, GHC.Generic, Read)
|
||||
|
||||
instance NFData MSYS2Env
|
||||
|
||||
data KeepDirs = Always
|
||||
| Errors
|
||||
| Never
|
||||
@@ -548,7 +648,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
|
||||
@@ -587,6 +689,17 @@ data VersionRange = SimpleRange (NonEmpty VersionCmp) -- And
|
||||
|
||||
instance NFData VersionRange
|
||||
|
||||
instance Pretty VersionCmp where
|
||||
pPrint (VR_gt v) = text "> " <> pPrint v
|
||||
pPrint (VR_gteq v) = text ">= " <> pPrint v
|
||||
pPrint (VR_lt v) = text "< " <> pPrint v
|
||||
pPrint (VR_lteq v) = text "<= " <> pPrint v
|
||||
pPrint (VR_eq v) = text "= " <> pPrint v
|
||||
|
||||
instance Pretty VersionRange where
|
||||
pPrint (SimpleRange xs) = foldl1 (\x y -> x <> text " && " <> y) $ NE.map pPrint xs
|
||||
pPrint (OrRange xs vr) = foldMap pPrint xs <> " || " <> pPrint vr
|
||||
|
||||
instance Pretty Versioning where
|
||||
pPrint = text . T.unpack . prettyV
|
||||
|
||||
@@ -623,15 +736,7 @@ data ProcessError = NonZeroExit Int FilePath [String]
|
||||
| NoSuchPid FilePath [String]
|
||||
deriving Show
|
||||
|
||||
instance Pretty ProcessError where
|
||||
pPrint (NonZeroExit e exe args) =
|
||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "failed with exit code" <+> text (show e <> ".")
|
||||
pPrint (PTerminated exe args) =
|
||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "terminated."
|
||||
pPrint (PStopped exe args) =
|
||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "stopped."
|
||||
pPrint (NoSuchPid exe args) =
|
||||
text "Could not find PID for process running " <+> pPrint exe <+> text " with arguments " <+> text (show args) <+> text "."
|
||||
|
||||
data CapturedProcess = CapturedProcess
|
||||
{ _exitCode :: ExitCode
|
||||
, _stdOut :: BL.ByteString
|
||||
@@ -666,3 +771,21 @@ type PromptQuestion = Text
|
||||
|
||||
data PromptResponse = PromptYes | PromptNo
|
||||
deriving (Show, Eq)
|
||||
|
||||
data ToolVersion = GHCVersion GHCTargetVersion
|
||||
| ToolVersion Version
|
||||
| ToolTag Tag
|
||||
| ToolDay Day
|
||||
deriving (Eq, Show)
|
||||
|
||||
instance Pretty ToolVersion where
|
||||
pPrint (GHCVersion v) = pPrint v
|
||||
pPrint (ToolVersion v) = pPrint v
|
||||
pPrint (ToolTag t) = pPrint t
|
||||
pPrint (ToolDay d) = text (show d)
|
||||
|
||||
|
||||
|
||||
data BuildSystem = Hadrian
|
||||
| Make
|
||||
deriving (Show, Eq)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user