Compare commits

..

111 Commits

Author SHA1 Message Date
ea6c8d338c Bump ghcup in bootstrap script 2023-02-24 19:52:50 +08:00
ae625b181c Improve pull_release_artifacts 2023-02-24 19:52:41 +08:00
89ae54a083 Set release date 2023-02-24 00:00:29 +08:00
1bd73591ba Update data/metadata 2023-02-23 23:58:16 +08:00
f709f6e714 Update ChangeLog 2023-02-23 23:56:46 +08:00
3d7e07c371 Merge branch 'issue-796' 2023-02-23 23:52:38 +08:00
8bf17379ac Fix windows bootstrap, fixes #796 2023-02-23 23:41:25 +08:00
4b1225ad71 Merge branch 'issue-797' 2023-02-23 23:15:48 +08:00
d628848af6 Silence hlint 2023-02-23 23:15:08 +08:00
48381be001 Bump GHC 9.2.5 to 9.2.6 2023-02-23 23:07:46 +08:00
b547324253 Smarter variants for 'listDirectory', fixing #797 2023-02-23 21:47:50 +08:00
2b1599c234 Fix windows golden file 2023-02-23 20:57:40 +08:00
7ac8989dfc Bump to 0.1.19.2 2023-02-21 23:01:08 +08:00
cd6666ed30 Merge branch 'latest-prerelease' 2023-02-21 23:00:47 +08:00
5b7478438a Merge branch 'issue-787' 2023-02-21 23:00:31 +08:00
4a830d9fb7 Fix regression in JFS support, fixes #787 2023-02-21 22:48:22 +08:00
785fb895b4 Implement 'latest-prerelease' tag wrt #788 2023-02-21 22:22:11 +08:00
75e801e9e6 Merge branch 'ghcup-0.1.19.1' 2023-02-20 00:03:26 +08:00
6ffd5328a4 Improve sftp-symlink-artifacts.sh 2023-02-20 00:01:11 +08:00
ed509e482b Improve pull_release_artifacts 2023-02-19 23:58:25 +08:00
420323f43b Update bootstrap script to 0.1.19.1 2023-02-19 23:58:07 +08:00
432962792c Update ghcup-metadata 2023-02-19 22:56:33 +08:00
cb193f6069 Update ChangeLog for 0.1.19.1 2023-02-19 22:55:47 +08:00
2f268b6a25 Bump GHCup version 2023-02-19 22:44:28 +08:00
580606af14 Merge remote-tracking branch 'origin/pr/773' 2023-02-19 22:42:08 +08:00
faa1c3992b Merge branch 'issue-762' 2023-02-19 22:41:27 +08:00
d17efef853 Merge branch 'issue-784' 2023-02-19 21:38:41 +08:00
179d4dd493 Fixup 2023-02-19 19:33:01 +08:00
e03c5ee4a1 Don't fail on setModificationTime, fixes #784
Related:

* https://github.com/actions/runner-images/issues/7061
* https://github.com/actions/runner-images/pull/7068
2023-02-19 19:24:45 +08:00
e57a8abd3d Merge branch 'issue-751' 2023-02-19 19:23:48 +08:00
5fa10390a3 Fix CI 2023-02-19 19:15:09 +08:00
e1e6f579d5 Use debian:10 rather 2023-02-19 18:48:42 +08:00
72f8e53344 Fix CI 2023-02-19 17:32:28 +08:00
9c464ec9fc Don't fail if the duplicate is the last element 2023-02-19 17:25:14 +08:00
1c9b296a5e Merge remote-tracking branch 'origin/pr/782' 2023-02-18 19:44:25 +08:00
Bryan Richter
275522584e Remove deprecated www 2023-02-17 13:30:29 +02:00
Bryan Richter
804520c4bb Remove duplicate js/css includes 2023-02-17 12:56:51 +02:00
Bryan Richter
9d25581f3c Use favicon from gitlab.haskell.org
The current .png is presumably the wrong shape and looks flattened.

Plus, mkdocs complained that 'site_favicon' was an unrecognised
configuration name, so I used the method described in the docs instead:

https://www.mkdocs.org/user-guide/customizing-your-theme/#using-the-theme_dir
2023-02-17 12:55:27 +02:00
Bryan Richter
e798037d80 Simplify removal of next/prev buttons
As documented on how to override template blocks:

https://www.mkdocs.org/user-guide/customizing-your-theme/#overriding-template-blocks

This is a big diff. I tested it by generating docs before and after the
change, and they were functionally identical.
2023-02-17 12:53:28 +02:00
Bryan Richter
2afe5858cb Remove unused/missing javascript 2023-02-17 10:44:34 +02:00
f575dcdad6 Improve usability on 'ghcup config add-release-channel'
Fixes #751 (or so I hope).
2023-02-12 19:58:08 +08:00
6cf9967e7c Work around missing libtinfo.so.6 2023-02-12 18:41:40 +08:00
15a75d790a Build arm binaries in bionic images, fixes #762 2023-02-12 17:16:32 +08:00
988672ea75 Build arm images for bionic as well wrh #762 2023-02-12 17:16:27 +08:00
6d3e8d65e1 Make readDirEntPortable more robust 2023-02-11 18:51:34 +08:00
895e4b3f18 Merge branch 'issue-775' 2023-02-11 18:38:39 +08:00
20f0505120 Don't implicitly smuggle in config options
Fixes #775
2023-02-09 00:04:53 +08:00
31e83cac5e Don't configure meta-mode = Strict in bootstrap 2023-02-08 22:42:17 +08:00
ksqsf
9baba88f75 Add a known mirror 2023-02-08 22:09:04 +08:00
d3a1115b99 Fix FreeBSD URL 2023-02-04 01:00:52 +08:00
6d46849fec Merge remote-tracking branch 'origin/issue-766' 2023-02-03 23:58:50 +08:00
53e324bfee Fix failure on JFS filesystems
Some filesystems always return DT_UNKNOWN for d_type, since
it's non-portable.

For those cases we use 'stat' to figure out the file type.

Similar to: https://github.com/ggreer/the_silver_searcher/pull/37
2023-02-03 22:48:05 +08:00
2e39b7b603 Fix FreeBSD URL 2023-02-03 22:43:41 +08:00
048932bf50 Fix _eghcup invocations 2023-02-01 16:53:25 +08:00
69d325bf90 Set metadata fetching mode to strict in bootstrap script
And improve error messages.
2023-02-01 16:44:10 +08:00
3d1b8859cd Merge remote-tracking branch 'origin/pr/759' 2023-01-26 22:05:35 +08:00
db89ca9942 Merge remote-tracking branch 'origin/pr/758' 2023-01-26 22:05:30 +08:00
bba009d98c Merge remote-tracking branch 'origin/pr/760' 2023-01-26 22:04:38 +08:00
9d954ea174 Add platforms to i386 alpine 2023-01-26 21:18:11 +08:00
da9c9049d2 Fix alpine32/Dockerfile 2023-01-26 21:04:07 +08:00
a4c00d2c56 Make version shortcuts work with 'ghcup set', fixes #757 2023-01-24 15:24:03 +08:00
Zixian Cai
b30f565871 Fix index.md as well 2023-01-23 16:07:36 +11:00
Zixian Cai
fa378a1d34 Fix section hyperlink 2023-01-23 16:06:00 +11:00
timo-a
119efb1ff4 fix link
currently resolves to: https://www.haskell.org/ghcup/install/install/#supported-tools
this commit fixes it to https://www.haskell.org/ghcup/install/#supported-tools
2023-01-22 15:36:14 +01:00
1fb4101b49 Fix msys2 URL, wrt #755 2023-01-21 17:58:26 +08:00
ec8333b223 Small CI fixes 2023-01-18 22:04:02 +08:00
54b979aa0b Merge remote-tracking branch 'origin/pr/748' 2023-01-16 21:14:15 +08:00
ba274307c0 Improve CI 2023-01-16 20:29:16 +08:00
Rui Chen
a623d0809d build: remove travis config
Signed-off-by: Rui Chen <rui@chenrui.dev>
2023-01-14 13:24:45 -05:00
e00899d176 Disable simdutf on windows, wrt #745 2023-01-14 00:59:52 +08:00
a38ca1954b Fix build on unix with -ftui 2023-01-13 12:33:40 +08:00
3f5a19c63e Post release cleanup 2023-01-13 12:07:32 +08:00
525e9672e8 Make cirrus CI task discoverable 2023-01-13 11:16:13 +08:00
070c6e1cf1 Add missing entry to CHANGELOG 2023-01-13 10:57:57 +08:00
195fd00e0a Add CHANGELOG for 0.1.19.0 2023-01-13 10:41:49 +08:00
733d014c19 Bump version to 0.1.19.0 2023-01-13 10:13:51 +08:00
16039769d5 Refreeze 2023-01-13 10:12:34 +08:00
5eeb8ca9fc Fix windows 2023-01-13 00:26:15 +08:00
317a06bbc3 Fix ARM build 2023-01-13 00:03:12 +08:00
f693adcd7c Fix FreeBSD build for text-2.0 2023-01-12 23:53:03 +08:00
ac88d2bd50 Fix cache eviction 2023-01-12 23:44:53 +08:00
a427146de5 Update dependencies and make buildable with GHC-9.4.4 2023-01-12 13:52:08 +08:00
a16bcddeaa Update dependencies 2023-01-12 13:01:12 +08:00
74edf1fc07 Merge branch 'testsuite' 2023-01-12 12:58:39 +08:00
1e32639873 Implement 'ghcup test ghc' based on the bindist testsuite 2023-01-12 12:58:10 +08:00
0704d2640a Document how to install windows manually, fixes #697 2023-01-12 00:45:16 +08:00
26a6368d79 Merge remote-tracking branch 'origin/pr/700' 2023-01-08 22:26:19 +08:00
54af66d115 Merge branch 'HF-errors' 2023-01-05 21:39:23 +08:00
850799c21a Merge remote-tracking branch 'origin/pr/739' 2023-01-05 21:32:07 +08:00
d4834d7541 Update docs/about.md
Co-authored-by: tomjaguarpaw <tom-github.com@jaguarpaw.co.uk>
2023-01-05 07:32:51 +08:00
2895dd9d13 Bump cabal-cache with amazonka patch 2023-01-04 21:08:10 +08:00
eb9a0b66c4 Document distribution policies 2023-01-04 18:51:40 +08:00
8d0432b961 Make sure FreeBSD runner uses GMT
This should fix parsing issues in amazonka and
cabal-cache:

* https://github.com/haskell-works/cabal-cache/issues/207
* https://github.com/brendanhay/amazonka/issues/866
2023-01-04 16:56:07 +08:00
ab2c01d1c9 Don't install stack by default in CI 2023-01-04 16:50:55 +08:00
fffaa65b7f Don't install stack by default in CI 2023-01-04 00:58:05 +08:00
703be0a706 Add support for mirrors wrt #357 2023-01-04 00:36:07 +08:00
4be97ffd7c Pad and use hyperlinks 2023-01-03 23:43:46 +08:00
009f9211a9 Integrate with errors.haskell.org
Fixes #434
2023-01-03 23:43:46 +08:00
109187eb6f Merge branch 'issue-367-content-prop' 2023-01-03 23:17:35 +08:00
e881705323 Merge branch 'issue-440' 2023-01-03 22:47:12 +08:00
ea06c155a7 Merge branch 'issue-695' 2023-01-03 22:46:52 +08:00
d4732e15a7 Merge branch 'issue-716' 2023-01-03 22:46:13 +08:00
db6f784a1f Merge branch 'error-handling' 2023-01-03 22:45:25 +08:00
82e3837dd9 Update windows golden test file 2023-01-02 21:42:52 +08:00
957c5918b8 Upload golden files on failure 2023-01-02 20:47:49 +08:00
9d4c923649 Add content-length property to downloads
This is optional for now. Fixes #367
2023-01-02 20:41:42 +08:00
24c36ef856 Fix failure with --isolate=dir --force
Fixes #695
2023-01-02 20:39:27 +08:00
d5a680e3c6 Don't clean up tmp dirs when --keep=always 2023-01-02 20:38:26 +08:00
e116a2392e Enable arm tests 2023-01-01 21:40:04 +08:00
7dd6f1f4a4 Expose metadata-caching to --help 2023-01-01 19:19:37 +08:00
4d82c37539 Add --metadata-fetching-mode arg, fixes #440 2023-01-01 19:16:32 +08:00
105 changed files with 10873 additions and 8428 deletions

View File

@@ -1,10 +1,11 @@
freebsd_instance:
image_family: freebsd-13-1
task:
build_task:
name: build
env:
GHC_VER: 9.2.4
CABAL_VER: 3.6.2.0
CABAL_VER: 3.8.1.0
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
ARCH: 64
RUNNER_OS: FreeBSD
@@ -12,11 +13,13 @@ task:
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]
AWS_ACCESS_KEY_ID: ENCRYPTED[6ed6287e2dd78ab5f84b22232c5245834ab042bd8ba443883aaf4b4d1ecc0481add1fdfad5ae6f6a8cfb418e6f19b2fc]
AWS_SECRET_ACCESS_KEY: ENCRYPTED[16f3cda2954c7cee99444e6788eb5997382aa4ce1477e7523fef2586077541f43b5c816156961fc6b4677259679875a7]
S3_HOST: ENCRYPTED[ce961780a33159f7d1d8046956b5ac6ebc3bfc8149428e5f538576cda51d9f3d0c35b79cdd1e325793639ff6e31f889d]
install_script: pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake
install_script: pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake llvm14
script:
- tzsetup Etc/GMT
- adjkerntz -a
- bash .github/scripts/build.sh
- bash .github/scripts/test.sh
binaries_artifacts:

View File

@@ -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
View 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+"$@"}

View File

@@ -2,75 +2,34 @@
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)
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 ./dist-newstyle/cache/plan.json "out/${ARTIFACT}.plan.json"

View File

@@ -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() {
@@ -34,10 +24,6 @@ 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"
@@ -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
;;
@@ -134,25 +121,36 @@ download_cabal_cache() {
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() {

30
.github/scripts/env.sh vendored Normal file
View File

@@ -0,0 +1,30 @@
#!/bin/sh
if [ "${RUNNER_OS}" = "Windows" ] ; then
ext=".exe"
else
ext=''
fi
export DEBIAN_FRONTEND=noninteractive
export TZ=Asia/Singapore
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

View File

@@ -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}"

View File

@@ -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

View File

@@ -2,7 +2,6 @@
set -eux
. .github/scripts/prereq.sh
. .github/scripts/common.sh
@@ -191,7 +190,7 @@ 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-0.0.7.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 +200,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-0.0.7.yaml list
etag3=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
sha3=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
[ "${etag2}" = "${etag3}" ]

View File

@@ -20,7 +20,6 @@ jobs:
BOOTSTRAP_HASKELL_NONINTERACTIVE: yes
ARCH: 64
JSON_VERSION: "0.0.7"
APT_GET: "sudo apt-get"
strategy:
matrix:
include:
@@ -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,8 @@ jobs:
- if: runner.os == 'Windows'
name: Run bootstrap
run: ./scripts/bootstrap/bootstrap-haskell.ps1 -InstallDir ${GITHUB_WORKSPACE} -BootstrapUrl ${GITHUB_WORKSPACE}/bootstrap-haskell -InBash
run: |
$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
shell: pwsh

View File

@@ -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 }}

View File

@@ -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,74 @@ 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, aarch32-linux]
steps:
- uses: docker://arm64v8/ubuntu:focal
name: Cleanup
name: Cleanup (aarch64 linux)
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)
uses: docker/build-push-action@v3
with:
context: ./docker/arm32v7
push: true
tags: hasufell/arm32v7-ubuntu-haskell:focal
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/focal
push: true
tags: hasufell/arm32v7-debian-haskell:10
platforms: linux/arm
docker-aarch:
runs-on: [self-hosted, Linux, ARM64]
steps:
- uses: docker://arm64v8/ubuntu:focal
name: Cleanup (aarch64 linux)
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-debian-haskell:10
platforms: linux/arm64

View File

@@ -17,7 +17,7 @@ jobs:
name: Build linux binary
runs-on: ${{ matrix.os }}
env:
CABAL_VER: 3.6.2.0
CABAL_VER: 3.8.1.0
JSON_VERSION: "0.0.7"
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -81,7 +81,7 @@ jobs:
name: Build ARM binary
runs-on: ${{ matrix.os }}
env:
CABAL_VER: 3.6.2.0
CABAL_VER: 3.8.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 }}
@@ -90,16 +90,16 @@ jobs:
fail-fast: true
matrix:
include:
- os: [self-hosted, Linux, aarch64]
- os: [self-hosted, Linux, ARM64, aarch32-linux]
ARTIFACT: "armv7-linux-ghcup"
GHC_VER: 8.10.7
GHC_VER: 9.2.2
ARCH: ARM
- os: [self-hosted, Linux, aarch64]
- os: [self-hosted, Linux, ARM64]
ARTIFACT: "aarch64-linux-ghcup"
GHC_VER: 8.10.7
GHC_VER: 9.2.6
ARCH: ARM64
steps:
- uses: docker://arm64v8/ubuntu:focal
- uses: docker://arm64v8/debian:10
name: Cleanup (aarch64 linux)
with:
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
@@ -115,7 +115,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 +129,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,7 +154,7 @@ jobs:
name: Build binary (Mac/Win)
runs-on: ${{ matrix.os }}
env:
CABAL_VER: 3.6.2.0
CABAL_VER: 3.8.1.0
MACOSX_DEPLOYMENT_TARGET: 10.13
JSON_VERSION: "0.0.7"
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -164,13 +164,13 @@ 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.2.6
ARCH: ARM64
- os: macOS-10.15
ARTIFACT: "x86_64-apple-darwin-ghcup"
GHC_VER: 9.2.5
GHC_VER: 9.2.6
ARCH: 64
- os: windows-latest
ARTIFACT: "x86_64-mingw64-ghcup"
@@ -182,8 +182,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@11 autoconf automake
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$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"
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,13 +242,12 @@ jobs:
path: |
./out/*
test-linux:
name: Test linux
needs: "build-linux"
runs-on: ${{ matrix.os }}
env:
CABAL_VER: 3.6.2.0
CABAL_VER: 3.8.1.0
JSON_VERSION: "0.0.7"
strategy:
matrix:
@@ -264,37 +303,46 @@ 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
uses: actions/upload-artifact@v3
with:
name: testfiles
path: |
./test/golden/unix/GHCupInfo*json
test-arm:
name: Test ARM
needs: "build-arm"
runs-on: ${{ matrix.os }}
env:
CABAL_VER: 3.6.2.0
CABAL_VER: 3.8.1.0
JSON_VERSION: "0.0.7"
strategy:
matrix:
include:
- os: [self-hosted, Linux, aarch64]
- os: [self-hosted, Linux, ARM64, aarch32-linux]
ARTIFACT: "armv7-linux-ghcup"
GHC_VER: 8.10.7
GHC_VER: 9.2.2
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.2.6
ARCH: ARM64
DISTRO: Ubuntu
steps:
- uses: docker://arm64v8/ubuntu:focal
- uses: docker://arm64v8/debian:10
name: Cleanup (aarch64 linux)
with:
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
@@ -310,8 +358,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:
@@ -321,8 +369,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:
@@ -331,25 +379,33 @@ jobs:
GHC_VER: ${{ matrix.GHC_VER }}
DISTRO: Ubuntu
- if: failure()
name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: testfiles
path: |
./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.8.1.0
MACOSX_DEPLOYMENT_TARGET: 10.13
JSON_VERSION: "0.0.7"
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.2.6
ARCH: ARM64
DISTRO: na
- os: macOS-10.15
ARTIFACT: "x86_64-apple-darwin-ghcup"
GHC_VER: 9.2.5
GHC_VER: 9.2.6
ARCH: 64
DISTRO: na
- os: windows-latest
@@ -369,7 +425,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 }}
@@ -377,6 +447,22 @@ jobs:
GHC_VER: ${{ matrix.GHC_VER }}
DISTRO: ${{ matrix.DISTRO }}
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
- if: failure() && runner.os == 'Windows'
name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: testfiles
path: |
./test/golden/windows/GHCupInfo*json
- if: failure() && runner.os != 'Windows'
name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: testfiles
path: |
./test/golden/unix/GHCupInfo*json
hls:
name: hls
needs: build-linux
@@ -384,7 +470,7 @@ jobs:
env:
GHC_VERSION: "8.10.7"
HLS_TARGET_VERSION: "1.8.0.0"
CABAL_VERSION: "3.6.2.0"
CABAL_VERSION: "3.8.1.0"
JSON_VERSION: "0.0.7"
ARTIFACT: "x86_64-linux-ghcup"
DISTRO: Ubuntu
@@ -404,9 +490,9 @@ 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

View File

@@ -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

View File

@@ -1,5 +1,41 @@
# Revision history for ghcup
## 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)

View File

@@ -4,6 +4,7 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ViewPatterns #-}
module BrickMain where
@@ -95,11 +96,11 @@ data BrickState = BrickState
keyHandlers :: KeyBindings
-> [ ( Vty.Key
, BrickSettings -> String
, BrickState -> EventM n (Next BrickState)
, BrickState -> EventM String BrickState ()
)
]
keyHandlers KeyBindings {..} =
[ (bQuit, const "Quit" , halt)
[ (bQuit, const "Quit" , \_ -> halt)
, (bInstall, const "Install" , withIOAction install')
, (bUninstall, const "Uninstall", withIOAction del')
, (bSet, const "Set" , withIOAction set')
@@ -114,14 +115,14 @@ keyHandlers KeyBindings {..} =
if showAllTools then "Don't show all tools" else "Show all tools"
, hideShowHandler showAllVersions (not . showAllTools)
)
, (bUp, const "Up", \BrickState {..} -> continue BrickState{ appState = moveCursor 1 appState Up, .. })
, (bDown, const "Down", \BrickState {..} -> continue BrickState{ appState = moveCursor 1 appState Down, .. })
, (bUp, const "Up", \BrickState {..} -> put BrickState{ appState = moveCursor 1 appState Up, .. })
, (bDown, const "Down", \BrickState {..} -> put BrickState{ appState = moveCursor 1 appState Down, .. })
]
where
hideShowHandler f p BrickState{..} =
let newAppSettings = appSettings { showAllVersions = f appSettings , showAllTools = p appSettings }
newInternalState = constructList appData newAppSettings (Just appState)
in continue (BrickState appData newAppSettings newInternalState appKeys)
in put (BrickState appData newAppSettings newInternalState appKeys)
showKey :: Vty.Key -> String
@@ -142,7 +143,7 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
where
footer =
withAttr "help"
withAttr (attrName "help")
. txtWrap
. T.pack
. foldr1 (\x y -> x <> " " <> y)
@@ -154,12 +155,15 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
<+> minHSize 15 (str "Version")
<+> padLeft (Pad 1) (minHSize 25 $ str "Tags")
<+> padLeft (Pad 5) (str "Notes")
renderList' = withDefAttr listAttr . drawListElements renderItem True
renderItem _ b listResult@ListResult{..} =
renderList' bis@BrickInternalState{..} =
let getMinLength = length . intercalate "," . fmap tagToString
minLength = V.maximum $ V.map (getMinLength . lTag) clr
in withDefAttr listAttr . drawListElements (renderItem minLength) True $ bis
renderItem minTagSize _ b listResult@ListResult{lTag = lTag', ..} =
let marks = if
| lSet -> (withAttr "set" $ str "✔✔")
| lInstalled -> (withAttr "installed" $ str "")
| otherwise -> (withAttr "not-installed" $ str "")
| lSet -> (withAttr (attrName "set") $ str "✔✔")
| lInstalled -> (withAttr (attrName "installed") $ str "")
| otherwise -> (withAttr (attrName "not-installed") $ str "")
ver = case lCross of
Nothing -> T.unpack . prettyVer $ lVer
Just c -> T.unpack (c <> "-" <> prettyVer lVer)
@@ -167,13 +171,13 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
| lNoBindist && not lInstalled
&& not b -- TODO: overloading dim and active ignores active
-- so we hack around it here
= updateAttrMap (const dimAttrs) . withAttr "no-bindist"
= updateAttrMap (const dimAttrs) . withAttr (attrName "no-bindist")
| otherwise = id
hooray
| elem Latest lTag && not lInstalled =
withAttr "hooray"
| elem Latest lTag' && not lInstalled =
withAttr (attrName "hooray")
| otherwise = id
active = if b then putCursor "GHCup" (Location (0,0)) . forceAttr "active" else id
active = if b then putCursor "GHCup" (Location (0,0)) . forceAttr (attrName "active") else id
in hooray $ active $ dim
( marks
<+> padLeft (Pad 2)
@@ -181,8 +185,8 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
(printTool lTool)
)
<+> minHSize 15 (str ver)
<+> (let l = catMaybes . fmap printTag $ sort lTag
in padLeft (Pad 1) $ minHSize 25 $ if null l
<+> (let l = catMaybes . fmap printTag $ sort lTag'
in padLeft (Pad 1) $ minHSize minTagSize $ if null l
then emptyWidget
else foldr1 (\x y -> x <+> str "," <+> y) l
)
@@ -195,11 +199,12 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
<+> vLimit 1 (fill ' ')
)
printTag Recommended = Just $ withAttr "recommended" $ str "recommended"
printTag Latest = Just $ withAttr "latest" $ str "latest"
printTag Prerelease = Just $ withAttr "prerelease" $ str "prerelease"
printTag Recommended = Just $ withAttr (attrName "recommended") $ str "recommended"
printTag Latest = Just $ withAttr (attrName "latest") $ str "latest"
printTag Prerelease = Just $ withAttr (attrName "prerelease") $ str "prerelease"
printTag (Base pvp'') = Just $ str ("base-" ++ T.unpack (prettyPVP pvp''))
printTag Old = Nothing
printTag LatestPrerelease = Just $ withAttr (attrName "latest-prerelease") $ str "latest-prerelease"
printTag (UnknownTag t) = Just $ str t
printTool Cabal = str "cabal"
@@ -209,10 +214,10 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
printTool Stack = str "Stack"
printNotes ListResult {..} =
(if hlsPowered then [withAttr "hls-powered" $ str "hls-powered"] else mempty
(if hlsPowered then [withAttr (attrName "hls-powered") $ str "hls-powered"] else mempty
)
++ (if fromSrc then [withAttr "compiled" $ str "compiled"] else mempty)
++ (if lStray then [withAttr "stray" $ str "stray"] else mempty)
++ (if fromSrc then [withAttr (attrName "compiled") $ str "compiled"] else mempty)
++ (if lStray then [withAttr (attrName "stray") $ str "stray"] else mempty)
-- | Draws the list elements.
--
@@ -242,8 +247,8 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
selItemAttr = if foc
then withDefAttr listSelectedFocusedAttr
else withDefAttr listSelectedAttr
makeVisible = if isSelected then visible . selItemAttr else id
in addSeparator $ makeVisible elemWidget
makeVisible' = if isSelected then visible . selItemAttr else id
in addSeparator $ makeVisible' elemWidget
in render
$ viewport "GHCup" Vertical
@@ -258,8 +263,8 @@ minHSize s' = hLimit s' . vLimit 1 . (<+> fill ' ')
app :: AttrMap -> AttrMap -> App BrickState e String
app attrs dimAttrs =
App { appDraw = \st -> [ui dimAttrs st]
, appHandleEvent = eventHandler
, appStartEvent = return
, appHandleEvent = \be -> get >>= \s -> eventHandler s be
, appStartEvent = return ()
, appAttrMap = const attrs
, appChooseCursor = showFirstCursor
}
@@ -267,18 +272,19 @@ app attrs dimAttrs =
defaultAttributes :: Bool -> AttrMap
defaultAttributes no_color = attrMap
Vty.defAttr
[ ("active" , Vty.defAttr `withBackColor` Vty.blue)
, ("not-installed", Vty.defAttr `withForeColor` Vty.red)
, ("set" , Vty.defAttr `withForeColor` Vty.green)
, ("installed" , Vty.defAttr `withForeColor` Vty.green)
, ("recommended" , Vty.defAttr `withForeColor` Vty.green)
, ("hls-powered" , Vty.defAttr `withForeColor` Vty.green)
, ("latest" , Vty.defAttr `withForeColor` Vty.yellow)
, ("prerelease" , Vty.defAttr `withForeColor` Vty.red)
, ("compiled" , Vty.defAttr `withForeColor` Vty.blue)
, ("stray" , Vty.defAttr `withForeColor` Vty.blue)
, ("help" , Vty.defAttr `withStyle` Vty.italic)
, ("hooray" , Vty.defAttr `withForeColor` Vty.brightWhite)
[ (attrName "active" , Vty.defAttr `withBackColor` Vty.blue)
, (attrName "not-installed", Vty.defAttr `withForeColor` Vty.red)
, (attrName "set" , Vty.defAttr `withForeColor` Vty.green)
, (attrName "installed" , Vty.defAttr `withForeColor` Vty.green)
, (attrName "recommended" , Vty.defAttr `withForeColor` Vty.green)
, (attrName "hls-powered" , Vty.defAttr `withForeColor` Vty.green)
, (attrName "latest" , Vty.defAttr `withForeColor` Vty.yellow)
, (attrName "latest-prerelease" , Vty.defAttr `withForeColor` Vty.red)
, (attrName "prerelease" , Vty.defAttr `withForeColor` Vty.red)
, (attrName "compiled" , Vty.defAttr `withForeColor` Vty.blue)
, (attrName "stray" , Vty.defAttr `withForeColor` Vty.blue)
, (attrName "help" , Vty.defAttr `withStyle` Vty.italic)
, (attrName "hooray" , Vty.defAttr `withForeColor` Vty.brightWhite)
]
where
withForeColor | no_color = const
@@ -292,31 +298,31 @@ defaultAttributes no_color = attrMap
dimAttributes :: Bool -> AttrMap
dimAttributes no_color = attrMap
(Vty.defAttr `Vty.withStyle` Vty.dim)
[ ("active" , Vty.defAttr `withBackColor` Vty.blue) -- has no effect ??
, ("no-bindist", Vty.defAttr `Vty.withStyle` Vty.dim)
[ (attrName "active" , Vty.defAttr `withBackColor` Vty.blue) -- has no effect ??
, (attrName "no-bindist", Vty.defAttr `Vty.withStyle` Vty.dim)
]
where
withBackColor | no_color = \attr _ -> attr `Vty.withStyle` Vty.reverseVideo
| otherwise = Vty.withBackColor
eventHandler :: BrickState -> BrickEvent n e -> EventM n (Next BrickState)
eventHandler :: BrickState -> BrickEvent String e -> EventM String BrickState ()
eventHandler st@BrickState{..} ev = do
AppState { keyBindings = kb } <- liftIO $ readIORef settings'
case ev of
(MouseDown _ Vty.BScrollUp _ _) ->
continue (BrickState { appState = moveCursor 1 appState Up, .. })
put (BrickState { appState = moveCursor 1 appState Up, .. })
(MouseDown _ Vty.BScrollDown _ _) ->
continue (BrickState { appState = moveCursor 1 appState Down, .. })
(VtyEvent (Vty.EvResize _ _)) -> continue st
put (BrickState { appState = moveCursor 1 appState Down, .. })
(VtyEvent (Vty.EvResize _ _)) -> put st
(VtyEvent (Vty.EvKey Vty.KUp _)) ->
continue BrickState{ appState = moveCursor 1 appState Up, .. }
put BrickState{ appState = moveCursor 1 appState Up, .. }
(VtyEvent (Vty.EvKey Vty.KDown _)) ->
continue BrickState{ appState = moveCursor 1 appState Down, .. }
put BrickState{ appState = moveCursor 1 appState Down, .. }
(VtyEvent (Vty.EvKey key _)) ->
case find (\(key', _, _) -> key' == key) (keyHandlers kb) of
Nothing -> continue st
Nothing -> put st
Just (_, _, handler) -> handler st
_ -> continue st
_ -> put st
moveCursor :: Int -> BrickInternalState -> Direction -> BrickInternalState
@@ -329,13 +335,14 @@ moveCursor steps ais@BrickInternalState{..} direction =
-- | Suspend the current UI and run an IO action in terminal. If the
-- IO action returns a Left value, then it's thrown as userError.
withIOAction :: (BrickState
withIOAction :: Ord n
=> (BrickState
-> (Int, ListResult)
-> ReaderT AppState IO (Either String a))
-> BrickState
-> EventM n (Next BrickState)
-> EventM n BrickState ()
withIOAction action as = case listSelectedElement' (appState as) of
Nothing -> continue as
Nothing -> put as
Just (ix, e) -> do
suspendAndResume $ do
settings <- readIORef settings'
@@ -434,6 +441,7 @@ install' _ (_, ListResult {..}) = do
, BuildFailed
, TagNotFound
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, DirNotEmpty
@@ -486,7 +494,7 @@ install' _ (_, ListResult {..}) = do
pure $ Right ()
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
VLeft (V NoUpdate) -> pure $ Right ()
VLeft e -> pure $ Left $ prettyShow e <> "\n"
VLeft e -> pure $ Left $ prettyHFError e <> "\n"
<> "Also check the logs in ~/.ghcup/logs"
@@ -523,7 +531,7 @@ set' bs input@(_, ListResult {..}) = do
logInfo "Setting now..."
set' bs input
PromptNo -> pure $ Left (prettyShow e)
PromptNo -> pure $ Left (prettyHFError e)
where
userPrompt = L.toStrict . B.toLazyText . B.fromString $
"This Version of "
@@ -531,7 +539,7 @@ set' bs input@(_, ListResult {..}) = do
<> " you are trying to set is not installed.\n"
<> "Would you like to install it first? [Y/N]: "
_ -> pure $ Left (prettyShow e)
_ -> pure $ Left (prettyHFError e)
@@ -559,7 +567,7 @@ del' _ (_, ListResult {..}) = do
forM_ (_viPostRemove =<< vi) $ \msg ->
logInfo msg
pure $ Right ()
VLeft e -> pure $ Left (prettyShow e)
VLeft e -> pure $ Left (prettyHFError e)
changelog' :: (MonadReader AppState m, MonadIO m)
@@ -579,7 +587,7 @@ changelog' _ (_, ListResult {..}) = do
Windows -> "start"
exec cmd [T.unpack $ decUTF8Safe $ serializeURIRef' uri] Nothing Nothing >>= \case
Right _ -> pure $ Right ()
Left e -> pure $ Left $ prettyShow e
Left e -> pure $ Left $ prettyHFError e
settings' :: IORef AppState
@@ -632,12 +640,12 @@ getGHCupInfo = do
r <-
flip runReaderT settings
. runE @'[DigestError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError]
. runE @'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError]
$ liftE getDownloadsF
case r of
VRight a -> pure $ Right a
VLeft e -> pure $ Left (prettyShow e)
VLeft e -> pure $ Left (prettyHFError e)
getAppData :: Maybe GHCupInfo

View File

@@ -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
@@ -67,13 +69,13 @@ import URI.ByteString
import qualified Data.ByteString.UTF8 as UTF8
data Options = Options
{
-- global options
optVerbose :: Maybe Bool
, optCache :: Maybe Bool
, optMetaCache :: Maybe Integer
, optMetaMode :: Maybe MetaMode
, optPlatform :: Maybe PlatformRequest
, optUrlSource :: Maybe URI
, optNoVerify :: Maybe Bool
@@ -87,6 +89,7 @@ data Options = Options
data Command
= Install (Either InstallCommand InstallOptions)
| Test TestCommand
| InstallCabalLegacy InstallOptions
| Set (Either SetCommand SetOptions)
| UnSet UnsetCommand
@@ -108,6 +111,7 @@ data Command
| Prefetch PrefetchCommand
| GC GCOptions
| Run RunOptions
| PrintAppErrors
@@ -116,7 +120,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)
@@ -203,6 +208,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
@@ -340,3 +353,10 @@ com =
<> commandGroup "Nuclear Commands:"
<> hidden
)
<|> subparser
(command
"print-app-errors"
(info (pure PrintAppErrors <**> helper)
(progDesc ""))
<> internal
)

View File

@@ -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
@@ -148,6 +149,6 @@ changelog ChangeLogOptions{..} runAppState runLogger = do
Nothing
>>= \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

View File

@@ -246,8 +246,9 @@ toolVersionTagEither 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
('b':'a':'s':'e':'-':ver') -> case pvp (T.pack ver') of
Right x -> Right (Base x)
Left _ -> Left $ "Invalid PVP version for base " <> ver'
@@ -452,7 +453,7 @@ tagCompleter tool add = listIOCompleter $ do
let allTags = filter (/= Old)
$ _viTags =<< M.elems (availableToolVersions (_ghcupDownloads ghcupInfo) tool)
pure $ nub $ (add ++) $ fmap tagToString allTags
VLeft _ -> pure (nub $ ["recommended", "latest"] ++ add)
VLeft _ -> pure (nub $ ["recommended", "latest", "latest-prerelease"] ++ add)
versionCompleter :: Maybe ListCriteria -> Tool -> Completer
versionCompleter criteria tool = versionCompleter' criteria tool (const True)
@@ -706,6 +707,9 @@ fromVersion' (SetToolVersion v) tool = do
fromVersion' (SetToolTag Latest) tool = do
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
bimap mkTVer Just <$> getLatest dls tool ?? TagNotFound Latest tool
fromVersion' (SetToolTag LatestPrerelease) tool = do
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
bimap mkTVer Just <$> getLatestPrerelease dls tool ?? TagNotFound LatestPrerelease tool
fromVersion' (SetToolTag Recommended) tool = do
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
bimap mkTVer Just <$> getRecommended dls tool ?? TagNotFound Recommended tool

View File

@@ -40,7 +40,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
@@ -420,6 +419,7 @@ hlsCompileOpts =
type GHCEffects = '[ AlreadyInstalled
, BuildFailed
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, GHCupSetError
@@ -443,6 +443,7 @@ type GHCEffects = '[ AlreadyInstalled
type HLSEffects = '[ AlreadyInstalled
, BuildFailed
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, GHCupSetError
@@ -544,14 +545,14 @@ 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!"
@@ -606,12 +607,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

View File

@@ -51,7 +51,7 @@ data ConfigCommand
= ShowConfig
| SetConfig String (Maybe String)
| InitConfig
| AddReleaseChannel URI
| AddReleaseChannel Bool URI
@@ -59,7 +59,7 @@ data ConfigCommand
--[ Parsers ]--
---------------
configP :: Parser ConfigCommand
configP = subparser
( command "init" initP
@@ -74,7 +74,7 @@ configP = subparser
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))
addP = info (AddReleaseChannel <$> switch (long "force" <> help "Delete existing entry (if any) and append instead of failing") <*> argument (eitherReader uriParser) (metavar "URI" <> completer fileUri))
(progDesc "Add a release channel from a URI")
@@ -120,19 +120,38 @@ 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
, kShowAllTools = kShowAllTools kbl <|> kShowAllTools kbr
}
@@ -140,6 +159,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 +171,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)
@@ -183,27 +206,55 @@ config configCommand settings keybindings runLogger = case configCommand of
pure $ ExitFailure 65
VLeft _ -> 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 uri -> do
r <- runE @'[DuplicateReleaseChannel] $ do
case urlSource settings of
AddSource xs -> do
case checkDuplicate xs (Right uri) of
Duplicate
| not force -> throwE (DuplicateReleaseChannel uri)
DuplicateLast -> pure ()
_ -> lift $ doConfig (defaultUserSettings { uUrlSource = Just $ AddSource (appendUnique xs (Right uri)) })
GHCupURL -> do
lift $ doConfig (defaultUserSettings { uUrlSource = Just $ AddSource [Right uri] })
pure ()
OwnSource xs -> do
case checkDuplicate xs (Right uri) of
Duplicate
| not force -> throwE (DuplicateReleaseChannel uri)
DuplicateLast -> pure ()
_ -> lift $ doConfig (defaultUserSettings { uUrlSource = Just $ OwnSource (appendUnique xs (Right uri)) })
OwnSpec spec -> do
lift $ doConfig (defaultUserSettings { uUrlSource = Just $ OwnSource [Left spec, Right uri] })
pure ()
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
-- appends the element to the end of the list, but also removes it from the existing list
appendUnique :: Eq a => [a] -> a -> [a]
appendUnique xs' e = go xs'
where
go [] = [e]
go (x:xs)
| x == e = go xs -- skip
| otherwise = x : go xs
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 ()

View File

@@ -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

View File

@@ -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)
@@ -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

View File

@@ -38,7 +38,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
@@ -243,6 +242,7 @@ type InstallEffects = '[ AlreadyInstalled
, BuildFailed
, TagNotFound
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, TarDirDoesNotExist
@@ -271,6 +271,7 @@ type InstallGHCEffects = '[ AlreadyInstalled
, BuildFailed
, CopyError
, DigestError
, ContentLengthError
, DirNotEmpty
, DownloadFailed
, FileAlreadyExistsError
@@ -332,7 +333,7 @@ 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-.*") "")
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing)
(_tvVersion v)
(maybe GHCupInternal IsolateDir isolateDir)
forceInstall
@@ -349,10 +350,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
@@ -366,22 +367,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
@@ -402,7 +403,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 "")
(DownloadInfo uri Nothing "" Nothing)
v
(maybe GHCupInternal IsolateDir isolateDir)
forceInstall
@@ -416,14 +417,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 $
@@ -431,7 +432,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
@@ -452,7 +453,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer HLS
-- TODO: support legacy
liftE $ runBothE' (installHLSBindist
(DownloadInfo uri (if isWindows then Nothing else Just (RegexDir "haskell-language-server-*")) "")
(DownloadInfo uri (if isWindows then Nothing else Just (RegexDir "haskell-language-server-*")) "" Nothing)
v
(maybe GHCupInternal IsolateDir isolateDir)
forceInstall
@@ -466,14 +467,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 $
@@ -481,7 +482,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
@@ -501,7 +502,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 "")
(DownloadInfo uri Nothing "" Nothing)
v
(maybe GHCupInternal IsolateDir isolateDir)
forceInstall
@@ -515,14 +516,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 $
@@ -530,6 +531,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

View File

@@ -107,6 +107,7 @@ printListResult no_color raw lr = do
printTag Prerelease = color Red "prerelease"
printTag (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
printTag (UnknownTag t ) = t
printTag LatestPrerelease = color Red "latest-prerelease"
printTag Old = ""
let

View File

@@ -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)
@@ -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

View File

@@ -30,7 +30,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)
@@ -153,6 +152,7 @@ type PrefetchEffects = '[ TagNotFound
, NoToolVersionSet
, NoDownload
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, JSONError
@@ -215,5 +215,5 @@ prefetch prefetchCommand runAppState runLogger =
VRight _ -> do
pure ExitSuccess
VLeft e -> do
runLogger $ logError $ T.pack $ prettyShow e
runLogger $ logError $ T.pack $ prettyHFError e
pure $ ExitFailure 15

View File

@@ -34,7 +34,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)
@@ -179,7 +178,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 =
@@ -194,7 +193,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 15
rmHLS' tv =
@@ -209,7 +208,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 15
rmStack' tv =
@@ -224,7 +223,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 15
postRmLog vi =

View File

@@ -40,7 +40,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
@@ -177,6 +176,7 @@ type RunEffects = '[ AlreadyInstalled
, BuildFailed
, TagNotFound
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, TarDirDoesNotExist
@@ -254,7 +254,7 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
liftIO $ putStr tmp
pure ExitSuccess
(cmd:args) -> do
newEnv <- liftIO $ addToPath tmp
newEnv <- liftIO $ addToPath tmp runAppendPATH
#ifndef IS_WINDOWS
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
pure ExitSuccess
@@ -265,11 +265,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
@@ -343,6 +343,7 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
, DownloadFailed
, DirNotEmpty
, DigestError
, ContentLengthError
, BuildFailed
, ArchiveResult
, AlreadyInstalled
@@ -440,17 +441,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

View File

@@ -35,7 +35,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 Data.Bifunctor (second)
@@ -260,7 +259,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 +271,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 +282,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 +300,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 +317,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 +335,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

View 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
import Codec.Archive
#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 Nothing 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
, 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 (_tvVersion 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) (_tvVersion 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

View File

@@ -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

View File

@@ -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)
@@ -189,7 +188,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)

View File

@@ -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)
@@ -88,6 +87,7 @@ upgradeOptsP =
type UpgradeEffects = '[ DigestError
, ContentLengthError
, GPGError
, NoDownload
, NoUpdate
@@ -151,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

View File

@@ -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)
@@ -288,7 +287,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 +301,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 +317,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

View File

@@ -63,7 +63,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,12 +73,13 @@ 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
@@ -88,6 +89,7 @@ toSettings options = do
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
@@ -174,7 +176,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 +207,19 @@ 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, GPGError, JSONError , DownloadFailed, FileDoesNotExistError]
. runE @'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed, FileDoesNotExistError]
$ liftE getDownloadsF
)
>>= \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
@@ -265,7 +267,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
VRight _ -> pure ()
VLeft e -> do
runLogger
(logError $ T.pack $ prettyShow e)
(logError $ T.pack $ prettyHFError e)
exitWith (ExitFailure 30)
pure s'
@@ -294,13 +296,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 +313,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 ()

View File

@@ -5,17 +5,10 @@ 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,
any.aeson >= 2.0.1.0
package libarchive
flags: -system-libarchive
@@ -32,6 +25,5 @@ package aeson
package streamly
flags: +use-unliftio
allow-newer: base, ghc-prim, template-haskell, language-c
with-compiler: ghc-8.10.7

View File

@@ -1,8 +1,9 @@
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.8.1.0,
any.HUnit ==1.6.2.0,
any.HsOpenSSL ==0.11.7.2,
any.HsOpenSSL ==0.11.7.4,
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
any.OneTuple ==0.3.1,
any.QuickCheck ==2.14.2,
@@ -10,13 +11,13 @@ constraints: any.Cabal ==3.6.2.0,
any.StateVar ==1.2.2,
any.abstract-deque ==0.3,
abstract-deque -usecas,
any.aeson ==2.0.3.0,
any.aeson ==2.1.1.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-terminal ==0.11.4,
ansi-terminal -example +win32-2-13-1,
any.ansi-wl-pprint ==0.6.9,
ansi-wl-pprint -example,
any.array ==0.5.4.0,
@@ -28,23 +29,27 @@ constraints: any.Cabal ==3.6.2.0,
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.12.2,
any.base-compat-batteries ==0.12.2,
any.base-orphans ==0.8.7,
any.base16-bytestring ==1.0.2.0,
any.base64-bytestring ==1.2.1.0,
any.bifunctors ==5.5.12,
any.bifunctors ==5.5.14,
bifunctors +semigroups +tagged,
any.bimap ==0.5.0,
any.binary ==0.8.8.0,
any.binary-instances ==1.0.3,
any.binary-orphans ==1.0.3,
any.blaze-builder ==0.4.2.2,
any.brick ==0.64.2,
any.brick ==1.5,
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.5,
any.cabal-plan ==0.7.2.3,
cabal-plan -_ -exe -license-report,
any.call-stack ==0.4.0,
any.case-insensitive ==1.2.1.0,
@@ -52,14 +57,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.5.0,
config-ini -enable-doctests,
any.containers ==0.6.5.1,
any.contravariant ==1.5.5,
@@ -69,6 +72,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,
@@ -80,58 +84,57 @@ constraints: any.Cabal ==3.6.2.0,
dlist -werror,
any.exceptions ==0.10.4,
any.filepath ==1.4.2.1,
any.free ==5.1.8,
any.free ==5.1.10,
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,
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.hashable ==1.4.2.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.heaps ==0.4,
any.hpc ==0.6.1.0,
any.hsc2hs ==0.68.8,
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.8,
any.hspec-core ==2.10.8,
any.hspec-discover ==2.10.8,
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.indexed-traversable-instances ==0.1.1.1,
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,
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.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.11,
any.mtl ==2.2.2,
any.network ==3.1.2.7,
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,
@@ -143,7 +146,7 @@ constraints: any.Cabal ==3.6.2.0,
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.16.1,
any.parser-combinators ==1.3.0,
parser-combinators -dev,
any.polyparse ==1.13,
@@ -155,12 +158,12 @@ constraints: any.Cabal ==3.6.2.0,
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.3,
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.resourcet ==1.2.6,
any.retry ==0.8.1.2,
retry -lib-werror,
any.rts ==1.0.1,
@@ -173,11 +176,11 @@ constraints: any.Cabal ==3.6.2.0,
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.split ==0.2.3.5,
any.splitmix ==0.1.0.4,
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,
@@ -185,20 +188,24 @@ constraints: any.Cabal ==3.6.2.0,
any.tagged ==0.8.6.1,
tagged +deepseq +transformers,
any.tagsoup ==0.14.8,
any.tar ==0.5.1.1,
tar -old-bytestring -old-time,
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-size ==0.3.3,
any.terminfo ==0.4.1.4,
any.text ==1.2.4.1,
any.text ==2.0.1,
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.12,
any.tf-random ==0.5,
any.th-abstraction ==0.4.3.0,
any.th-compat ==0.1.3,
any.th-abstraction ==0.4.5.0,
any.th-compat ==0.1.4,
any.th-lift ==0.8.2,
any.th-lift-instances ==0.1.19,
any.th-lift-instances ==0.1.20,
any.these ==1.1.1.1,
these +assoc,
any.time ==1.9.3,
@@ -207,12 +214,12 @@ constraints: any.Cabal ==3.6.2.0,
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-bytestring ==0.3.7.8,
any.unix-compat ==0.6,
unix-compat -old-time,
any.unliftio-core ==0.2.0.1,
@@ -224,8 +231,9 @@ constraints: any.Cabal ==3.6.2.0,
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.vector-binary-instances ==0.2.5.2,
any.versions ==5.0.4,
any.vty ==5.37,
any.witherable ==0.4.2,
any.word-wrap ==0.5,
any.word8 ==0.1.3,
@@ -235,4 +243,4 @@ constraints: any.Cabal ==3.6.2.0,
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 2023-01-12T04:22:48Z

View File

@@ -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.0.2

View File

@@ -1,238 +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.15.1.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.8.0,
any.blaze-builder ==0.4.2.2,
any.brick ==0.64.2,
brick -demos,
any.bytestring ==0.10.12.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.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-clist ==0.2,
any.data-fix ==0.3.2,
any.deepseq ==1.4.5.0,
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.filepath ==1.4.2.1,
any.free ==5.1.8,
any.fusion-plugin-types ==0.1.0,
any.generic-arbitrary ==0.2.2,
any.ghc ==9.0.2,
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.haskus-utils-data ==1.4,
any.haskus-utils-types ==1.5.1,
any.haskus-utils-variant ==3.2.1,
any.heaps ==0.4,
any.hpc ==0.6.1.0,
any.hsc2hs ==0.68.8,
hsc2hs -in-ghc-tree,
any.hspec ==2.9.7,
any.hspec-core ==2.9.7,
any.hspec-discover ==2.9.7,
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.14.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.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,
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.0,
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.17.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

View File

@@ -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

View File

@@ -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

View File

@@ -2,19 +2,11 @@ packages: ./ghcup.cabal
optional-packages: ./vendored/*/*.cabal
optimization: 2
package ghcup
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,
any.aeson >= 2.0.1.0
package libarchive
flags: -system-libarchive
@@ -31,4 +23,3 @@ package aeson
package streamly
flags: +use-unliftio
allow-newer: base, ghc-prim, template-haskell, language-c

View File

@@ -1,2 +1,2 @@
-- windows picks weird version
constraints: any.hsc2hs ==0.68.7
constraints: any.hsc2hs ==0.68.8

50
cabal.project.release Normal file
View File

@@ -0,0 +1,50 @@
packages: ./ghcup.cabal
optional-packages: ./vendored/*/*.cabal
optimization: 2
if os(linux)
package ghcup
flags: +tui
if arch(x86_64) || arch(i386)
package *
ghc-options: -split-sections -optl-static
elif os(darwin)
constraints: zlib +bundled-c-zlib,
lzma +static
package ghcup
flags: +tui
elif os(mingw32)
constraints: zlib +bundled-c-zlib,
lzma +static,
text -simdutf
package ghcup
flags: -tui
elif os(freebsd)
constraints: zlib +bundled-c-zlib,
zip +disable-zstd
package *
ghc-options: -split-sections -pgmc clang++14
package ghcup
flags: +tui
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

View File

@@ -40,6 +40,12 @@ key-bindings:
# of the file. These usually are in '~/.ghcup/cache/ghcup-<ver>.yaml'.
meta-cache: 300 # in seconds
# 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. For more detailed explanation
# check the 'URLSource' type in the code.
url-source:
@@ -86,3 +92,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"

View File

@@ -1,4 +1,4 @@
FROM i386/alpine:3.12
FROM --platform=linux/i386 i386/alpine:3.12
ENV LANG C.UTF-8

View 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.17.8
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
# 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=8.10.7
ARG CABAL_INSTALL=3.6.2.0
ARG STACK=2.9.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"]

View File

@@ -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

View 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.18.0
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
# 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=8.10.7
ARG CABAL_INSTALL=3.6.2.0
ARG STACK=2.9.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"]

View 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}"

View File

@@ -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

View 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}"

View File

@@ -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

View File

@@ -163,6 +163,7 @@ 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)
2. [https://mirrors.ustc.edu.cn/help/ghcup.html](https://mirrors.ustc.edu.cn/help/ghcup.html)
### (Pre-)Release channels

View File

@@ -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>&nbsp;&middot;&nbsp;</b> <a href="https://www.haskell.org/ghcup/install/#manual-install">I don't like curl | sh</a> <div class="show-all-platforms"><b>&nbsp;&middot;&nbsp;</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>&nbsp;&middot;&nbsp;</b> <a href="https://www.haskell.org/ghcup/install/#manual-installation">I don't like curl | sh</a> <div class="show-all-platforms"><b>&nbsp;&middot;&nbsp;</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>&nbsp;&middot;&nbsp;</b> <a href="https://www.haskell.org/ghcup/install/#manual-install">I don't like curl | sh</a> <div class="show-all-platforms"><b>&nbsp;&middot;&nbsp;</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>&nbsp;&middot;&nbsp;</b> <a href="https://www.haskell.org/ghcup/install/#manual-installation">I don't like curl | sh</a> <div class="show-all-platforms"><b>&nbsp;&middot;&nbsp;</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>
----

View File

@@ -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?
@@ -240,6 +240,8 @@ 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.
@@ -251,6 +253,60 @@ 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.
## Vim integration
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).

View File

@@ -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 %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

4
docs/overrides/main.html Normal file
View File

@@ -0,0 +1,4 @@
{% extends "base.html" %}
<!-- Get rid of the next/prev buttons -->
{% block next_prev %}
{% endblock %}

View File

@@ -1,6 +1,6 @@
cabal-version: 3.0
cabal-version: 2.4
name: ghcup
version: 0.1.18.1
version: 0.1.19.2
license: LGPL-3.0-only
license-file: LICENSE
copyright: Julian Ospald 2020
@@ -25,10 +25,10 @@ extra-source-files:
cbits/dirutils.h
data/build_mk/cross
data/build_mk/default
test/data/dir/.keep
test/data/file
test/golden/unix/GHCupInfo.json
test/golden/windows/GHCupInfo.json
test/data/file
test/data/dir/.keep
source-repository head
type: git
@@ -143,9 +143,9 @@ library
, split ^>=0.2.3.4
, streamly ^>=0.8.2
, strict-base ^>=0.4
, template-haskell >=2.7 && <2.18
, template-haskell >=2.7 && <2.20
, temporary ^>=1.3
, text ^>=1.2.4.0
, text ^>=2.0
, time ^>=1.9.3
, transformers ^>=0.5
, unliftio-core ^>=0.2.0.1
@@ -161,7 +161,7 @@ library
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,22 +185,21 @@ 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
, terminal-size ^>=0.3.3
, unix ^>=2.7
, unix-bytestring ^>=0.3.7.3
if (flag(tui) && !os(windows))
cpp-options: -DBRICK
build-depends: vty >=5.28.2 && <5.34
build-depends: vty ^>=5.37
executable ghcup
main-is: Main.hs
@@ -219,6 +218,7 @@ executable ghcup
GHCup.OptParse.Rm
GHCup.OptParse.Run
GHCup.OptParse.Set
GHCup.OptParse.Test
GHCup.OptParse.ToolRequirements
GHCup.OptParse.UnSet
GHCup.OptParse.Upgrade
@@ -241,40 +241,40 @@ 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
, 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
, 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
, 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.20
, temporary ^>=1.3
, text ^>=2.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
if flag(internal-downloader)
cpp-options: -DINTERNAL_DOWNLOADER
@@ -283,10 +283,10 @@ executable ghcup
cpp-options: -DBRICK
other-modules: BrickMain
build-depends:
, brick ^>=0.64
, brick ^>=1.5
, transformers ^>=0.5
, unix ^>=2.7
, vty >=5.28.2 && <5.34
, vty ^>=5.37
if os(windows)
cpp-options: -DIS_WINDOWS
@@ -304,9 +304,9 @@ test-suite ghcup-test
hs-source-dirs: 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 +335,12 @@ 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
, uri-bytestring ^>=0.3.2.2
, versions >=4.0.1 && <5.1
if os(windows)
cpp-options: -DIS_WINDOWS
else
build-depends:
, unix ^>=2.7
build-depends: unix ^>=2.7

View File

@@ -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)
@@ -106,6 +105,7 @@ fetchToolBindist :: ( MonadFail m
-> Maybe FilePath
-> Excepts
'[ DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -288,6 +288,7 @@ upgradeGHCup :: ( MonadMask m
-> Excepts
'[ CopyError
, DigestError
, ContentLengthError
, GPGError
, GPGError
, DownloadFailed
@@ -308,7 +309,7 @@ upgradeGHCup mtarget force' fatal = do
dli <- liftE $ getDownloadInfo GHCup latestVer
tmp <- fromGHCupPath <$> lift withGHCupTmpDir
let fn = "ghcup" <> exeExt
p <- liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) tmp (Just fn) False
p <- liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) tmp (Just fn) False
let destDir = takeDirectory destFile
destFile = fromMaybe (binDir </> fn) mtarget
lift $ logDebug $ "mkdir -p " <> T.pack destDir
@@ -326,7 +327,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

View File

@@ -50,7 +50,6 @@ import System.FilePath
import System.IO.Error
import qualified Data.Text as T
import Text.PrettyPrint.HughesPJClass (prettyShow)
@@ -81,6 +80,7 @@ installCabalBindist :: ( MonadMask m
'[ AlreadyInstalled
, CopyError
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -184,6 +184,7 @@ installCabalBin :: ( MonadMask m
'[ AlreadyInstalled
, CopyError
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -233,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 ()

View File

@@ -75,7 +75,6 @@ import System.Exit
import System.FilePath
import System.IO.Error
import System.IO.Temp
import Text.PrettyPrint.HughesPJClass ( prettyShow )
import URI.ByteString
import qualified Crypto.Hash.SHA256 as SHA256
@@ -114,7 +113,7 @@ getDownloadsF :: ( FromJSONKey Tool
, MonadMask m
)
=> Excepts
'[DigestError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError]
'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError]
m
GHCupInfo
getDownloadsF = do
@@ -162,17 +161,21 @@ getBase :: ( MonadReader env m
, MonadMask m
)
=> URI
-> Excepts '[GPGError, DigestError, JSONError, FileDoesNotExistError] m GHCupInfo
-> Excepts '[DownloadFailed, GPGError, DigestError, ContentLengthError, JSONError, FileDoesNotExistError] m GHCupInfo
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
@@ -184,7 +187,7 @@ getBase uri = do
liftE
. onE_ (onError actualYaml)
. lEM' @_ @_ @'[JSONError] (\(displayException -> e) -> JSONDecodeError $ unlines [e, "Consider removing " <> actualYaml <> " manually."])
. liftIO
. liftIO
. Y.decodeFileEither
$ actualYaml
where
@@ -229,6 +232,7 @@ getBase uri = do
-> Excepts
'[ DownloadFailed
, DigestError
, ContentLengthError
, GPGError
]
m1
@@ -242,7 +246,7 @@ getBase uri = do
Settings { metaCache } <- lift getSettings
-- for local files, let's short-circuit and ignore access time
if | scheme == "file" -> liftE $ download uri' Nothing Nothing (fromGHCupPath cacheDir) Nothing True
if | scheme == "file" -> liftE $ download uri' Nothing Nothing Nothing (fromGHCupPath cacheDir) Nothing True
| e -> do
accessTime <- fmap utcTimeToPOSIXSeconds $ liftIO $ getAccessTime json_file
let sinceLastAccess = utcTimeToPOSIXSeconds currentTime - accessTime
@@ -258,9 +262,13 @@ getBase uri = do
where
dlWithMod modTime json_file = do
let (dir, fn) = splitFileName json_file
f <- liftE $ download uri' (Just $ over pathL' (<> ".sig") uri') Nothing dir (Just fn) True
liftIO $ setModificationTime f modTime
liftIO $ setAccessTime f modTime
f <- liftE $ download uri' (Just $ over pathL' (<> ".sig") uri') Nothing Nothing dir (Just fn) True
-- 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
@@ -324,23 +332,26 @@ download :: ( MonadReader env m
=> URI
-> Maybe URI -- ^ URI for gpg sig
-> Maybe T.Text -- ^ expected hash
-> Maybe Integer -- ^ expected content length
-> FilePath -- ^ destination dir (ignored for file:// scheme)
-> Maybe FilePath -- ^ optional filename
-> Bool -- ^ whether to read an write etags
-> Excepts '[DigestError , DownloadFailed, GPGError] m FilePath
download uri gpgUri eDigest dest mfn etags
| scheme == "https" = dl
| scheme == "http" = dl
-> Excepts '[DigestError, ContentLengthError, DownloadFailed, GPGError] m FilePath
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_ 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
@@ -351,7 +362,7 @@ download uri gpgUri eDigest dest mfn etags
-- download
flip onException
(lift $ hideError doesNotExistErrorType $ recycleFile (tmpFile baseDestFile))
$ catchAllE @_ @'[GPGError, ProcessError, DownloadFailed, UnsupportedScheme, DigestError] @'[DigestError, DownloadFailed, GPGError]
$ catchAllE @_ @'[GPGError, ProcessError, DownloadFailed, UnsupportedScheme, DigestError, ContentLengthError] @'[DigestError, ContentLengthError, DownloadFailed, GPGError]
(\e' -> do
lift $ hideError doesNotExistErrorType $ recycleFile (tmpFile baseDestFile)
case e' of
@@ -386,7 +397,7 @@ download uri gpgUri eDigest 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
@@ -401,19 +412,37 @@ download uri gpgUri eDigest dest mfn etags
CapturedProcess { _stdErr } -> lift $ logDebug $ decUTF8Safe' _stdErr
_ -> pure ()
forM_ eCSize (liftE . flip checkCSize baseDestFile)
forM_ eDigest (liftE . flip checkDigest baseDestFile)
pure baseDestFile
curlDL :: (MonadCatch m, MonadMask m, MonadIO m) => [String] -> FilePath -> URI -> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
curlDL :: ( MonadCatch m
, MonadMask m
, MonadIO m
)
=> [String]
-> FilePath
-> URI
-> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
curlDL o' destFile (decUTF8Safe . serializeURIRef' -> uri') = do
let destFileTemp = tmpFile destFile
flip finally (try @_ @SomeException $ rmFile destFileTemp) $ do
liftE $ lEM @_ @'[ProcessError] $ exec "curl"
(o' ++ ["-fL", "-o", destFileTemp, T.unpack uri']) Nothing Nothing
(o' ++ ["-fL", "-o", destFileTemp, T.unpack uri']
++ maybe [] (\s -> ["--max-filesize", show s]) eCSize
) Nothing Nothing
liftIO $ renameFile destFileTemp destFile
curlEtagsDL :: (MonadReader env m, HasLog env, MonadCatch m, MonadMask m, MonadIO m)
=> [String] -> FilePath -> URI -> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
curlEtagsDL :: ( MonadReader env m
, HasLog env
, MonadCatch m
, MonadMask m
, MonadIO m
)
=> [String]
-> FilePath
-> URI
-> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
curlEtagsDL o' destFile (decUTF8Safe . serializeURIRef' -> uri') = do
let destFileTemp = tmpFile destFile
dh <- liftIO $ emptySystemTempFile "curl-header"
@@ -440,7 +469,14 @@ download uri gpgUri eDigest dest mfn etags
lift $ writeEtags destFile (parseEtags headers)
wgetDL :: (MonadCatch m, MonadMask m, MonadIO m) => [String] -> FilePath -> URI -> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
wgetDL :: ( MonadCatch m
, MonadMask m
, MonadIO m
)
=> [String]
-> FilePath
-> URI
-> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
wgetDL o' destFile (decUTF8Safe . serializeURIRef' -> uri') = do
let destFileTemp = tmpFile destFile
flip finally (try @_ @SomeException $ rmFile destFileTemp) $ do
@@ -449,8 +485,16 @@ download uri gpgUri eDigest dest mfn etags
liftIO $ renameFile destFileTemp destFile
wgetEtagsDL :: (MonadReader env m, HasLog env, MonadCatch m, MonadMask m, MonadIO m)
=> [String] -> FilePath -> URI -> Excepts '[ProcessError, DownloadFailed, UnsupportedScheme] m ()
wgetEtagsDL :: ( MonadReader env m
, HasLog env
, MonadCatch m
, MonadMask m
, MonadIO 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
@@ -471,7 +515,10 @@ download uri gpgUri eDigest dest mfn etags
| otherwise -> throwE (NonZeroExit i' "wget" opts)
#if defined(INTERNAL_DOWNLOADER)
internalDL :: (MonadCatch m, MonadMask m, MonadIO m)
internalDL :: ( MonadCatch m
, MonadMask m
, MonadIO m
)
=> FilePath -> URI -> Excepts '[DownloadFailed, UnsupportedScheme] m ()
internalDL destFile uri' = do
let destFileTemp = tmpFile destFile
@@ -481,11 +528,16 @@ download uri gpgUri eDigest dest mfn etags
@'[DownloadFailed]
(\e@(HTTPNotModified _) ->
throwE @_ @'[DownloadFailed] (DownloadFailed (toVariantAt @0 e :: V '[HTTPNotModified])))
$ downloadToFile https host fullPath port destFileTemp mempty
$ downloadToFile https host fullPath port destFileTemp mempty eCSize
liftIO $ renameFile destFileTemp destFile
internalEtagsDL :: (MonadReader env m, HasLog env, MonadCatch m, MonadMask m, MonadIO m)
internalEtagsDL :: ( MonadReader env m
, HasLog env
, MonadCatch m
, MonadMask m
, MonadIO m
)
=> FilePath -> URI -> Excepts '[DownloadFailed, UnsupportedScheme] m ()
internalEtagsDL destFile uri' = do
let destFileTemp = tmpFile destFile
@@ -497,7 +549,7 @@ download uri gpgUri eDigest dest mfn etags
liftE
$ catchE @HTTPNotModified @'[DownloadFailed] @'[] (\(HTTPNotModified etag) -> lift $ writeEtags destFile (pure $ Just etag))
$ do
r <- downloadToFile https host fullPath port destFileTemp addHeaders
r <- downloadToFile https host fullPath port destFileTemp addHeaders eCSize
liftIO $ renameFile destFileTemp destFile
lift $ writeEtags destFile (pure $ decUTF8Safe <$> getHeader r "etag")
#endif
@@ -505,7 +557,7 @@ download uri gpgUri eDigest dest mfn etags
-- Manage to find a file we can write the body into.
getDestFile :: Monad m => URI -> Maybe FilePath -> Excepts '[NoUrlBase] m FilePath
getDestFile uri' mfn' =
getDestFile uri' mfn' =
let path = view pathL' uri'
in case mfn' of
Just fn -> pure (dest </> fn)
@@ -574,14 +626,14 @@ downloadCached :: ( MonadReader env m
)
=> DownloadInfo
-> Maybe FilePath -- ^ optional filename
-> Excepts '[DigestError , DownloadFailed, GPGError] m FilePath
-> Excepts '[DigestError, ContentLengthError, DownloadFailed, GPGError] m FilePath
downloadCached dli mfn = do
Settings{ cache } <- lift getSettings
case cache of
True -> downloadCached' dli mfn Nothing
False -> do
tmp <- lift withGHCupTmpDir
liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (fromGHCupPath tmp) mfn False
liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) (fromGHCupPath tmp) mfn False
downloadCached' :: ( MonadReader env m
@@ -596,7 +648,7 @@ downloadCached' :: ( MonadReader env m
=> DownloadInfo
-> Maybe FilePath -- ^ optional filename
-> Maybe FilePath -- ^ optional destination dir (default: cacheDir)
-> Excepts '[DigestError , DownloadFailed, GPGError] m FilePath
-> Excepts '[DigestError, ContentLengthError, DownloadFailed, GPGError] m FilePath
downloadCached' dli mfn mDestDir = do
Dirs { cacheDir } <- lift getDirs
let destDir = fromMaybe (fromGHCupPath cacheDir) mDestDir
@@ -605,9 +657,10 @@ downloadCached' dli mfn mDestDir = do
fileExists <- liftIO $ doesFileExist cachfile
if
| fileExists -> 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)) destDir mfn False
| otherwise -> liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) destDir mfn False
@@ -638,6 +691,25 @@ checkDigest eDigest file = do
cDigest <- throwEither . E.decodeUtf8' . B16.encode . SHA256.hashlazy $ c
when ((cDigest /= eDigest) && verify) $ throwE (DigestError file cDigest eDigest)
checkCSize :: ( MonadReader env m
, HasDirs env
, HasSettings env
, MonadIO m
, MonadThrow m
, HasLog env
)
=> Integer
-> FilePath
-> Excepts '[ContentLengthError] m ()
checkCSize eCSize file = do
Settings{ noVerify } <- lift getSettings
let verify = not noVerify
when verify $ do
let p' = takeFileName file
lift $ logInfo $ "verifying content length of: " <> T.pack p'
cSize <- liftIO $ getFileSize file
when ((eCSize /= cSize) && verify) $ throwE (ContentLengthError (Just file) (Just cSize) eCSize)
-- | Get additional curl args from env. This is an undocumented option.
getCurlOpts :: IO [String]
@@ -685,3 +757,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

View File

@@ -17,14 +17,12 @@ import Control.Exception.Safe
import Control.Monad
import Control.Monad.Reader
import Data.ByteString ( ByteString )
import Data.ByteString.Builder
import Data.CaseInsensitive ( CI, original, mk )
import Data.IORef
import Data.Maybe
import Data.Text.Read
import Haskus.Utils.Variant.Excepts
import Network.Http.Client hiding ( URL )
import Optics
import Prelude hiding ( abs
, readFile
, writeFile
@@ -33,7 +31,6 @@ import System.ProgressBar
import URI.ByteString
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as L
import qualified Data.Map.Strict as M
import qualified System.IO.Streams as Streams
@@ -46,27 +43,6 @@ import qualified System.IO.Streams as Streams
----------------------------
-- | Load the result of this download into memory at once.
downloadBS' :: MonadIO m
=> Bool -- ^ https?
-> ByteString -- ^ host (e.g. "www.example.com")
-> ByteString -- ^ path (e.g. "/my/file") including query
-> Maybe Int -- ^ optional port (e.g. 3000)
-> Excepts
'[ HTTPStatusError
, URIParseError
, UnsupportedScheme
, NoLocationHeader
, TooManyRedirs
]
m
L.ByteString
downloadBS' https host path port = do
bref <- liftIO $ newIORef (mempty :: Builder)
let stepper bs = modifyIORef bref (<> byteString bs)
void $ downloadInternal False https host path port stepper (pure ()) mempty
liftIO (readIORef bref <&> toLazyByteString)
downloadToFile :: (MonadMask m, MonadIO m)
=> Bool -- ^ https?
@@ -75,8 +51,9 @@ downloadToFile :: (MonadMask m, MonadIO m)
-> Maybe Int -- ^ optional port (e.g. 3000)
-> FilePath -- ^ destination file to create and write to
-> M.Map (CI ByteString) ByteString -- ^ additional headers
-> Maybe Integer -- ^ expected content length
-> Excepts '[DownloadFailed, HTTPNotModified] m Response
downloadToFile https host fullPath port destFile addHeaders = do
downloadToFile https host fullPath port destFile addHeaders eCSize = do
let stepper = BS.appendFile destFile
setup = BS.writeFile destFile mempty
catchAllE (\case
@@ -84,7 +61,7 @@ downloadToFile https host fullPath port destFile addHeaders = do
| i == 304
, Just e <- M.lookup (mk "etag") headers -> throwE $ HTTPNotModified (decUTF8Safe e)
v -> throwE $ DownloadFailed v
) $ downloadInternal True https host fullPath port stepper setup addHeaders
) $ downloadInternal True https host fullPath port stepper setup addHeaders eCSize
downloadInternal :: MonadIO m
@@ -96,19 +73,21 @@ downloadInternal :: MonadIO m
-> (ByteString -> IO a) -- ^ the consuming step function
-> IO a -- ^ setup action
-> M.Map (CI ByteString) ByteString -- ^ additional headers
-> Maybe Integer
-> Excepts
'[ HTTPStatusError
, URIParseError
, UnsupportedScheme
, NoLocationHeader
, TooManyRedirs
, ContentLengthError
]
m
Response
downloadInternal = go (5 :: Int)
where
go redirs progressBar https host path port consumer setup addHeaders = do
go redirs progressBar https host path port consumer setup addHeaders eCSize = do
r <- liftIO $ withConnection' https host port action
veitherToExcepts r >>= \case
Right r' ->
@@ -138,25 +117,39 @@ downloadInternal = go (5 :: Int)
followRedirectURL bs = case parseURI strictURIParserOptions bs of
Right uri' -> do
(https', host', fullPath', port') <- liftE $ uriToQuadruple uri'
go (redirs - 1) progressBar https' host' fullPath' port' consumer setup addHeaders
go (redirs - 1) progressBar https' host' fullPath' port' consumer setup addHeaders eCSize
Left e -> throwE e
downloadStream r i' = do
void setup
let size = case getHeader r "Content-Length" of
Just x' -> case decimal $ decUTF8Safe x' of
Left _ -> 0
Right (r', _) -> r'
Nothing -> 0
Left _ -> Nothing
Right (r', _) -> Just r'
Nothing -> Nothing
(mpb :: Maybe (ProgressBar ())) <- if progressBar
then Just <$> newProgressBar defStyle 10 (Progress 0 size ())
else pure Nothing
forM_ size $ \s -> forM_ eCSize $ \es -> when (es /= s) $ throwIO (ContentLengthError Nothing (Just s) es)
let size' = eCSize <|> size
(mpb :: Maybe (ProgressBar ())) <- case (progressBar, size') of
(True, Just size'') -> Just <$> newProgressBar defStyle 10 (Progress 0 (fromInteger size'') ())
_ -> pure Nothing
ior <- liftIO $ newIORef 0
outStream <- liftIO $ Streams.makeOutputStream
(\case
Just bs -> do
forM_ mpb $ \pb -> incProgress pb (BS.length bs)
let len = BS.length bs
forM_ mpb $ \pb -> incProgress pb len
-- check we don't exceed size
forM_ size' $ \s -> do
cs <- readIORef ior
when ((cs + toInteger len) > s) $ throwIO (ContentLengthError Nothing (Just (cs + toInteger len)) s)
modifyIORef ior (+ toInteger len)
void $ consumer bs
Nothing -> pure ()
)

View File

@@ -6,6 +6,7 @@
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes #-}
{-|
Module : GHCup.Errors
@@ -34,9 +35,156 @@ 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(..))
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 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
, ""
, "# 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
, ""
, "# 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 +199,32 @@ 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
deriving Show
instance Pretty NoDownload where
pPrint NoDownload =
text "Unable to find a download for the requested version/distro."
text (eDesc (Proxy :: Proxy NoDownload))
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 +234,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 +258,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 +282,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 +295,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 +307,10 @@ 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 the next version of a tool (the one after the currently
-- set one).
data NextVerNotFound = NextVerNotFound Tool
@@ -131,6 +320,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 +333,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 +345,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
@@ -158,6 +358,10 @@ instance Pretty NotInstalled where
pPrint (NotInstalled tool ver) =
text "The version" <+> pPrint ver <+> 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 +369,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 +383,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 +395,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 +408,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 +422,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 +433,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,7 +447,11 @@ 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."
-- | File digest verification failed.
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
@@ -227,6 +459,10 @@ 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
@@ -235,6 +471,10 @@ 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
@@ -243,6 +483,10 @@ 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
@@ -251,13 +495,21 @@ instance Pretty HTTPNotModified where
pPrint (HTTPNotModified etag) =
text "Remote resource not modifed, 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 "The 'Location' header was expected during a 3xx redirect, but not found."
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
@@ -265,7 +517,11 @@ data TooManyRedirs = TooManyRedirs
instance Pretty TooManyRedirs where
pPrint TooManyRedirs =
text "Too many redirections."
text (eDesc (Proxy :: Proxy TooManyRedirs))
instance HFErrorProject TooManyRedirs where
eBase _ = 260
eDesc _ = "Too many redirections."
-- | A patch could not be applied.
data PatchFailed = PatchFailed
@@ -273,7 +529,11 @@ data PatchFailed = PatchFailed
instance Pretty PatchFailed where
pPrint PatchFailed =
text "A patch could not be applied."
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
@@ -281,7 +541,11 @@ data NoToolRequirements = NoToolRequirements
instance Pretty NoToolRequirements where
pPrint NoToolRequirements =
text "The Tool requirements could not be found."
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
@@ -290,6 +554,10 @@ 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
@@ -297,19 +565,31 @@ 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 "A download was required or requested, but '--offline' was specified."
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 "Could not find Hadrian build files. Does this GHC version support Hadrian builds?"
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
@@ -332,12 +612,56 @@ instance Pretty ToolShadowed where
<> " 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
instance Pretty ContentLengthError where
pPrint (ContentLengthError Nothing Nothing expectedSize) =
text "Content length exceeded expected size:"
<+> text (show expectedSize)
<+> text "\nConsider removing the file in case it's cached and try again."
pPrint (ContentLengthError Nothing (Just currentSize) expectedSize) =
text "Content length error. Expected"
<+> text (show expectedSize) <+> text "but got" <+> pPrint currentSize <+> text
"\nConsider removing the file in case it's cached and try again."
pPrint (ContentLengthError (Just fp) (Just currentSize) expectedSize) =
text "Content length error for" <+> text (fp <> ": expected")
<+> text (show expectedSize) <+> text "but got" <+> pPrint currentSize <+> text
"\nConsider removing the file in case it's cached and try again."
pPrint (ContentLengthError (Just fp) Nothing expectedSize) =
text "Content length error for" <+> text (fp <> ": expected")
<+> text (show expectedSize) <+> text "\nConsider removing the file in case it's cached and try again."
instance Exception ContentLengthError
instance HFErrorProject ContentLengthError where
eBase _ = 340
eDesc _ = "File content length verification failed"
data DuplicateReleaseChannel = DuplicateReleaseChannel URI
deriving Show
instance HFErrorProject DuplicateReleaseChannel where
eBase _ = 350
eDesc _ = "Duplicate release channel detected when adding URI.\nGiving up. You can use '--force' to remove and append the duplicate URI (this may change order/semantics)."
instance Pretty DuplicateReleaseChannel where
pPrint (DuplicateReleaseChannel uri) =
text $ "Duplicate release channel detected when adding: \n "
<> (T.unpack . E.decodeUtf8With E.lenientDecode . serializeURIRef') uri
<> "\nGiving up. You can use '--force' to remove and append the duplicate URI (this may change order/semantics)."
-------------------------
--[ 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) =
@@ -347,7 +671,12 @@ 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) =
@@ -358,9 +687,31 @@ instance Pretty InstallSetError where
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) =
@@ -370,18 +721,28 @@ 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."
---------------------------------------------
--[ True Exceptions (e.g. for MonadThrow) ]--
@@ -398,6 +759,10 @@ instance Pretty ParseError where
instance Exception ParseError
instance HFErrorProject ParseError where
eBase _ = 500
eDesc _ = "A parse error occured."
data UnexpectedListLength = UnexpectedListLength String
deriving Show
@@ -408,6 +773,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
@@ -417,6 +786,10 @@ instance Pretty NoUrlBase where
instance Exception NoUrlBase
instance HFErrorProject NoUrlBase where
eBase _ = 520
eDesc _ = "URL does not have a base filename."
------------------------
@@ -436,6 +809,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)
@@ -454,6 +844,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"
@@ -462,5 +868,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."

View File

@@ -86,6 +86,144 @@ data GHCVer v = SourceDist v
--------------------
--[ 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
)
=> Version
-> [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
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
-> Version
-> [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
-> Version -- ^ 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)
-> Version -- ^ The GHC version
-> [T.Text] -- ^ additional configure args for bindist
-> Excepts '[ProcessError] m ()
testUnpackedGHC path ver addMakeArgs = do
lift $ logInfo $ "Testing GHC version " <> prettyVer ver <> "!"
ghcDir <- lift $ ghcupGHCDir (mkTVer ver)
let ghcBinDir = fromGHCupPath ghcDir </> "bin"
env <- liftIO $ addToPath ghcBinDir False
lEM $ make' (fmap T.unpack addMakeArgs)
(Just $ fromGHCupPath path)
"ghc-test"
(Just $ ("STAGE1_GHC", "ghc-" <> T.unpack (prettyVer ver)) : env)
pure ()
---------------------
--[ Tool fetching ]--
---------------------
@@ -109,6 +247,7 @@ fetchGHCSrc :: ( MonadFail m
-> Maybe FilePath
-> Excepts
'[ DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -152,6 +291,7 @@ installGHCBindist :: ( MonadFail m
'[ AlreadyInstalled
, BuildFailed
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -357,6 +497,7 @@ installGHCBin :: ( MonadFail m
'[ AlreadyInstalled
, BuildFailed
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -456,7 +597,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
@@ -628,6 +769,7 @@ compileGHC :: ( MonadMask m
'[ AlreadyInstalled
, BuildFailed
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, GHCupSetError
@@ -684,7 +826,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
-- download source tarball
tmpDownload <- lift withGHCupTmpDir
tmpUnpack <- lift mkGhcupTmpDir
tar <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpDownload) Nothing False
tar <- liftE $ download uri Nothing Nothing Nothing (fromGHCupPath tmpDownload) Nothing False
(bf, tver) <- liftE $ cleanUpOnError @'[UnknownArchive, ArchiveResult, ProcessError] tmpUnpack $ do
liftE $ unpackToDir (fromGHCupPath tmpUnpack) tar
let regex = [s|^(.*/)*boot$|] :: B.ByteString
@@ -706,7 +848,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
GitDist GitBranch{..} -> do
tmpUnpack <- lift mkGhcupTmpDir
let git args = execLogged "git" ("--no-pager":args) (Just $ fromGHCupPath tmpUnpack) "git" Nothing
tver <- reThrowAll @_ @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, DownloadFailed, GPGError] DownloadFailed $ do
tver <- reThrowAll @_ @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, ContentLengthError, DownloadFailed, GPGError] DownloadFailed $ do
let rep = fromMaybe "https://gitlab.haskell.org/ghc/ghc.git" repo
lift $ logInfo $ "Fetching git repo " <> T.pack rep <> " at ref " <> T.pack ref <> " (this may take a while)"
lEM $ git [ "init" ]
@@ -716,7 +858,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadr
, fromString rep ]
-- figure out if we can do a shallow clone
remoteBranches <- catchE @ProcessError @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, DownloadFailed, GPGError] @'[PatchFailed, NotFoundInPATH, DigestError, DownloadFailed, GPGError] (\(_ :: ProcessError) -> pure [])
remoteBranches <- catchE @ProcessError @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, ContentLengthError, DownloadFailed, GPGError] @'[PatchFailed, NotFoundInPATH, DigestError, DownloadFailed, GPGError] (\(_ :: ProcessError) -> pure [])
$ fmap processBranches $ gitOut ["ls-remote", "--heads", "origin"] (fromGHCupPath tmpUnpack)
let shallow_clone
| isCommitHash ref = True

View File

@@ -68,7 +68,6 @@ 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
@@ -105,6 +104,7 @@ installHLSBindist :: ( MonadMask m
'[ AlreadyInstalled
, CopyError
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -297,6 +297,7 @@ installHLSBin :: ( MonadMask m
'[ AlreadyInstalled
, CopyError
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -344,6 +345,7 @@ compileHLS :: ( MonadMask m
, GPGError
, DownloadFailed
, DigestError
, ContentLengthError
, UnknownArchive
, TarDirDoesNotExist
, ArchiveResult
@@ -401,7 +403,7 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal upda
-- download source tarball
tmpDownload <- lift withGHCupTmpDir
tmpUnpack <- lift mkGhcupTmpDir
tar <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpDownload) Nothing False
tar <- liftE $ download uri Nothing Nothing Nothing (fromGHCupPath tmpDownload) Nothing False
(cf, tver) <- liftE $ cleanUpOnError tmpUnpack $ do
unpackToDir (fromGHCupPath tmpUnpack) tar
let regex = [s|^(.*/)*haskell-language-server\.cabal$|] :: B.ByteString
@@ -481,7 +483,7 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal upda
liftE $ runBuildAction
tmpUnpack
(reThrowAll @_ @'[GPGError, DownloadFailed, DigestError, PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed $ fromGHCupPath workdir) $ do
(reThrowAll @_ @'[GPGError, DownloadFailed, DigestError, ContentLengthError, PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed $ fromGHCupPath workdir) $ do
let tmpInstallDir = fromGHCupPath workdir </> "out"
liftIO $ createDirRecursive' tmpInstallDir
@@ -497,7 +499,7 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal upda
| otherwise -> pure (takeFileName cp)
Just (Right uri) -> do
tmpUnpack' <- lift withGHCupTmpDir
cp <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpUnpack') (Just "cabal.project") False
cp <- liftE $ download uri Nothing Nothing Nothing (fromGHCupPath tmpUnpack') (Just "cabal.project") False
copyFileE cp (fromGHCupPath workdir </> "cabal.project") False
pure "cabal.project"
Nothing
@@ -511,7 +513,7 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal upda
| otherwise -> pure "cabal.project"
forM_ cabalProjectLocal $ \uri -> do
tmpUnpack' <- lift withGHCupTmpDir
cpl <- liftE $ download uri Nothing Nothing (fromGHCupPath tmpUnpack') (Just (cp <.> "local")) False
cpl <- liftE $ download uri Nothing Nothing Nothing (fromGHCupPath tmpUnpack') (Just (cp <.> "local")) False
copyFileE cpl (fromGHCupPath workdir </> cp <.> "local") False
artifacts <- forM (sort ghcs) $ \ghc -> do
let ghcInstallDir = tmpInstallDir </> T.unpack (prettyVer ghc)
@@ -631,7 +633,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

View File

@@ -41,24 +41,26 @@ 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
-- 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)

View File

@@ -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
@@ -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)

View File

@@ -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)

View File

@@ -50,7 +50,6 @@ import System.FilePath
import System.IO.Error
import qualified Data.Text as T
import Text.PrettyPrint.HughesPJClass (prettyShow)
@@ -82,6 +81,7 @@ installStackBin :: ( MonadMask m
'[ AlreadyInstalled
, CopyError
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -120,6 +120,7 @@ installStackBindist :: ( MonadMask m
'[ AlreadyInstalled
, CopyError
, DigestError
, ContentLengthError
, GPGError
, DownloadFailed
, NoDownload
@@ -232,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 Cabal pa stackbin ver)
pure ()

View File

@@ -35,7 +35,7 @@ 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(..) )
@@ -66,7 +66,7 @@ data GHCupInfo = GHCupInfo
, _ghcupDownloads :: GHCupDownloads
, _globalTools :: Map GlobalTool DownloadInfo
}
deriving (Show, GHC.Generic)
deriving (Show, GHC.Generic, Eq)
instance NFData GHCupInfo
@@ -87,7 +87,7 @@ data Requirements = Requirements
{ _distroPKGs :: [Text]
, _notes :: Text
}
deriving (Show, GHC.Generic)
deriving (Show, GHC.Generic, Eq)
instance NFData Requirements
@@ -138,6 +138,7 @@ data VersionInfo = VersionInfo
{ _viTags :: [Tag] -- ^ version specific tag
, _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
@@ -153,6 +154,7 @@ instance NFData VersionInfo
data Tag = Latest
| Recommended
| Prerelease
| LatestPrerelease
| Base PVP
| Old -- ^ old versions are hidden by default in TUI
| UnknownTag String -- ^ used for upwardscompat
@@ -166,6 +168,7 @@ tagToString Latest = "latest"
tagToString Prerelease = "prerelease"
tagToString (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
tagToString (UnknownTag t ) = t
tagToString LatestPrerelease = "latest-prerelease"
tagToString Old = ""
instance Pretty Tag where
@@ -174,6 +177,7 @@ instance Pretty Tag where
pPrint Prerelease = text "prerelease"
pPrint (Base pvp'') = text ("base-" ++ T.unpack (prettyPVP pvp''))
pPrint (UnknownTag t ) = text t
pPrint LatestPrerelease = text "latest-prerelease"
pPrint Old = mempty
data Architecture = A_64
@@ -262,6 +266,7 @@ data DownloadInfo = DownloadInfo
{ _dlUri :: URI
, _dlSubdir :: Maybe TarDir
, _dlHash :: Text
, _dlCSize :: Maybe Integer
}
deriving (Eq, Ord, GHC.Generic, Show)
@@ -273,6 +278,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
@@ -297,10 +319,16 @@ 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
@@ -309,18 +337,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)
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
@@ -330,6 +360,7 @@ fromSettings Settings{..} Nothing =
, uUrlSource = Just urlSource
, uGPGSetting = Just gpgSetting
, uPlatformOverride = platformOverride
, uMirrors = Just mirrors
}
fromSettings Settings{..} (Just KeyBindings{..}) =
let ukb = UserKeyBindings
@@ -346,6 +377,7 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
in UserSettings {
uCache = Just cache
, uMetaCache = Just metaCache
, uMetaMode = Just metaMode
, uNoVerify = Just noVerify
, uVerbose = Just verbose
, uKeepDirs = Just keepDirs
@@ -355,6 +387,7 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
, uUrlSource = Just urlSource
, uGPGSetting = Just gpgSetting
, uPlatformOverride = platformOverride
, uMirrors = Just mirrors
}
data UserKeyBindings = UserKeyBindings
@@ -384,7 +417,9 @@ data KeyBindings = KeyBindings
deriving (Show, GHC.Generic)
instance NFData KeyBindings
#if defined(IS_WINDOWS) || !defined(BRICK)
instance NFData Key
#endif
defaultKeyBindings :: KeyBindings
defaultKeyBindings = KeyBindings
@@ -426,6 +461,7 @@ instance NFData LeanAppState
data Settings = Settings
{ cache :: Bool
, metaCache :: Integer
, metaMode :: MetaMode
, noVerify :: Bool
, keepDirs :: KeepDirs
, downloader :: Downloader
@@ -435,6 +471,7 @@ data Settings = Settings
, gpgSetting :: GPGSetting
, noColor :: Bool -- this also exists in LoggerConfig
, platformOverride :: Maybe PlatformRequest
, mirrors :: DownloadMirrors
}
deriving (Show, GHC.Generic)
@@ -442,7 +479,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
@@ -622,15 +659,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

View File

@@ -29,6 +29,7 @@ import Control.Applicative ( (<|>) )
import Data.Aeson hiding (Key)
import Data.Aeson.TH
import Data.Aeson.Types hiding (Key)
import Data.ByteString ( ByteString )
import Data.List.NonEmpty ( NonEmpty(..) )
import Data.Text.Encoding as E
import Data.Versions
@@ -43,6 +44,7 @@ import qualified Text.Megaparsec as MP
import qualified Text.Megaparsec.Char as MPC
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''MetaMode
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Architecture
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''LinuxDistro
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VSep
@@ -64,6 +66,7 @@ instance ToJSON Tag where
toJSON Prerelease = String "Prerelease"
toJSON Old = String "old"
toJSON (Base pvp'') = String ("base-" <> prettyPVP pvp'')
toJSON LatestPrerelease = String "LatestPrerelease"
toJSON (UnknownTag x ) = String (T.pack x)
instance FromJSON Tag where
@@ -71,6 +74,7 @@ instance FromJSON Tag where
"Latest" -> pure Latest
"Recommended" -> pure Recommended
"Prerelease" -> pure Prerelease
"LatestPrerelease" -> pure LatestPrerelease
"old" -> pure Old
('b' : 'a' : 's' : 'e' : '-' : ver') -> case pvp (T.pack ver') of
Right x -> pure $ Base x
@@ -224,6 +228,12 @@ instance FromJSON VersionCmp where
Right r -> pure r
Left e -> fail (MP.errorBundlePretty e)
instance ToJSON ByteString where
toJSON = toJSON . E.decodeUtf8With E.lenientDecode
instance FromJSON ByteString where
parseJSON = withText "ByteString" $ \t -> pure $ E.encodeUtf8 t
versionCmpToText :: VersionCmp -> T.Text
versionCmpToText (VR_gt ver') = "> " <> prettyV ver'
versionCmpToText (VR_gteq ver') = ">= " <> prettyV ver'
@@ -319,6 +329,12 @@ deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''GHCupI
deriveToJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''URLSource
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''Key
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "k-") . T.pack . kebab $ str' } ''UserKeyBindings
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel, unwrapUnaryRecords = True } ''Port
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel, unwrapUnaryRecords = True } ''Host
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''UserInfo
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' (T.unpack . T.toLower) . T.stripPrefix (T.pack "authority") . T.pack $ str' } ''Authority
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''DownloadMirror
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''DownloadMirrors
deriveToJSON defaultOptions { fieldLabelModifier = kebab } ''Settings
deriveToJSON defaultOptions { fieldLabelModifier = drop 2 . kebab } ''KeyBindings -- move under key-bindings key
@@ -355,4 +371,3 @@ instance FromJSON URLSource where
pure (AddSource r)
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "u-") . T.pack . kebab $ str' } ''UserSettings

View File

@@ -93,6 +93,7 @@ import qualified Data.List.NonEmpty as NE
import qualified Streamly.Prelude as S
import Control.DeepSeq (force)
import GHC.IO (evaluate)
import System.Environment (getEnvironment, setEnv)
-- $setup
@@ -334,7 +335,7 @@ ghcSet mtarget = do
getInstalledGHCs :: (MonadReader env m, HasDirs env, MonadIO m) => m [Either FilePath GHCTargetVersion]
getInstalledGHCs = do
ghcdir <- ghcupGHCBaseDir
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectory (fromGHCupPath ghcdir)
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectoryDirs (fromGHCupPath ghcdir)
forM fs $ \f -> case parseGHCupGHCDir f of
Right r -> pure $ Right r
Left _ -> pure $ Left f
@@ -437,7 +438,7 @@ getInstalledHLSs = do
Nothing -> pure $ Left f
hlsdir <- ghcupHLSBaseDir
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectory (fromGHCupPath hlsdir)
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectoryDirs (fromGHCupPath hlsdir)
new <- forM fs $ \f -> case parseGHCupHLSDir f of
Right r -> pure $ Right r
Left _ -> pure $ Left f
@@ -625,7 +626,7 @@ hlsInternalServerScripts ver mghcVer = do
dir <- ghcupHLSDir ver
let bdir = fromGHCupPath dir </> "bin"
fmap (bdir </>) . filter (\f -> maybe True (\gv -> ("-" <> T.unpack (prettyVer gv)) `isSuffixOf` f) mghcVer)
<$> liftIO (listDirectory bdir)
<$> liftIO (listDirectoryFiles bdir)
-- | Get all binaries for a hls version from the ~/.ghcup/hls/<ver>/lib/haskell-language-server-<ver>/bin directory, if any.
-- Returns the full path.
@@ -638,7 +639,7 @@ hlsInternalServerBinaries ver mghcVer = do
let regex = makeRegexOpts compExtended execBlank ([s|^haskell-language-server-.*$|] :: ByteString)
(Just bdir) <- fmap headMay $ liftIO $ expandFilePath [Left (dir </> "lib"), Right regex, Left "bin"]
fmap (bdir </>) . filter (\f -> maybe True (\gv -> ("-" <> T.unpack (prettyVer gv)) `isSuffixOf` f) mghcVer)
<$> liftIO (listDirectory bdir)
<$> liftIO (listDirectoryFiles bdir)
-- | Get all libraries for a hls version from the ~/.ghcup/hls/<ver>/lib/haskell-language-server-<ver>/lib/<ghc-ver>/
-- directory, if any.
@@ -651,7 +652,7 @@ hlsInternalServerLibs ver ghcVer = do
dir <- fromGHCupPath <$> ghcupHLSDir ver
let regex = makeRegexOpts compExtended execBlank ([s|^haskell-language-server-.*$|] :: ByteString)
(Just bdir) <- fmap headMay $ liftIO $ expandFilePath [Left (dir </> "lib"), Right regex, Left ("lib" </> T.unpack (prettyVer ghcVer))]
fmap (bdir </>) <$> liftIO (listDirectory bdir)
fmap (bdir </>) <$> liftIO (listDirectoryFiles bdir)
-- | Get the wrapper binary for an hls version, if any.
@@ -891,6 +892,9 @@ getTagged tag =
getLatest :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
getLatest av tool = headOf (ix tool % getTagged Latest) av
getLatestPrerelease :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
getLatestPrerelease av tool = headOf (ix tool % getTagged LatestPrerelease) av
getRecommended :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
getRecommended av tool = headOf (ix tool % getTagged Recommended) av
@@ -932,7 +936,7 @@ ghcToolFiles ver = do
whenM (fmap not $ ghcInstalled ver)
(throwE (NotInstalled GHC ver))
files <- liftIO (listDirectory bindir >>= filterM (doesFileExist . (bindir </>)))
files <- liftIO (listDirectoryFiles bindir >>= filterM (doesFileExist . (bindir </>)))
pure (getUniqueTools . groupToolFiles . fmap (dropSuffix exeExt) $ files)
where
@@ -967,11 +971,28 @@ make :: ( MonadThrow m
=> [String]
-> Maybe FilePath
-> m (Either ProcessError ())
make args workdir = do
make args workdir = make' args workdir "ghc-make" Nothing
-- | Calls gmake if it exists in PATH, otherwise make.
make' :: ( MonadThrow m
, MonadIO m
, MonadReader env m
, HasDirs env
, HasLog env
, HasSettings env
)
=> [String]
-> Maybe FilePath
-> FilePath -- ^ log filename (opened in append mode)
-> Maybe [(String, String)] -- ^ optional environment
-> m (Either ProcessError ())
make' args workdir logfile menv = do
spaths <- liftIO getSearchPath
has_gmake <- isJust <$> liftIO (searchPath spaths "gmake")
let mymake = if has_gmake then "gmake" else "make"
execLogged mymake args workdir "ghc-make" Nothing
execLogged mymake args workdir logfile menv
makeOut :: (MonadReader env m, HasDirs env, MonadIO m)
=> [String]
@@ -1035,13 +1056,13 @@ applyAnyPatch :: ( MonadReader env m
, MonadIO m)
=> Maybe (Either FilePath [URI])
-> FilePath
-> Excepts '[PatchFailed, DownloadFailed, DigestError, GPGError] m ()
-> Excepts '[PatchFailed, DownloadFailed, DigestError, ContentLengthError, GPGError] m ()
applyAnyPatch Nothing _ = pure ()
applyAnyPatch (Just (Left pdir)) workdir = liftE $ applyPatches pdir workdir
applyAnyPatch (Just (Right uris)) workdir = do
tmpUnpack <- fromGHCupPath <$> lift withGHCupTmpDir
forM_ uris $ \uri -> do
patch <- liftE $ download uri Nothing Nothing tmpUnpack Nothing False
patch <- liftE $ download uri Nothing Nothing Nothing tmpUnpack Nothing False
liftE $ applyPatch patch workdir
@@ -1172,7 +1193,7 @@ ensureGlobalTools :: ( MonadMask m
, MonadUnliftIO m
, MonadFail m
)
=> Excepts '[GPGError, DigestError , DownloadFailed, NoDownload] m ()
=> Excepts '[GPGError, DigestError, ContentLengthError, DownloadFailed, NoDownload] m ()
ensureGlobalTools
| isWindows = do
(GHCupInfo _ _ gTools) <- lift getGHCupInfo
@@ -1184,8 +1205,8 @@ ensureGlobalTools
lift $ logWarn "Digest doesn't match, redownloading gs.exe..."
lift $ logDebug ("rm -f " <> T.pack (fromGHCupPath (cacheDir dirs) </> "gs.exe"))
lift $ hideError doesNotExistErrorType $ recycleFile (fromGHCupPath (cacheDir dirs) </> "gs.exe")
liftE @'[GPGError, DigestError , DownloadFailed] $ dl
) `catchE` liftE @'[GPGError, DigestError , DownloadFailed] dl
liftE @'[GPGError, DigestError, ContentLengthError, DownloadFailed] $ dl
) `catchE` liftE @'[GPGError, DigestError, ContentLengthError, DownloadFailed] dl
| otherwise = pure ()
@@ -1282,6 +1303,22 @@ warnAboutHlsCompatibility = do
addToPath :: FilePath
-> Bool -- ^ if False will prepend
-> IO [(String, String)]
addToPath path append = do
cEnv <- Map.fromList <$> getEnvironment
let paths = ["PATH", "Path"]
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
{- HLINT ignore "Redundant bracket" -}
newPath = intercalate [searchPathSeparator] (if append 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
-----------
--[ Git ]--
-----------
@@ -1301,7 +1338,7 @@ gitOut args dir = do
ExitSuccess -> pure $ T.pack $ stripNewlineEnd $ T.unpack $ decUTF8Safe' _stdOut
ExitFailure c -> do
let pe = NonZeroExit c "git" args
lift $ logDebug $ T.pack (prettyShow pe)
lift $ logDebug $ T.pack (prettyHFError pe)
throwE pe
processBranches :: T.Text -> [String]

View File

@@ -42,6 +42,9 @@ module GHCup.Utils.Dirs
, removeDirectoryRecursive
, removePathForcibly
, listDirectoryFiles
, listDirectoryDirs
-- System.Directory re-exports
, createDirectory
, createDirectoryIfMissing
@@ -130,7 +133,7 @@ import Data.Maybe
import Data.Versions
import GHC.IO.Exception ( IOErrorType(NoSuchThing) )
import Haskus.Utils.Variant.Excepts
import Optics
import Optics hiding ( uncons )
import Safe
import System.Directory hiding ( removeDirectory
, removeDirectoryRecursive
@@ -465,15 +468,22 @@ withGHCupTmpDir :: ( MonadReader env m
, MonadMask m
, MonadIO m)
=> m GHCupPath
withGHCupTmpDir = snd <$> withRunInIO (\run ->
run
$ allocate
(run mkGhcupTmpDir)
(\fp ->
handleIO (\e -> run
$ logDebug ("Resource cleanup failed for " <> T.pack (fromGHCupPath fp) <> ", error was: " <> T.pack (displayException e)))
. removePathForcibly
$ fp))
withGHCupTmpDir = do
Settings{keepDirs} <- getSettings
snd <$> withRunInIO (\run ->
run
$ allocate
(run mkGhcupTmpDir)
(\fp -> if -- we don't know whether there was a failure, so can only
-- decide for 'Always'
| keepDirs == Always -> pure ()
| otherwise -> handleIO (\e -> run
$ logDebug ("Resource cleanup failed for "
<> T.pack (fromGHCupPath fp)
<> ", error was: "
<> T.pack (displayException e)))
. removePathForcibly
$ fp))
@@ -522,6 +532,29 @@ cleanupTrash = do
) $ liftIO $ removePathForcibly (recycleDir `appendGHCupPath` fp))
-- | List *actual files* in a directory, ignoring empty files and a couple
-- of blacklisted files, such as '.DS_Store' on mac.
listDirectoryFiles :: FilePath -> IO [FilePath]
listDirectoryFiles fp = do
listDirectory fp >>= filterM (doesFileExist . (fp </>)) <&> filter (\fp' -> not (isHidden fp') && not (isBlacklisted fp'))
-- | List *actual directories* in a directory, ignoring empty directories and a couple
-- of blacklisted files, such as '.DS_Store' on mac.
listDirectoryDirs :: FilePath -> IO [FilePath]
listDirectoryDirs fp = do
listDirectory fp >>= filterM (doesDirectoryExist . (fp </>)) <&> filter (\fp' -> not (isHidden fp') && not (isBlacklisted fp'))
isHidden :: FilePath -> Bool
isHidden fp'
| isWindows = False
| Just ('.', _) <- uncons fp' = True
| otherwise = False
isBlacklisted :: FilePath -> Bool
{- HLINT ignore "Use ==" -}
isBlacklisted fp' = fp' `elem` [".DS_Store"]
-- System.Directory re-exports with GHCupPath

View File

@@ -2,7 +2,6 @@ site_name: GHCup
site_url: https://www.haskell.org/ghcup
site_description: GHCup is the main installer for the general purpose language Haskell.
site_author: GHCup Team
site_favicon: haskell_logo.png
repo_url: https://github.com/haskell/ghcup-hs

View File

@@ -28,7 +28,7 @@
plat="$(uname -s)"
arch=$(uname -m)
ghver="0.1.18.0"
ghver="0.1.19.2"
: "${GHCUP_BASE_URL:=https://downloads.haskell.org/~ghcup}"
export GHCUP_SKIP_UPDATE_CHECK=yes
@@ -119,20 +119,26 @@ edo() {
"$@" || die "\"$*\" failed!"
}
eghcup_raw() {
"${GHCUP_BIN}/ghcup" "$@" || die "\"ghcup $*\" failed!"
}
eghcup() {
edo _eghcup "$@"
_eghcup "$@"
}
_eghcup() {
if [ -n "${BOOTSTRAP_HASKELL_YAML}" ] ; then
args="-s ${BOOTSTRAP_HASKELL_YAML}"
args="-s ${BOOTSTRAP_HASKELL_YAML} --metadata-fetching-mode=Strict"
else
args="--metadata-fetching-mode=Strict"
fi
if [ -z "${BOOTSTRAP_HASKELL_VERBOSE}" ] ; then
# shellcheck disable=SC2086
"${GHCUP_BIN}/ghcup" ${args} "$@"
"${GHCUP_BIN}/ghcup" ${args} "$@" || die "\"ghcup ${args} $*\" failed!"
else
# shellcheck disable=SC2086
"${GHCUP_BIN}/ghcup" ${args} --verbose "$@"
"${GHCUP_BIN}/ghcup" ${args} --verbose "$@" || die "\"ghcup ${args} --verbose $*\" failed!"
fi
}
@@ -147,7 +153,7 @@ _ecabal() {
}
ecabal() {
edo _ecabal "$@"
_ecabal "$@" || die "\"cabal $*\" failed!"
}
_done() {
@@ -282,14 +288,6 @@ download_ghcup() {
esac
;;
"FreeBSD"|"freebsd")
if freebsd-version | grep -E '^12.*' ; then
freebsd_ver=12
elif freebsd-version | grep -E '^13.*' ; then
freebsd_ver=13
else
die "Unsupported FreeBSD version! Please report a bug at https://github.com/haskell/ghcup-hs/issues"
fi
case "${arch}" in
x86_64|amd64)
;;
@@ -299,7 +297,7 @@ download_ghcup() {
*) die "Unknown architecture: ${arch}"
;;
esac
_url=${GHCUP_BASE_URL}/${ghver}/x86_64-freebsd${freebsd_ver}-ghcup-${ghver}
_url=${GHCUP_BASE_URL}/${ghver}/x86_64-portbld-freebsd-ghcup-${ghver}
;;
"Darwin"|"darwin")
case "${arch}" in
@@ -387,10 +385,10 @@ download_ghcup() {
edo . "${GHCUP_DIR}"/env
case "${BOOTSTRAP_HASKELL_DOWNLOADER}" in
"curl")
eghcup config set downloader Curl
eghcup_raw config set downloader Curl
;;
"wget")
eghcup config set downloader Wget
eghcup_raw config set downloader Wget
;;
*)
die "Unknown downloader: ${BOOTSTRAP_HASKELL_DOWNLOADER}"
@@ -795,7 +793,7 @@ edo mkdir -p "${GHCUP_BIN}"
if command -V "ghcup" >/dev/null 2>&1 ; then
if [ -z "${BOOTSTRAP_HASKELL_NO_UPGRADE}" ] ; then
_eghcup upgrade || download_ghcup
( _eghcup upgrade ) || download_ghcup
fi
else
download_ghcup
@@ -842,17 +840,17 @@ fi
case $ask_hls_answer in
1)
_eghcup --cache install hls || warn "HLS installation failed, continuing anyway"
(_eghcup --cache install hls) || warn "HLS installation failed, continuing anyway"
;;
*) ;;
esac
case $ask_stack_answer in
1)
_eghcup --cache install stack || die "Stack installation failed"
(_eghcup --cache install stack) || die "Stack installation failed"
;;
2)
_eghcup --cache install stack || die "Stack installation failed"
(_eghcup --cache install stack) || die "Stack installation failed"
edo mkdir -p "${STACK_ROOOT:-$HOME/.stack}"/hooks
hook_exe="${STACK_ROOOT:-$HOME/.stack}"/hooks/ghc-install.sh
hook_url="https://www.haskell.org/ghcup/sh/hooks/stack/ghc-install.sh"

View File

@@ -432,12 +432,13 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
}
Print-Msg -msg ('Downloading Msys2 archive {0}...' -f $Msys2Version)
$archive = ('msys2-base-x86_64-{0}.sfx.exe' -f $Msys2Version)
$msysUrl = ('https://repo.msys2.org/distrib/x86_64/{0}' -f "$archive")
$archivePath = ('{0}\{1}' -f ([IO.Path]::GetTempPath()), "$archive")
if ((Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) -and !($DisableCurl)) {
Exec "curl.exe" '-o' "$archivePath" ('https://repo.msys2.org/distrib/x86_64/{0}' -f "$archive")
Exec "curl.exe" '-o' "$archivePath" "$msysUrl"
} else {
Get-FileWCSynchronous -url ('https://repo.msys2.org/distrib/{0}' -f $archive) -destinationFolder ([IO.Path]::GetTempPath()) -includeStats
Get-FileWCSynchronous -url "$msysUrl" -destinationFolder ([IO.Path]::GetTempPath()) -includeStats
}
Print-Msg -msg 'Extracting Msys2 archive...'

View File

@@ -1,49 +1,37 @@
#!/bin/bash
set -eu
set -o pipefail
tag=v$1
ver=$1
shopt -s extglob
dest=$2
gpg_user=$3
RELEASE=$1
SIGNER=$2
TAG=${RELEASE/v/}
mkdir -p "${dest}"
echo "RELEASE: $RELEASE"
echo "SIGNER: $SIGNER"
cd "${dest}"
for com in gh gpg curl sha256sum ; do
command -V ${com} >/dev/null 2>&1
done
base_url="https://gitlab.haskell.org/api/v4/projects/618/jobs/artifacts/${tag}/raw"
[ ! -e "gh-release-artifacts/${RELEASE}" ]
curl -f -o "x86_64-apple-darwin-ghcup-${ver}" \
"${base_url}/out/x86_64-apple-darwin-ghcup-${ver}?job=release:darwin"
mkdir -p "gh-release-artifacts/${RELEASE}"
curl -f -o "aarch64-apple-darwin-ghcup-${ver}" \
"${base_url}/out/aarch64-apple-darwin-ghcup-${ver}?job=release:darwin:aarch64"
git archive --format=tar.gz -o "gh-release-artifacts/${RELEASE}/ghcup-${TAG}-src.tar.gz" --prefix="ghcup-${TAG}/" HEAD
curl -f -o "x86_64-freebsd12-ghcup-${ver}" \
"${base_url}/out/x86_64-portbld-freebsd-ghcup-${ver}?job=release:freebsd12"
cd "gh-release-artifacts/${RELEASE}"
curl -f -o "x86_64-freebsd13-ghcup-${ver}" \
"${base_url}/out/x86_64-portbld-freebsd-ghcup-${ver}?job=release:freebsd13"
curl -f -o "i386-linux-ghcup-${ver}" \
"${base_url}/out/i386-linux-ghcup-${ver}?job=release:linux:32bit"
curl -f -o "x86_64-linux-ghcup-${ver}" \
"${base_url}/out/x86_64-linux-ghcup-${ver}?job=release:linux:64bit"
curl -f -o "aarch64-linux-ghcup-${ver}" \
"${base_url}/out/aarch64-linux-ghcup-${ver}?job=release:linux:aarch64"
curl -f -o "armv7-linux-ghcup-${ver}" \
"${base_url}/out/armv7-linux-ghcup-${ver}?job=release:linux:armv7"
curl -f -o "x86_64-mingw64-ghcup-${ver}.exe" \
"${base_url}/out/x86_64-mingw64-ghcup-${ver}.exe?job=release:windows"
rm -f *.sig
sha256sum *-ghcup-* > SHA256SUMS
gpg --detach-sign -u ${gpg_user} SHA256SUMS
for f in *-ghcup-* ; do gpg --detach-sign -u ${gpg_user} $f ; done
# github
gh release download "$RELEASE"
# cirrus
curl -L -o "x86_64-portbld-freebsd-ghcup-${TAG}" \
"https://api.cirrus-ci.com/v1/artifact/github/haskell/ghcup-hs/build/binaries/out/x86_64-portbld-freebsd-ghcup-${RELEASE}?branch=${RELEASE}"
sha256sum ./*-ghcup-* > SHA256SUMS
gpg --detach-sign -u "${SIGNER}" SHA256SUMS
gh release upload "$RELEASE" "ghcup-${TAG}-src.tar.gz" "x86_64-portbld-freebsd-ghcup-${TAG}" SHA256SUMS SHA256SUMS.sig

View File

@@ -21,16 +21,14 @@ rm i386-linux-ghcup
rm x86_64-apple-darwin-ghcup
rm x86_64-linux-ghcup
rm x86_64-mingw64-ghcup.exe
rm x86_64-freebsd12-ghcup
rm x86_64-freebsd13-ghcup
rm x86_64-portbld-freebsd-ghcup
symlink ${ver}/aarch64-apple-darwin-ghcup-${ver} aarch64-apple-darwin-ghcup
symlink ${ver}/aarch64-linux-ghcup-${ver} aarch64-linux-ghcup
symlink ${ver}/armv7-linux-ghcup-${ver} armv7-linux-ghcup
symlink ${ver}/i386-linux-ghcup-${ver} i386-linux-ghcup
symlink ${ver}/x86_64-apple-darwin-ghcup-${ver} x86_64-apple-darwin-ghcup
symlink ${ver}/x86_64-freebsd12-ghcup-${ver} x86_64-freebsd12-ghcup
symlink ${ver}/x86_64-freebsd13-ghcup-${ver} x86_64-freebsd13-ghcup
symlink ${ver}/x86_64-portbld-freebsd-ghcup-${ver} x86_64-portbld-freebsd-ghcup
symlink ${ver}/x86_64-linux-ghcup-${ver} x86_64-linux-ghcup
symlink ${ver}/x86_64-mingw64-ghcup-${ver}.exe x86_64-mingw64-ghcup.exe
EOF

View File

@@ -25,22 +25,28 @@ put SHA256SUMS
put SHA256SUMS.sig
put aarch64-apple-darwin-ghcup-${ver}
put aarch64-apple-darwin-ghcup-${ver}.sig
put aarch64-apple-darwin-ghcup.plan.json
put aarch64-linux-ghcup-${ver}
put aarch64-linux-ghcup-${ver}.sig
put aarch64-linux-ghcup.plan.json
put armv7-linux-ghcup-${ver}
put armv7-linux-ghcup-${ver}.sig
put armv7-linux-ghcup.plan.json
put i386-linux-ghcup-${ver}
put i386-linux-ghcup-${ver}.sig
put i386-linux-ghcup.plan.json
put x86_64-apple-darwin-ghcup-${ver}
put x86_64-apple-darwin-ghcup-${ver}.sig
put x86_64-freebsd12-ghcup-${ver}
put x86_64-freebsd12-ghcup-${ver}.sig
put x86_64-freebsd13-ghcup-${ver}
put x86_64-freebsd13-ghcup-${ver}.sig
put x86_64-apple-darwin-ghcup.plan.json
put x86_64-portbld-freebsd-ghcup-${ver}
put x86_64-portbld-freebsd-ghcup-${ver}.sig
put x86_64-portbld-freebsd-ghcup.plan.json
put x86_64-linux-ghcup-${ver}
put x86_64-linux-ghcup-${ver}.sig
put x86_64-linux-ghcup.plan.json
put x86_64-mingw64-ghcup-${ver}.exe
put x86_64-mingw64-ghcup-${ver}.exe.sig
put x86_64-mingw64-ghcup.plan.json
EOF
curl -X PURGE https://downloads.haskell.org/~ghcup/${ver}/

View File

@@ -24,11 +24,11 @@ spec = do
-- https://github.com/haskell/ghcup-hs/issues/415
describe "GHCup.Prelude.File.Posix.Traversals" $ do
it "readDirEnt" $ do
dirstream <- liftIO $ openDirStream "test/data"
(dt1, fp1) <- readDirEnt dirstream
(dt2, fp2) <- readDirEnt dirstream
(dt3, fp3) <- readDirEnt dirstream
(dt4, fp4) <- readDirEnt dirstream
dirstream <- liftIO $ openDirStreamPortable "test/data"
(dt1, fp1) <- readDirEntPortable dirstream
(dt2, fp2) <- readDirEntPortable dirstream
(dt3, fp3) <- readDirEntPortable dirstream
(dt4, fp4) <- readDirEntPortable dirstream
let xs = sortOn snd [ (dt1, fp1), (dt2, fp2)
, (dt3, fp3), (dt4, fp4)
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +0,0 @@
<svg width="71" height="55" viewBox="0 0 71 55" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M60.1045 4.8978C55.5792 2.8214 50.7265 1.2916 45.6527 0.41542C45.5603 0.39851 45.468 0.440769 45.4204 0.525289C44.7963 1.6353 44.105 3.0834 43.6209 4.2216C38.1637 3.4046 32.7345 3.4046 27.3892 4.2216C26.905 3.0581 26.1886 1.6353 25.5617 0.525289C25.5141 0.443589 25.4218 0.40133 25.3294 0.41542C20.2584 1.2888 15.4057 2.8186 10.8776 4.8978C10.8384 4.9147 10.8048 4.9429 10.7825 4.9795C1.57795 18.7309 -0.943561 32.1443 0.293408 45.3914C0.299005 45.4562 0.335386 45.5182 0.385761 45.5576C6.45866 50.0174 12.3413 52.7249 18.1147 54.5195C18.2071 54.5477 18.305 54.5139 18.3638 54.4378C19.7295 52.5728 20.9469 50.6063 21.9907 48.5383C22.0523 48.4172 21.9935 48.2735 21.8676 48.2256C19.9366 47.4931 18.0979 46.6 16.3292 45.5858C16.1893 45.5041 16.1781 45.304 16.3068 45.2082C16.679 44.9293 17.0513 44.6391 17.4067 44.3461C17.471 44.2926 17.5606 44.2813 17.6362 44.3151C29.2558 49.6202 41.8354 49.6202 53.3179 44.3151C53.3935 44.2785 53.4831 44.2898 53.5502 44.3433C53.9057 44.6363 54.2779 44.9293 54.6529 45.2082C54.7816 45.304 54.7732 45.5041 54.6333 45.5858C52.8646 46.6197 51.0259 47.4931 49.0921 48.2228C48.9662 48.2707 48.9102 48.4172 48.9718 48.5383C50.038 50.6034 51.2554 52.5699 52.5959 54.435C52.6519 54.5139 52.7526 54.5477 52.845 54.5195C58.6464 52.7249 64.529 50.0174 70.6019 45.5576C70.6551 45.5182 70.6887 45.459 70.6943 45.3942C72.1747 30.0791 68.2147 16.7757 60.1968 4.9823C60.1772 4.9429 60.1437 4.9147 60.1045 4.8978ZM23.7259 37.3253C20.2276 37.3253 17.3451 34.1136 17.3451 30.1693C17.3451 26.225 20.1717 23.0133 23.7259 23.0133C27.308 23.0133 30.1626 26.2532 30.1066 30.1693C30.1066 34.1136 27.28 37.3253 23.7259 37.3253ZM47.3178 37.3253C43.8196 37.3253 40.9371 34.1136 40.9371 30.1693C40.9371 26.225 43.7636 23.0133 47.3178 23.0133C50.9 23.0133 53.7545 26.2532 53.6986 30.1693C53.6986 34.1136 50.9 37.3253 47.3178 37.3253Z" fill="#23272A"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="71" height="55" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,208 +0,0 @@
The ghcup website, excluding ghcup, fonts, bootstrap-haskell script are subject
to the license below. Design, javascript and css are used from the rustup
project: https://github.com/rust-lang/rustup.rs/tree/master/www
===============================================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 75 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<title>Matrix (protocol) logo</title>
<g fill="#040404">
<path d="m0.936 0.732v30.52h2.194v0.732h-3.035v-31.98h3.034v0.732zm8.45 9.675v1.544h0.044a4.461 4.461 0 0 1 1.487-1.368c0.58-0.323 1.245-0.485 1.993-0.485 0.72 0 1.377 0.14 1.972 0.42 0.595 0.279 1.047 0.771 1.355 1.477 0.338-0.5 0.796-0.941 1.377-1.323 0.58-0.383 1.266-0.574 2.06-0.574 0.602 0 1.16 0.074 1.674 0.22 0.514 0.148 0.954 0.383 1.322 0.707 0.366 0.323 0.653 0.746 0.859 1.268 0.205 0.522 0.308 1.15 0.308 1.887v7.633h-3.127v-6.464c0-0.383-0.015-0.743-0.044-1.082a2.305 2.305 0 0 0-0.242-0.882 1.473 1.473 0 0 0-0.584-0.596c-0.257-0.146-0.606-0.22-1.047-0.22-0.44 0-0.796 0.085-1.068 0.253-0.272 0.17-0.485 0.39-0.639 0.662a2.654 2.654 0 0 0-0.308 0.927 7.074 7.074 0 0 0-0.078 1.048v6.354h-3.128v-6.398c0-0.338-7e-3 -0.673-0.021-1.004a2.825 2.825 0 0 0-0.188-0.916 1.411 1.411 0 0 0-0.55-0.673c-0.258-0.168-0.636-0.253-1.135-0.253a2.33 2.33 0 0 0-0.584 0.1 1.94 1.94 0 0 0-0.705 0.374c-0.228 0.184-0.422 0.449-0.584 0.794-0.161 0.346-0.242 0.798-0.242 1.357v6.619h-3.129v-11.41zm16.46 1.677a3.751 3.751 0 0 1 1.233-1.17 5.37 5.37 0 0 1 1.685-0.629 9.579 9.579 0 0 1 1.884-0.187c0.573 0 1.153 0.04 1.74 0.121 0.588 0.081 1.124 0.24 1.609 0.475 0.484 0.235 0.88 0.562 1.19 0.981 0.308 0.42 0.462 0.975 0.462 1.666v5.934c0 0.516 0.03 1.008 0.088 1.478 0.058 0.471 0.161 0.824 0.308 1.06h-3.171a4.435 4.435 0 0 1-0.22-1.104c-0.5 0.515-1.087 0.876-1.762 1.081a7.084 7.084 0 0 1-2.071 0.31c-0.544 0-1.05-0.067-1.52-0.2a3.472 3.472 0 0 1-1.234-0.617 2.87 2.87 0 0 1-0.826-1.059c-0.199-0.426-0.298-0.934-0.298-1.522 0-0.647 0.114-1.18 0.342-1.6 0.227-0.419 0.52-0.753 0.881-1.004 0.36-0.25 0.771-0.437 1.234-0.562 0.462-0.125 0.929-0.224 1.399-0.298 0.47-0.073 0.932-0.132 1.387-0.176 0.456-0.044 0.86-0.11 1.212-0.199 0.353-0.088 0.631-0.217 0.837-0.386s0.301-0.415 0.287-0.74c0-0.337-0.055-0.606-0.166-0.804a1.217 1.217 0 0 0-0.44-0.464 1.737 1.737 0 0 0-0.639-0.22 5.292 5.292 0 0 0-0.782-0.055c-0.617 0-1.101 0.132-1.454 0.397-0.352 0.264-0.558 0.706-0.617 1.323h-3.128c0.044-0.735 0.227-1.345 0.55-1.83zm6.179 4.423a5.095 5.095 0 0 1-0.639 0.165 9.68 9.68 0 0 1-0.716 0.11c-0.25 0.03-0.5 0.067-0.749 0.11a5.616 5.616 0 0 0-0.694 0.177 2.057 2.057 0 0 0-0.594 0.298c-0.17 0.125-0.305 0.284-0.408 0.474-0.103 0.192-0.154 0.434-0.154 0.728 0 0.28 0.051 0.515 0.154 0.706 0.103 0.192 0.242 0.342 0.419 0.453 0.176 0.11 0.381 0.187 0.617 0.231 0.234 0.044 0.477 0.066 0.726 0.066 0.617 0 1.094-0.102 1.432-0.309 0.338-0.205 0.587-0.452 0.75-0.739 0.16-0.286 0.26-0.576 0.297-0.87 0.036-0.295 0.055-0.53 0.055-0.707v-1.17a1.4 1.4 0 0 1-0.496 0.277zm11.86-6.1v2.096h-2.291v5.647c0 0.53 0.088 0.883 0.264 1.059 0.176 0.177 0.529 0.265 1.057 0.265 0.177 0 0.345-7e-3 0.507-0.022 0.161-0.015 0.316-0.037 0.463-0.066v2.426a7.49 7.49 0 0 1-0.882 0.089 21.67 21.67 0 0 1-0.947 0.022c-0.484 0-0.944-0.034-1.377-0.1a3.233 3.233 0 0 1-1.145-0.386 2.04 2.04 0 0 1-0.782-0.816c-0.191-0.353-0.287-0.816-0.287-1.39v-6.728h-1.894v-2.096h1.894v-3.42h3.129v3.42h2.29zm4.471 0v2.118h0.044a3.907 3.907 0 0 1 1.454-1.754 4.213 4.213 0 0 1 1.036-0.497 3.734 3.734 0 0 1 1.145-0.176c0.206 0 0.433 0.037 0.683 0.11v2.912a5.862 5.862 0 0 0-0.528-0.077 5.566 5.566 0 0 0-0.595-0.033c-0.573 0-1.058 0.096-1.454 0.287a2.52 2.52 0 0 0-0.958 0.783 3.143 3.143 0 0 0-0.518 1.158 6.32 6.32 0 0 0-0.154 1.434v5.14h-3.128v-11.4zm5.684-1.765v-2.582h3.128v2.582h-3.127zm3.128 1.765v11.4h-3.127v-11.4h3.128zm1.63 0h3.569l2.005 2.978 1.982-2.978h3.459l-3.745 5.339 4.208 6.067h-3.57l-2.378-3.596-2.38 3.596h-3.502l4.097-6.001zm15.3 20.84v-30.52h-2.194v-0.732h3.035v31.98h-3.035v-0.732z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="800.3468"
width="733.88495"
version="1.1"
id="svg4"
sodipodi:docname="Octicons-bug.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.85253906"
inkscape:cx="367.1386"
inkscape:cy="432.23826"
inkscape:window-width="3828"
inkscape:window-height="2081"
inkscape:window-x="0"
inkscape:window-y="46"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="m 243.6206,76.877783 c -52.874,56.780997 -38.281,147.468997 -38.281,147.468997 0,0 53.968,64 160,64 106.031,0 160.031,-64 160.031,-64 0,0 14.375,-89.469 -37.375,-146.311997 32.375,-18.031 51.438,-44.094 43.562,-61.812 -8.938,-19.9689999 -48.375,-21.7499999 -88.25,-3.969 -14.812,6.594 -27.438,14.969 -37.25,23.875 -12.438,-2.25 -25.625,-3.781 -40.72,-3.781 -14.061,0 -26.561,1.344 -38.344,3.25 -9.656,-8.75 -22.062,-16.875 -36.531,-23.344 -39.875,-17.7189999 -79.375,-15.9379999 -88.25,3.969 -7.748,17.343 10.284,42.686 41.408,60.655 z m 401.125,413.218997 c -8.25,-1.75 -16.125,-2.75 -23.75,-3.5 0,-2.125 0.375,-4.125 0.375,-6.312 0,-33.594 -4.75,-65.654 -12.438,-96.125 16.438,1.406 37.375,-2.375 58.562,-11.779 39.875,-17.781 65,-48.375 56.125,-68.219 -8.875,-19.969 -48.375,-21.75 -88.25,-3.969 -18.625,8.312 -33.812,19.469 -44,30.906 -7.75,-18.25 -16.5,-35.781 -26.812,-51.719 -30.188,25.156 -87.312,62.719 -167.062,71.062 v 321.781 c 0,0 -0.25,32 -32.031,32 -31.75,0 -32,-32 -32,-32 v -321.657 c -79.811,-8.344 -136.968,-45.969 -167.093,-71.062 -9.875,15.312 -18.375,32 -25.938,49.344 -10.281,-10.625 -24.625,-20.844 -41.969,-28.594 -39.875,-17.719 -79.375,-15.938 -88.25,3.969 -8.9060001,19.906 16.25,50.438 56.125,68.219 19.844,8.846 39.531,12.812 55.469,12.096 -7.656,30.404 -12.469,62.344 -12.469,95.812 0,2.188 0.375,4.25 0.438,6.5 -6.719,0.75 -13.688,1.75 -20.781,3.25 -51.969,10.75 -91.7810001,37.625 -88.84400014,59.812 2.93800004,22.312 47.50000014,31.5 99.59400014,20.688 6.781,-1.375 13.438,-3.125 19.781,-5.062 9.156,40.809 23.812,78.684 44.094,111.309 -12.031,6.062 -24.531,15 -36.031,26.625 -31.876,31.875 -44.812,70.625 -28.876,86.563 15.938,15.937 54.656,3 86.531,-28.812 9.344,-9.375 16.844,-19.25 22.656,-29 43.532,42.624 98.063,68.124 157.563,68.124 60.343,0 115.781,-26.25 159.531,-69.938 5.875,10.312 13.75,20.812 23.625,30.688 31.812,31.875 70.625,44.812 86.562,28.875 15.937,-15.937 3,-54.625 -28.875,-86.5 -12.312,-12.375 -25.688,-21.75 -38.438,-27.938 20.125,-32.5 34.625,-70.375 43.688,-111.062 7.188,2.25 14.688,4.375 22.562,6.062 52.061,10.812 96.625,1.562 99.625,-20.688 2.813,-22.124 -36.999,-48.999 -88.999,-59.749 z"
id="path2" />
</svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1.66em" height="2em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3l3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7c-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2c1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1s-1 .45-1 1s-.45 1-1 1H3c-.55 0-1 .45-1 1z" fill="#626262"/></svg>

Before

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,92 +0,0 @@
Copyright (c) 2011, Raph Levien (firstname.lastname@gmail.com), Copyright (c) 2012, Cyreal (cyreal.org)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

View File

@@ -1,258 +0,0 @@
@font-face {
font-family: 'Fira Sans';
font-style: normal;
font-weight: 300;
src: local('Fira Sans Light'), url("fonts/FiraSans-Light.woff") format('woff');
}
@font-face {
font-family: 'Fira Sans';
font-style: normal;
font-weight: 400;
src: local('Fira Sans'), url("fonts/FiraSans-Regular.woff") format('woff');
}
@font-face {
font-family: 'Fira Sans';
font-style: normal;
font-weight: 500;
src: local('Fira Sans Medium'), url("fonts/FiraSans-Medium.woff") format('woff');
}
@font-face {
font-family: 'Work Sans';
font-style: normal;
font-weight: 500;
src: local('Work Sans Medium'), url("fonts/WorkSans-Medium.ttf") format('ttf');
}
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata Regular'), url("fonts/Inconsolata-Regular.ttf") format('ttf');
}
body {
margin-top: 2em;
background-color: white;
color: #515151;
font-family: "Fira Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
font-weight: 300;
font-size: 25px;
}
pre {
font-family: Inconsolata,Menlo,Monaco,Consolas,"Courier New",monospace;
font-weight: 400;
}
body#idx #pitch > a {
font-weight: 500;
line-height: 2em;
}
a {
color: #428bca;
text-decoration: none;
}
a:hover {
color: rgb(42, 100, 150);
}
body#idx > * {
margin-left: auto;
margin-right: auto;
text-align: center;
width: 37em;
}
body#idx > #pitch {
width: 30rem;
}
#pitch em {
font-style: normal;
font-weight: 400;
}
body#idx p {
margin-top: 2em;
margin-bottom: 2em;
}
body#idx p.other-help {
font-size: 0.6em;
}
.instructions {
background-color: rgb(250, 250, 250);
margin-left: auto;
margin-right: auto;
border-radius: 3px;
border: 1px solid rgb(204, 204, 204);
box-shadow: 0px 1px 4px 0px rgb(204, 204, 204);
}
.instructions > * {
width: 40rem;
margin-left: auto;
margin-right: auto;
}
.instructions div.command-button {
display: flex;
align-items: center;
}
.instructions div.command-button button {
color: white;
/* border: none; */
background-color: rgb(242, 242, 242);
border-width: 2px;
border-style: solid;
border-radius: 3px;
margin-left: 0.5rem;
margin-right: auto;
margin-top: 25px;
margin-bottom: 25px;
text-align: center;
padding: 18px;
}
.instructions div.command-button button:hover {
background: rgb(100, 100, 100);
}
.instructions div.command-button button:focus {
background: rgb(222, 222, 222);
}
hr {
margin-top: 2em;
margin-bottom: 2em;
}
span.code {
font-family: 'Lucida Console', monospace;
}
#platform-instructions-linux div > pre,
#platform-instructions-mac div > pre,
#platform-instructions-freebsd div > pre,
#platform-instructions-win32 div > pre,
#platform-instructions-win64 div > pre,
#platform-instructions-default div > div > pre,
#platform-instructions-unknown div > div > pre {
background-color: #515151;
color: white;
margin-left: auto;
padding-top: 1rem;
padding-bottom: 1rem;
padding-right: 1rem;
text-align: center;
border-radius: 3px;
box-shadow: inset 0px 0px 20px 0px #333333;
font-size: 0.6em;
width: 40rem;
}
#platform-instructions-win32 a.windows-download,
#platform-instructions-win64 a.windows-download,
#platform-instructions-default a.windows-download,
#platform-instructions-unknown a.windows-download {
display: block;
padding-top: 0.4rem;
padding-bottom: 0.6rem;
font-family: "Work Sans", "Fira Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
font-weight: 500;
letter-spacing: 0.1rem;
}
/* This is the box that prints navigator.platform, navigator.appVersion values */
#platform-instructions-unknown > div:first-of-type {
font-size: 16px;
line-height: 2rem;
}
#help {
margin-bottom: 0px !important;
}
#collective {
margin-top: 1em !important;
margin-bottom: 0px !important;
}
#about {
margin-top: 0.5em !important;
font-size: 16px;
line-height: 2em;
}
#about > img {
width: 30px;
height: 30px;
transform: translateY(11px);
}
#platform-button {
background-color: #515151;
color: white;
margin-left: auto;
margin-right: auto;
padding: 1em;
}
.ghcup-command:before {
color: #999;
content: " $ ";
}
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
/* border-bottom: 1px dotted black; [> If you want dots under the hoverable text <] */
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: #555;
color: #fff;
text-align: center;
padding: 5px 0;
border-radius: 6px;
/* Position the tooltip text */
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -60px;
/* Fade in tooltip */
opacity: 0;
transition: opacity 0.3s;
}
/* Tooltip arrow */
.tooltip .tooltiptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}

Some files were not shown because too many files have changed in this diff Show More