Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
1a450545f2
|
|||
|
8fe26d7042
|
|||
|
7fd27cd635
|
|||
|
fff2599c2c
|
|||
|
efb81e4bac
|
|||
|
6a5043b68f
|
|||
|
44e8bec74c
|
|||
|
f564b1b533
|
|||
|
e6ce466700
|
|||
|
0f8c3ba9d9
|
|||
|
d5483facdc
|
15
.cirrus.yml
15
.cirrus.yml
@@ -1,11 +1,10 @@
|
|||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-13-2
|
image_family: freebsd-13-1
|
||||||
|
|
||||||
build_task:
|
task:
|
||||||
name: build
|
|
||||||
env:
|
env:
|
||||||
GHC_VER: 9.2.4
|
GHC_VER: 9.2.4
|
||||||
CABAL_VER: 3.8.1.0
|
CABAL_VER: 3.6.2.0
|
||||||
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
||||||
ARCH: 64
|
ARCH: 64
|
||||||
RUNNER_OS: FreeBSD
|
RUNNER_OS: FreeBSD
|
||||||
@@ -13,12 +12,10 @@ build_task:
|
|||||||
GITHUB_WORKSPACE: ${CIRRUS_WORKING_DIR}
|
GITHUB_WORKSPACE: ${CIRRUS_WORKING_DIR}
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
CIRRUS_CLONE_SUBMODULES: true
|
CIRRUS_CLONE_SUBMODULES: true
|
||||||
AWS_ACCESS_KEY_ID: ENCRYPTED[6ed6287e2dd78ab5f84b22232c5245834ab042bd8ba443883aaf4b4d1ecc0481add1fdfad5ae6f6a8cfb418e6f19b2fc]
|
AWS_ACCESS_KEY_ID: ENCRYPTED[3e99c4ac040871f213abd616ec66952d954dc289cdd97772f88e58a74d08a2250133437780fe98b7aedf7ef1fb32f5eb]
|
||||||
AWS_SECRET_ACCESS_KEY: ENCRYPTED[16f3cda2954c7cee99444e6788eb5997382aa4ce1477e7523fef2586077541f43b5c816156961fc6b4677259679875a7]
|
AWS_SECRET_ACCESS_KEY: ENCRYPTED[5910cfd77a922ff7fc06eeb6a6b9f79d4867863e541f06eb2c4cfecae0613650e3e0588373fa8d9249d295d76cf9cb3b]
|
||||||
S3_HOST: ENCRYPTED[ce961780a33159f7d1d8046956b5ac6ebc3bfc8149428e5f538576cda51d9f3d0c35b79cdd1e325793639ff6e31f889d]
|
S3_HOST: ENCRYPTED[ce961780a33159f7d1d8046956b5ac6ebc3bfc8149428e5f538576cda51d9f3d0c35b79cdd1e325793639ff6e31f889d]
|
||||||
install_script:
|
install_script: pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake
|
||||||
- sed -i.bak -e 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
|
|
||||||
- pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake llvm14
|
|
||||||
script:
|
script:
|
||||||
- tzsetup Etc/GMT
|
- tzsetup Etc/GMT
|
||||||
- adjkerntz -a
|
- adjkerntz -a
|
||||||
|
|||||||
4
.github/scripts/bootstrap.sh
vendored
4
.github/scripts/bootstrap.sh
vendored
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
set -eux
|
set -eux
|
||||||
|
|
||||||
. .github/scripts/env.sh
|
. .github/scripts/prereq.sh
|
||||||
|
|
||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
|
|
||||||
@@ -13,6 +13,4 @@ git describe --always
|
|||||||
./scripts/bootstrap/bootstrap-haskell
|
./scripts/bootstrap/bootstrap-haskell
|
||||||
|
|
||||||
[ "$(ghc --numeric-version)" = "${BOOTSTRAP_HASKELL_GHC_VERSION}" ]
|
[ "$(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
27
.github/scripts/brew.sh
vendored
@@ -1,27 +0,0 @@
|
|||||||
#!/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+"$@"}
|
|
||||||
|
|
||||||
75
.github/scripts/build.sh
vendored
75
.github/scripts/build.sh
vendored
@@ -2,34 +2,75 @@
|
|||||||
|
|
||||||
set -eux
|
set -eux
|
||||||
|
|
||||||
|
. .github/scripts/prereq.sh
|
||||||
. .github/scripts/common.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
|
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
|
# build
|
||||||
ecabal update
|
ecabal update
|
||||||
build_with_cache --project-file=cabal.project.release -w "${GHC}" --enable-tests
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
# set up artifacts
|
# set up artifacts
|
||||||
mkdir -p out
|
mkdir -p out
|
||||||
binary=$(cabal --project-file=cabal.project.release list-bin ghcup)
|
binary=$(cabal list-bin ghcup)
|
||||||
binary_test=$(cabal --project-file=cabal.project.release list-bin ghcup-test)
|
binary_test=$(cabal list-bin ghcup-test)
|
||||||
ver=$("${binary}" --numeric-version)
|
ver=$("${binary}" --numeric-version)
|
||||||
strip_binary "${binary}"
|
strip_binary "${binary}"
|
||||||
cp "${binary}" "out/${ARTIFACT}-${ver}${ext}"
|
cp "${binary}" "out/${ARTIFACT}-${ver}"
|
||||||
cp "${binary_test}" "out/test-${ARTIFACT}-${ver}${ext}"
|
cp "${binary_test}" "out/test-${ARTIFACT}-${ver}"
|
||||||
cp ./dist-newstyle/cache/plan.json "out/${ARTIFACT}.plan.json"
|
cp ./dist-newstyle/cache/plan.json "out/${ARTIFACT}.plan.json"
|
||||||
|
|
||||||
|
|||||||
13
.github/scripts/cabal-cache.sh
vendored
13
.github/scripts/cabal-cache.sh
vendored
@@ -1,13 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
case "$(uname -s)" in
|
|
||||||
MSYS_*|MINGW*)
|
|
||||||
ext=".exe"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
ext=""
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo "cabal-cache disabled (CABAL_CACHE_DISABLE set)"
|
|
||||||
|
|
||||||
68
.github/scripts/common.sh
vendored
68
.github/scripts/common.sh
vendored
@@ -1,13 +1,23 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
. .github/scripts/env.sh
|
if [ "${RUNNER_OS}" = "Windows" ] ; then
|
||||||
|
ext=".exe"
|
||||||
|
else
|
||||||
|
ext=''
|
||||||
|
fi
|
||||||
|
|
||||||
ecabal() {
|
ecabal() {
|
||||||
cabal "$@"
|
cabal "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
nonfatal() {
|
sync_from_retry() {
|
||||||
"$@" || "$* failed"
|
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 ; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_from() {
|
sync_from() {
|
||||||
@@ -15,7 +25,7 @@ sync_from() {
|
|||||||
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cabal-cache.sh sync-from-archive \
|
cabal-cache sync-from-archive \
|
||||||
--host-name-override=${S3_HOST} \
|
--host-name-override=${S3_HOST} \
|
||||||
--host-port-override=443 \
|
--host-port-override=443 \
|
||||||
--host-ssl-override=True \
|
--host-ssl-override=True \
|
||||||
@@ -24,12 +34,16 @@ sync_from() {
|
|||||||
--archive-uri "s3://ghcup-hs/${RUNNER_OS}-${ARCH}-${DISTRO}"
|
--archive-uri "s3://ghcup-hs/${RUNNER_OS}-${ARCH}-${DISTRO}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sync_to_retry() {
|
||||||
|
sync_to || { sleep 9 ; sync_to || { sleep 20 ; sync_to ; } }
|
||||||
|
}
|
||||||
|
|
||||||
sync_to() {
|
sync_to() {
|
||||||
if [ "${RUNNER_OS}" != "Windows" ] ; then
|
if [ "${RUNNER_OS}" != "Windows" ] ; then
|
||||||
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cabal-cache.sh sync-to-archive \
|
cabal-cache sync-to-archive \
|
||||||
--host-name-override=${S3_HOST} \
|
--host-name-override=${S3_HOST} \
|
||||||
--host-port-override=443 \
|
--host-port-override=443 \
|
||||||
--host-ssl-override=True \
|
--host-ssl-override=True \
|
||||||
@@ -67,7 +81,6 @@ git_describe() {
|
|||||||
download_cabal_cache() {
|
download_cabal_cache() {
|
||||||
(
|
(
|
||||||
set -e
|
set -e
|
||||||
mkdir -p "$HOME/.local/bin"
|
|
||||||
dest="$HOME/.local/bin/cabal-cache"
|
dest="$HOME/.local/bin/cabal-cache"
|
||||||
url=""
|
url=""
|
||||||
exe=""
|
exe=""
|
||||||
@@ -115,46 +128,31 @@ download_cabal_cache() {
|
|||||||
mv "cabal-cache${exe}" "${dest}${exe}"
|
mv "cabal-cache${exe}" "${dest}${exe}"
|
||||||
chmod +x "${dest}${exe}"
|
chmod +x "${dest}${exe}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install shell wrapper
|
|
||||||
cp "${CI_PROJECT_DIR}"/.github/scripts/cabal-cache.sh "$HOME"/.local/bin/
|
|
||||||
chmod +x "$HOME"/.local/bin/cabal-cache.sh
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
build_with_cache() {
|
build_with_cache() {
|
||||||
ecabal configure "$@"
|
ecabal configure "$@"
|
||||||
ecabal build --dependencies-only "$@" --dry-run
|
ecabal build --dependencies-only "$@" --dry-run
|
||||||
sync_from
|
sync_from_retry
|
||||||
ecabal build --dependencies-only "$@" || sync_to
|
ecabal build --dependencies-only "$@" || sync_to_retry
|
||||||
sync_to
|
sync_to_retry
|
||||||
ecabal build "$@"
|
ecabal build "$@"
|
||||||
sync_to
|
sync_to_retry
|
||||||
}
|
}
|
||||||
|
|
||||||
install_ghcup() {
|
install_ghcup() {
|
||||||
case "${RUNNER_OS}" in
|
find "$GHCUP_INSTALL_BASE_PREFIX"
|
||||||
"Linux")
|
mkdir -p "$GHCUP_BIN"
|
||||||
case "${ARCH}" in
|
mkdir -p "$GHCUP_BIN"/../cache
|
||||||
"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
|
|
||||||
}
|
|
||||||
|
|
||||||
install_ghcup_curl_sh() {
|
if [ "${RUNNER_OS}" = "FreeBSD" ] ; then
|
||||||
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
|
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 BOOTSTRAP_HASKELL_INSTALL_NO_STACK=yes sh
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
strip_binary() {
|
strip_binary() {
|
||||||
|
|||||||
30
.github/scripts/env.sh
vendored
30
.github/scripts/env.sh
vendored
@@ -1,30 +0,0 @@
|
|||||||
#!/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
|
|
||||||
7
.github/scripts/hls.sh
vendored
7
.github/scripts/hls.sh
vendored
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
set -eux
|
set -eux
|
||||||
|
|
||||||
|
. .github/scripts/prereq.sh
|
||||||
. .github/scripts/common.sh
|
. .github/scripts/common.sh
|
||||||
|
|
||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
@@ -33,7 +34,7 @@ sha_sum "$(raw_eghcup --offline whereis ghcup)"
|
|||||||
git_describe
|
git_describe
|
||||||
|
|
||||||
eghcup install ghc "${GHC_VERSION}"
|
eghcup install ghc "${GHC_VERSION}"
|
||||||
eghcup install cabal "${CABAL_VERSION}"
|
eghcup install cabal
|
||||||
|
|
||||||
ecabal update
|
ecabal update
|
||||||
|
|
||||||
@@ -56,9 +57,9 @@ eghcup debug-info
|
|||||||
cd "haskell-language-server-${HLS_TARGET_VERSION}/"
|
cd "haskell-language-server-${HLS_TARGET_VERSION}/"
|
||||||
ecabal configure -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)"
|
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
|
ecabal build --dependencies-only -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)" --dry-run
|
||||||
sync_from
|
sync_from_retry
|
||||||
ecabal build --dependencies-only -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)" || sync_to
|
ecabal build --dependencies-only -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)" || sync_to
|
||||||
sync_to
|
sync_to_retry
|
||||||
)
|
)
|
||||||
|
|
||||||
eghcup -v compile hls -j "$(nproc)" -g "${HLS_TARGET_VERSION}" --ghc "${GHC_VERSION}"
|
eghcup -v compile hls -j "$(nproc)" -g "${HLS_TARGET_VERSION}" --ghc "${GHC_VERSION}"
|
||||||
|
|||||||
66
.github/scripts/prereq.sh
vendored
Normal file
66
.github/scripts/prereq.sh
vendored
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
5
.github/scripts/test.sh
vendored
5
.github/scripts/test.sh
vendored
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
set -eux
|
set -eux
|
||||||
|
|
||||||
|
. .github/scripts/prereq.sh
|
||||||
. .github/scripts/common.sh
|
. .github/scripts/common.sh
|
||||||
|
|
||||||
|
|
||||||
@@ -190,7 +191,7 @@ sha=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
|||||||
# invalidate access time timer, which is 5minutes, so we re-download
|
# invalidate access time timer, which is 5minutes, so we re-download
|
||||||
touch -a -m -t '199901010101' "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
touch -a -m -t '199901010101' "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
||||||
# redownload same file with some newlines added
|
# redownload same file with some newlines added
|
||||||
raw_eghcup -s https://raw.githubusercontent.com/haskell/ghcup-metadata/exp/ghcup-0.0.7.yaml list
|
raw_eghcup -s https://www.haskell.org/ghcup/exp/ghcup-${JSON_VERSION}.yaml list
|
||||||
# snapshot new yaml and etags file
|
# snapshot new yaml and etags file
|
||||||
etag2=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
etag2=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
||||||
sha2=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
sha2=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||||
@@ -200,7 +201,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
|
# 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"
|
touch -a -m -t '199901010101' "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
||||||
# this time, we expect the same hash and etag
|
# this time, we expect the same hash and etag
|
||||||
raw_eghcup -s https://raw.githubusercontent.com/haskell/ghcup-metadata/exp/ghcup-0.0.7.yaml list
|
raw_eghcup -s https://www.haskell.org/ghcup/exp/ghcup-${JSON_VERSION}.yaml list
|
||||||
etag3=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
etag3=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
||||||
sha3=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
sha3=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||||
[ "${etag2}" = "${etag3}" ]
|
[ "${etag2}" = "${etag3}" ]
|
||||||
|
|||||||
18
.github/workflows/bootstrap.yaml
vendored
18
.github/workflows/bootstrap.yaml
vendored
@@ -20,12 +20,13 @@ jobs:
|
|||||||
BOOTSTRAP_HASKELL_NONINTERACTIVE: yes
|
BOOTSTRAP_HASKELL_NONINTERACTIVE: yes
|
||||||
ARCH: 64
|
ARCH: 64
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
|
APT_GET: "sudo apt-get"
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
DISTRO: Ubuntu
|
DISTRO: Ubuntu
|
||||||
- os: macOS-11
|
- os: macOS-10.15
|
||||||
DISTRO: na
|
DISTRO: na
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
DISTRO: na
|
DISTRO: na
|
||||||
@@ -35,15 +36,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
|
|
||||||
- if: runner.os == 'Linux'
|
- if: runner.os != 'Windows'
|
||||||
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
|
name: Run bootstrap
|
||||||
run: sh ./.github/scripts/bootstrap.sh
|
run: sh ./.github/scripts/bootstrap.sh
|
||||||
env:
|
env:
|
||||||
@@ -51,8 +44,5 @@ jobs:
|
|||||||
|
|
||||||
- if: runner.os == 'Windows'
|
- if: runner.os == 'Windows'
|
||||||
name: Run bootstrap
|
name: Run bootstrap
|
||||||
run: |
|
run: ./scripts/bootstrap/bootstrap-haskell.ps1 -InstallDir ${GITHUB_WORKSPACE} -BootstrapUrl ${GITHUB_WORKSPACE}/bootstrap-haskell -InBash
|
||||||
$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
|
shell: pwsh
|
||||||
|
|||||||
2
.github/workflows/cache.yaml
vendored
2
.github/workflows/cache.yaml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
args: --recursive
|
args: --recursive
|
||||||
env:
|
env:
|
||||||
AWS_S3_ENDPOINT: https://${{ secrets.S3_HOST }}
|
AWS_S3_ENDPOINT: ${{ secrets.S3_HOST }}
|
||||||
AWS_S3_BUCKET: ghcup-hs
|
AWS_S3_BUCKET: ghcup-hs
|
||||||
AWS_REGION: us-west-2
|
AWS_REGION: us-west-2
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
|||||||
87
.github/workflows/docker.yaml
vendored
87
.github/workflows/docker.yaml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
- cron: '0 0 * * *'
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker-alpine32:
|
docker-alpine:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -26,24 +26,7 @@ jobs:
|
|||||||
context: ./docker/alpine32
|
context: ./docker/alpine32
|
||||||
push: true
|
push: true
|
||||||
tags: hasufell/i386-alpine-haskell:3.12
|
tags: hasufell/i386-alpine-haskell:3.12
|
||||||
platforms: |
|
platforms: linux/i386
|
||||||
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)
|
- name: Build and push (alpine 64bit)
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
with:
|
with:
|
||||||
@@ -52,74 +35,34 @@ jobs:
|
|||||||
tags: hasufell/alpine-haskell:3.12
|
tags: hasufell/alpine-haskell:3.12
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
|
|
||||||
docker-arm32:
|
docker-arm:
|
||||||
runs-on: [self-hosted, Linux, ARM64]
|
runs-on: [self-hosted, Linux, aarch64]
|
||||||
steps:
|
steps:
|
||||||
- uses: docker://arm64v8/ubuntu:focal
|
- uses: docker://arm64v8/ubuntu:focal
|
||||||
name: Cleanup (aarch64 linux)
|
name: Cleanup
|
||||||
with:
|
with:
|
||||||
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
args: rm -rf .ghcup/ cabal/ dist-newstyle/ out/
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- name: Build and push (arm64v8)
|
||||||
- name: Build and push (debian buster)
|
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
with:
|
with:
|
||||||
context: ./docker/arm32v7/buster
|
context: ./docker/arm64v8/
|
||||||
push: true
|
|
||||||
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-ubuntu-haskell:focal
|
|
||||||
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
|
push: true
|
||||||
tags: hasufell/arm64v8-ubuntu-haskell:focal
|
tags: hasufell/arm64v8-ubuntu-haskell:focal
|
||||||
platforms: linux/arm64
|
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
|
||||||
|
platforms: linux/arm
|
||||||
|
|||||||
134
.github/workflows/release.yaml
vendored
134
.github/workflows/release.yaml
vendored
@@ -12,16 +12,12 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: '0 2 * * *'
|
- cron: '0 2 * * *'
|
||||||
|
|
||||||
env:
|
|
||||||
CABAL_CACHE_DISABLE: ${{ vars.CABAL_CACHE_DISABLE }}
|
|
||||||
CABAL_CACHE_NONFATAL: yes
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-linux:
|
build-linux:
|
||||||
name: Build linux binary
|
name: Build linux binary
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CABAL_VER: 3.10.1.0
|
CABAL_VER: 3.6.2.0
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
@@ -85,7 +81,7 @@ jobs:
|
|||||||
name: Build ARM binary
|
name: Build ARM binary
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CABAL_VER: 3.10.1.0
|
CABAL_VER: 3.6.2.0
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
@@ -94,16 +90,16 @@ jobs:
|
|||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: [self-hosted, Linux, ARM64]
|
- os: [self-hosted, Linux, aarch64]
|
||||||
ARTIFACT: "armv7-linux-ghcup"
|
ARTIFACT: "armv7-linux-ghcup"
|
||||||
GHC_VER: 9.2.2
|
GHC_VER: 8.10.7
|
||||||
ARCH: ARM
|
ARCH: ARM
|
||||||
- os: [self-hosted, Linux, ARM64]
|
- os: [self-hosted, Linux, aarch64]
|
||||||
ARTIFACT: "aarch64-linux-ghcup"
|
ARTIFACT: "aarch64-linux-ghcup"
|
||||||
GHC_VER: 9.2.6
|
GHC_VER: 8.10.7
|
||||||
ARCH: ARM64
|
ARCH: ARM64
|
||||||
steps:
|
steps:
|
||||||
- uses: docker://arm64v8/debian:10
|
- uses: docker://arm64v8/ubuntu:focal
|
||||||
name: Cleanup (aarch64 linux)
|
name: Cleanup (aarch64 linux)
|
||||||
with:
|
with:
|
||||||
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||||
@@ -119,7 +115,7 @@ jobs:
|
|||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
|
|
||||||
- if: matrix.ARCH == 'ARM'
|
- if: matrix.ARCH == 'ARM'
|
||||||
uses: docker://hasufell/arm32v7-debian-haskell:10
|
uses: docker://hasufell/arm32v7-ubuntu-haskell:focal
|
||||||
name: Run build (armv7 linux)
|
name: Run build (armv7 linux)
|
||||||
with:
|
with:
|
||||||
args: sh .github/scripts/build.sh
|
args: sh .github/scripts/build.sh
|
||||||
@@ -133,7 +129,7 @@ jobs:
|
|||||||
S3_HOST: ${{ env.S3_HOST }}
|
S3_HOST: ${{ env.S3_HOST }}
|
||||||
|
|
||||||
- if: matrix.ARCH == 'ARM64'
|
- if: matrix.ARCH == 'ARM64'
|
||||||
uses: docker://hasufell/arm64v8-debian-haskell:10
|
uses: docker://hasufell/arm64v8-ubuntu-haskell:focal
|
||||||
name: Run build (aarch64 linux)
|
name: Run build (aarch64 linux)
|
||||||
with:
|
with:
|
||||||
args: sh .github/scripts/build.sh
|
args: sh .github/scripts/build.sh
|
||||||
@@ -158,7 +154,7 @@ jobs:
|
|||||||
name: Build binary (Mac/Win)
|
name: Build binary (Mac/Win)
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CABAL_VER: 3.10.1.0
|
CABAL_VER: 3.6.2.0
|
||||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
@@ -168,13 +164,13 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: [self-hosted, macOS, ARM64]
|
- os: [self-hosted, macOS, aarch64]
|
||||||
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
||||||
GHC_VER: 9.2.6
|
GHC_VER: 9.2.5
|
||||||
ARCH: ARM64
|
ARCH: ARM64
|
||||||
- os: macOS-11
|
- os: macOS-10.15
|
||||||
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
||||||
GHC_VER: 9.2.6
|
GHC_VER: 9.2.5
|
||||||
ARCH: 64
|
ARCH: 64
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
ARTIFACT: "x86_64-mingw64-ghcup"
|
ARTIFACT: "x86_64-mingw64-ghcup"
|
||||||
@@ -186,48 +182,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
|
|
||||||
- if: matrix.ARCH == 'ARM64' && runner.os == 'macOS'
|
- name: Run build (windows/mac)
|
||||||
name: Run build
|
run: bash .github/scripts/build.sh
|
||||||
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:
|
env:
|
||||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
ARCH: ${{ matrix.ARCH }}
|
ARCH: ${{ matrix.ARCH }}
|
||||||
@@ -246,12 +202,13 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
./out/*
|
./out/*
|
||||||
|
|
||||||
|
|
||||||
test-linux:
|
test-linux:
|
||||||
name: Test linux
|
name: Test linux
|
||||||
needs: "build-linux"
|
needs: "build-linux"
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CABAL_VER: 3.10.1.0
|
CABAL_VER: 3.6.2.0
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -307,14 +264,13 @@ jobs:
|
|||||||
|
|
||||||
- if: matrix.DISTRO != 'Alpine'
|
- if: matrix.DISTRO != 'Alpine'
|
||||||
name: Run test (64 bit linux)
|
name: Run test (64 bit linux)
|
||||||
run: |
|
run: sh .github/scripts/test.sh
|
||||||
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:
|
env:
|
||||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
ARCH: ${{ matrix.ARCH }}
|
ARCH: ${{ matrix.ARCH }}
|
||||||
GHC_VER: ${{ matrix.GHC_VER }}
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
DISTRO: ${{ matrix.DISTRO }}
|
DISTRO: ${{ matrix.DISTRO }}
|
||||||
|
APT_GET: "sudo apt-get"
|
||||||
|
|
||||||
- if: failure()
|
- if: failure()
|
||||||
name: Upload artifact
|
name: Upload artifact
|
||||||
@@ -329,24 +285,24 @@ jobs:
|
|||||||
needs: "build-arm"
|
needs: "build-arm"
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CABAL_VER: 3.10.1.0
|
CABAL_VER: 3.6.2.0
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: [self-hosted, Linux, ARM64]
|
- os: [self-hosted, Linux, aarch64]
|
||||||
ARTIFACT: "armv7-linux-ghcup"
|
ARTIFACT: "armv7-linux-ghcup"
|
||||||
GHC_VER: 9.2.2
|
GHC_VER: 8.10.7
|
||||||
ARCH: ARM
|
ARCH: ARM
|
||||||
DISTRO: Ubuntu
|
DISTRO: Ubuntu
|
||||||
- os: [self-hosted, Linux, ARM64]
|
- os: [self-hosted, Linux, aarch64]
|
||||||
ARTIFACT: "aarch64-linux-ghcup"
|
ARTIFACT: "aarch64-linux-ghcup"
|
||||||
GHC_VER: 9.2.6
|
GHC_VER: 8.10.7
|
||||||
ARCH: ARM64
|
ARCH: ARM64
|
||||||
DISTRO: Ubuntu
|
DISTRO: Ubuntu
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: docker://arm64v8/debian:10
|
- uses: docker://arm64v8/ubuntu:focal
|
||||||
name: Cleanup (aarch64 linux)
|
name: Cleanup (aarch64 linux)
|
||||||
with:
|
with:
|
||||||
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||||
@@ -362,7 +318,7 @@ jobs:
|
|||||||
path: ./out
|
path: ./out
|
||||||
|
|
||||||
- if: matrix.ARCH == 'ARM'
|
- if: matrix.ARCH == 'ARM'
|
||||||
uses: docker://hasufell/arm32v7-debian-haskell:10
|
uses: docker://hasufell/arm32v7-ubuntu-haskell:focal
|
||||||
name: Run test (armv7 linux)
|
name: Run test (armv7 linux)
|
||||||
with:
|
with:
|
||||||
args: sh .github/scripts/test.sh
|
args: sh .github/scripts/test.sh
|
||||||
@@ -373,7 +329,7 @@ jobs:
|
|||||||
DISTRO: Ubuntu
|
DISTRO: Ubuntu
|
||||||
|
|
||||||
- if: matrix.ARCH == 'ARM64'
|
- if: matrix.ARCH == 'ARM64'
|
||||||
uses: docker://hasufell/arm64v8-debian-haskell:10
|
uses: docker://hasufell/arm64v8-ubuntu-haskell:focal
|
||||||
name: Run test (aarch64 linux)
|
name: Run test (aarch64 linux)
|
||||||
with:
|
with:
|
||||||
args: sh .github/scripts/test.sh
|
args: sh .github/scripts/test.sh
|
||||||
@@ -396,20 +352,20 @@ jobs:
|
|||||||
needs: "build-macwin"
|
needs: "build-macwin"
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
CABAL_VER: 3.10.1.0
|
CABAL_VER: 3.6.2.0
|
||||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: [self-hosted, macOS, ARM64]
|
- os: [self-hosted, macOS, aarch64]
|
||||||
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
||||||
GHC_VER: 9.2.6
|
GHC_VER: 9.2.5
|
||||||
ARCH: ARM64
|
ARCH: ARM64
|
||||||
DISTRO: na
|
DISTRO: na
|
||||||
- os: macOS-11
|
- os: macOS-10.15
|
||||||
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
||||||
GHC_VER: 9.2.6
|
GHC_VER: 9.2.5
|
||||||
ARCH: 64
|
ARCH: 64
|
||||||
DISTRO: na
|
DISTRO: na
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
@@ -429,21 +385,7 @@ jobs:
|
|||||||
name: artifacts
|
name: artifacts
|
||||||
path: ./out
|
path: ./out
|
||||||
|
|
||||||
- if: runner.os == 'macOS'
|
- name: Run test (windows/mac)
|
||||||
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
|
run: bash .github/scripts/test.sh
|
||||||
env:
|
env:
|
||||||
ARTIFACT: ${{ matrix.ARTIFACT }}
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
@@ -474,7 +416,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GHC_VERSION: "8.10.7"
|
GHC_VERSION: "8.10.7"
|
||||||
HLS_TARGET_VERSION: "1.8.0.0"
|
HLS_TARGET_VERSION: "1.8.0.0"
|
||||||
CABAL_VERSION: "3.8.1.0"
|
CABAL_VERSION: "3.6.2.0"
|
||||||
JSON_VERSION: "0.0.7"
|
JSON_VERSION: "0.0.7"
|
||||||
ARTIFACT: "x86_64-linux-ghcup"
|
ARTIFACT: "x86_64-linux-ghcup"
|
||||||
DISTRO: Ubuntu
|
DISTRO: Ubuntu
|
||||||
@@ -494,9 +436,9 @@ jobs:
|
|||||||
path: ./out
|
path: ./out
|
||||||
|
|
||||||
- name: Run hls build
|
- name: Run hls build
|
||||||
run: |
|
run: sh .github/scripts/hls.sh
|
||||||
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
|
env:
|
||||||
sh .github/scripts/hls.sh
|
APT_GET: "sudo apt-get"
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: release
|
name: release
|
||||||
|
|||||||
25
.travis.yml
Normal file
25
.travis.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
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
|
||||||
45
CHANGELOG.md
45
CHANGELOG.md
@@ -1,50 +1,5 @@
|
|||||||
# Revision history for ghcup
|
# Revision history for ghcup
|
||||||
|
|
||||||
## 0.1.19.4 -- 2023-7-02
|
|
||||||
|
|
||||||
* fix missing TUI for aarch64 linux binaries
|
|
||||||
|
|
||||||
## 0.1.19.3 -- 2023-6-29
|
|
||||||
|
|
||||||
* Implement support for nightlies, wrt [#824](https://github.com/haskell/ghcup-hs/issues/824)
|
|
||||||
* Fix GC with XDG dirs, fixes [#810](https://github.com/haskell/ghcup-hs/issues/810)
|
|
||||||
|
|
||||||
## 0.1.19.2 -- 2023-2-24
|
|
||||||
|
|
||||||
* Follow-up fix for JFS/ReiserFS and other filesystem that don't support `d_type`, fixes [#787](https://github.com/haskell/ghcup-hs/issues/787)
|
|
||||||
- the previous release had a bug that invalidated that broke it
|
|
||||||
* Implement 'latest-prerelease' tag wrt [#788](https://github.com/haskell/ghcup-hs/issues/788)
|
|
||||||
* Fix 'Could not parse version of stray directory.DS_Store' warnings on macOs wrt [#797](https://github.com/haskell/ghcup-hs/issues/797)
|
|
||||||
|
|
||||||
## 0.1.19.1 -- 2023-2-19
|
|
||||||
|
|
||||||
* Fix GHCup on JFS/ReiserFS and other filesystem that don't support `d_type`, fixes [#766](https://github.com/haskell/ghcup-hs/issues/766)
|
|
||||||
* Don't fail on setModificationTime, fixes [#784](https://github.com/haskell/ghcup-hs/issues/784) and many GitHub actions issues
|
|
||||||
* Make armv7/aarch64 linux binaries more portable (built on Debian buster)
|
|
||||||
* Improve usability on 'ghcup config add-release-channel', fixes [#751](https://github.com/haskell/ghcup-hs/issues/751)
|
|
||||||
* Make version shortcuts work with 'ghcup set', fixes [#757](https://github.com/haskell/ghcup-hs/issues/757)
|
|
||||||
* Don't implicitly smuggle in config options in `ghcup config set` wrt [#775](https://github.com/haskell/ghcup-hs/issues/775)
|
|
||||||
* Fix build on unix with -ftui
|
|
||||||
|
|
||||||
## 0.1.19.0 -- 2023-1-13
|
|
||||||
|
|
||||||
* restore proper support for FreeBSD and Linux armv7
|
|
||||||
* integrate with [errors.haskell.org](https://errors.haskell.org/index.html), wrt [#434](https://github.com/haskell/ghcup-hs/issues/434)
|
|
||||||
* allow to overwrite distro detection via config wrt [#421](https://github.com/haskell/ghcup-hs/issues/421)
|
|
||||||
- this is particularly useful for e.g. Ubuntu derivates, where ghcup doesn't pick the optimal bindist, also see the [GHCup documentation on overriding distro detection](https://www.haskell.org/ghcup/guide/#overriding-distro-detection)
|
|
||||||
* Add proper support for mirrors wrt [#357](https://github.com/haskell/ghcup-hs/issues/357)
|
|
||||||
* fix a (harmless) bug in `ghcup nuke` on windows
|
|
||||||
* improvements to `ghcup add-release-channel` wrt [#708](https://github.com/haskell/ghcup-hs/issues/708)
|
|
||||||
* fix building newer GHC from source wrt [#433](https://github.com/haskell/ghcup-hs/issues/433)
|
|
||||||
* Fix `ghcup install hls -u` on windows
|
|
||||||
* Fix failure with `--isolate=dir --force`
|
|
||||||
* Add `--metadata-fetching-mode` arg, fixes [#440](https://github.com/haskell/ghcup-hs/issues/440)
|
|
||||||
* Add content-length property to downloads
|
|
||||||
* [Fix a grave bug on armv7](https://github.com/haskell/ghcup-hs/commit/78ee956df2618862f421178a565c82548ff7e578) during installation wrt [#415](https://github.com/haskell/ghcup-hs/issues/415)
|
|
||||||
* improve many warning/error messages (contributions by @taylorfausak)
|
|
||||||
* some minor optimization in `ghcup whereis ghcup`
|
|
||||||
* improve `--keep=always` to not clean up directories in certain circumstances
|
|
||||||
|
|
||||||
## 0.1.18.1 -- 2022-08-06
|
## 0.1.18.1 -- 2022-08-06
|
||||||
|
|
||||||
* fix sdist and unbreak hackage, wrt [#399](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/399)
|
* fix sdist and unbreak hackage, wrt [#399](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/399)
|
||||||
|
|||||||
621
app/ghcup/AnsiMain.hs
Normal file
621
app/ghcup/AnsiMain.hs
Normal file
@@ -0,0 +1,621 @@
|
|||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
{-# LANGUAGE MultiWayIf #-}
|
||||||
|
|
||||||
|
module AnsiMain where
|
||||||
|
|
||||||
|
import GHCup
|
||||||
|
import GHCup.Download
|
||||||
|
import GHCup.Errors
|
||||||
|
import GHCup.Prelude ( decUTF8Safe )
|
||||||
|
import GHCup.Prelude.File
|
||||||
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.Process
|
||||||
|
import GHCup.Prompts
|
||||||
|
import GHCup.Types hiding ( LeanAppState(..) )
|
||||||
|
import GHCup.Types.Optics ( getDirs )
|
||||||
|
import GHCup.Utils
|
||||||
|
|
||||||
|
import Data.List (sort, intersperse)
|
||||||
|
import Data.Versions (prettyPVP, prettyVer)
|
||||||
|
import Codec.Archive
|
||||||
|
import Control.Monad.IO.Class
|
||||||
|
-- import System.Console.ANSI
|
||||||
|
import System.Console.ANSI
|
||||||
|
import Terminal.Game
|
||||||
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
|
|
||||||
|
import Control.Exception.Safe
|
||||||
|
import Control.Monad ( when, forM_ )
|
||||||
|
import Control.Monad.ST
|
||||||
|
import Control.Monad.Reader ( ReaderT(runReaderT), MonadReader, ask, lift )
|
||||||
|
import Control.Monad.Trans.Except
|
||||||
|
import Control.Monad.Trans.Resource
|
||||||
|
import Data.Functor
|
||||||
|
import Data.STRef
|
||||||
|
import Data.IORef
|
||||||
|
import Data.Maybe ( fromMaybe, catMaybes )
|
||||||
|
import qualified Data.Text as Tx
|
||||||
|
import qualified Data.Tuple as T
|
||||||
|
import qualified Data.Vector as V
|
||||||
|
import GHC.IO ( unsafePerformIO )
|
||||||
|
import Haskus.Utils.Variant.Excepts
|
||||||
|
import System.Exit
|
||||||
|
import System.Environment (getExecutablePath)
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.Lazy.Builder as B
|
||||||
|
import qualified Data.Text.Lazy as L
|
||||||
|
import System.FilePath
|
||||||
|
import URI.ByteString (serializeURIRef')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data Direction = Up
|
||||||
|
| Down
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data BrickData = BrickData
|
||||||
|
{ lr :: [ListResult]
|
||||||
|
}
|
||||||
|
deriving Show
|
||||||
|
|
||||||
|
data BrickSettings = BrickSettings
|
||||||
|
{ showAllVersions :: Bool
|
||||||
|
, showAllTools :: Bool
|
||||||
|
}
|
||||||
|
deriving Show
|
||||||
|
|
||||||
|
data BrickInternalState = BrickInternalState
|
||||||
|
{ clr :: V.Vector ListResult
|
||||||
|
, ix :: Int
|
||||||
|
}
|
||||||
|
deriving Show
|
||||||
|
|
||||||
|
data BrickState = BrickState
|
||||||
|
{ appData :: BrickData
|
||||||
|
, appSettings :: BrickSettings
|
||||||
|
, appState :: BrickInternalState
|
||||||
|
, appKeys :: KeyBindings
|
||||||
|
, appQuit :: Bool
|
||||||
|
, appRestart :: Bool
|
||||||
|
, appMoreInput :: Maybe String
|
||||||
|
}
|
||||||
|
deriving Show
|
||||||
|
|
||||||
|
|
||||||
|
startGame :: BrickState -> IO BrickState
|
||||||
|
startGame g = do
|
||||||
|
g'@BrickState { appRestart } <- errorPress $ playGameT liftIO (ghcupGame g)
|
||||||
|
if appRestart
|
||||||
|
then do
|
||||||
|
putStrLn "Press enter to continue"
|
||||||
|
_ <- getLine
|
||||||
|
startGame $ g' { appRestart = False }
|
||||||
|
else pure g'
|
||||||
|
|
||||||
|
ansiMain :: AppState -> IO ()
|
||||||
|
ansiMain s = do
|
||||||
|
writeIORef settings' s
|
||||||
|
|
||||||
|
eAppData <- getAppData (Just $ ghcupInfo s)
|
||||||
|
case eAppData of
|
||||||
|
Right ad -> do
|
||||||
|
let g = BrickState ad
|
||||||
|
defaultAppSettings
|
||||||
|
(constructList ad defaultAppSettings Nothing)
|
||||||
|
(keyBindings (s :: AppState))
|
||||||
|
False
|
||||||
|
False
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
|
||||||
|
sizeCheck
|
||||||
|
void $ startGame g
|
||||||
|
cleanAndExit
|
||||||
|
Left e -> do
|
||||||
|
flip runReaderT s $ logError $ "Error building app state: " <> Tx.pack
|
||||||
|
(show e)
|
||||||
|
exitWith $ ExitFailure 2
|
||||||
|
|
||||||
|
|
||||||
|
where
|
||||||
|
sizeCheck :: IO ()
|
||||||
|
sizeCheck = let (w, h) = T.swap . snd $ boundaries in assertTermDims w h
|
||||||
|
|
||||||
|
|
||||||
|
ghcupGame :: BrickState -> Game BrickState
|
||||||
|
ghcupGame bs = Game 13
|
||||||
|
bs -- ticks per second
|
||||||
|
(\ge s e -> logicFun ge s e) -- logic function
|
||||||
|
(\r s -> centerFull r $ drawFun s r) -- draw function
|
||||||
|
(\s -> appQuit s || appRestart s) -- quit function
|
||||||
|
|
||||||
|
|
||||||
|
drawFun :: BrickState -> GEnv -> Plane
|
||||||
|
drawFun (BrickState {..}) GEnv{..} =
|
||||||
|
let focus pl = maybe pl
|
||||||
|
(\ix -> V.update pl (V.singleton (ix + 1, fmap invert $ pl V.! (ix + 1))))
|
||||||
|
mix
|
||||||
|
rows = V.fromList [header, [box (mw - 2) 1 '=']] V.++ renderItems
|
||||||
|
cols = V.foldr (\xs ys -> zipWith (:) xs ys) (repeat []) $ V.filter ((==5) . length) rows
|
||||||
|
padded = focus $ V.map (\xs -> zipWith padTo xs lengths) rows
|
||||||
|
lengths :: [Int]
|
||||||
|
lengths = fmap (maximum . fmap (fst . planeSize)) cols
|
||||||
|
in blankPlane mw mh
|
||||||
|
& (1, 1) % box 1 1 'X' -- '┌'
|
||||||
|
& (2, 1) % box 1 (mh - 3) '|' -- '│'
|
||||||
|
& (1, 2) % box (mw - 2) 1 '=' -- '─'
|
||||||
|
& (2, mw) % box 1 (mh - 3) '|' -- '│'
|
||||||
|
& (1, mw) % box 1 1 'X' -- '┐'
|
||||||
|
& (mh-1, 2) % box (mw - 2) 1 '=' -- '─'
|
||||||
|
& (mh-1, 1) % box 1 1 'X' -- '└'
|
||||||
|
& (mh-1, mw) % box 1 1 'X' -- '┘'
|
||||||
|
& (2, 2) % box (mw - 2) (mh - 3) ' ' -- ' '
|
||||||
|
& (2, 2) % vcat (hcat <$> V.toList padded)
|
||||||
|
& (mh, 1) % footer
|
||||||
|
& (1, mw `div` 2 - 2) % stringPlane "GHCup"
|
||||||
|
where
|
||||||
|
|
||||||
|
padTo :: Plane -> Int -> Plane
|
||||||
|
padTo plane x =
|
||||||
|
let lstr = fst $ planeSize plane
|
||||||
|
add' = x - lstr + 1
|
||||||
|
in if add' < 0 then plane else plane ||| stringPlane (replicate add' ' ')
|
||||||
|
mh :: Height
|
||||||
|
mw :: Width
|
||||||
|
(mh, mw) = T.swap eTermDims
|
||||||
|
footer = hcat
|
||||||
|
. intersperse (stringPlane " ")
|
||||||
|
. fmap stringPlane
|
||||||
|
$ ["q:Quit", "i:Install", "u:Uninstall", "s:Set", "c:Changelog", "a:all versions", "↑:Up", "↓:Down"]
|
||||||
|
header = fmap stringPlane [" ", "Tool", "Version", "Tags", "Notes"]
|
||||||
|
(renderItems, mix) = drawListElements renderItem appState
|
||||||
|
renderItem _ _ listResult@ListResult{..} =
|
||||||
|
let marks = if
|
||||||
|
| lSet -> color Green Vivid $ stringPlane "IS"
|
||||||
|
| lInstalled -> color Green Vivid $ stringPlane "I "
|
||||||
|
| otherwise -> color Red Vivid $ stringPlane "X "
|
||||||
|
ver = case lCross of
|
||||||
|
Nothing -> stringPlane . Tx.unpack . prettyVer $ lVer
|
||||||
|
Just c -> stringPlane . Tx.unpack $ (c <> "-" <> prettyVer lVer)
|
||||||
|
tool = printTool lTool
|
||||||
|
tag = let l = catMaybes . fmap printTag $ sort lTag
|
||||||
|
in if null l then blankPlane 1 1 else foldr1 (\x y -> x ||| stringPlane "," ||| y) l
|
||||||
|
notes = let n = printNotes listResult
|
||||||
|
in if null n
|
||||||
|
then blankPlane 1 1
|
||||||
|
else foldr1 (\x y -> x ||| stringPlane "," ||| y) n
|
||||||
|
|
||||||
|
in [marks ||| space, tool, ver, tag, notes]
|
||||||
|
|
||||||
|
printTag Recommended = Just $ color Green Dull $ stringPlane "recommended"
|
||||||
|
printTag Latest = Just $ color Yellow Dull $ stringPlane "latest"
|
||||||
|
printTag Prerelease = Just $ color Red Dull $ stringPlane "prerelease"
|
||||||
|
printTag (Base pvp'') = Just $ stringPlane ("base-" ++ T.unpack (prettyPVP pvp''))
|
||||||
|
printTag Old = Nothing
|
||||||
|
printTag (UnknownTag t) = Just $ stringPlane t
|
||||||
|
|
||||||
|
printTool Cabal = stringPlane "cabal"
|
||||||
|
printTool GHC = stringPlane "GHC"
|
||||||
|
printTool GHCup = stringPlane "GHCup"
|
||||||
|
printTool HLS = stringPlane "HLS"
|
||||||
|
printTool Stack = stringPlane "Stack"
|
||||||
|
|
||||||
|
printNotes ListResult {..} =
|
||||||
|
(if hlsPowered then [color Green Dull $ stringPlane "hls-powered"] else mempty
|
||||||
|
)
|
||||||
|
++ (if fromSrc then [color Blue Dull $ stringPlane "compiled"] else mempty)
|
||||||
|
++ (if lStray then [color Blue Dull $ stringPlane "stray"] else mempty)
|
||||||
|
|
||||||
|
space = stringPlane " "
|
||||||
|
|
||||||
|
-- | Draws the list elements.
|
||||||
|
--
|
||||||
|
-- Evaluates the underlying container up to, and a bit beyond, the
|
||||||
|
-- selected element. The exact amount depends on available height
|
||||||
|
-- for drawing and 'listItemHeight'. At most, it will evaluate up to
|
||||||
|
-- element @(i + h + 1)@ where @i@ is the selected index and @h@ is the
|
||||||
|
-- available height.
|
||||||
|
drawListElements :: (Int -> Bool -> ListResult -> [Plane])
|
||||||
|
-> BrickInternalState
|
||||||
|
-> (V.Vector [Plane], Maybe Int)
|
||||||
|
drawListElements drawElem is@(BrickInternalState clr _) =
|
||||||
|
let es = clr
|
||||||
|
listSelected = fmap fst $ listSelectedElement' is
|
||||||
|
|
||||||
|
(drawnElements, selIx) = runST $ do
|
||||||
|
ref <- newSTRef (Nothing :: Maybe Int)
|
||||||
|
vec <- newSTRef (mempty :: V.Vector [Plane])
|
||||||
|
elem' <- newSTRef 0
|
||||||
|
void $ flip V.imapM es $ \i' e -> do
|
||||||
|
let isSelected = Just i' == listSelected
|
||||||
|
elemWidget = drawElem i' isSelected e
|
||||||
|
case es V.!? (i' - 1) of
|
||||||
|
Just e' | lTool e' /= lTool e -> do
|
||||||
|
modifySTRef elem' (+2)
|
||||||
|
i <- readSTRef elem'
|
||||||
|
when isSelected $ writeSTRef ref (Just i)
|
||||||
|
modifySTRef vec (`V.snoc` [hBorder])
|
||||||
|
modifySTRef vec (`V.snoc` elemWidget)
|
||||||
|
pure ()
|
||||||
|
_ -> do
|
||||||
|
modifySTRef elem' (+1)
|
||||||
|
i <- readSTRef elem'
|
||||||
|
when isSelected $ writeSTRef ref (Just i)
|
||||||
|
modifySTRef vec (`V.snoc` elemWidget)
|
||||||
|
pure ()
|
||||||
|
i <- readSTRef ref
|
||||||
|
arr <- readSTRef vec
|
||||||
|
pure (arr, i)
|
||||||
|
in (makeVisible drawnElements (mh - 5) selIx, selIx)
|
||||||
|
where
|
||||||
|
makeVisible :: V.Vector [Plane] -> Height -> Maybe Int -> V.Vector [Plane]
|
||||||
|
makeVisible listElements drawableHeight (Just ix) =
|
||||||
|
let listHeight = V.length listElements
|
||||||
|
in if | listHeight <= 0 -> listElements
|
||||||
|
| listHeight > drawableHeight ->
|
||||||
|
if | ix <= drawableHeight -> makeVisible (V.init listElements) drawableHeight (Just ix)
|
||||||
|
| otherwise -> makeVisible (V.tail listElements) drawableHeight (Just (ix - 1))
|
||||||
|
| otherwise -> listElements
|
||||||
|
makeVisible listElements _ Nothing = listElements
|
||||||
|
|
||||||
|
hBorder = box (mw - 2) 1 '='
|
||||||
|
|
||||||
|
|
||||||
|
logicFun :: GEnv -> BrickState -> Event -> IO BrickState
|
||||||
|
logicFun _ gs (KeyPress 'q') = pure gs { appQuit = True }
|
||||||
|
logicFun _ gs@BrickState{appMoreInput = Nothing} (KeyPress '\ESC') = pure gs { appMoreInput = Just "\ESC" }
|
||||||
|
logicFun _ gs@BrickState{appMoreInput = Just "\ESC"} (KeyPress '[') = pure gs { appMoreInput = Just "\ESC[" }
|
||||||
|
logicFun _ gs@BrickState{appMoreInput = Just "\ESC[", appState = s'} (KeyPress 'A')
|
||||||
|
= pure gs { appMoreInput = Nothing, appState = moveCursor 1 s' Up }
|
||||||
|
logicFun _ gs@BrickState{appMoreInput = Just "\ESC[", appState = s'} (KeyPress 'B')
|
||||||
|
= pure gs { appMoreInput = Nothing, appState = moveCursor 1 s' Down }
|
||||||
|
logicFun _ gs@BrickState{appMoreInput = Just _} _ = pure gs { appMoreInput = Nothing }
|
||||||
|
logicFun _ gs (KeyPress 'i') = do
|
||||||
|
bs <- withIOAction install' gs
|
||||||
|
pure bs { appRestart = True }
|
||||||
|
logicFun _ gs (KeyPress 'u') = do
|
||||||
|
bs <- withIOAction del' gs
|
||||||
|
pure bs { appRestart = True }
|
||||||
|
logicFun _ gs (KeyPress 's') = do
|
||||||
|
bs <- withIOAction set' gs
|
||||||
|
pure bs { appRestart = True }
|
||||||
|
logicFun _ gs (KeyPress 'c') = do
|
||||||
|
bs <- withIOAction changelog' gs
|
||||||
|
pure bs { appRestart = True }
|
||||||
|
logicFun _ gs (KeyPress 'a') = pure $ hideShowHandler (not . showAllVersions) showAllTools gs
|
||||||
|
where
|
||||||
|
hideShowHandler :: (BrickSettings -> Bool) -> (BrickSettings -> Bool) -> BrickState -> BrickState
|
||||||
|
hideShowHandler f p BrickState{..} =
|
||||||
|
let newAppSettings = appSettings { showAllVersions = f appSettings , showAllTools = p appSettings }
|
||||||
|
newInternalState = constructList appData newAppSettings (Just appState)
|
||||||
|
in BrickState appData newAppSettings newInternalState appKeys appQuit appRestart appMoreInput
|
||||||
|
|
||||||
|
-- windows powershell
|
||||||
|
logicFun _ gs@BrickState{ appState = s' } (KeyPress 'P') = pure gs { appMoreInput = Nothing, appState = moveCursor 1 s' Down }
|
||||||
|
logicFun _ gs@BrickState{ appState = s' } (KeyPress 'H') = pure gs { appMoreInput = Nothing, appState = moveCursor 1 s' Up }
|
||||||
|
|
||||||
|
logicFun _ gs Tick = pure gs
|
||||||
|
logicFun _ gs (KeyPress _) = pure gs
|
||||||
|
|
||||||
|
withIOAction :: (BrickState
|
||||||
|
-> (Int, ListResult)
|
||||||
|
-> ReaderT AppState IO (Either String a))
|
||||||
|
-> BrickState
|
||||||
|
-> IO BrickState
|
||||||
|
withIOAction action as = case listSelectedElement' (appState as) of
|
||||||
|
Nothing -> pure as
|
||||||
|
Just (ix, e) -> do
|
||||||
|
clearScreen
|
||||||
|
|
||||||
|
settings <- readIORef settings'
|
||||||
|
flip runReaderT settings $ action as (ix, e) >>= \case
|
||||||
|
Left err -> liftIO $ putStrLn ("Error: " <> err)
|
||||||
|
Right _ -> liftIO $ putStrLn "Success"
|
||||||
|
getAppData Nothing >>= \case
|
||||||
|
Right data' -> do
|
||||||
|
pure (updateList data' as)
|
||||||
|
Left err -> throwIO $ userError err
|
||||||
|
|
||||||
|
moveCursor :: Int -> BrickInternalState -> Direction -> BrickInternalState
|
||||||
|
moveCursor steps ais@BrickInternalState{..} direction =
|
||||||
|
let newIx = if direction == Down then ix + steps else ix - steps
|
||||||
|
in case clr V.!? newIx of
|
||||||
|
Just _ -> BrickInternalState { ix = newIx, .. }
|
||||||
|
Nothing -> ais
|
||||||
|
|
||||||
|
defaultAppSettings :: BrickSettings
|
||||||
|
defaultAppSettings =
|
||||||
|
BrickSettings { showAllVersions = False, showAllTools = False }
|
||||||
|
|
||||||
|
-- | Update app data and list internal state based on new evidence.
|
||||||
|
-- This synchronises @BrickInternalState@ with @BrickData@
|
||||||
|
-- and @BrickSettings@.
|
||||||
|
updateList :: BrickData -> BrickState -> BrickState
|
||||||
|
updateList appD BrickState{..} =
|
||||||
|
let newInternalState = constructList appD appSettings (Just appState)
|
||||||
|
in BrickState { appState = newInternalState
|
||||||
|
, appData = appD
|
||||||
|
, appSettings = appSettings
|
||||||
|
, appKeys = appKeys
|
||||||
|
, appQuit = appQuit
|
||||||
|
, appRestart = appRestart
|
||||||
|
, appMoreInput = appMoreInput
|
||||||
|
}
|
||||||
|
|
||||||
|
constructList
|
||||||
|
:: BrickData
|
||||||
|
-> BrickSettings
|
||||||
|
-> Maybe BrickInternalState
|
||||||
|
-> BrickInternalState
|
||||||
|
constructList appD appSettings = replaceLR
|
||||||
|
(filterVisible (showAllVersions appSettings) (showAllTools appSettings))
|
||||||
|
(lr appD)
|
||||||
|
|
||||||
|
|
||||||
|
-- | Replace the @appState@ or construct it based on a filter function
|
||||||
|
-- and a new @[ListResult]@ evidence.
|
||||||
|
-- When passed an existing @appState@, tries to keep the selected element.
|
||||||
|
replaceLR
|
||||||
|
:: (ListResult -> Bool)
|
||||||
|
-> [ListResult]
|
||||||
|
-> Maybe BrickInternalState
|
||||||
|
-> BrickInternalState
|
||||||
|
replaceLR filterF lr s =
|
||||||
|
let oldElem = s >>= listSelectedElement'
|
||||||
|
newVec = V.fromList . filter filterF $ lr
|
||||||
|
newSelected =
|
||||||
|
case oldElem >>= \(_, oldE) -> V.findIndex (toolEqual oldE) newVec of
|
||||||
|
Just ix -> ix
|
||||||
|
Nothing -> selectLatest newVec
|
||||||
|
in BrickInternalState newVec newSelected
|
||||||
|
where
|
||||||
|
toolEqual e1 e2 =
|
||||||
|
lTool e1 == lTool e2 && lVer e1 == lVer e2 && lCross e1 == lCross e2
|
||||||
|
|
||||||
|
|
||||||
|
filterVisible :: Bool -> Bool -> ListResult -> Bool
|
||||||
|
filterVisible v t e
|
||||||
|
| lInstalled e = True
|
||||||
|
| v, not t, lTool e `notElem` hiddenTools = True
|
||||||
|
| not v, t, Old `notElem` lTag e = True
|
||||||
|
| v, t = True
|
||||||
|
| otherwise = (Old `notElem` lTag e) && (lTool e `notElem` hiddenTools)
|
||||||
|
|
||||||
|
|
||||||
|
hiddenTools :: [Tool]
|
||||||
|
hiddenTools = []
|
||||||
|
|
||||||
|
|
||||||
|
selectLatest :: V.Vector ListResult -> Int
|
||||||
|
selectLatest = fromMaybe 0
|
||||||
|
. V.findIndex (\ListResult {..} -> lTool == GHC && Latest `elem` lTag)
|
||||||
|
|
||||||
|
|
||||||
|
listSelectedElement' :: BrickInternalState -> Maybe (Int, ListResult)
|
||||||
|
listSelectedElement' BrickInternalState {..} = fmap (ix, ) $ clr V.!? ix
|
||||||
|
|
||||||
|
|
||||||
|
boundaries :: (Coords, Coords)
|
||||||
|
boundaries = ((1, 1), (24, 80))
|
||||||
|
|
||||||
|
install' :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m, MonadMask m, MonadUnliftIO m)
|
||||||
|
=> BrickState
|
||||||
|
-> (Int, ListResult)
|
||||||
|
-> m (Either String ())
|
||||||
|
install' _ (_, ListResult {..}) = do
|
||||||
|
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
||||||
|
|
||||||
|
let run =
|
||||||
|
runResourceT
|
||||||
|
. runE
|
||||||
|
@'[ AlreadyInstalled
|
||||||
|
, ArchiveResult
|
||||||
|
, UnknownArchive
|
||||||
|
, FileDoesNotExistError
|
||||||
|
, CopyError
|
||||||
|
, NoDownload
|
||||||
|
, NotInstalled
|
||||||
|
, BuildFailed
|
||||||
|
, TagNotFound
|
||||||
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
|
, GPGError
|
||||||
|
, DownloadFailed
|
||||||
|
, DirNotEmpty
|
||||||
|
, NoUpdate
|
||||||
|
, TarDirDoesNotExist
|
||||||
|
, FileAlreadyExistsError
|
||||||
|
, ProcessError
|
||||||
|
, ToolShadowed
|
||||||
|
, UninstallFailed
|
||||||
|
, MergeFileTreeError
|
||||||
|
]
|
||||||
|
|
||||||
|
run (do
|
||||||
|
ce <- liftIO $ fmap (either (const Nothing) Just) $
|
||||||
|
try @_ @SomeException $ getExecutablePath >>= canonicalizePath
|
||||||
|
dirs <- lift getDirs
|
||||||
|
case lTool of
|
||||||
|
GHC -> do
|
||||||
|
let vi = getVersionInfo lVer GHC dls
|
||||||
|
liftE $ installGHCBin lVer GHCupInternal False [] $> (vi, dirs, ce)
|
||||||
|
Cabal -> do
|
||||||
|
let vi = getVersionInfo lVer Cabal dls
|
||||||
|
liftE $ installCabalBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
|
GHCup -> do
|
||||||
|
let vi = snd <$> getLatest dls GHCup
|
||||||
|
liftE $ upgradeGHCup Nothing False False $> (vi, dirs, ce)
|
||||||
|
HLS -> do
|
||||||
|
let vi = getVersionInfo lVer HLS dls
|
||||||
|
liftE $ installHLSBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
|
Stack -> do
|
||||||
|
let vi = getVersionInfo lVer Stack dls
|
||||||
|
liftE $ installStackBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight (vi, Dirs{..}, Just ce) -> do
|
||||||
|
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo msg
|
||||||
|
case lTool of
|
||||||
|
GHCup -> do
|
||||||
|
up <- liftIO $ fmap (either (const Nothing) Just)
|
||||||
|
$ try @_ @SomeException $ canonicalizePath (binDir </> "ghcup" <.> exeExt)
|
||||||
|
when ((normalise <$> up) == Just (normalise ce)) $
|
||||||
|
-- TODO: track cli arguments of previous invocation
|
||||||
|
void $ liftIO $ exec ce ["tui"] Nothing Nothing
|
||||||
|
logInfo "Please restart 'ghcup' for the changes to take effect"
|
||||||
|
_ -> pure ()
|
||||||
|
pure $ Right ()
|
||||||
|
VRight (vi, _, _) -> do
|
||||||
|
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo msg
|
||||||
|
logInfo "Please restart 'ghcup' for the changes to take effect"
|
||||||
|
pure $ Right ()
|
||||||
|
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
||||||
|
VLeft (V NoUpdate) -> pure $ Right ()
|
||||||
|
VLeft e -> pure $ Left $ prettyShow e <> "\n"
|
||||||
|
<> "Also check the logs in ~/.ghcup/logs"
|
||||||
|
|
||||||
|
|
||||||
|
set' :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m, MonadMask m, MonadUnliftIO m)
|
||||||
|
=> BrickState
|
||||||
|
-> (Int, ListResult)
|
||||||
|
-> m (Either String ())
|
||||||
|
set' bs input@(_, ListResult {..}) = do
|
||||||
|
settings <- liftIO $ readIORef settings'
|
||||||
|
|
||||||
|
let run =
|
||||||
|
flip runReaderT settings
|
||||||
|
. runE @'[FileDoesNotExistError , NotInstalled , TagNotFound]
|
||||||
|
|
||||||
|
run (do
|
||||||
|
case lTool of
|
||||||
|
GHC -> liftE $ setGHC (GHCTargetVersion lCross lVer) SetGHCOnly Nothing $> ()
|
||||||
|
Cabal -> liftE $ setCabal lVer $> ()
|
||||||
|
HLS -> liftE $ setHLS lVer SetHLSOnly Nothing $> ()
|
||||||
|
Stack -> liftE $ setStack lVer $> ()
|
||||||
|
GHCup -> pure ()
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight _ -> pure $ Right ()
|
||||||
|
VLeft e -> case e of
|
||||||
|
(V (NotInstalled tool _)) -> do
|
||||||
|
promptAnswer <- getUserPromptResponse userPrompt
|
||||||
|
case promptAnswer of
|
||||||
|
PromptYes -> do
|
||||||
|
res <- install' bs input
|
||||||
|
case res of
|
||||||
|
(Left err) -> pure $ Left err
|
||||||
|
(Right _) -> do
|
||||||
|
logInfo "Setting now..."
|
||||||
|
set' bs input
|
||||||
|
|
||||||
|
PromptNo -> pure $ Left (prettyShow e)
|
||||||
|
where
|
||||||
|
userPrompt = L.toStrict . B.toLazyText . B.fromString $
|
||||||
|
"This Version of "
|
||||||
|
<> show tool
|
||||||
|
<> " you are trying to set is not installed.\n"
|
||||||
|
<> "Would you like to install it first? [Y/N]: "
|
||||||
|
|
||||||
|
_ -> pure $ Left (prettyShow e)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
del' :: (MonadReader AppState m, MonadIO m, MonadFail m, MonadMask m, MonadUnliftIO m)
|
||||||
|
=> BrickState
|
||||||
|
-> (Int, ListResult)
|
||||||
|
-> m (Either String ())
|
||||||
|
del' _ (_, ListResult {..}) = do
|
||||||
|
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
||||||
|
|
||||||
|
let run = runE @'[NotInstalled, UninstallFailed]
|
||||||
|
|
||||||
|
run (do
|
||||||
|
let vi = getVersionInfo lVer lTool dls
|
||||||
|
case lTool of
|
||||||
|
GHC -> liftE $ rmGHCVer (GHCTargetVersion lCross lVer) $> vi
|
||||||
|
Cabal -> liftE $ rmCabalVer lVer $> vi
|
||||||
|
HLS -> liftE $ rmHLSVer lVer $> vi
|
||||||
|
Stack -> liftE $ rmStackVer lVer $> vi
|
||||||
|
GHCup -> pure Nothing
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight vi -> do
|
||||||
|
forM_ (_viPostRemove =<< vi) $ \msg ->
|
||||||
|
logInfo msg
|
||||||
|
pure $ Right ()
|
||||||
|
VLeft e -> pure $ Left (prettyShow e)
|
||||||
|
|
||||||
|
|
||||||
|
changelog' :: (MonadReader AppState m, MonadIO m)
|
||||||
|
=> BrickState
|
||||||
|
-> (Int, ListResult)
|
||||||
|
-> m (Either String ())
|
||||||
|
changelog' _ (_, ListResult {..}) = do
|
||||||
|
AppState { pfreq, ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
||||||
|
case getChangeLog dls lTool (Left lVer) of
|
||||||
|
Nothing -> pure $ Left $
|
||||||
|
"Could not find ChangeLog for " <> prettyShow lTool <> ", version " <> T.unpack (prettyVer lVer)
|
||||||
|
Just uri -> do
|
||||||
|
let cmd = case _rPlatform pfreq of
|
||||||
|
Darwin -> "open"
|
||||||
|
Linux _ -> "xdg-open"
|
||||||
|
FreeBSD -> "xdg-open"
|
||||||
|
Windows -> "start"
|
||||||
|
exec cmd [T.unpack $ decUTF8Safe $ serializeURIRef' uri] Nothing Nothing >>= \case
|
||||||
|
Right _ -> pure $ Right ()
|
||||||
|
Left e -> pure $ Left $ prettyShow e
|
||||||
|
|
||||||
|
|
||||||
|
settings' :: IORef AppState
|
||||||
|
{-# NOINLINE settings' #-}
|
||||||
|
settings' = unsafePerformIO $ do
|
||||||
|
dirs <- getAllDirs
|
||||||
|
let loggerConfig = LoggerConfig { lcPrintDebug = False
|
||||||
|
, consoleOutter = \_ -> pure ()
|
||||||
|
, fileOutter = \_ -> pure ()
|
||||||
|
, fancyColors = True
|
||||||
|
}
|
||||||
|
newIORef $ AppState defaultSettings
|
||||||
|
dirs
|
||||||
|
defaultKeyBindings
|
||||||
|
(GHCupInfo mempty mempty mempty)
|
||||||
|
(PlatformRequest A_64 Darwin Nothing)
|
||||||
|
loggerConfig
|
||||||
|
|
||||||
|
|
||||||
|
getAppData :: Maybe GHCupInfo -> IO (Either String BrickData)
|
||||||
|
getAppData mgi = runExceptT $ do
|
||||||
|
r <- ExceptT $ maybe getGHCupInfo (pure . Right) mgi
|
||||||
|
liftIO $ modifyIORef settings' (\s -> s { ghcupInfo = r })
|
||||||
|
settings <- liftIO $ readIORef settings'
|
||||||
|
|
||||||
|
flip runReaderT settings $ do
|
||||||
|
lV <- listVersions Nothing Nothing
|
||||||
|
pure $ BrickData (reverse lV)
|
||||||
|
|
||||||
|
|
||||||
|
getGHCupInfo :: IO (Either String GHCupInfo)
|
||||||
|
getGHCupInfo = do
|
||||||
|
settings <- readIORef settings'
|
||||||
|
|
||||||
|
r <-
|
||||||
|
flip runReaderT settings
|
||||||
|
. runE
|
||||||
|
@'[ DigestError
|
||||||
|
, ContentLengthError
|
||||||
|
, GPGError
|
||||||
|
, JSONError
|
||||||
|
, DownloadFailed
|
||||||
|
, FileDoesNotExistError
|
||||||
|
]
|
||||||
|
$ liftE getDownloadsF
|
||||||
|
|
||||||
|
case r of
|
||||||
|
VRight a -> pure $ Right a
|
||||||
|
VLeft e -> pure $ Left (prettyShow e)
|
||||||
|
|
||||||
|
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
{-# LANGUAGE TypeApplications #-}
|
||||||
{-# LANGUAGE RankNTypes #-}
|
{-# LANGUAGE RankNTypes #-}
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
|
||||||
|
|
||||||
module BrickMain where
|
module BrickMain where
|
||||||
|
|
||||||
@@ -73,8 +72,8 @@ data BrickData = BrickData
|
|||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
data BrickSettings = BrickSettings
|
data BrickSettings = BrickSettings
|
||||||
{ showAllVersions :: Bool
|
{ showAllVersions :: Bool
|
||||||
, showAllTools :: Bool
|
, showAllTools :: Bool
|
||||||
}
|
}
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
@@ -96,11 +95,11 @@ data BrickState = BrickState
|
|||||||
keyHandlers :: KeyBindings
|
keyHandlers :: KeyBindings
|
||||||
-> [ ( Vty.Key
|
-> [ ( Vty.Key
|
||||||
, BrickSettings -> String
|
, BrickSettings -> String
|
||||||
, BrickState -> EventM String BrickState ()
|
, BrickState -> EventM n (Next BrickState)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
keyHandlers KeyBindings {..} =
|
keyHandlers KeyBindings {..} =
|
||||||
[ (bQuit, const "Quit" , \_ -> halt)
|
[ (bQuit, const "Quit" , halt)
|
||||||
, (bInstall, const "Install" , withIOAction install')
|
, (bInstall, const "Install" , withIOAction install')
|
||||||
, (bUninstall, const "Uninstall", withIOAction del')
|
, (bUninstall, const "Uninstall", withIOAction del')
|
||||||
, (bSet, const "Set" , withIOAction set')
|
, (bSet, const "Set" , withIOAction set')
|
||||||
@@ -115,14 +114,14 @@ keyHandlers KeyBindings {..} =
|
|||||||
if showAllTools then "Don't show all tools" else "Show all tools"
|
if showAllTools then "Don't show all tools" else "Show all tools"
|
||||||
, hideShowHandler showAllVersions (not . showAllTools)
|
, hideShowHandler showAllVersions (not . showAllTools)
|
||||||
)
|
)
|
||||||
, (bUp, const "Up", \BrickState {..} -> put BrickState{ appState = moveCursor 1 appState Up, .. })
|
, (bUp, const "Up", \BrickState {..} -> continue BrickState{ appState = moveCursor 1 appState Up, .. })
|
||||||
, (bDown, const "Down", \BrickState {..} -> put BrickState{ appState = moveCursor 1 appState Down, .. })
|
, (bDown, const "Down", \BrickState {..} -> continue BrickState{ appState = moveCursor 1 appState Down, .. })
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
hideShowHandler f p BrickState{..} =
|
hideShowHandler f p BrickState{..} =
|
||||||
let newAppSettings = appSettings { showAllVersions = f appSettings , showAllTools = p appSettings }
|
let newAppSettings = appSettings { showAllVersions = f appSettings , showAllTools = p appSettings }
|
||||||
newInternalState = constructList appData newAppSettings (Just appState)
|
newInternalState = constructList appData newAppSettings (Just appState)
|
||||||
in put (BrickState appData newAppSettings newInternalState appKeys)
|
in continue (BrickState appData newAppSettings newInternalState appKeys)
|
||||||
|
|
||||||
|
|
||||||
showKey :: Vty.Key -> String
|
showKey :: Vty.Key -> String
|
||||||
@@ -143,7 +142,7 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
|
|
||||||
where
|
where
|
||||||
footer =
|
footer =
|
||||||
withAttr (attrName "help")
|
withAttr "help"
|
||||||
. txtWrap
|
. txtWrap
|
||||||
. T.pack
|
. T.pack
|
||||||
. foldr1 (\x y -> x <> " " <> y)
|
. foldr1 (\x y -> x <> " " <> y)
|
||||||
@@ -155,15 +154,12 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
<+> minHSize 15 (str "Version")
|
<+> minHSize 15 (str "Version")
|
||||||
<+> padLeft (Pad 1) (minHSize 25 $ str "Tags")
|
<+> padLeft (Pad 1) (minHSize 25 $ str "Tags")
|
||||||
<+> padLeft (Pad 5) (str "Notes")
|
<+> padLeft (Pad 5) (str "Notes")
|
||||||
renderList' bis@BrickInternalState{..} =
|
renderList' = withDefAttr listAttr . drawListElements renderItem True
|
||||||
let minTagSize = V.maximum $ V.map (length . intercalate "," . fmap tagToString . lTag) clr
|
renderItem _ b listResult@ListResult{..} =
|
||||||
minVerSize = V.maximum $ V.map (\ListResult{..} -> T.length $ tVerToText (GHCTargetVersion lCross lVer)) clr
|
|
||||||
in withDefAttr listAttr . drawListElements (renderItem minTagSize minVerSize) True $ bis
|
|
||||||
renderItem minTagSize minVerSize _ b listResult@ListResult{lTag = lTag', ..} =
|
|
||||||
let marks = if
|
let marks = if
|
||||||
| lSet -> (withAttr (attrName "set") $ str "✔✔")
|
| lSet -> (withAttr "set" $ str "✔✔")
|
||||||
| lInstalled -> (withAttr (attrName "installed") $ str "✓ ")
|
| lInstalled -> (withAttr "installed" $ str "✓ ")
|
||||||
| otherwise -> (withAttr (attrName "not-installed") $ str "✗ ")
|
| otherwise -> (withAttr "not-installed" $ str "✗ ")
|
||||||
ver = case lCross of
|
ver = case lCross of
|
||||||
Nothing -> T.unpack . prettyVer $ lVer
|
Nothing -> T.unpack . prettyVer $ lVer
|
||||||
Just c -> T.unpack (c <> "-" <> prettyVer lVer)
|
Just c -> T.unpack (c <> "-" <> prettyVer lVer)
|
||||||
@@ -171,22 +167,22 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
| lNoBindist && not lInstalled
|
| lNoBindist && not lInstalled
|
||||||
&& not b -- TODO: overloading dim and active ignores active
|
&& not b -- TODO: overloading dim and active ignores active
|
||||||
-- so we hack around it here
|
-- so we hack around it here
|
||||||
= updateAttrMap (const dimAttrs) . withAttr (attrName "no-bindist")
|
= updateAttrMap (const dimAttrs) . withAttr "no-bindist"
|
||||||
| otherwise = id
|
| otherwise = id
|
||||||
hooray
|
hooray
|
||||||
| elem Latest lTag' && not lInstalled =
|
| elem Latest lTag && not lInstalled =
|
||||||
withAttr (attrName "hooray")
|
withAttr "hooray"
|
||||||
| otherwise = id
|
| otherwise = id
|
||||||
active = if b then putCursor "GHCup" (Location (0,0)) . forceAttr (attrName "active") else id
|
active = if b then putCursor "GHCup" (Location (0,0)) . forceAttr "active" else id
|
||||||
in hooray $ active $ dim
|
in hooray $ active $ dim
|
||||||
( marks
|
( marks
|
||||||
<+> padLeft (Pad 2)
|
<+> padLeft (Pad 2)
|
||||||
( minHSize 6
|
( minHSize 6
|
||||||
(printTool lTool)
|
(printTool lTool)
|
||||||
)
|
)
|
||||||
<+> minHSize minVerSize (str ver)
|
<+> minHSize 15 (str ver)
|
||||||
<+> (let l = catMaybes . fmap printTag $ sort lTag'
|
<+> (let l = catMaybes . fmap printTag $ sort lTag
|
||||||
in padLeft (Pad 1) $ minHSize minTagSize $ if null l
|
in padLeft (Pad 1) $ minHSize 25 $ if null l
|
||||||
then emptyWidget
|
then emptyWidget
|
||||||
else foldr1 (\x y -> x <+> str "," <+> y) l
|
else foldr1 (\x y -> x <+> str "," <+> y) l
|
||||||
)
|
)
|
||||||
@@ -199,14 +195,11 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
<+> vLimit 1 (fill ' ')
|
<+> vLimit 1 (fill ' ')
|
||||||
)
|
)
|
||||||
|
|
||||||
printTag Recommended = Just $ withAttr (attrName "recommended") $ str "recommended"
|
printTag Recommended = Just $ withAttr "recommended" $ str "recommended"
|
||||||
printTag Latest = Just $ withAttr (attrName "latest") $ str "latest"
|
printTag Latest = Just $ withAttr "latest" $ str "latest"
|
||||||
printTag Prerelease = Just $ withAttr (attrName "prerelease") $ str "prerelease"
|
printTag Prerelease = Just $ withAttr "prerelease" $ str "prerelease"
|
||||||
printTag Nightly = Just $ withAttr (attrName "nightly") $ str "nightly"
|
|
||||||
printTag (Base pvp'') = Just $ str ("base-" ++ T.unpack (prettyPVP pvp''))
|
printTag (Base pvp'') = Just $ str ("base-" ++ T.unpack (prettyPVP pvp''))
|
||||||
printTag Old = Nothing
|
printTag Old = Nothing
|
||||||
printTag LatestPrerelease = Just $ withAttr (attrName "latest-prerelease") $ str "latest-prerelease"
|
|
||||||
printTag LatestNightly = Just $ withAttr (attrName "latest-nightly") $ str "latest-nightly"
|
|
||||||
printTag (UnknownTag t) = Just $ str t
|
printTag (UnknownTag t) = Just $ str t
|
||||||
|
|
||||||
printTool Cabal = str "cabal"
|
printTool Cabal = str "cabal"
|
||||||
@@ -216,13 +209,10 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
printTool Stack = str "Stack"
|
printTool Stack = str "Stack"
|
||||||
|
|
||||||
printNotes ListResult {..} =
|
printNotes ListResult {..} =
|
||||||
(if hlsPowered then [withAttr (attrName "hls-powered") $ str "hls-powered"] else mempty
|
(if hlsPowered then [withAttr "hls-powered" $ str "hls-powered"] else mempty
|
||||||
)
|
)
|
||||||
++ (if fromSrc then [withAttr (attrName "compiled") $ str "compiled"] else mempty)
|
++ (if fromSrc then [withAttr "compiled" $ str "compiled"] else mempty)
|
||||||
++ (if lStray then [withAttr (attrName "stray") $ str "stray"] else mempty)
|
++ (if lStray then [withAttr "stray" $ str "stray"] else mempty)
|
||||||
++ (case lReleaseDay of
|
|
||||||
Nothing -> mempty
|
|
||||||
Just d -> [withAttr (attrName "day") $ str (show d)])
|
|
||||||
|
|
||||||
-- | Draws the list elements.
|
-- | Draws the list elements.
|
||||||
--
|
--
|
||||||
@@ -252,8 +242,8 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
selItemAttr = if foc
|
selItemAttr = if foc
|
||||||
then withDefAttr listSelectedFocusedAttr
|
then withDefAttr listSelectedFocusedAttr
|
||||||
else withDefAttr listSelectedAttr
|
else withDefAttr listSelectedAttr
|
||||||
makeVisible' = if isSelected then visible . selItemAttr else id
|
makeVisible = if isSelected then visible . selItemAttr else id
|
||||||
in addSeparator $ makeVisible' elemWidget
|
in addSeparator $ makeVisible elemWidget
|
||||||
|
|
||||||
in render
|
in render
|
||||||
$ viewport "GHCup" Vertical
|
$ viewport "GHCup" Vertical
|
||||||
@@ -268,8 +258,8 @@ minHSize s' = hLimit s' . vLimit 1 . (<+> fill ' ')
|
|||||||
app :: AttrMap -> AttrMap -> App BrickState e String
|
app :: AttrMap -> AttrMap -> App BrickState e String
|
||||||
app attrs dimAttrs =
|
app attrs dimAttrs =
|
||||||
App { appDraw = \st -> [ui dimAttrs st]
|
App { appDraw = \st -> [ui dimAttrs st]
|
||||||
, appHandleEvent = \be -> get >>= \s -> eventHandler s be
|
, appHandleEvent = eventHandler
|
||||||
, appStartEvent = return ()
|
, appStartEvent = return
|
||||||
, appAttrMap = const attrs
|
, appAttrMap = const attrs
|
||||||
, appChooseCursor = showFirstCursor
|
, appChooseCursor = showFirstCursor
|
||||||
}
|
}
|
||||||
@@ -277,22 +267,18 @@ app attrs dimAttrs =
|
|||||||
defaultAttributes :: Bool -> AttrMap
|
defaultAttributes :: Bool -> AttrMap
|
||||||
defaultAttributes no_color = attrMap
|
defaultAttributes no_color = attrMap
|
||||||
Vty.defAttr
|
Vty.defAttr
|
||||||
[ (attrName "active" , Vty.defAttr `withBackColor` Vty.blue)
|
[ ("active" , Vty.defAttr `withBackColor` Vty.blue)
|
||||||
, (attrName "not-installed" , Vty.defAttr `withForeColor` Vty.red)
|
, ("not-installed", Vty.defAttr `withForeColor` Vty.red)
|
||||||
, (attrName "set" , Vty.defAttr `withForeColor` Vty.green)
|
, ("set" , Vty.defAttr `withForeColor` Vty.green)
|
||||||
, (attrName "installed" , Vty.defAttr `withForeColor` Vty.green)
|
, ("installed" , Vty.defAttr `withForeColor` Vty.green)
|
||||||
, (attrName "recommended" , Vty.defAttr `withForeColor` Vty.green)
|
, ("recommended" , Vty.defAttr `withForeColor` Vty.green)
|
||||||
, (attrName "hls-powered" , Vty.defAttr `withForeColor` Vty.green)
|
, ("hls-powered" , Vty.defAttr `withForeColor` Vty.green)
|
||||||
, (attrName "latest" , Vty.defAttr `withForeColor` Vty.yellow)
|
, ("latest" , Vty.defAttr `withForeColor` Vty.yellow)
|
||||||
, (attrName "latest-prerelease" , Vty.defAttr `withForeColor` Vty.red)
|
, ("prerelease" , Vty.defAttr `withForeColor` Vty.red)
|
||||||
, (attrName "latest-nightly" , Vty.defAttr `withForeColor` Vty.red)
|
, ("compiled" , Vty.defAttr `withForeColor` Vty.blue)
|
||||||
, (attrName "prerelease" , Vty.defAttr `withForeColor` Vty.red)
|
, ("stray" , Vty.defAttr `withForeColor` Vty.blue)
|
||||||
, (attrName "nightly" , Vty.defAttr `withForeColor` Vty.red)
|
, ("help" , Vty.defAttr `withStyle` Vty.italic)
|
||||||
, (attrName "compiled" , Vty.defAttr `withForeColor` Vty.blue)
|
, ("hooray" , Vty.defAttr `withForeColor` Vty.brightWhite)
|
||||||
, (attrName "stray" , Vty.defAttr `withForeColor` Vty.blue)
|
|
||||||
, (attrName "day" , Vty.defAttr `withForeColor` Vty.blue)
|
|
||||||
, (attrName "help" , Vty.defAttr `withStyle` Vty.italic)
|
|
||||||
, (attrName "hooray" , Vty.defAttr `withForeColor` Vty.brightWhite)
|
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
withForeColor | no_color = const
|
withForeColor | no_color = const
|
||||||
@@ -306,31 +292,31 @@ defaultAttributes no_color = attrMap
|
|||||||
dimAttributes :: Bool -> AttrMap
|
dimAttributes :: Bool -> AttrMap
|
||||||
dimAttributes no_color = attrMap
|
dimAttributes no_color = attrMap
|
||||||
(Vty.defAttr `Vty.withStyle` Vty.dim)
|
(Vty.defAttr `Vty.withStyle` Vty.dim)
|
||||||
[ (attrName "active" , Vty.defAttr `withBackColor` Vty.blue) -- has no effect ??
|
[ ("active" , Vty.defAttr `withBackColor` Vty.blue) -- has no effect ??
|
||||||
, (attrName "no-bindist", Vty.defAttr `Vty.withStyle` Vty.dim)
|
, ("no-bindist", Vty.defAttr `Vty.withStyle` Vty.dim)
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
withBackColor | no_color = \attr _ -> attr `Vty.withStyle` Vty.reverseVideo
|
withBackColor | no_color = \attr _ -> attr `Vty.withStyle` Vty.reverseVideo
|
||||||
| otherwise = Vty.withBackColor
|
| otherwise = Vty.withBackColor
|
||||||
|
|
||||||
eventHandler :: BrickState -> BrickEvent String e -> EventM String BrickState ()
|
eventHandler :: BrickState -> BrickEvent n e -> EventM n (Next BrickState)
|
||||||
eventHandler st@BrickState{..} ev = do
|
eventHandler st@BrickState{..} ev = do
|
||||||
AppState { keyBindings = kb } <- liftIO $ readIORef settings'
|
AppState { keyBindings = kb } <- liftIO $ readIORef settings'
|
||||||
case ev of
|
case ev of
|
||||||
(MouseDown _ Vty.BScrollUp _ _) ->
|
(MouseDown _ Vty.BScrollUp _ _) ->
|
||||||
put (BrickState { appState = moveCursor 1 appState Up, .. })
|
continue (BrickState { appState = moveCursor 1 appState Up, .. })
|
||||||
(MouseDown _ Vty.BScrollDown _ _) ->
|
(MouseDown _ Vty.BScrollDown _ _) ->
|
||||||
put (BrickState { appState = moveCursor 1 appState Down, .. })
|
continue (BrickState { appState = moveCursor 1 appState Down, .. })
|
||||||
(VtyEvent (Vty.EvResize _ _)) -> put st
|
(VtyEvent (Vty.EvResize _ _)) -> continue st
|
||||||
(VtyEvent (Vty.EvKey Vty.KUp _)) ->
|
(VtyEvent (Vty.EvKey Vty.KUp _)) ->
|
||||||
put BrickState{ appState = moveCursor 1 appState Up, .. }
|
continue BrickState{ appState = moveCursor 1 appState Up, .. }
|
||||||
(VtyEvent (Vty.EvKey Vty.KDown _)) ->
|
(VtyEvent (Vty.EvKey Vty.KDown _)) ->
|
||||||
put BrickState{ appState = moveCursor 1 appState Down, .. }
|
continue BrickState{ appState = moveCursor 1 appState Down, .. }
|
||||||
(VtyEvent (Vty.EvKey key _)) ->
|
(VtyEvent (Vty.EvKey key _)) ->
|
||||||
case find (\(key', _, _) -> key' == key) (keyHandlers kb) of
|
case find (\(key', _, _) -> key' == key) (keyHandlers kb) of
|
||||||
Nothing -> put st
|
Nothing -> continue st
|
||||||
Just (_, _, handler) -> handler st
|
Just (_, _, handler) -> handler st
|
||||||
_ -> put st
|
_ -> continue st
|
||||||
|
|
||||||
|
|
||||||
moveCursor :: Int -> BrickInternalState -> Direction -> BrickInternalState
|
moveCursor :: Int -> BrickInternalState -> Direction -> BrickInternalState
|
||||||
@@ -343,14 +329,13 @@ moveCursor steps ais@BrickInternalState{..} direction =
|
|||||||
|
|
||||||
-- | Suspend the current UI and run an IO action in terminal. If the
|
-- | 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.
|
-- IO action returns a Left value, then it's thrown as userError.
|
||||||
withIOAction :: Ord n
|
withIOAction :: (BrickState
|
||||||
=> (BrickState
|
|
||||||
-> (Int, ListResult)
|
-> (Int, ListResult)
|
||||||
-> ReaderT AppState IO (Either String a))
|
-> ReaderT AppState IO (Either String a))
|
||||||
-> BrickState
|
-> BrickState
|
||||||
-> EventM n BrickState ()
|
-> EventM n (Next BrickState)
|
||||||
withIOAction action as = case listSelectedElement' (appState as) of
|
withIOAction action as = case listSelectedElement' (appState as) of
|
||||||
Nothing -> put as
|
Nothing -> continue as
|
||||||
Just (ix, e) -> do
|
Just (ix, e) -> do
|
||||||
suspendAndResume $ do
|
suspendAndResume $ do
|
||||||
settings <- readIORef settings'
|
settings <- readIORef settings'
|
||||||
@@ -419,17 +404,13 @@ filterVisible :: Bool -> Bool -> ListResult -> Bool
|
|||||||
filterVisible v t e | lInstalled e = True
|
filterVisible v t e | lInstalled e = True
|
||||||
| v
|
| v
|
||||||
, not t
|
, not t
|
||||||
, Nightly `notElem` lTag e
|
|
||||||
, lTool e `notElem` hiddenTools = True
|
, lTool e `notElem` hiddenTools = True
|
||||||
| not v
|
| not v
|
||||||
, t
|
, t
|
||||||
, Old `notElem` lTag e
|
, Old `notElem` lTag e = True
|
||||||
, Nightly `notElem` lTag e = True
|
|
||||||
| v
|
| v
|
||||||
, Nightly `notElem` lTag e
|
|
||||||
, t = True
|
, t = True
|
||||||
| otherwise = (Old `notElem` lTag e) &&
|
| otherwise = (Old `notElem` lTag e) &&
|
||||||
(Nightly `notElem` lTag e) &&
|
|
||||||
(lTool e `notElem` hiddenTools)
|
(lTool e `notElem` hiddenTools)
|
||||||
|
|
||||||
|
|
||||||
@@ -472,19 +453,19 @@ install' _ (_, ListResult {..}) = do
|
|||||||
dirs <- lift getDirs
|
dirs <- lift getDirs
|
||||||
case lTool of
|
case lTool of
|
||||||
GHC -> do
|
GHC -> do
|
||||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) GHC dls
|
let vi = getVersionInfo lVer GHC dls
|
||||||
liftE $ installGHCBin (GHCTargetVersion lCross lVer) GHCupInternal False [] $> (vi, dirs, ce)
|
liftE $ installGHCBin lVer GHCupInternal False [] $> (vi, dirs, ce)
|
||||||
Cabal -> do
|
Cabal -> do
|
||||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) Cabal dls
|
let vi = getVersionInfo lVer Cabal dls
|
||||||
liftE $ installCabalBin lVer GHCupInternal False $> (vi, dirs, ce)
|
liftE $ installCabalBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
GHCup -> do
|
GHCup -> do
|
||||||
let vi = snd <$> getLatest dls GHCup
|
let vi = snd <$> getLatest dls GHCup
|
||||||
liftE $ upgradeGHCup Nothing False False $> (vi, dirs, ce)
|
liftE $ upgradeGHCup Nothing False False $> (vi, dirs, ce)
|
||||||
HLS -> do
|
HLS -> do
|
||||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) HLS dls
|
let vi = getVersionInfo lVer HLS dls
|
||||||
liftE $ installHLSBin lVer GHCupInternal False $> (vi, dirs, ce)
|
liftE $ installHLSBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
Stack -> do
|
Stack -> do
|
||||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) Stack dls
|
let vi = getVersionInfo lVer Stack dls
|
||||||
liftE $ installStackBin lVer GHCupInternal False $> (vi, dirs, ce)
|
liftE $ installStackBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -565,7 +546,7 @@ del' _ (_, ListResult {..}) = do
|
|||||||
let run = runE @'[NotInstalled, UninstallFailed]
|
let run = runE @'[NotInstalled, UninstallFailed]
|
||||||
|
|
||||||
run (do
|
run (do
|
||||||
let vi = getVersionInfo (GHCTargetVersion lCross lVer) lTool dls
|
let vi = getVersionInfo lVer lTool dls
|
||||||
case lTool of
|
case lTool of
|
||||||
GHC -> liftE $ rmGHCVer (GHCTargetVersion lCross lVer) $> vi
|
GHC -> liftE $ rmGHCVer (GHCTargetVersion lCross lVer) $> vi
|
||||||
Cabal -> liftE $ rmCabalVer lVer $> vi
|
Cabal -> liftE $ rmCabalVer lVer $> vi
|
||||||
@@ -575,7 +556,7 @@ del' _ (_, ListResult {..}) = do
|
|||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
when (lTool == GHC) $ logGHCPostRm (mkTVer lVer)
|
logGHCPostRm (mkTVer lVer)
|
||||||
forM_ (_viPostRemove =<< vi) $ \msg ->
|
forM_ (_viPostRemove =<< vi) $ \msg ->
|
||||||
logInfo msg
|
logInfo msg
|
||||||
pure $ Right ()
|
pure $ Right ()
|
||||||
@@ -588,7 +569,7 @@ changelog' :: (MonadReader AppState m, MonadIO m)
|
|||||||
-> m (Either String ())
|
-> m (Either String ())
|
||||||
changelog' _ (_, ListResult {..}) = do
|
changelog' _ (_, ListResult {..}) = do
|
||||||
AppState { pfreq, ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
AppState { pfreq, ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
||||||
case getChangeLog dls lTool (ToolVersion lVer) of
|
case getChangeLog dls lTool (Left lVer) of
|
||||||
Nothing -> pure $ Left $
|
Nothing -> pure $ Left $
|
||||||
"Could not find ChangeLog for " <> prettyShow lTool <> ", version " <> T.unpack (prettyVer lVer)
|
"Could not find ChangeLog for " <> prettyShow lTool <> ", version " <> T.unpack (prettyVer lVer)
|
||||||
Just uri -> do
|
Just uri -> do
|
||||||
@@ -668,5 +649,5 @@ getAppData mgi = runExceptT $ do
|
|||||||
settings <- liftIO $ readIORef settings'
|
settings <- liftIO $ readIORef settings'
|
||||||
|
|
||||||
flip runReaderT settings $ do
|
flip runReaderT settings $ do
|
||||||
lV <- listVersions Nothing [] False True (Nothing, Nothing)
|
lV <- listVersions Nothing Nothing
|
||||||
pure $ BrickData (reverse lV)
|
pure $ BrickData (reverse lV)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
module GHCup.OptParse (
|
module GHCup.OptParse (
|
||||||
module GHCup.OptParse.Common
|
module GHCup.OptParse.Common
|
||||||
, module GHCup.OptParse.Install
|
, module GHCup.OptParse.Install
|
||||||
, module GHCup.OptParse.Test
|
|
||||||
, module GHCup.OptParse.Set
|
, module GHCup.OptParse.Set
|
||||||
, module GHCup.OptParse.UnSet
|
, module GHCup.OptParse.UnSet
|
||||||
, module GHCup.OptParse.Rm
|
, module GHCup.OptParse.Rm
|
||||||
@@ -32,7 +31,6 @@ module GHCup.OptParse (
|
|||||||
|
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.OptParse.Install
|
import GHCup.OptParse.Install
|
||||||
import GHCup.OptParse.Test
|
|
||||||
import GHCup.OptParse.Set
|
import GHCup.OptParse.Set
|
||||||
import GHCup.OptParse.UnSet
|
import GHCup.OptParse.UnSet
|
||||||
import GHCup.OptParse.Rm
|
import GHCup.OptParse.Rm
|
||||||
@@ -89,7 +87,6 @@ data Options = Options
|
|||||||
|
|
||||||
data Command
|
data Command
|
||||||
= Install (Either InstallCommand InstallOptions)
|
= Install (Either InstallCommand InstallOptions)
|
||||||
| Test TestCommand
|
|
||||||
| InstallCabalLegacy InstallOptions
|
| InstallCabalLegacy InstallOptions
|
||||||
| Set (Either SetCommand SetOptions)
|
| Set (Either SetCommand SetOptions)
|
||||||
| UnSet UnsetCommand
|
| UnSet UnsetCommand
|
||||||
@@ -107,6 +104,9 @@ data Command
|
|||||||
| Nuke
|
| Nuke
|
||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
| Interactive
|
| Interactive
|
||||||
|
#endif
|
||||||
|
#if defined(ANSI)
|
||||||
|
| InteractiveAnsi
|
||||||
#endif
|
#endif
|
||||||
| Prefetch PrefetchCommand
|
| Prefetch PrefetchCommand
|
||||||
| GC GCOptions
|
| GC GCOptions
|
||||||
@@ -187,8 +187,19 @@ opts =
|
|||||||
com :: Parser Command
|
com :: Parser Command
|
||||||
com =
|
com =
|
||||||
subparser
|
subparser
|
||||||
#if defined(BRICK)
|
#if defined(ANSI)
|
||||||
( command
|
( command
|
||||||
|
"tui-ansi"
|
||||||
|
( (\_ -> InteractiveAnsi)
|
||||||
|
<$> info
|
||||||
|
helper
|
||||||
|
( progDesc "Start the interactive GHCup UI (ansi)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<>
|
||||||
|
#endif
|
||||||
|
#if defined(BRICK)
|
||||||
|
command
|
||||||
"tui"
|
"tui"
|
||||||
( (\_ -> Interactive)
|
( (\_ -> Interactive)
|
||||||
<$> info
|
<$> info
|
||||||
@@ -198,7 +209,7 @@ com =
|
|||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
#else
|
#else
|
||||||
( command
|
command
|
||||||
#endif
|
#endif
|
||||||
"install"
|
"install"
|
||||||
( Install
|
( Install
|
||||||
@@ -208,14 +219,6 @@ com =
|
|||||||
<> footerDoc (Just $ text installToolFooter)
|
<> footerDoc (Just $ text installToolFooter)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<> command
|
|
||||||
"test"
|
|
||||||
(info
|
|
||||||
(Test <$> testParser <**> helper)
|
|
||||||
( progDesc "Run tests for a tool (if any) [EXPERIMENTAL!]"
|
|
||||||
<> footerDoc (Just $ text testFooter)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<> command
|
<> command
|
||||||
"set"
|
"set"
|
||||||
(info
|
(info
|
||||||
@@ -244,8 +247,7 @@ com =
|
|||||||
<> command
|
<> command
|
||||||
"list"
|
"list"
|
||||||
(info (List <$> listOpts <**> helper)
|
(info (List <$> listOpts <**> helper)
|
||||||
(progDesc "Show available GHCs and other tools"
|
(progDesc "Show available GHCs and other tools")
|
||||||
<> footerDoc (Just $ text listToolFooter))
|
|
||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
"upgrade"
|
"upgrade"
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import qualified Data.Text as T
|
|||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
|
import Data.Versions
|
||||||
import URI.ByteString (serializeURIRef')
|
import URI.ByteString (serializeURIRef')
|
||||||
import Data.Char (toLower)
|
import Data.Char (toLower)
|
||||||
|
|
||||||
@@ -80,7 +81,7 @@ changelogP =
|
|||||||
<> completer toolCompleter
|
<> completer toolCompleter
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional (toolVersionTagArgument [] Nothing)
|
<*> optional (toolVersionTagArgument Nothing Nothing)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -114,15 +115,20 @@ changelog :: ( Monad m
|
|||||||
changelog ChangeLogOptions{..} runAppState runLogger = do
|
changelog ChangeLogOptions{..} runAppState runLogger = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- runAppState getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- runAppState getGHCupInfo
|
||||||
let tool = fromMaybe GHC clTool
|
let tool = fromMaybe GHC clTool
|
||||||
ver' = fromMaybe
|
ver' = maybe
|
||||||
(ToolTag Latest)
|
(Right Latest)
|
||||||
|
(\case
|
||||||
|
GHCVersion tv -> Left (_tvVersion tv)
|
||||||
|
ToolVersion tv -> Left tv
|
||||||
|
ToolTag t -> Right t
|
||||||
|
)
|
||||||
clToolVer
|
clToolVer
|
||||||
muri = getChangeLog dls tool ver'
|
muri = getChangeLog dls tool ver'
|
||||||
case muri of
|
case muri of
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
runLogger
|
runLogger
|
||||||
(logWarn $
|
(logWarn $
|
||||||
"Could not find ChangeLog for " <> T.pack (prettyShow tool) <> ", version " <> T.pack (prettyShow ver')
|
"Could not find ChangeLog for " <> T.pack (prettyShow tool) <> ", version " <> either prettyVer (T.pack . show) ver'
|
||||||
)
|
)
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
Just uri -> do
|
Just uri -> do
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
{-# LANGUAGE TypeApplications #-}
|
||||||
{-# LANGUAGE NumericUnderscores #-}
|
{-# LANGUAGE NumericUnderscores #-}
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
|
||||||
|
|
||||||
module GHCup.OptParse.Common where
|
module GHCup.OptParse.Common where
|
||||||
|
|
||||||
@@ -46,8 +45,6 @@ import Data.Functor
|
|||||||
import Data.List ( nub, sort, sortBy, isPrefixOf, stripPrefix )
|
import Data.List ( nub, sort, sortBy, isPrefixOf, stripPrefix )
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Time.Calendar ( Day )
|
|
||||||
import Data.Time.Format ( parseTimeM, defaultTimeLocale )
|
|
||||||
import Data.Versions hiding ( str )
|
import Data.Versions hiding ( str )
|
||||||
import Data.Void
|
import Data.Void
|
||||||
import qualified Data.Vector as V
|
import qualified Data.Vector as V
|
||||||
@@ -75,26 +72,26 @@ import qualified Cabal.Config as CC
|
|||||||
--[ Types ]--
|
--[ Types ]--
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
data ToolVersion = GHCVersion GHCTargetVersion
|
||||||
|
| ToolVersion Version
|
||||||
|
| ToolTag Tag
|
||||||
|
|
||||||
-- a superset of ToolVersion
|
-- a superset of ToolVersion
|
||||||
data SetToolVersion = SetGHCVersion GHCTargetVersion
|
data SetToolVersion = SetGHCVersion GHCTargetVersion
|
||||||
| SetToolVersion Version
|
| SetToolVersion Version
|
||||||
| SetToolTag Tag
|
| SetToolTag Tag
|
||||||
| SetToolDay Day
|
|
||||||
| SetRecommended
|
| SetRecommended
|
||||||
| SetNext
|
| SetNext
|
||||||
|
|
||||||
prettyToolVer :: ToolVersion -> String
|
prettyToolVer :: ToolVersion -> String
|
||||||
prettyToolVer (GHCVersion v') = T.unpack $ tVerToText v'
|
prettyToolVer (GHCVersion v') = T.unpack $ tVerToText v'
|
||||||
prettyToolVer (ToolVersion v') = T.unpack $ prettyVer v'
|
prettyToolVer (ToolVersion v') = T.unpack $ prettyVer v'
|
||||||
prettyToolVer (ToolTag t) = show t
|
prettyToolVer (ToolTag t) = show t
|
||||||
prettyToolVer (ToolDay day) = show day
|
|
||||||
|
|
||||||
toSetToolVer :: Maybe ToolVersion -> SetToolVersion
|
toSetToolVer :: Maybe ToolVersion -> SetToolVersion
|
||||||
toSetToolVer (Just (GHCVersion v')) = SetGHCVersion v'
|
toSetToolVer (Just (GHCVersion v')) = SetGHCVersion v'
|
||||||
toSetToolVer (Just (ToolVersion v')) = SetToolVersion v'
|
toSetToolVer (Just (ToolVersion v')) = SetToolVersion v'
|
||||||
toSetToolVer (Just (ToolTag t')) = SetToolTag t'
|
toSetToolVer (Just (ToolTag t')) = SetToolTag t'
|
||||||
toSetToolVer (Just (ToolDay d')) = SetToolDay d'
|
|
||||||
toSetToolVer Nothing = SetRecommended
|
toSetToolVer Nothing = SetRecommended
|
||||||
|
|
||||||
|
|
||||||
@@ -105,28 +102,28 @@ toSetToolVer Nothing = SetRecommended
|
|||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
||||||
toolVersionTagArgument :: [ListCriteria] -> Maybe Tool -> Parser ToolVersion
|
toolVersionTagArgument :: Maybe ListCriteria -> Maybe Tool -> Parser ToolVersion
|
||||||
toolVersionTagArgument criteria tool =
|
toolVersionTagArgument criteria tool =
|
||||||
argument (eitherReader (parser tool))
|
argument (eitherReader (parser tool))
|
||||||
(metavar (mv tool)
|
(metavar (mv tool)
|
||||||
<> completer (tagCompleter (fromMaybe GHC tool) [])
|
<> completer (tagCompleter (fromMaybe GHC tool) [])
|
||||||
<> foldMap (completer . versionCompleter criteria) tool)
|
<> foldMap (completer . versionCompleter criteria) tool)
|
||||||
where
|
where
|
||||||
mv (Just GHC) = "GHC_VERSION|TAG|RELEASE_DATE"
|
mv (Just GHC) = "GHC_VERSION|TAG"
|
||||||
mv (Just HLS) = "HLS_VERSION|TAG|RELEASE_DATE"
|
mv (Just HLS) = "HLS_VERSION|TAG"
|
||||||
mv _ = "VERSION|TAG|RELEASE_DATE"
|
mv _ = "VERSION|TAG"
|
||||||
|
|
||||||
parser (Just GHC) = ghcVersionTagEither
|
parser (Just GHC) = ghcVersionTagEither
|
||||||
parser Nothing = ghcVersionTagEither
|
parser Nothing = ghcVersionTagEither
|
||||||
parser _ = toolVersionTagEither
|
parser _ = toolVersionTagEither
|
||||||
|
|
||||||
|
|
||||||
versionParser' :: [ListCriteria] -> Maybe Tool -> Parser Version
|
versionParser' :: Maybe ListCriteria -> Maybe Tool -> Parser Version
|
||||||
versionParser' criteria tool = argument
|
versionParser' criteria tool = argument
|
||||||
(eitherReader (first show . version . T.pack))
|
(eitherReader (first show . version . T.pack))
|
||||||
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
||||||
|
|
||||||
ghcVersionArgument :: [ListCriteria] -> Maybe Tool -> Parser GHCTargetVersion
|
ghcVersionArgument :: Maybe ListCriteria -> Maybe Tool -> Parser GHCTargetVersion
|
||||||
ghcVersionArgument criteria tool = argument (eitherReader ghcVersionEither)
|
ghcVersionArgument criteria tool = argument (eitherReader ghcVersionEither)
|
||||||
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
||||||
|
|
||||||
@@ -240,23 +237,21 @@ isolateParser f = case isValid f && isAbsolute f of
|
|||||||
-- this accepts cross prefix
|
-- this accepts cross prefix
|
||||||
ghcVersionTagEither :: String -> Either String ToolVersion
|
ghcVersionTagEither :: String -> Either String ToolVersion
|
||||||
ghcVersionTagEither s' =
|
ghcVersionTagEither s' =
|
||||||
second ToolDay (dayParser s') <|> second ToolTag (tagEither s') <|> second GHCVersion (ghcVersionEither s')
|
second ToolTag (tagEither s') <|> second GHCVersion (ghcVersionEither s')
|
||||||
|
|
||||||
-- this ignores cross prefix
|
-- this ignores cross prefix
|
||||||
toolVersionTagEither :: String -> Either String ToolVersion
|
toolVersionTagEither :: String -> Either String ToolVersion
|
||||||
toolVersionTagEither s' =
|
toolVersionTagEither s' =
|
||||||
second ToolDay (dayParser s') <|> second ToolTag (tagEither s') <|> second ToolVersion (toolVersionEither s')
|
second ToolTag (tagEither s') <|> second ToolVersion (toolVersionEither s')
|
||||||
|
|
||||||
tagEither :: String -> Either String Tag
|
tagEither :: String -> Either String Tag
|
||||||
tagEither s' = case fmap toLower s' of
|
tagEither s' = case fmap toLower s' of
|
||||||
"recommended" -> Right Recommended
|
"recommended" -> Right Recommended
|
||||||
"latest" -> Right Latest
|
"latest" -> Right Latest
|
||||||
"latest-prerelease" -> Right LatestPrerelease
|
|
||||||
"latest-nightly" -> Right LatestNightly
|
|
||||||
('b':'a':'s':'e':'-':ver') -> case pvp (T.pack ver') of
|
('b':'a':'s':'e':'-':ver') -> case pvp (T.pack ver') of
|
||||||
Right x -> Right (Base x)
|
Right x -> Right (Base x)
|
||||||
Left _ -> Left $ "Invalid PVP version for base " <> ver'
|
Left _ -> Left $ "Invalid PVP version for base " <> ver'
|
||||||
other -> Left $ "Unknown tag " <> other
|
other -> Left $ "Unknown tag " <> other
|
||||||
|
|
||||||
|
|
||||||
ghcVersionEither :: String -> Either String GHCTargetVersion
|
ghcVersionEither :: String -> Either String GHCTargetVersion
|
||||||
@@ -265,7 +260,7 @@ ghcVersionEither =
|
|||||||
|
|
||||||
toolVersionEither :: String -> Either String Version
|
toolVersionEither :: String -> Either String Version
|
||||||
toolVersionEither =
|
toolVersionEither =
|
||||||
first (const "Not a valid version") . MP.parse (version' <* MP.eof) "" . T.pack
|
first (const "Not a valid version") . MP.parse version' "" . T.pack
|
||||||
|
|
||||||
|
|
||||||
toolParser :: String -> Either String Tool
|
toolParser :: String -> Either String Tool
|
||||||
@@ -276,22 +271,12 @@ toolParser s' | t == T.pack "ghc" = Right GHC
|
|||||||
| otherwise = Left ("Unknown tool: " <> s')
|
| otherwise = Left ("Unknown tool: " <> s')
|
||||||
where t = T.toLower (T.pack s')
|
where t = T.toLower (T.pack s')
|
||||||
|
|
||||||
dayParser :: String -> Either String Day
|
|
||||||
dayParser s = maybe (Left $ "Could not parse \"" <> s <> "\". Expected format is: YYYY-MM-DD") Right
|
|
||||||
$ parseTimeM True defaultTimeLocale "%Y-%-m-%-d" s
|
|
||||||
|
|
||||||
|
|
||||||
criteriaParser :: String -> Either String ListCriteria
|
criteriaParser :: String -> Either String ListCriteria
|
||||||
criteriaParser s' | t == T.pack "installed" = Right $ ListInstalled True
|
criteriaParser s' | t == T.pack "installed" = Right ListInstalled
|
||||||
| t == T.pack "set" = Right $ ListSet True
|
| t == T.pack "set" = Right ListSet
|
||||||
| t == T.pack "available" = Right $ ListAvailable True
|
| t == T.pack "available" = Right ListAvailable
|
||||||
| t == T.pack "+installed" = Right $ ListInstalled True
|
| otherwise = Left ("Unknown criteria: " <> s')
|
||||||
| t == T.pack "+set" = Right $ ListSet True
|
|
||||||
| t == T.pack "+available" = Right $ ListAvailable True
|
|
||||||
| t == T.pack "-installed" = Right $ ListInstalled False
|
|
||||||
| t == T.pack "-set" = Right $ ListSet False
|
|
||||||
| t == T.pack "-available" = Right $ ListAvailable False
|
|
||||||
| otherwise = Left ("Unknown criteria: " <> s')
|
|
||||||
where t = T.toLower (T.pack s')
|
where t = T.toLower (T.pack s')
|
||||||
|
|
||||||
|
|
||||||
@@ -467,12 +452,12 @@ tagCompleter tool add = listIOCompleter $ do
|
|||||||
let allTags = filter (/= Old)
|
let allTags = filter (/= Old)
|
||||||
$ _viTags =<< M.elems (availableToolVersions (_ghcupDownloads ghcupInfo) tool)
|
$ _viTags =<< M.elems (availableToolVersions (_ghcupDownloads ghcupInfo) tool)
|
||||||
pure $ nub $ (add ++) $ fmap tagToString allTags
|
pure $ nub $ (add ++) $ fmap tagToString allTags
|
||||||
VLeft _ -> pure (nub $ ["recommended", "latest", "latest-prerelease"] ++ add)
|
VLeft _ -> pure (nub $ ["recommended", "latest"] ++ add)
|
||||||
|
|
||||||
versionCompleter :: [ListCriteria] -> Tool -> Completer
|
versionCompleter :: Maybe ListCriteria -> Tool -> Completer
|
||||||
versionCompleter criteria tool = versionCompleter' criteria tool (const True)
|
versionCompleter criteria tool = versionCompleter' criteria tool (const True)
|
||||||
|
|
||||||
versionCompleter' :: [ListCriteria] -> Tool -> (Version -> Bool) -> Completer
|
versionCompleter' :: Maybe ListCriteria -> Tool -> (Version -> Bool) -> Completer
|
||||||
versionCompleter' criteria tool filter' = listIOCompleter $ do
|
versionCompleter' criteria tool filter' = listIOCompleter $ do
|
||||||
dirs' <- liftIO getAllDirs
|
dirs' <- liftIO getAllDirs
|
||||||
let loggerConfig = LoggerConfig
|
let loggerConfig = LoggerConfig
|
||||||
@@ -501,7 +486,7 @@ versionCompleter' criteria tool filter' = listIOCompleter $ do
|
|||||||
|
|
||||||
runEnv = flip runReaderT appState
|
runEnv = flip runReaderT appState
|
||||||
|
|
||||||
installedVersions <- runEnv $ listVersions (Just tool) criteria False False (Nothing, Nothing)
|
installedVersions <- runEnv $ listVersions (Just tool) criteria
|
||||||
return $ fmap (T.unpack . prettyVer) . filter filter' . fmap lVer $ installedVersions
|
return $ fmap (T.unpack . prettyVer) . filter filter' . fmap lVer $ installedVersions
|
||||||
|
|
||||||
|
|
||||||
@@ -669,7 +654,6 @@ fromVersion :: ( HasLog env
|
|||||||
-> Tool
|
-> Tool
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ TagNotFound
|
'[ TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
] m (GHCTargetVersion, Maybe VersionInfo)
|
] m (GHCTargetVersion, Maybe VersionInfo)
|
||||||
@@ -688,58 +672,46 @@ fromVersion' :: ( HasLog env
|
|||||||
-> Tool
|
-> Tool
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ TagNotFound
|
'[ TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
] m (GHCTargetVersion, Maybe VersionInfo)
|
] m (GHCTargetVersion, Maybe VersionInfo)
|
||||||
fromVersion' SetRecommended tool = do
|
fromVersion' SetRecommended tool = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
second Just <$> getRecommended dls tool
|
bimap mkTVer Just <$> getRecommended dls tool
|
||||||
?? TagNotFound Recommended tool
|
?? TagNotFound Recommended tool
|
||||||
fromVersion' (SetGHCVersion v) tool = do
|
fromVersion' (SetGHCVersion v) tool = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo v tool dls
|
let vi = getVersionInfo (_tvVersion v) tool dls
|
||||||
case pvp $ prettyVer (_tvVersion v) of -- need to be strict here
|
case pvp $ prettyVer (_tvVersion v) of -- need to be strict here
|
||||||
Left _ -> pure (v, vi)
|
Left _ -> pure (v, vi)
|
||||||
Right pvpIn ->
|
Right pvpIn ->
|
||||||
lift (getLatestToolFor tool (_tvTarget v) pvpIn dls) >>= \case
|
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
||||||
Just (pvp_, vi', mt) -> do
|
Just (pvp_, vi') -> do
|
||||||
v' <- lift $ pvpToVersion pvp_ ""
|
v' <- lift $ pvpToVersion pvp_ ""
|
||||||
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
||||||
pure (GHCTargetVersion mt v', Just vi')
|
pure (GHCTargetVersion (_tvTarget v) v', Just vi')
|
||||||
Nothing -> pure (v, vi)
|
Nothing -> pure (v, vi)
|
||||||
fromVersion' (SetToolVersion (mkTVer -> v)) tool = do
|
fromVersion' (SetToolVersion v) tool = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo v tool dls
|
let vi = getVersionInfo v tool dls
|
||||||
case pvp $ prettyVer (_tvVersion v) of -- need to be strict here
|
case pvp $ prettyVer v of -- need to be strict here
|
||||||
Left _ -> pure (v, vi)
|
Left _ -> pure (mkTVer v, vi)
|
||||||
Right pvpIn ->
|
Right pvpIn ->
|
||||||
lift (getLatestToolFor tool (_tvTarget v) pvpIn dls) >>= \case
|
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
||||||
Just (pvp_, vi', mt) -> do
|
Just (pvp_, vi') -> do
|
||||||
v' <- lift $ pvpToVersion pvp_ ""
|
v' <- lift $ pvpToVersion pvp_ ""
|
||||||
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
when (v' /= v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
||||||
pure (GHCTargetVersion mt v', Just vi')
|
pure (GHCTargetVersion mempty v', Just vi')
|
||||||
Nothing -> pure (v, vi)
|
Nothing -> pure (mkTVer v, vi)
|
||||||
fromVersion' (SetToolTag Latest) tool = do
|
fromVersion' (SetToolTag Latest) tool = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
bimap id Just <$> getLatest dls tool ?? TagNotFound Latest tool
|
bimap mkTVer Just <$> getLatest dls tool ?? TagNotFound Latest tool
|
||||||
fromVersion' (SetToolDay day) tool = do
|
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
|
||||||
bimap id Just <$> case getByReleaseDay dls tool day of
|
|
||||||
Left ad -> throwE $ DayNotFound day tool ad
|
|
||||||
Right v -> pure v
|
|
||||||
fromVersion' (SetToolTag LatestPrerelease) tool = do
|
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
|
||||||
bimap id Just <$> getLatestPrerelease dls tool ?? TagNotFound LatestPrerelease tool
|
|
||||||
fromVersion' (SetToolTag LatestNightly) tool = do
|
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
|
||||||
bimap id Just <$> getLatestNightly dls tool ?? TagNotFound LatestNightly tool
|
|
||||||
fromVersion' (SetToolTag Recommended) tool = do
|
fromVersion' (SetToolTag Recommended) tool = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
bimap id Just <$> getRecommended dls tool ?? TagNotFound Recommended tool
|
bimap mkTVer Just <$> getRecommended dls tool ?? TagNotFound Recommended tool
|
||||||
fromVersion' (SetToolTag (Base pvp'')) GHC = do
|
fromVersion' (SetToolTag (Base pvp'')) GHC = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
bimap id Just <$> getLatestBaseVersion dls pvp'' ?? TagNotFound (Base pvp'') GHC
|
bimap mkTVer Just <$> getLatestBaseVersion dls pvp'' ?? TagNotFound (Base pvp'') GHC
|
||||||
fromVersion' SetNext tool = do
|
fromVersion' SetNext tool = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
next <- case tool of
|
next <- case tool of
|
||||||
@@ -784,7 +756,7 @@ fromVersion' SetNext tool = do
|
|||||||
. sort
|
. sort
|
||||||
$ stacks) ?? NoToolVersionSet tool
|
$ stacks) ?? NoToolVersionSet tool
|
||||||
GHCup -> fail "GHCup cannot be set"
|
GHCup -> fail "GHCup cannot be set"
|
||||||
let vi = getVersionInfo next tool dls
|
let vi = getVersionInfo (_tvVersion next) tool dls
|
||||||
pure (next, vi)
|
pure (next, vi)
|
||||||
fromVersion' (SetToolTag t') tool =
|
fromVersion' (SetToolTag t') tool =
|
||||||
throwE $ TagNotFound t' tool
|
throwE $ TagNotFound t' tool
|
||||||
@@ -800,15 +772,15 @@ checkForUpdates :: ( MonadReader env m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> m [(Tool, GHCTargetVersion)]
|
=> m [(Tool, Version)]
|
||||||
checkForUpdates = do
|
checkForUpdates = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
||||||
lInstalled <- listVersions Nothing [ListInstalled True] False False (Nothing, Nothing)
|
lInstalled <- listVersions Nothing (Just ListInstalled)
|
||||||
let latestInstalled tool = (fmap (\lr -> GHCTargetVersion (lCross lr) (lVer lr)) . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
||||||
|
|
||||||
ghcup <- forMM (getLatest dls GHCup) $ \(GHCTargetVersion _ l, _) -> do
|
ghcup <- forMM (getLatest dls GHCup) $ \(l, _) -> do
|
||||||
(Right ghcup_ver) <- pure $ version $ prettyPVP ghcUpVer
|
(Right ghcup_ver) <- pure $ version $ prettyPVP ghcUpVer
|
||||||
if (l > ghcup_ver) then pure $ Just (GHCup, mkTVer l) else pure Nothing
|
if (l > ghcup_ver) then pure $ Just (GHCup, l) else pure Nothing
|
||||||
|
|
||||||
otherTools <- forM [GHC, Cabal, HLS, Stack] $ \t ->
|
otherTools <- forM [GHC, Cabal, HLS, Stack] $ \t ->
|
||||||
forMM (getLatest dls t) $ \(l, _) -> do
|
forMM (getLatest dls t) $ \(l, _) -> do
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ data CompileCommand = CompileGHC GHCCompileOptions
|
|||||||
|
|
||||||
|
|
||||||
data GHCCompileOptions = GHCCompileOptions
|
data GHCCompileOptions = GHCCompileOptions
|
||||||
{ targetGhc :: GHC.GHCVer
|
{ targetGhc :: GHC.GHCVer Version
|
||||||
, bootstrapGhc :: Either Version FilePath
|
, bootstrapGhc :: Either Version FilePath
|
||||||
, jobs :: Maybe Int
|
, jobs :: Maybe Int
|
||||||
, buildConfig :: Maybe FilePath
|
, buildConfig :: Maybe FilePath
|
||||||
@@ -170,7 +170,7 @@ ghcCompileOpts =
|
|||||||
)
|
)
|
||||||
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
||||||
"The tool version to compile"
|
"The tool version to compile"
|
||||||
<> (completer $ versionCompleter [] GHC)
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
)
|
)
|
||||||
) <|>
|
) <|>
|
||||||
(GHC.GitDist <$> (GitBranch <$> option
|
(GHC.GitDist <$> (GitBranch <$> option
|
||||||
@@ -205,7 +205,7 @@ ghcCompileOpts =
|
|||||||
<> metavar "BOOTSTRAP_GHC"
|
<> metavar "BOOTSTRAP_GHC"
|
||||||
<> help
|
<> help
|
||||||
"The GHC version (or full path) to bootstrap with (must be installed)"
|
"The GHC version (or full path) to bootstrap with (must be installed)"
|
||||||
<> (completer $ versionCompleter [] GHC)
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
@@ -258,7 +258,7 @@ ghcCompileOpts =
|
|||||||
)
|
)
|
||||||
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
||||||
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
||||||
<> (completer $ versionCompleter [] GHC)
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -291,7 +291,7 @@ hlsCompileOpts =
|
|||||||
)
|
)
|
||||||
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
||||||
"The version to compile (pulled from hackage)"
|
"The version to compile (pulled from hackage)"
|
||||||
<> (completer $ versionCompleter' [] HLS (either (const False) (const True) . V.pvp . V.prettyVer))
|
<> (completer $ versionCompleter' Nothing HLS (either (const False) (const True) . V.pvp . V.prettyVer))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<|>
|
<|>
|
||||||
@@ -311,7 +311,7 @@ hlsCompileOpts =
|
|||||||
)
|
)
|
||||||
(long "source-dist" <> metavar "VERSION" <> help
|
(long "source-dist" <> metavar "VERSION" <> help
|
||||||
"The version to compile (pulled from packaged git sources)"
|
"The version to compile (pulled from packaged git sources)"
|
||||||
<> (completer $ versionCompleter [] HLS)
|
<> (completer $ versionCompleter Nothing HLS)
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
<|>
|
<|>
|
||||||
@@ -343,7 +343,7 @@ hlsCompileOpts =
|
|||||||
)
|
)
|
||||||
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
||||||
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
||||||
<> (completer $ versionCompleter [] HLS)
|
<> (completer $ versionCompleter Nothing HLS)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<|>
|
<|>
|
||||||
@@ -403,7 +403,7 @@ hlsCompileOpts =
|
|||||||
option (eitherReader ghcVersionTagEither)
|
option (eitherReader ghcVersionTagEither)
|
||||||
( long "ghc" <> metavar "GHC_VERSION|TAG" <> help "For which GHC version to compile for (can be specified multiple times)"
|
( long "ghc" <> metavar "GHC_VERSION|TAG" <> help "For which GHC version to compile for (can be specified multiple times)"
|
||||||
<> completer (tagCompleter GHC [])
|
<> completer (tagCompleter GHC [])
|
||||||
<> completer (versionCompleter [] GHC))
|
<> completer (versionCompleter Nothing GHC))
|
||||||
)
|
)
|
||||||
<*> many (argument str (metavar "CABAL_ARGS" <> help "Additional arguments to cabal install, prefix with '-- ' (longopts)"))
|
<*> many (argument str (metavar "CABAL_ARGS" <> help "Additional arguments to cabal install, prefix with '-- ' (longopts)"))
|
||||||
|
|
||||||
@@ -453,7 +453,6 @@ type HLSEffects = '[ AlreadyInstalled
|
|||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
, TarDirDoesNotExist
|
, TarDirDoesNotExist
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
, NotInstalled
|
, NotInstalled
|
||||||
@@ -511,7 +510,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
case targetHLS of
|
case targetHLS of
|
||||||
HLS.SourceDist targetVer -> do
|
HLS.SourceDist targetVer -> do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo (mkTVer targetVer) HLS dls
|
let vi = getVersionInfo targetVer HLS dls
|
||||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||||
lift $ logInfo msg
|
lift $ logInfo msg
|
||||||
lift $ logInfo
|
lift $ logInfo
|
||||||
@@ -531,7 +530,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
patches
|
patches
|
||||||
cabalArgs
|
cabalArgs
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo (mkTVer targetVer) HLS dls
|
let vi = getVersionInfo targetVer HLS dls
|
||||||
when setCompile $ void $ liftE $
|
when setCompile $ void $ liftE $
|
||||||
setHLS targetVer SetHLSOnly Nothing
|
setHLS targetVer SetHLSOnly Nothing
|
||||||
pure (vi, targetVer)
|
pure (vi, targetVer)
|
||||||
@@ -555,12 +554,15 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyHFError e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 9
|
pure $ ExitFailure 9
|
||||||
|
(CompileGHC GHCCompileOptions { hadrian = True, crossTarget = Just _ }) -> do
|
||||||
|
runLogger $ logError "Hadrian cross compile support is not yet implemented!"
|
||||||
|
pure $ ExitFailure 9
|
||||||
(CompileGHC GHCCompileOptions {..}) ->
|
(CompileGHC GHCCompileOptions {..}) ->
|
||||||
runCompileGHC runAppState (do
|
runCompileGHC runAppState (do
|
||||||
case targetGhc of
|
case targetGhc of
|
||||||
GHC.SourceDist targetVer -> do
|
GHC.SourceDist targetVer -> do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo (mkTVer targetVer) GHC dls
|
let vi = getVersionInfo targetVer GHC dls
|
||||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||||
lift $ logInfo msg
|
lift $ logInfo msg
|
||||||
lift $ logInfo
|
lift $ logInfo
|
||||||
@@ -568,8 +570,10 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||||
_ -> pure ()
|
_ -> pure ()
|
||||||
targetVer <- liftE $ compileGHC
|
targetVer <- liftE $ compileGHC
|
||||||
targetGhc
|
((\case
|
||||||
crossTarget
|
GHC.SourceDist v -> GHC.SourceDist $ GHCTargetVersion crossTarget v
|
||||||
|
GHC.GitDist g -> GHC.GitDist g
|
||||||
|
GHC.RemoteDist r -> GHC.RemoteDist r) targetGhc)
|
||||||
ovewrwiteVer
|
ovewrwiteVer
|
||||||
bootstrapGhc
|
bootstrapGhc
|
||||||
jobs
|
jobs
|
||||||
@@ -580,7 +584,7 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
|||||||
hadrian
|
hadrian
|
||||||
(maybe GHCupInternal IsolateDir isolateDir)
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo targetVer GHC dls
|
let vi = getVersionInfo (_tvVersion targetVer) GHC dls
|
||||||
when setCompile $ void $ liftE $
|
when setCompile $ void $ liftE $
|
||||||
setGHC targetVer SetGHCOnly Nothing
|
setGHC targetVer SetGHCOnly Nothing
|
||||||
pure (vi, targetVer)
|
pure (vi, targetVer)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ data ConfigCommand
|
|||||||
= ShowConfig
|
= ShowConfig
|
||||||
| SetConfig String (Maybe String)
|
| SetConfig String (Maybe String)
|
||||||
| InitConfig
|
| InitConfig
|
||||||
| AddReleaseChannel Bool URI
|
| AddReleaseChannel URI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ configP = subparser
|
|||||||
showP = info (pure ShowConfig) (progDesc "Show current config (default)")
|
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))
|
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"))
|
argsP = SetConfig <$> argument str (metavar "<JSON_VALUE | YAML_KEY>") <*> optional (argument str (metavar "YAML_VALUE"))
|
||||||
addP = info (AddReleaseChannel <$> switch (long "force" <> help "Delete existing entry (if any) and append instead of failing") <*> argument (eitherReader uriParser) (metavar "URI" <> completer fileUri))
|
addP = info (AddReleaseChannel <$> argument (eitherReader uriParser) (metavar "URI" <> completer fileUri))
|
||||||
(progDesc "Add a release channel from a URI")
|
(progDesc "Add a release channel from a URI")
|
||||||
|
|
||||||
|
|
||||||
@@ -120,38 +120,20 @@ formatConfig :: UserSettings -> String
|
|||||||
formatConfig = UTF8.toString . Y.encode
|
formatConfig = UTF8.toString . Y.encode
|
||||||
|
|
||||||
|
|
||||||
updateSettings :: UserSettings -> UserSettings -> UserSettings
|
updateSettings :: UserSettings -> Settings -> Settings
|
||||||
updateSettings usl usr =
|
updateSettings UserSettings{..} Settings{..} =
|
||||||
let cache' = uCache usl <|> uCache usr
|
let cache' = fromMaybe cache uCache
|
||||||
metaCache' = uMetaCache usl <|> uMetaCache usr
|
metaCache' = fromMaybe metaCache uMetaCache
|
||||||
metaMode' = uMetaMode usl <|> uMetaMode usr
|
metaMode' = fromMaybe metaMode uMetaMode
|
||||||
noVerify' = uNoVerify usl <|> uNoVerify usr
|
noVerify' = fromMaybe noVerify uNoVerify
|
||||||
verbose' = uVerbose usl <|> uVerbose usr
|
keepDirs' = fromMaybe keepDirs uKeepDirs
|
||||||
keepDirs' = uKeepDirs usl <|> uKeepDirs usr
|
downloader' = fromMaybe downloader uDownloader
|
||||||
downloader' = uDownloader usl <|> uDownloader usr
|
verbose' = fromMaybe verbose uVerbose
|
||||||
urlSource' = uUrlSource usl <|> uUrlSource usr
|
urlSource' = fromMaybe urlSource uUrlSource
|
||||||
noNetwork' = uNoNetwork usl <|> uNoNetwork usr
|
noNetwork' = fromMaybe noNetwork uNoNetwork
|
||||||
gpgSetting' = uGPGSetting usl <|> uGPGSetting usr
|
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
||||||
platformOverride' = uPlatformOverride usl <|> uPlatformOverride usr
|
platformOverride' = uPlatformOverride <|> platformOverride
|
||||||
mirrors' = uMirrors usl <|> uMirrors usr
|
in Settings cache' metaCache' metaMode' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor platformOverride'
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -159,9 +141,6 @@ updateSettings usl usr =
|
|||||||
--[ Entrypoint ]--
|
--[ 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
|
config :: forall m. ( Monad m
|
||||||
@@ -171,11 +150,10 @@ config :: forall m. ( Monad m
|
|||||||
)
|
)
|
||||||
=> ConfigCommand
|
=> ConfigCommand
|
||||||
-> Settings
|
-> Settings
|
||||||
-> UserSettings
|
|
||||||
-> KeyBindings
|
-> KeyBindings
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
config configCommand settings userConf keybindings runLogger = case configCommand of
|
config configCommand settings keybindings runLogger = case configCommand of
|
||||||
InitConfig -> do
|
InitConfig -> do
|
||||||
path <- getConfigFilePath
|
path <- getConfigFilePath
|
||||||
liftIO $ writeFile path $ formatConfig $ fromSettings settings (Just keybindings)
|
liftIO $ writeFile path $ formatConfig $ fromSettings settings (Just keybindings)
|
||||||
@@ -206,55 +184,27 @@ config configCommand settings userConf keybindings runLogger = case configComman
|
|||||||
pure $ ExitFailure 65
|
pure $ ExitFailure 65
|
||||||
VLeft _ -> pure $ ExitFailure 65
|
VLeft _ -> pure $ ExitFailure 65
|
||||||
|
|
||||||
AddReleaseChannel force uri -> do
|
AddReleaseChannel uri -> do
|
||||||
r <- runE @'[DuplicateReleaseChannel] $ do
|
case urlSource settings of
|
||||||
case urlSource settings of
|
AddSource xs -> do
|
||||||
AddSource xs -> do
|
doConfig (defaultUserSettings { uUrlSource = Just $ AddSource (xs <> [Right uri]) })
|
||||||
case checkDuplicate xs (Right uri) of
|
pure ExitSuccess
|
||||||
Duplicate
|
GHCupURL -> do
|
||||||
| not force -> throwE (DuplicateReleaseChannel uri)
|
doConfig (defaultUserSettings { uUrlSource = Just $ AddSource [Right uri] })
|
||||||
DuplicateLast -> pure ()
|
pure ExitSuccess
|
||||||
_ -> lift $ doConfig (defaultUserSettings { uUrlSource = Just $ AddSource (appendUnique xs (Right uri)) })
|
OwnSource xs -> do
|
||||||
GHCupURL -> do
|
doConfig (defaultUserSettings { uUrlSource = Just $ OwnSource (xs <> [Right uri]) })
|
||||||
lift $ doConfig (defaultUserSettings { uUrlSource = Just $ AddSource [Right uri] })
|
pure ExitSuccess
|
||||||
pure ()
|
OwnSpec spec -> do
|
||||||
OwnSource xs -> do
|
doConfig (defaultUserSettings { uUrlSource = Just $ OwnSource ([Left spec, Right uri]) })
|
||||||
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
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
|
||||||
runLogger $ logError $ T.pack $ prettyHFError e
|
|
||||||
pure $ ExitFailure 15
|
|
||||||
|
|
||||||
where
|
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 :: MonadIO m => UserSettings -> m ()
|
||||||
doConfig usersettings = do
|
doConfig usersettings = do
|
||||||
let settings' = updateSettings usersettings userConf
|
let settings' = updateSettings usersettings settings
|
||||||
path <- liftIO getConfigFilePath
|
path <- liftIO getConfigFilePath
|
||||||
liftIO $ writeFile path $ formatConfig $ settings'
|
liftIO $ writeFile path $ formatConfig $ fromSettings settings' (Just keybindings)
|
||||||
runLogger $ logDebug $ T.pack $ show settings'
|
runLogger $ logDebug $ T.pack $ show settings'
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ installOpts tool =
|
|||||||
<> completer (toolDlCompleter (fromMaybe GHC tool))
|
<> completer (toolDlCompleter (fromMaybe GHC tool))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> (Just <$> toolVersionTagArgument [] tool)
|
<*> (Just <$> toolVersionTagArgument Nothing tool)
|
||||||
)
|
)
|
||||||
<|> pure (Nothing, Nothing)
|
<|> pure (Nothing, Nothing)
|
||||||
)
|
)
|
||||||
@@ -241,7 +241,6 @@ type InstallEffects = '[ AlreadyInstalled
|
|||||||
, NotInstalled
|
, NotInstalled
|
||||||
, BuildFailed
|
, BuildFailed
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, DigestError
|
, DigestError
|
||||||
, ContentLengthError
|
, ContentLengthError
|
||||||
, GPGError
|
, GPGError
|
||||||
@@ -285,7 +284,6 @@ type InstallGHCEffects = '[ AlreadyInstalled
|
|||||||
, NotInstalled
|
, NotInstalled
|
||||||
, ProcessError
|
, ProcessError
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, TarDirDoesNotExist
|
, TarDirDoesNotExist
|
||||||
, UninstallFailed
|
, UninstallFailed
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
@@ -324,7 +322,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
Nothing -> runInstGHC s' $ do
|
Nothing -> runInstGHC s' $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||||
liftE $ runBothE' (installGHCBin
|
liftE $ runBothE' (installGHCBin
|
||||||
v
|
(_tvVersion v)
|
||||||
(maybe GHCupInternal IsolateDir isolateDir)
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
addConfArgs
|
addConfArgs
|
||||||
@@ -335,8 +333,8 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
runInstGHC s'{ settings = settings {noVerify = True}} $ do
|
runInstGHC s'{ settings = settings {noVerify = True}} $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||||
liftE $ runBothE' (installGHCBindist
|
liftE $ runBothE' (installGHCBindist
|
||||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing Nothing)
|
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing)
|
||||||
v
|
(_tvVersion v)
|
||||||
(maybe GHCupInternal IsolateDir isolateDir)
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
addConfArgs
|
addConfArgs
|
||||||
@@ -405,7 +403,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Cabal
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Cabal
|
||||||
liftE $ runBothE' (installCabalBindist
|
liftE $ runBothE' (installCabalBindist
|
||||||
(DownloadInfo uri Nothing "" Nothing Nothing)
|
(DownloadInfo uri Nothing "" Nothing)
|
||||||
v
|
v
|
||||||
(maybe GHCupInternal IsolateDir isolateDir)
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
@@ -455,7 +453,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer HLS
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer HLS
|
||||||
-- TODO: support legacy
|
-- TODO: support legacy
|
||||||
liftE $ runBothE' (installHLSBindist
|
liftE $ runBothE' (installHLSBindist
|
||||||
(DownloadInfo uri (if isWindows then Nothing else Just (RegexDir "haskell-language-server-*")) "" Nothing Nothing)
|
(DownloadInfo uri (if isWindows then Nothing else Just (RegexDir "haskell-language-server-*")) "" Nothing)
|
||||||
v
|
v
|
||||||
(maybe GHCupInternal IsolateDir isolateDir)
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
@@ -504,7 +502,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Stack
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Stack
|
||||||
liftE $ runBothE' (installStackBindist
|
liftE $ runBothE' (installStackBindist
|
||||||
(DownloadInfo uri Nothing "" Nothing Nothing)
|
(DownloadInfo uri Nothing "" Nothing)
|
||||||
v
|
v
|
||||||
(maybe GHCupInternal IsolateDir isolateDir)
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
{-# LANGUAGE RankNTypes #-}
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
|
||||||
@@ -13,9 +12,9 @@ module GHCup.OptParse.List where
|
|||||||
|
|
||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Prelude
|
import GHCup.Prelude
|
||||||
|
import GHCup.Prelude.Ansi
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.Prelude.String.QQ
|
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -26,7 +25,6 @@ import Data.Char
|
|||||||
import Data.List ( intercalate, sort )
|
import Data.List ( intercalate, sort )
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Time.Calendar ( Day )
|
|
||||||
import Data.Versions hiding ( str )
|
import Data.Versions hiding ( str )
|
||||||
import Data.Void
|
import Data.Void
|
||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
@@ -53,10 +51,6 @@ import qualified Text.Megaparsec.Char as MPC
|
|||||||
data ListOptions = ListOptions
|
data ListOptions = ListOptions
|
||||||
{ loTool :: Maybe Tool
|
{ loTool :: Maybe Tool
|
||||||
, lCriteria :: Maybe ListCriteria
|
, lCriteria :: Maybe ListCriteria
|
||||||
, lFrom :: Maybe Day
|
|
||||||
, lTo :: Maybe Day
|
|
||||||
, lHideOld :: Bool
|
|
||||||
, lShowNightly :: Bool
|
|
||||||
, lRawFormat :: Bool
|
, lRawFormat :: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,6 +61,7 @@ data ListOptions = ListOptions
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
listOpts :: Parser ListOptions
|
listOpts :: Parser ListOptions
|
||||||
listOpts =
|
listOpts =
|
||||||
ListOptions
|
ListOptions
|
||||||
@@ -75,7 +70,7 @@ listOpts =
|
|||||||
(eitherReader toolParser)
|
(eitherReader toolParser)
|
||||||
(short 't' <> long "tool" <> metavar "<ghc|cabal|hls|stack>" <> help
|
(short 't' <> long "tool" <> metavar "<ghc|cabal|hls|stack>" <> help
|
||||||
"Tool to list versions for. Default is all"
|
"Tool to list versions for. Default is all"
|
||||||
<> completer toolCompleter
|
<> completer (toolCompleter)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -84,53 +79,15 @@ listOpts =
|
|||||||
( short 'c'
|
( short 'c'
|
||||||
<> long "show-criteria"
|
<> long "show-criteria"
|
||||||
<> metavar "<installed|set|available>"
|
<> metavar "<installed|set|available>"
|
||||||
<> help "Apply filtering criteria, prefix with + or -"
|
<> help "Show only installed/set/available tool versions"
|
||||||
<> completer (listCompleter
|
<> completer (listCompleter ["installed", "set", "available"])
|
||||||
[ "+installed", "+set", "+available", "-installed", "-set", "-available"])
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
|
||||||
(option
|
|
||||||
(eitherReader dayParser)
|
|
||||||
(short 's' <> long "since" <> metavar "YYYY-MM-DD" <> help
|
|
||||||
"List only tools with release date starting at YYYY-MM-DD or later"
|
|
||||||
<> completer toolCompleter
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<*> optional
|
|
||||||
(option
|
|
||||||
(eitherReader dayParser)
|
|
||||||
(short 'u' <> long "until" <> metavar "YYYY-MM-DD" <> help
|
|
||||||
"List only tools with release date earlier than YYYY-MM-DD"
|
|
||||||
<> completer toolCompleter
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<*> switch
|
|
||||||
(short 'o' <> long "hide-old" <> help "Hide 'old' GHC versions (installed ones are always shown)"
|
|
||||||
)
|
|
||||||
<*> switch
|
|
||||||
(short 'n' <> long "show-nightly" <> help "Show nightlies (installed ones are always shown)"
|
|
||||||
)
|
|
||||||
<*> switch
|
<*> switch
|
||||||
(short 'r' <> long "raw-format" <> help "More machine-parsable format"
|
(short 'r' <> long "raw-format" <> help "More machine-parsable format"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
--------------
|
|
||||||
--[ Footer ]--
|
|
||||||
--------------
|
|
||||||
|
|
||||||
|
|
||||||
listToolFooter :: String
|
|
||||||
listToolFooter = [s|Discussion:
|
|
||||||
Lists tool versions with optional criteria.
|
|
||||||
Nightlies are by default hidden.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
# query nightlies in a specific range
|
|
||||||
ghcup list --show-nightly --since 2022-12-07 --until 2022-12-31
|
|
||||||
# show all installed GHC versions
|
|
||||||
ghcup list -t ghc -c installed|]
|
|
||||||
|
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
@@ -149,11 +106,8 @@ printListResult no_color raw lr = do
|
|||||||
printTag Recommended = color Green "recommended"
|
printTag Recommended = color Green "recommended"
|
||||||
printTag Latest = color Yellow "latest"
|
printTag Latest = color Yellow "latest"
|
||||||
printTag Prerelease = color Red "prerelease"
|
printTag Prerelease = color Red "prerelease"
|
||||||
printTag Nightly = color Red "nightly"
|
|
||||||
printTag (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
|
printTag (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
|
||||||
printTag (UnknownTag t ) = t
|
printTag (UnknownTag t ) = t
|
||||||
printTag LatestPrerelease = color Red "latest-prerelease"
|
|
||||||
printTag LatestNightly = color Red "latest-nightly"
|
|
||||||
printTag Old = ""
|
printTag Old = ""
|
||||||
|
|
||||||
let
|
let
|
||||||
@@ -182,9 +136,6 @@ printListResult no_color raw lr = do
|
|||||||
)
|
)
|
||||||
++ (if fromSrc then [color Blue "compiled"] else mempty)
|
++ (if fromSrc then [color Blue "compiled"] else mempty)
|
||||||
++ (if lStray then [color Yellow "stray"] else mempty)
|
++ (if lStray then [color Yellow "stray"] else mempty)
|
||||||
++ (case lReleaseDay of
|
|
||||||
Nothing -> mempty
|
|
||||||
Just d -> [color Blue (show d)])
|
|
||||||
++ (if lNoBindist
|
++ (if lNoBindist
|
||||||
then [color Red "no-bindist"]
|
then [color Red "no-bindist"]
|
||||||
else mempty
|
else mempty
|
||||||
@@ -205,89 +156,6 @@ printListResult no_color raw lr = do
|
|||||||
add' = x - lstr
|
add' = x - lstr
|
||||||
in if add' < 0 then str' else str' ++ replicate add' ' '
|
in if add' < 0 then str' else str' ++ replicate add' ' '
|
||||||
|
|
||||||
-- | Calculate the render width of a string, considering
|
|
||||||
-- wide characters (counted as double width), ANSI escape codes
|
|
||||||
-- (not counted), and line breaks (in a multi-line string, the longest
|
|
||||||
-- line determines the width).
|
|
||||||
strWidth :: String -> Int
|
|
||||||
strWidth =
|
|
||||||
maximum
|
|
||||||
. (0 :)
|
|
||||||
. map (foldr (\a b -> charWidth a + b) 0)
|
|
||||||
. lines
|
|
||||||
. stripAnsi
|
|
||||||
|
|
||||||
-- | Strip ANSI escape sequences from a string.
|
|
||||||
--
|
|
||||||
-- >>> stripAnsi "\ESC[31m-1\ESC[m"
|
|
||||||
-- "-1"
|
|
||||||
stripAnsi :: String -> String
|
|
||||||
stripAnsi s' =
|
|
||||||
case
|
|
||||||
MP.parseMaybe (many $ "" <$ MP.try ansi <|> pure <$> MP.anySingle) s'
|
|
||||||
of
|
|
||||||
Nothing -> error "Bad ansi escape" -- PARTIAL: should not happen
|
|
||||||
Just xs -> concat xs
|
|
||||||
where
|
|
||||||
-- This parses lots of invalid ANSI escape codes, but that should be fine
|
|
||||||
ansi =
|
|
||||||
MPC.string "\ESC[" *> digitSemicolons *> suffix MP.<?> "ansi" :: MP.Parsec
|
|
||||||
Void
|
|
||||||
String
|
|
||||||
Char
|
|
||||||
digitSemicolons = MP.takeWhileP Nothing (\c -> isDigit c || c == ';')
|
|
||||||
suffix = MP.oneOf ['A', 'B', 'C', 'D', 'H', 'J', 'K', 'f', 'm', 's', 'u']
|
|
||||||
|
|
||||||
-- | Get the designated render width of a character: 0 for a combining
|
|
||||||
-- character, 1 for a regular character, 2 for a wide character.
|
|
||||||
-- (Wide characters are rendered as exactly double width in apps and
|
|
||||||
-- fonts that support it.) (From Pandoc.)
|
|
||||||
charWidth :: Char -> Int
|
|
||||||
charWidth c = case c of
|
|
||||||
_ | c < '\x0300' -> 1
|
|
||||||
| c >= '\x0300' && c <= '\x036F' -> 0
|
|
||||||
| -- combining
|
|
||||||
c >= '\x0370' && c <= '\x10FC' -> 1
|
|
||||||
| c >= '\x1100' && c <= '\x115F' -> 2
|
|
||||||
| c >= '\x1160' && c <= '\x11A2' -> 1
|
|
||||||
| c >= '\x11A3' && c <= '\x11A7' -> 2
|
|
||||||
| c >= '\x11A8' && c <= '\x11F9' -> 1
|
|
||||||
| c >= '\x11FA' && c <= '\x11FF' -> 2
|
|
||||||
| c >= '\x1200' && c <= '\x2328' -> 1
|
|
||||||
| c >= '\x2329' && c <= '\x232A' -> 2
|
|
||||||
| c >= '\x232B' && c <= '\x2E31' -> 1
|
|
||||||
| c >= '\x2E80' && c <= '\x303E' -> 2
|
|
||||||
| c == '\x303F' -> 1
|
|
||||||
| c >= '\x3041' && c <= '\x3247' -> 2
|
|
||||||
| c >= '\x3248' && c <= '\x324F' -> 1
|
|
||||||
| -- ambiguous
|
|
||||||
c >= '\x3250' && c <= '\x4DBF' -> 2
|
|
||||||
| c >= '\x4DC0' && c <= '\x4DFF' -> 1
|
|
||||||
| c >= '\x4E00' && c <= '\xA4C6' -> 2
|
|
||||||
| c >= '\xA4D0' && c <= '\xA95F' -> 1
|
|
||||||
| c >= '\xA960' && c <= '\xA97C' -> 2
|
|
||||||
| c >= '\xA980' && c <= '\xABF9' -> 1
|
|
||||||
| c >= '\xAC00' && c <= '\xD7FB' -> 2
|
|
||||||
| c >= '\xD800' && c <= '\xDFFF' -> 1
|
|
||||||
| c >= '\xE000' && c <= '\xF8FF' -> 1
|
|
||||||
| -- ambiguous
|
|
||||||
c >= '\xF900' && c <= '\xFAFF' -> 2
|
|
||||||
| c >= '\xFB00' && c <= '\xFDFD' -> 1
|
|
||||||
| c >= '\xFE00' && c <= '\xFE0F' -> 1
|
|
||||||
| -- ambiguous
|
|
||||||
c >= '\xFE10' && c <= '\xFE19' -> 2
|
|
||||||
| c >= '\xFE20' && c <= '\xFE26' -> 1
|
|
||||||
| c >= '\xFE30' && c <= '\xFE6B' -> 2
|
|
||||||
| c >= '\xFE70' && c <= '\xFEFF' -> 1
|
|
||||||
| c >= '\xFF01' && c <= '\xFF60' -> 2
|
|
||||||
| c >= '\xFF61' && c <= '\x16A38' -> 1
|
|
||||||
| c >= '\x1B000' && c <= '\x1B001' -> 2
|
|
||||||
| c >= '\x1D000' && c <= '\x1F1FF' -> 1
|
|
||||||
| c >= '\x1F200' && c <= '\x1F251' -> 2
|
|
||||||
| c >= '\x1F300' && c <= '\x1F773' -> 1
|
|
||||||
| c >= '\x20000' && c <= '\x3FFFD' -> 2
|
|
||||||
| otherwise -> 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -309,7 +177,7 @@ list :: ( Monad m
|
|||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
list ListOptions{..} no_color runAppState =
|
list ListOptions{..} no_color runAppState =
|
||||||
runAppState (do
|
runAppState (do
|
||||||
l <- listVersions loTool (maybeToList lCriteria) lHideOld lShowNightly (lFrom, lTo)
|
l <- listVersions loTool lCriteria
|
||||||
liftIO $ printListResult no_color lRawFormat l
|
liftIO $ printListResult no_color lRawFormat l
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ nuke appState runLogger = do
|
|||||||
|
|
||||||
lift $ logInfo "Initiating Nuclear Sequence 🚀🚀🚀"
|
lift $ logInfo "Initiating Nuclear Sequence 🚀🚀🚀"
|
||||||
lift $ logInfo "Nuking in 3...2...1"
|
lift $ logInfo "Nuking in 3...2...1"
|
||||||
|
|
||||||
lInstalled <- lift $ listVersions Nothing [ListInstalled True] False True (Nothing, Nothing)
|
lInstalled <- lift $ listVersions Nothing (Just ListInstalled)
|
||||||
|
|
||||||
forM_ lInstalled (liftE . rmTool)
|
forM_ lInstalled (liftE . rmTool)
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ prefetchP = subparser
|
|||||||
<$> (PrefetchGHCOptions
|
<$> (PrefetchGHCOptions
|
||||||
<$> ( switch (short 's' <> long "source" <> help "Download source tarball instead of bindist") <**> helper )
|
<$> ( switch (short 's' <> long "source" <> help "Download source tarball instead of bindist") <**> helper )
|
||||||
<*> optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
<*> optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||||
<*> optional (toolVersionTagArgument [] (Just GHC)) )
|
<*> optional (toolVersionTagArgument Nothing (Just GHC)) )
|
||||||
( progDesc "Download GHC assets for installation")
|
( progDesc "Download GHC assets for installation")
|
||||||
)
|
)
|
||||||
<>
|
<>
|
||||||
@@ -92,7 +92,7 @@ prefetchP = subparser
|
|||||||
(info
|
(info
|
||||||
(PrefetchCabal
|
(PrefetchCabal
|
||||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||||
<*> ( optional (toolVersionTagArgument [] (Just Cabal)) <**> helper ))
|
<*> ( optional (toolVersionTagArgument Nothing (Just Cabal)) <**> helper ))
|
||||||
( progDesc "Download cabal assets for installation")
|
( progDesc "Download cabal assets for installation")
|
||||||
)
|
)
|
||||||
<>
|
<>
|
||||||
@@ -101,7 +101,7 @@ prefetchP = subparser
|
|||||||
(info
|
(info
|
||||||
(PrefetchHLS
|
(PrefetchHLS
|
||||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||||
<*> ( optional (toolVersionTagArgument [] (Just HLS)) <**> helper ))
|
<*> ( optional (toolVersionTagArgument Nothing (Just HLS)) <**> helper ))
|
||||||
( progDesc "Download HLS assets for installation")
|
( progDesc "Download HLS assets for installation")
|
||||||
)
|
)
|
||||||
<>
|
<>
|
||||||
@@ -110,7 +110,7 @@ prefetchP = subparser
|
|||||||
(info
|
(info
|
||||||
(PrefetchStack
|
(PrefetchStack
|
||||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||||
<*> ( optional (toolVersionTagArgument [] (Just Stack)) <**> helper ))
|
<*> ( optional (toolVersionTagArgument Nothing (Just Stack)) <**> helper ))
|
||||||
( progDesc "Download stack assets for installation")
|
( progDesc "Download stack assets for installation")
|
||||||
)
|
)
|
||||||
<>
|
<>
|
||||||
@@ -148,7 +148,6 @@ Examples:
|
|||||||
|
|
||||||
|
|
||||||
type PrefetchEffects = '[ TagNotFound
|
type PrefetchEffects = '[ TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
, NoDownload
|
, NoDownload
|
||||||
@@ -195,7 +194,7 @@ prefetch prefetchCommand runAppState runLogger =
|
|||||||
forM_ pfCacheDir (liftIO . createDirRecursive')
|
forM_ pfCacheDir (liftIO . createDirRecursive')
|
||||||
(v, _) <- liftE $ fromVersion mt GHC
|
(v, _) <- liftE $ fromVersion mt GHC
|
||||||
if pfGHCSrc
|
if pfGHCSrc
|
||||||
then liftE $ fetchGHCSrc v pfCacheDir
|
then liftE $ fetchGHCSrc (_tvVersion v) pfCacheDir
|
||||||
else liftE $ fetchToolBindist (_tvVersion v) GHC pfCacheDir
|
else liftE $ fetchToolBindist (_tvVersion v) GHC pfCacheDir
|
||||||
PrefetchCabal PrefetchOptions {pfCacheDir} mt -> do
|
PrefetchCabal PrefetchOptions {pfCacheDir} mt -> do
|
||||||
forM_ pfCacheDir (liftIO . createDirRecursive')
|
forM_ pfCacheDir (liftIO . createDirRecursive')
|
||||||
|
|||||||
@@ -80,19 +80,19 @@ rmParser =
|
|||||||
<> command
|
<> command
|
||||||
"cabal"
|
"cabal"
|
||||||
( RmCabal
|
( RmCabal
|
||||||
<$> info (versionParser' [ListInstalled True] (Just Cabal) <**> helper)
|
<$> info (versionParser' (Just ListInstalled) (Just Cabal) <**> helper)
|
||||||
(progDesc "Remove Cabal version")
|
(progDesc "Remove Cabal version")
|
||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
"hls"
|
"hls"
|
||||||
( RmHLS
|
( RmHLS
|
||||||
<$> info (versionParser' [ListInstalled True] (Just HLS) <**> helper)
|
<$> info (versionParser' (Just ListInstalled) (Just HLS) <**> helper)
|
||||||
(progDesc "Remove haskell-language-server version")
|
(progDesc "Remove haskell-language-server version")
|
||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
"stack"
|
"stack"
|
||||||
( RmStack
|
( RmStack
|
||||||
<$> info (versionParser' [ListInstalled True] (Just Stack) <**> helper)
|
<$> info (versionParser' (Just ListInstalled) (Just Stack) <**> helper)
|
||||||
(progDesc "Remove stack version")
|
(progDesc "Remove stack version")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -102,7 +102,7 @@ rmParser =
|
|||||||
|
|
||||||
|
|
||||||
rmOpts :: Maybe Tool -> Parser RmOptions
|
rmOpts :: Maybe Tool -> Parser RmOptions
|
||||||
rmOpts tool = RmOptions <$> ghcVersionArgument [ListInstalled True] tool
|
rmOpts tool = RmOptions <$> ghcVersionArgument (Just ListInstalled) tool
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
|||||||
liftE $
|
liftE $
|
||||||
rmGHCVer ghcVer
|
rmGHCVer ghcVer
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
pure (getVersionInfo ghcVer GHC dls)
|
pure (getVersionInfo (_tvVersion ghcVer) GHC dls)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
@@ -186,7 +186,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
|||||||
liftE $
|
liftE $
|
||||||
rmCabalVer tv
|
rmCabalVer tv
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
pure (getVersionInfo (mkTVer tv) Cabal dls)
|
pure (getVersionInfo tv Cabal dls)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
@@ -201,7 +201,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
|||||||
liftE $
|
liftE $
|
||||||
rmHLSVer tv
|
rmHLSVer tv
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
pure (getVersionInfo (mkTVer tv) HLS dls)
|
pure (getVersionInfo tv HLS dls)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
@@ -216,7 +216,7 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
|||||||
liftE $
|
liftE $
|
||||||
rmStackVer tv
|
rmStackVer tv
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
pure (getVersionInfo (mkTVer tv) Stack dls)
|
pure (getVersionInfo tv Stack dls)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ runOpts =
|
|||||||
(eitherReader ghcVersionTagEither)
|
(eitherReader ghcVersionTagEither)
|
||||||
(metavar "GHC_VERSION" <> long "ghc" <> help "The ghc version"
|
(metavar "GHC_VERSION" <> long "ghc" <> help "The ghc version"
|
||||||
<> completer (tagCompleter GHC [])
|
<> completer (tagCompleter GHC [])
|
||||||
<> (completer $ versionCompleter [] GHC)
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -100,7 +100,7 @@ runOpts =
|
|||||||
(eitherReader toolVersionTagEither)
|
(eitherReader toolVersionTagEither)
|
||||||
(metavar "CABAL_VERSION" <> long "cabal" <> help "The cabal version"
|
(metavar "CABAL_VERSION" <> long "cabal" <> help "The cabal version"
|
||||||
<> completer (tagCompleter Cabal [])
|
<> completer (tagCompleter Cabal [])
|
||||||
<> (completer $ versionCompleter [] Cabal)
|
<> (completer $ versionCompleter Nothing Cabal)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -108,7 +108,7 @@ runOpts =
|
|||||||
(eitherReader toolVersionTagEither)
|
(eitherReader toolVersionTagEither)
|
||||||
(metavar "HLS_VERSION" <> long "hls" <> help "The HLS version"
|
(metavar "HLS_VERSION" <> long "hls" <> help "The HLS version"
|
||||||
<> completer (tagCompleter HLS [])
|
<> completer (tagCompleter HLS [])
|
||||||
<> (completer $ versionCompleter [] HLS)
|
<> (completer $ versionCompleter Nothing HLS)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -116,7 +116,7 @@ runOpts =
|
|||||||
(eitherReader toolVersionTagEither)
|
(eitherReader toolVersionTagEither)
|
||||||
(metavar "STACK_VERSION" <> long "stack" <> help "The stack version"
|
(metavar "STACK_VERSION" <> long "stack" <> help "The stack version"
|
||||||
<> completer (tagCompleter Stack [])
|
<> completer (tagCompleter Stack [])
|
||||||
<> (completer $ versionCompleter [] Stack)
|
<> (completer $ versionCompleter Nothing Stack)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -132,7 +132,7 @@ runOpts =
|
|||||||
<*> switch
|
<*> switch
|
||||||
(short 'q' <> long "quick" <> help "Avoid any expensive work (such as downloads, version/tag resolution etc.). Disables --install.")
|
(short 'q' <> long "quick" <> help "Avoid any expensive work (such as downloads, version/tag resolution etc.). Disables --install.")
|
||||||
<*> many (argument str (metavar "COMMAND" <> help "The command to run, with arguments (use longopts --). If omitted, just prints the created bin/ dir to stdout and exits."))
|
<*> many (argument str (metavar "COMMAND" <> help "The command to run, with arguments (use longopts --). If omitted, just prints the created bin/ dir to stdout and exits."))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -175,7 +175,6 @@ type RunEffects = '[ AlreadyInstalled
|
|||||||
, NotInstalled
|
, NotInstalled
|
||||||
, BuildFailed
|
, BuildFailed
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, DigestError
|
, DigestError
|
||||||
, ContentLengthError
|
, ContentLengthError
|
||||||
, GPGError
|
, GPGError
|
||||||
@@ -255,7 +254,7 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
|||||||
liftIO $ putStr tmp
|
liftIO $ putStr tmp
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
(cmd:args) -> do
|
(cmd:args) -> do
|
||||||
newEnv <- liftIO $ addToPath tmp runAppendPATH
|
newEnv <- liftIO $ addToPath tmp
|
||||||
#ifndef IS_WINDOWS
|
#ifndef IS_WINDOWS
|
||||||
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
@@ -283,7 +282,6 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
|||||||
)
|
)
|
||||||
=> Excepts
|
=> Excepts
|
||||||
'[ TagNotFound
|
'[ TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
] (ResourceT (ReaderT AppState m)) Toolchain
|
] (ResourceT (ReaderT AppState m)) Toolchain
|
||||||
@@ -334,7 +332,6 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
|||||||
-> FilePath
|
-> FilePath
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ TagNotFound
|
'[ TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
@@ -360,7 +357,7 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
|||||||
Just v -> do
|
Just v -> do
|
||||||
isInstalled <- lift $ checkIfToolInstalled' GHC v
|
isInstalled <- lift $ checkIfToolInstalled' GHC v
|
||||||
unless isInstalled $ when (runInstTool' && isNothing (_tvTarget v)) $ void $ liftE $ installGHCBin
|
unless isInstalled $ when (runInstTool' && isNothing (_tvTarget v)) $ void $ liftE $ installGHCBin
|
||||||
v
|
(_tvVersion v)
|
||||||
GHCupInternal
|
GHCupInternal
|
||||||
False
|
False
|
||||||
[]
|
[]
|
||||||
@@ -444,6 +441,17 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
|||||||
liftE $ setHLS v SetHLS_XYZ (Just tmp)
|
liftE $ setHLS v SetHLS_XYZ (Just tmp)
|
||||||
liftE $ setHLS v SetHLSOnly (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
|
createTmpDir :: ( MonadUnliftIO m
|
||||||
, MonadCatch m
|
, MonadCatch m
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
|
|||||||
@@ -139,9 +139,9 @@ setParser =
|
|||||||
setOpts :: Tool -> Parser SetOptions
|
setOpts :: Tool -> Parser SetOptions
|
||||||
setOpts tool = SetOptions <$>
|
setOpts tool = SetOptions <$>
|
||||||
(fromMaybe SetRecommended <$>
|
(fromMaybe SetRecommended <$>
|
||||||
optional (setVersionArgument [ListInstalled True] tool))
|
optional (setVersionArgument (Just ListInstalled) tool))
|
||||||
|
|
||||||
setVersionArgument :: [ListCriteria] -> Tool -> Parser SetToolVersion
|
setVersionArgument :: Maybe ListCriteria -> Tool -> Parser SetToolVersion
|
||||||
setVersionArgument criteria tool =
|
setVersionArgument criteria tool =
|
||||||
argument (eitherReader setEither)
|
argument (eitherReader setEither)
|
||||||
(metavar "VERSION|TAG|next"
|
(metavar "VERSION|TAG|next"
|
||||||
@@ -184,7 +184,6 @@ setFooter = [s|Discussion:
|
|||||||
type SetGHCEffects = '[ FileDoesNotExistError
|
type SetGHCEffects = '[ FileDoesNotExistError
|
||||||
, NotInstalled
|
, NotInstalled
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet]
|
, NoToolVersionSet]
|
||||||
|
|
||||||
@@ -199,7 +198,6 @@ runSetGHC runAppState =
|
|||||||
|
|
||||||
type SetCabalEffects = '[ NotInstalled
|
type SetCabalEffects = '[ NotInstalled
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet]
|
, NoToolVersionSet]
|
||||||
|
|
||||||
@@ -214,7 +212,6 @@ runSetCabal runAppState =
|
|||||||
|
|
||||||
type SetHLSEffects = '[ NotInstalled
|
type SetHLSEffects = '[ NotInstalled
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet]
|
, NoToolVersionSet]
|
||||||
|
|
||||||
@@ -229,7 +226,6 @@ runSetHLS runAppState =
|
|||||||
|
|
||||||
type SetStackEffects = '[ NotInstalled
|
type SetStackEffects = '[ NotInstalled
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet]
|
, NoToolVersionSet]
|
||||||
|
|
||||||
@@ -263,7 +259,7 @@ set :: forall m env.
|
|||||||
-> m (VEither eff GHCTargetVersion))
|
-> m (VEither eff GHCTargetVersion))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
set setCommand runAppState _ runLogger = case setCommand of
|
set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
||||||
(Right sopts) -> do
|
(Right sopts) -> do
|
||||||
runLogger (logWarn "This is an old-style command for setting GHC. Use 'ghcup set ghc' instead.")
|
runLogger (logWarn "This is an old-style command for setting GHC. Use 'ghcup set ghc' instead.")
|
||||||
setGHC' sopts
|
setGHC' sopts
|
||||||
@@ -275,7 +271,10 @@ set setCommand runAppState _ runLogger = case setCommand of
|
|||||||
where
|
where
|
||||||
setGHC' :: SetOptions
|
setGHC' :: SetOptions
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setGHC' SetOptions{ sToolVer } = runSetGHC runAppState (do
|
setGHC' SetOptions{ sToolVer } =
|
||||||
|
case sToolVer of
|
||||||
|
(SetGHCVersion v) -> runSetGHC runLeanAppState (liftE $ setGHC v SetGHCOnly Nothing >> pure v)
|
||||||
|
_ -> runSetGHC runAppState (do
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer GHC
|
v <- liftE $ fst <$> fromVersion' sToolVer GHC
|
||||||
liftE $ setGHC v SetGHCOnly Nothing
|
liftE $ setGHC v SetGHCOnly Nothing
|
||||||
)
|
)
|
||||||
@@ -292,7 +291,10 @@ set setCommand runAppState _ runLogger = case setCommand of
|
|||||||
|
|
||||||
setCabal' :: SetOptions
|
setCabal' :: SetOptions
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setCabal' SetOptions{ sToolVer } = runSetCabal runAppState (do
|
setCabal' SetOptions{ sToolVer } =
|
||||||
|
case sToolVer of
|
||||||
|
(SetToolVersion v) -> runSetCabal runLeanAppState (liftE $ setCabal v >> pure (mkTVer v))
|
||||||
|
_ -> runSetCabal runAppState (do
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer Cabal
|
v <- liftE $ fst <$> fromVersion' sToolVer Cabal
|
||||||
liftE $ setCabal (_tvVersion v)
|
liftE $ setCabal (_tvVersion v)
|
||||||
pure v
|
pure v
|
||||||
@@ -309,7 +311,10 @@ set setCommand runAppState _ runLogger = case setCommand of
|
|||||||
|
|
||||||
setHLS' :: SetOptions
|
setHLS' :: SetOptions
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setHLS' SetOptions{ sToolVer } = runSetHLS runAppState (do
|
setHLS' SetOptions{ sToolVer } =
|
||||||
|
case sToolVer of
|
||||||
|
(SetToolVersion v) -> runSetHLS runLeanAppState (liftE $ setHLS v SetHLSOnly Nothing >> pure (mkTVer v))
|
||||||
|
_ -> runSetHLS runAppState (do
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer HLS
|
v <- liftE $ fst <$> fromVersion' sToolVer HLS
|
||||||
liftE $ setHLS (_tvVersion v) SetHLSOnly Nothing
|
liftE $ setHLS (_tvVersion v) SetHLSOnly Nothing
|
||||||
pure v
|
pure v
|
||||||
@@ -327,7 +332,10 @@ set setCommand runAppState _ runLogger = case setCommand of
|
|||||||
|
|
||||||
setStack' :: SetOptions
|
setStack' :: SetOptions
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setStack' SetOptions{ sToolVer } = runSetStack runAppState (do
|
setStack' SetOptions{ sToolVer } =
|
||||||
|
case sToolVer of
|
||||||
|
(SetToolVersion v) -> runSetStack runLeanAppState (liftE $ setStack v >> pure (mkTVer v))
|
||||||
|
_ -> runSetStack runAppState (do
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer Stack
|
v <- liftE $ fst <$> fromVersion' sToolVer Stack
|
||||||
liftE $ setStack (_tvVersion v)
|
liftE $ setStack (_tvVersion v)
|
||||||
pure v
|
pure v
|
||||||
|
|||||||
@@ -1,189 +0,0 @@
|
|||||||
{-# 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 [] tool)
|
|
||||||
)
|
|
||||||
<|> pure (Nothing, Nothing)
|
|
||||||
)
|
|
||||||
<*> many (argument str (metavar "MAKE_ARGS" <> help "Additional arguments to 'make', prefix with '-- ' (longopts)"))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------
|
|
||||||
--[ Effect interpreters ]--
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
|
|
||||||
type TestGHCEffects = [ DigestError
|
|
||||||
, ContentLengthError
|
|
||||||
, GPGError
|
|
||||||
, DownloadFailed
|
|
||||||
, NoDownload
|
|
||||||
, ArchiveResult
|
|
||||||
, TarDirDoesNotExist
|
|
||||||
, UnknownArchive
|
|
||||||
, TestFailed
|
|
||||||
, NextVerNotFound
|
|
||||||
, TagNotFound
|
|
||||||
, DayNotFound
|
|
||||||
, NoToolVersionSet
|
|
||||||
]
|
|
||||||
|
|
||||||
runTestGHC :: AppState
|
|
||||||
-> Excepts TestGHCEffects (ResourceT (ReaderT AppState IO)) a
|
|
||||||
-> IO (VEither TestGHCEffects a)
|
|
||||||
runTestGHC appstate' =
|
|
||||||
flip runReaderT appstate'
|
|
||||||
. runResourceT
|
|
||||||
. runE
|
|
||||||
@TestGHCEffects
|
|
||||||
|
|
||||||
|
|
||||||
-------------------
|
|
||||||
--[ Entrypoints ]--
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
|
|
||||||
test :: TestCommand -> Settings -> IO AppState -> (ReaderT LeanAppState IO () -> IO ()) -> IO ExitCode
|
|
||||||
test testCommand settings getAppState' runLogger = case testCommand of
|
|
||||||
(TestGHC iopts) -> go iopts
|
|
||||||
where
|
|
||||||
go :: TestOptions -> IO ExitCode
|
|
||||||
go TestOptions{..} = do
|
|
||||||
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
|
||||||
(case testBindist of
|
|
||||||
Nothing -> runTestGHC s' $ do
|
|
||||||
(v, vi) <- liftE $ fromVersion testVer GHC
|
|
||||||
liftE $ testGHCVer v addMakeArgs
|
|
||||||
pure vi
|
|
||||||
Just uri -> do
|
|
||||||
runTestGHC s'{ settings = settings {noVerify = True}} $ do
|
|
||||||
(v, vi) <- liftE $ fromVersion testVer GHC
|
|
||||||
liftE $ testGHCBindist (DownloadInfo uri (Just $ RegexDir ".*/.*") "" Nothing Nothing) v addMakeArgs
|
|
||||||
pure vi
|
|
||||||
)
|
|
||||||
>>= \case
|
|
||||||
VRight _ -> do
|
|
||||||
runLogger $ logInfo "GHC test successful"
|
|
||||||
pure ExitSuccess
|
|
||||||
VLeft e -> do
|
|
||||||
runLogger $ do
|
|
||||||
logError $ T.pack $ prettyHFError e
|
|
||||||
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
|
||||||
pure $ ExitFailure 3
|
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ whereisP = subparser
|
|||||||
command
|
command
|
||||||
"ghc"
|
"ghc"
|
||||||
(WhereisTool GHC <$> info
|
(WhereisTool GHC <$> info
|
||||||
( optional (toolVersionTagArgument [] (Just GHC)) <**> helper )
|
( optional (toolVersionTagArgument Nothing (Just GHC)) <**> helper )
|
||||||
( progDesc "Get GHC location"
|
( progDesc "Get GHC location"
|
||||||
<> footerDoc (Just $ text whereisGHCFooter ))
|
<> footerDoc (Just $ text whereisGHCFooter ))
|
||||||
)
|
)
|
||||||
@@ -90,7 +90,7 @@ whereisP = subparser
|
|||||||
command
|
command
|
||||||
"cabal"
|
"cabal"
|
||||||
(WhereisTool Cabal <$> info
|
(WhereisTool Cabal <$> info
|
||||||
( optional (toolVersionTagArgument [] (Just Cabal)) <**> helper )
|
( optional (toolVersionTagArgument Nothing (Just Cabal)) <**> helper )
|
||||||
( progDesc "Get cabal location"
|
( progDesc "Get cabal location"
|
||||||
<> footerDoc (Just $ text whereisCabalFooter ))
|
<> footerDoc (Just $ text whereisCabalFooter ))
|
||||||
)
|
)
|
||||||
@@ -98,7 +98,7 @@ whereisP = subparser
|
|||||||
command
|
command
|
||||||
"hls"
|
"hls"
|
||||||
(WhereisTool HLS <$> info
|
(WhereisTool HLS <$> info
|
||||||
( optional (toolVersionTagArgument [] (Just HLS)) <**> helper )
|
( optional (toolVersionTagArgument Nothing (Just HLS)) <**> helper )
|
||||||
( progDesc "Get HLS location"
|
( progDesc "Get HLS location"
|
||||||
<> footerDoc (Just $ text whereisHLSFooter ))
|
<> footerDoc (Just $ text whereisHLSFooter ))
|
||||||
)
|
)
|
||||||
@@ -106,7 +106,7 @@ whereisP = subparser
|
|||||||
command
|
command
|
||||||
"stack"
|
"stack"
|
||||||
(WhereisTool Stack <$> info
|
(WhereisTool Stack <$> info
|
||||||
( optional (toolVersionTagArgument [] (Just Stack)) <**> helper )
|
( optional (toolVersionTagArgument Nothing (Just Stack)) <**> helper )
|
||||||
( progDesc "Get stack location"
|
( progDesc "Get stack location"
|
||||||
<> footerDoc (Just $ text whereisStackFooter ))
|
<> footerDoc (Just $ text whereisStackFooter ))
|
||||||
)
|
)
|
||||||
@@ -222,7 +222,6 @@ type WhereisEffects = '[ NotInstalled
|
|||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DayNotFound
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ module Main where
|
|||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
import BrickMain ( brickMain )
|
import BrickMain ( brickMain )
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(ANSI)
|
||||||
|
import AnsiMain ( ansiMain )
|
||||||
|
#endif
|
||||||
|
|
||||||
import qualified GHCup.GHC as GHC
|
import qualified GHCup.GHC as GHC
|
||||||
import qualified GHCup.HLS as HLS
|
import qualified GHCup.HLS as HLS
|
||||||
@@ -63,7 +66,7 @@ import qualified GHCup.Types as Types
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
toSettings :: Options -> IO (Settings, KeyBindings, UserSettings)
|
toSettings :: Options -> IO (Settings, KeyBindings)
|
||||||
toSettings options = do
|
toSettings options = do
|
||||||
noColor <- isJust <$> lookupEnv "NO_COLOR"
|
noColor <- isJust <$> lookupEnv "NO_COLOR"
|
||||||
userConf <- runE @'[ JSONError ] ghcupConfigFile >>= \case
|
userConf <- runE @'[ JSONError ] ghcupConfigFile >>= \case
|
||||||
@@ -73,7 +76,7 @@ toSettings options = do
|
|||||||
pure defaultUserSettings
|
pure defaultUserSettings
|
||||||
_ -> do
|
_ -> do
|
||||||
die "Unexpected error!"
|
die "Unexpected error!"
|
||||||
pure $ (\(s', k) -> (s', k, userConf)) $ mergeConf options userConf noColor
|
pure $ mergeConf options userConf noColor
|
||||||
where
|
where
|
||||||
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
||||||
mergeConf Options{..} UserSettings{..} noColor =
|
mergeConf Options{..} UserSettings{..} noColor =
|
||||||
@@ -89,7 +92,6 @@ toSettings options = do
|
|||||||
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
|
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
|
||||||
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
|
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
|
||||||
platformOverride = optPlatform <|> (uPlatformOverride <|> Types.platformOverride defaultSettings)
|
platformOverride = optPlatform <|> (uPlatformOverride <|> Types.platformOverride defaultSettings)
|
||||||
mirrors = fromMaybe (Types.mirrors defaultSettings) uMirrors
|
|
||||||
in (Settings {..}, keyBindings)
|
in (Settings {..}, keyBindings)
|
||||||
#if defined(INTERNAL_DOWNLOADER)
|
#if defined(INTERNAL_DOWNLOADER)
|
||||||
defaultDownloader = Internal
|
defaultDownloader = Internal
|
||||||
@@ -176,7 +178,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
|||||||
-- create ~/.ghcup dir
|
-- create ~/.ghcup dir
|
||||||
ensureDirectories dirs
|
ensureDirectories dirs
|
||||||
|
|
||||||
(settings, keybindings, userConf) <- toSettings opt
|
(settings, keybindings) <- toSettings opt
|
||||||
|
|
||||||
-- logger interpreter
|
-- logger interpreter
|
||||||
logfile <- runReaderT initGHCupFileLogging dirs
|
logfile <- runReaderT initGHCupFileLogging dirs
|
||||||
@@ -235,12 +237,15 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
|||||||
UnSet _ -> pure ()
|
UnSet _ -> pure ()
|
||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
Interactive -> pure ()
|
Interactive -> pure ()
|
||||||
|
#endif
|
||||||
|
#if defined(ANSI)
|
||||||
|
InteractiveAnsi -> pure ()
|
||||||
#endif
|
#endif
|
||||||
-- check for new tools
|
-- check for new tools
|
||||||
_
|
_
|
||||||
| Just False <- optVerbose -> pure ()
|
| Just False <- optVerbose -> pure ()
|
||||||
| otherwise -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
| otherwise -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
||||||
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, DayNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
||||||
newTools <- lift checkForUpdates
|
newTools <- lift checkForUpdates
|
||||||
forM_ newTools $ \newTool@(t, l) -> do
|
forM_ newTools $ \newTool@(t, l) -> do
|
||||||
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/283
|
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/283
|
||||||
@@ -249,7 +254,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
|||||||
case t of
|
case t of
|
||||||
GHCup -> runLogger $
|
GHCup -> runLogger $
|
||||||
logWarn ("New GHCup version available: "
|
logWarn ("New GHCup version available: "
|
||||||
<> tVerToText l
|
<> prettyVer l
|
||||||
<> ". To upgrade, run 'ghcup upgrade'")
|
<> ". To upgrade, run 'ghcup upgrade'")
|
||||||
_ -> runLogger $
|
_ -> runLogger $
|
||||||
logWarn ("New "
|
logWarn ("New "
|
||||||
@@ -258,7 +263,7 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
|||||||
<> "If you want to install this latest version, run 'ghcup install "
|
<> "If you want to install this latest version, run 'ghcup install "
|
||||||
<> T.pack (prettyShow t)
|
<> T.pack (prettyShow t)
|
||||||
<> " "
|
<> " "
|
||||||
<> tVerToText l
|
<> prettyVer l
|
||||||
<> "'")
|
<> "'")
|
||||||
Just _ -> pure ()
|
Just _ -> pure ()
|
||||||
|
|
||||||
@@ -293,17 +298,21 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
|||||||
Interactive -> do
|
Interactive -> do
|
||||||
s' <- appState
|
s' <- appState
|
||||||
liftIO $ brickMain s' >> pure ExitSuccess
|
liftIO $ brickMain s' >> pure ExitSuccess
|
||||||
|
#endif
|
||||||
|
#if defined(ANSI)
|
||||||
|
InteractiveAnsi -> do
|
||||||
|
s' <- appState
|
||||||
|
liftIO $ ansiMain s' >> pure ExitSuccess
|
||||||
#endif
|
#endif
|
||||||
Install installCommand -> install installCommand settings appState runLogger
|
Install installCommand -> install installCommand settings appState runLogger
|
||||||
InstallCabalLegacy iopts -> install (Left (InstallCabal iopts)) 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
|
Set setCommand -> set setCommand runAppState runLeanAppState runLogger
|
||||||
UnSet unsetCommand -> unset unsetCommand runLeanAppState runLogger
|
UnSet unsetCommand -> unset unsetCommand runLeanAppState runLogger
|
||||||
List lo -> list lo no_color runAppState
|
List lo -> list lo no_color runAppState
|
||||||
Rm rmCommand -> rm rmCommand runAppState runLogger
|
Rm rmCommand -> rm rmCommand runAppState runLogger
|
||||||
DInfo -> dinfo runAppState runLogger
|
DInfo -> dinfo runAppState runLogger
|
||||||
Compile compileCommand -> compile compileCommand settings dirs runAppState runLogger
|
Compile compileCommand -> compile compileCommand settings dirs runAppState runLogger
|
||||||
Config configCommand -> config configCommand settings userConf keybindings runLogger
|
Config configCommand -> config configCommand settings keybindings runLogger
|
||||||
Whereis whereisOptions
|
Whereis whereisOptions
|
||||||
whereisCommand -> whereis whereisCommand whereisOptions runAppState leanAppstate runLogger
|
whereisCommand -> whereis whereisCommand whereisOptions runAppState leanAppstate runLogger
|
||||||
Upgrade uOpts force' fatal -> upgrade uOpts force' fatal dirs runAppState runLogger
|
Upgrade uOpts force' fatal -> upgrade uOpts force' fatal dirs runAppState runLogger
|
||||||
@@ -332,10 +341,9 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
|||||||
, MonadCatch m
|
, MonadCatch m
|
||||||
)
|
)
|
||||||
=> Command
|
=> Command
|
||||||
-> (Tool, GHCTargetVersion)
|
-> (Tool, Version)
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ TagNotFound
|
'[ TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
] m Bool
|
] m Bool
|
||||||
@@ -368,13 +376,12 @@ Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
|||||||
)
|
)
|
||||||
=> Tool
|
=> Tool
|
||||||
-> Maybe ToolVersion
|
-> Maybe ToolVersion
|
||||||
-> GHCTargetVersion
|
-> Version
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ TagNotFound
|
'[ TagNotFound
|
||||||
, DayNotFound
|
|
||||||
, NextVerNotFound
|
, NextVerNotFound
|
||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
] m Bool
|
] m Bool
|
||||||
cmp' tool instVer ver = do
|
cmp' tool instVer ver = do
|
||||||
(v, _) <- liftE $ fromVersion instVer tool
|
(v, _) <- liftE $ fromVersion instVer tool
|
||||||
pure (v == ver)
|
pure (v == mkTVer ver)
|
||||||
|
|||||||
@@ -5,10 +5,17 @@ optional-packages: ./vendored/*/*.cabal
|
|||||||
optimization: 2
|
optimization: 2
|
||||||
|
|
||||||
package ghcup
|
package ghcup
|
||||||
|
tests: True
|
||||||
flags: +tui
|
flags: +tui
|
||||||
|
|
||||||
|
source-repository-package
|
||||||
|
type: git
|
||||||
|
location: https://github.com/bgamari/terminal-size.git
|
||||||
|
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
|
||||||
|
|
||||||
constraints: http-io-streams -brotli,
|
constraints: http-io-streams -brotli,
|
||||||
any.aeson >= 2.0.1.0
|
any.Cabal ==3.6.2.0,
|
||||||
|
any.aeson >= 2.0.1.0,
|
||||||
|
|
||||||
package libarchive
|
package libarchive
|
||||||
flags: -system-libarchive
|
flags: -system-libarchive
|
||||||
@@ -25,5 +32,6 @@ package aeson
|
|||||||
package streamly
|
package streamly
|
||||||
flags: +use-unliftio
|
flags: +use-unliftio
|
||||||
|
|
||||||
|
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||||
|
|
||||||
with-compiler: ghc-8.10.7
|
with-compiler: ghc-8.10.7
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
active-repositories: hackage.haskell.org:merge
|
active-repositories: hackage.haskell.org:merge
|
||||||
constraints: any.Cabal ==3.6.3.0,
|
constraints: any.Cabal ==3.6.2.0,
|
||||||
Cabal -bundled-binary-generic,
|
Cabal -bundled-binary-generic,
|
||||||
any.Cabal-syntax ==3.8.1.0,
|
|
||||||
any.HUnit ==1.6.2.0,
|
any.HUnit ==1.6.2.0,
|
||||||
any.HsOpenSSL ==0.11.7.4,
|
any.HsOpenSSL ==0.11.7.2,
|
||||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||||
any.OneTuple ==0.3.1,
|
any.OneTuple ==0.3.1,
|
||||||
any.QuickCheck ==2.14.2,
|
any.QuickCheck ==2.14.2,
|
||||||
@@ -11,13 +10,13 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.StateVar ==1.2.2,
|
any.StateVar ==1.2.2,
|
||||||
any.abstract-deque ==0.3,
|
any.abstract-deque ==0.3,
|
||||||
abstract-deque -usecas,
|
abstract-deque -usecas,
|
||||||
any.aeson ==2.1.1.0,
|
any.aeson ==2.0.3.0,
|
||||||
aeson -cffi +ordered-keymap,
|
aeson -cffi +ordered-keymap,
|
||||||
any.aeson-pretty ==0.8.9,
|
any.aeson-pretty ==0.8.9,
|
||||||
aeson-pretty +lib-only,
|
aeson-pretty +lib-only,
|
||||||
any.alex ==3.2.7.1,
|
any.alex ==3.2.7.1,
|
||||||
any.ansi-terminal ==0.11.4,
|
any.ansi-terminal ==0.11.3,
|
||||||
ansi-terminal -example +win32-2-13-1,
|
ansi-terminal -example,
|
||||||
any.ansi-wl-pprint ==0.6.9,
|
any.ansi-wl-pprint ==0.6.9,
|
||||||
ansi-wl-pprint -example,
|
ansi-wl-pprint -example,
|
||||||
any.array ==0.5.4.0,
|
any.array ==0.5.4.0,
|
||||||
@@ -29,27 +28,23 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.attoparsec ==0.14.4,
|
any.attoparsec ==0.14.4,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.base ==4.14.3.0,
|
any.base ==4.14.3.0,
|
||||||
any.base-compat ==0.12.2,
|
any.base-compat ==0.12.1,
|
||||||
any.base-compat-batteries ==0.12.2,
|
any.base-compat-batteries ==0.12.1,
|
||||||
any.base-orphans ==0.8.7,
|
any.base-orphans ==0.8.6,
|
||||||
any.base16-bytestring ==1.0.2.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base64-bytestring ==1.2.1.0,
|
any.base64-bytestring ==1.2.1.0,
|
||||||
any.bifunctors ==5.5.14,
|
any.bifunctors ==5.5.12,
|
||||||
bifunctors +semigroups +tagged,
|
bifunctors +semigroups +tagged,
|
||||||
any.bimap ==0.5.0,
|
|
||||||
any.binary ==0.8.8.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.blaze-builder ==0.4.2.2,
|
||||||
any.brick ==1.5,
|
any.brick ==0.64.2,
|
||||||
brick -demos,
|
brick -demos,
|
||||||
any.bytestring ==0.10.12.0,
|
any.bytestring ==0.10.12.0,
|
||||||
any.bz2 ==1.0.1.0,
|
any.bz2 ==1.0.1.0,
|
||||||
bz2 -cross +with-bzlib,
|
bz2 -cross +with-bzlib,
|
||||||
any.c2hs ==0.28.8,
|
any.c2hs ==0.28.8,
|
||||||
c2hs +base3 -regression,
|
c2hs +base3 -regression,
|
||||||
any.cabal-install-parsers ==0.5,
|
any.cabal-plan ==0.7.2.1,
|
||||||
any.cabal-plan ==0.7.2.3,
|
|
||||||
cabal-plan -_ -exe -license-report,
|
cabal-plan -_ -exe -license-report,
|
||||||
any.call-stack ==0.4.0,
|
any.call-stack ==0.4.0,
|
||||||
any.case-insensitive ==1.2.1.0,
|
any.case-insensitive ==1.2.1.0,
|
||||||
@@ -57,12 +52,14 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.chs-cabal ==0.1.1.1,
|
any.chs-cabal ==0.1.1.1,
|
||||||
any.chs-deps ==0.1.0.0,
|
any.chs-deps ==0.1.0.0,
|
||||||
chs-deps -cross,
|
chs-deps -cross,
|
||||||
|
any.clock ==0.8.3,
|
||||||
|
clock -llvm,
|
||||||
any.colour ==2.3.6,
|
any.colour ==2.3.6,
|
||||||
any.comonad ==5.0.8,
|
any.comonad ==5.0.8,
|
||||||
comonad +containers +distributive +indexed-traversable,
|
comonad +containers +distributive +indexed-traversable,
|
||||||
any.composition-prelude ==3.0.0.2,
|
any.composition-prelude ==3.0.0.2,
|
||||||
composition-prelude -development,
|
composition-prelude -development,
|
||||||
any.config-ini ==0.2.5.0,
|
any.config-ini ==0.2.4.0,
|
||||||
config-ini -enable-doctests,
|
config-ini -enable-doctests,
|
||||||
any.containers ==0.6.5.1,
|
any.containers ==0.6.5.1,
|
||||||
any.contravariant ==1.5.5,
|
any.contravariant ==1.5.5,
|
||||||
@@ -72,7 +69,6 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.cryptohash-sha1 ==0.11.101.0,
|
any.cryptohash-sha1 ==0.11.101.0,
|
||||||
any.cryptohash-sha256 ==0.11.102.1,
|
any.cryptohash-sha256 ==0.11.102.1,
|
||||||
cryptohash-sha256 -exe +use-cbits,
|
cryptohash-sha256 -exe +use-cbits,
|
||||||
any.data-array-byte ==0.1.0.1,
|
|
||||||
any.data-clist ==0.2,
|
any.data-clist ==0.2,
|
||||||
any.data-fix ==0.3.2,
|
any.data-fix ==0.3.2,
|
||||||
any.deepseq ==1.4.4.0,
|
any.deepseq ==1.4.4.0,
|
||||||
@@ -84,57 +80,58 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
dlist -werror,
|
dlist -werror,
|
||||||
any.exceptions ==0.10.4,
|
any.exceptions ==0.10.4,
|
||||||
any.filepath ==1.4.2.1,
|
any.filepath ==1.4.2.1,
|
||||||
any.free ==5.1.10,
|
any.free ==5.1.8,
|
||||||
any.fusion-plugin-types ==0.1.0,
|
any.fusion-plugin-types ==0.1.0,
|
||||||
any.generic-arbitrary ==0.2.2,
|
any.generic-arbitrary ==0.2.2,
|
||||||
any.generically ==0.1,
|
any.ghc ==8.10.7,
|
||||||
|
any.ghc-boot ==8.10.7,
|
||||||
any.ghc-boot-th ==8.10.7,
|
any.ghc-boot-th ==8.10.7,
|
||||||
any.ghc-byteorder ==4.11.0.0.10,
|
any.ghc-byteorder ==4.11.0.0.10,
|
||||||
|
any.ghc-heap ==8.10.7,
|
||||||
any.ghc-prim ==0.6.1,
|
any.ghc-prim ==0.6.1,
|
||||||
|
any.ghci ==8.10.7,
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.4.2.0,
|
any.hashable ==1.4.0.2,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable +containers +integer-gmp -random-initial-seed,
|
||||||
any.haskell-lexer ==1.1.1,
|
|
||||||
any.haskus-utils-data ==1.4,
|
any.haskus-utils-data ==1.4,
|
||||||
any.haskus-utils-types ==1.5.1,
|
any.haskus-utils-types ==1.5.1,
|
||||||
any.haskus-utils-variant ==3.2.1,
|
any.haskus-utils-variant ==3.2.1,
|
||||||
any.heaps ==0.4,
|
any.heaps ==0.4,
|
||||||
|
any.hpc ==0.6.1.0,
|
||||||
any.hsc2hs ==0.68.8,
|
any.hsc2hs ==0.68.8,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.10.8,
|
any.hspec ==2.9.7,
|
||||||
any.hspec-core ==2.10.8,
|
any.hspec-core ==2.9.7,
|
||||||
any.hspec-discover ==2.10.8,
|
any.hspec-discover ==2.9.7,
|
||||||
any.hspec-expectations ==0.8.2,
|
any.hspec-expectations ==0.8.2,
|
||||||
any.hspec-golden-aeson ==0.9.0.0,
|
any.hspec-golden-aeson ==0.9.0.0,
|
||||||
any.http-io-streams ==0.1.6.1,
|
any.http-io-streams ==0.1.6.1,
|
||||||
http-io-streams -brotli +fast-xor,
|
http-io-streams -brotli +fast-xor,
|
||||||
any.indexed-profunctors ==0.1.1,
|
any.indexed-profunctors ==0.1.1,
|
||||||
any.indexed-traversable ==0.1.2,
|
any.indexed-traversable ==0.1.2,
|
||||||
any.indexed-traversable-instances ==0.1.1.1,
|
any.indexed-traversable-instances ==0.1.1,
|
||||||
any.integer-gmp ==1.0.3.0,
|
any.integer-gmp ==1.0.3.0,
|
||||||
any.integer-logarithms ==1.0.3.1,
|
any.integer-logarithms ==1.0.3.1,
|
||||||
integer-logarithms -check-bounds +integer-gmp,
|
integer-logarithms -check-bounds +integer-gmp,
|
||||||
any.io-streams ==1.5.2.2,
|
any.io-streams ==1.5.2.1,
|
||||||
io-streams +network -nointeractivetests +zlib,
|
io-streams +network -nointeractivetests +zlib,
|
||||||
any.language-c ==0.9.2,
|
any.language-c ==0.9.1,
|
||||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||||
any.libarchive ==3.0.3.2,
|
any.libarchive ==3.0.3.2,
|
||||||
libarchive -cross -low-memory +no-exe -system-libarchive,
|
libarchive -cross -low-memory +no-exe -system-libarchive,
|
||||||
any.libyaml-streamly ==0.2.1,
|
any.libyaml-streamly ==0.2.1,
|
||||||
libyaml-streamly -no-unicode -system-libyaml,
|
libyaml-streamly -no-unicode -system-libyaml,
|
||||||
any.lockfree-queue ==0.2.4,
|
any.lockfree-queue ==0.2.3.1,
|
||||||
any.lukko ==0.1.1.3,
|
any.lzma-static ==5.2.5.4,
|
||||||
lukko +ofd-locking,
|
|
||||||
any.lzma-static ==5.2.5.5,
|
|
||||||
any.megaparsec ==9.2.1,
|
any.megaparsec ==9.2.1,
|
||||||
megaparsec -dev,
|
megaparsec -dev,
|
||||||
any.microlens ==0.4.13.1,
|
any.microlens ==0.4.12.0,
|
||||||
any.microlens-mtl ==0.2.0.3,
|
any.microlens-mtl ==0.2.0.2,
|
||||||
any.microlens-th ==0.4.3.11,
|
any.microlens-th ==0.4.3.10,
|
||||||
any.mtl ==2.2.2,
|
any.mtl ==2.2.2,
|
||||||
any.network ==3.1.2.7,
|
any.network ==3.1.2.7,
|
||||||
network -devel,
|
network -devel,
|
||||||
any.network-uri ==2.6.4.2,
|
any.network-uri ==2.6.4.1,
|
||||||
any.openssl-streams ==1.2.3.0,
|
any.openssl-streams ==1.2.3.0,
|
||||||
any.optics ==0.4.2,
|
any.optics ==0.4.2,
|
||||||
any.optics-core ==0.4.1,
|
any.optics-core ==0.4.1,
|
||||||
@@ -146,7 +143,7 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.os-release ==1.0.2.1,
|
any.os-release ==1.0.2.1,
|
||||||
os-release -devel,
|
os-release -devel,
|
||||||
any.parallel ==3.2.2.0,
|
any.parallel ==3.2.2.0,
|
||||||
any.parsec ==3.1.16.1,
|
any.parsec ==3.1.14.0,
|
||||||
any.parser-combinators ==1.3.0,
|
any.parser-combinators ==1.3.0,
|
||||||
parser-combinators -dev,
|
parser-combinators -dev,
|
||||||
any.polyparse ==1.13,
|
any.polyparse ==1.13,
|
||||||
@@ -158,12 +155,12 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||||
any.quickcheck-io ==0.2.0,
|
any.quickcheck-io ==0.2.0,
|
||||||
any.random ==1.2.1.1,
|
any.random ==1.2.1.1,
|
||||||
any.recursion-schemes ==5.2.2.3,
|
any.recursion-schemes ==5.2.2.2,
|
||||||
recursion-schemes +template-haskell,
|
recursion-schemes +template-haskell,
|
||||||
any.regex-base ==0.94.0.2,
|
any.regex-base ==0.94.0.2,
|
||||||
any.regex-posix ==0.96.0.1,
|
any.regex-posix ==0.96.0.1,
|
||||||
regex-posix -_regex-posix-clib,
|
regex-posix -_regex-posix-clib,
|
||||||
any.resourcet ==1.2.6,
|
any.resourcet ==1.2.5,
|
||||||
any.retry ==0.8.1.2,
|
any.retry ==0.8.1.2,
|
||||||
retry -lib-werror,
|
retry -lib-werror,
|
||||||
any.rts ==1.0.1,
|
any.rts ==1.0.1,
|
||||||
@@ -176,11 +173,11 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.semigroupoids ==5.3.7,
|
any.semigroupoids ==5.3.7,
|
||||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||||
any.setenv ==0.1.1.3,
|
any.setenv ==0.1.1.3,
|
||||||
any.split ==0.2.3.5,
|
any.split ==0.2.3.4,
|
||||||
any.splitmix ==0.1.0.4,
|
any.splitmix ==0.1.0.4,
|
||||||
splitmix -optimised-mixer,
|
splitmix -optimised-mixer,
|
||||||
any.stm ==2.5.0.1,
|
any.stm ==2.5.0.1,
|
||||||
any.streamly ==0.8.3,
|
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,
|
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,
|
any.strict ==0.4.0.1,
|
||||||
strict +assoc,
|
strict +assoc,
|
||||||
@@ -188,24 +185,20 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.tagged ==0.8.6.1,
|
any.tagged ==0.8.6.1,
|
||||||
tagged +deepseq +transformers,
|
tagged +deepseq +transformers,
|
||||||
any.tagsoup ==0.14.8,
|
any.tagsoup ==0.14.8,
|
||||||
any.tar ==0.5.1.1,
|
|
||||||
tar -old-bytestring -old-time,
|
|
||||||
any.template-haskell ==2.16.0.0,
|
any.template-haskell ==2.16.0.0,
|
||||||
any.temporary ==1.3,
|
any.temporary ==1.3,
|
||||||
any.terminal-progress-bar ==0.4.1,
|
any.terminal-progress-bar ==0.4.1,
|
||||||
any.terminal-size ==0.3.3,
|
any.terminal-size ==0.3.2.1,
|
||||||
any.terminfo ==0.4.1.4,
|
any.terminfo ==0.4.1.4,
|
||||||
any.text ==2.0.1,
|
any.text ==1.2.4.1,
|
||||||
text -developer +simdutf,
|
|
||||||
any.text-binary ==0.2.1.1,
|
|
||||||
any.text-short ==0.1.5,
|
any.text-short ==0.1.5,
|
||||||
text-short -asserts,
|
text-short -asserts,
|
||||||
any.text-zipper ==0.12,
|
any.text-zipper ==0.11,
|
||||||
any.tf-random ==0.5,
|
any.tf-random ==0.5,
|
||||||
any.th-abstraction ==0.4.5.0,
|
any.th-abstraction ==0.4.3.0,
|
||||||
any.th-compat ==0.1.4,
|
any.th-compat ==0.1.3,
|
||||||
any.th-lift ==0.8.2,
|
any.th-lift ==0.8.2,
|
||||||
any.th-lift-instances ==0.1.20,
|
any.th-lift-instances ==0.1.19,
|
||||||
any.these ==1.1.1.1,
|
any.these ==1.1.1.1,
|
||||||
these +assoc,
|
these +assoc,
|
||||||
any.time ==1.9.3,
|
any.time ==1.9.3,
|
||||||
@@ -214,12 +207,12 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.transformers ==0.5.6.2,
|
any.transformers ==0.5.6.2,
|
||||||
any.transformers-base ==0.4.6,
|
any.transformers-base ==0.4.6,
|
||||||
transformers-base +orphaninstances,
|
transformers-base +orphaninstances,
|
||||||
any.transformers-compat ==0.7.2,
|
any.transformers-compat ==0.7.1,
|
||||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||||
any.unicode-data ==0.3.1,
|
any.unicode-data ==0.3.0,
|
||||||
unicode-data -ucd2haskell,
|
unicode-data -ucd2haskell,
|
||||||
any.unix ==2.7.2.2,
|
any.unix ==2.7.2.2,
|
||||||
any.unix-bytestring ==0.3.7.8,
|
any.unix-bytestring ==0.3.7.7,
|
||||||
any.unix-compat ==0.6,
|
any.unix-compat ==0.6,
|
||||||
unix-compat -old-time,
|
unix-compat -old-time,
|
||||||
any.unliftio-core ==0.2.0.1,
|
any.unliftio-core ==0.2.0.1,
|
||||||
@@ -231,9 +224,8 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.uuid-types ==1.0.5,
|
any.uuid-types ==1.0.5,
|
||||||
any.vector ==0.12.3.1,
|
any.vector ==0.12.3.1,
|
||||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||||
any.vector-binary-instances ==0.2.5.2,
|
any.versions ==5.0.3,
|
||||||
any.versions ==5.0.4,
|
any.vty ==5.33,
|
||||||
any.vty ==5.37,
|
|
||||||
any.witherable ==0.4.2,
|
any.witherable ==0.4.2,
|
||||||
any.word-wrap ==0.5,
|
any.word-wrap ==0.5,
|
||||||
any.word8 ==0.1.3,
|
any.word8 ==0.1.3,
|
||||||
@@ -243,4 +235,4 @@ constraints: any.Cabal ==3.6.3.0,
|
|||||||
any.zlib ==0.6.3.0,
|
any.zlib ==0.6.3.0,
|
||||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||||
any.zlib-bindings ==0.1.1.5
|
any.zlib-bindings ==0.1.1.5
|
||||||
index-state: hackage.haskell.org 2023-01-12T04:22:48Z
|
index-state: hackage.haskell.org 2022-06-04T19:47:01Z
|
||||||
|
|||||||
37
cabal.ghc902.project
Normal file
37
cabal.ghc902.project
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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
|
||||||
238
cabal.ghc902.project.freeze
Normal file
238
cabal.ghc902.project.freeze
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
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
|
||||||
37
cabal.ghc923.project
Normal file
37
cabal.ghc923.project
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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
|
||||||
233
cabal.ghc923.project.freeze
Normal file
233
cabal.ghc923.project.freeze
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
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
|
||||||
@@ -2,11 +2,20 @@ packages: ./ghcup.cabal
|
|||||||
|
|
||||||
optional-packages: ./vendored/*/*.cabal
|
optional-packages: ./vendored/*/*.cabal
|
||||||
|
|
||||||
|
optimization: 2
|
||||||
|
|
||||||
package ghcup
|
package ghcup
|
||||||
flags: +tui
|
tests: True
|
||||||
|
flags: +tui-ansi
|
||||||
|
|
||||||
|
source-repository-package
|
||||||
|
type: git
|
||||||
|
location: https://github.com/bgamari/terminal-size.git
|
||||||
|
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
|
||||||
|
|
||||||
constraints: http-io-streams -brotli,
|
constraints: http-io-streams -brotli,
|
||||||
any.aeson >= 2.0.1.0
|
any.Cabal ==3.6.2.0,
|
||||||
|
any.aeson >= 2.0.1.0,
|
||||||
|
|
||||||
package libarchive
|
package libarchive
|
||||||
flags: -system-libarchive
|
flags: -system-libarchive
|
||||||
@@ -23,3 +32,4 @@ package aeson
|
|||||||
package streamly
|
package streamly
|
||||||
flags: +use-unliftio
|
flags: +use-unliftio
|
||||||
|
|
||||||
|
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
-- windows picks weird version
|
-- windows picks weird version
|
||||||
constraints: any.hsc2hs ==0.68.8
|
constraints: any.hsc2hs ==0.68.7
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
@@ -92,30 +92,3 @@ url-source:
|
|||||||
# tag: Linux
|
# tag: Linux
|
||||||
# version: '18.04'
|
# version: '18.04'
|
||||||
platform-override: null
|
platform-override: null
|
||||||
|
|
||||||
# Support for mirrors. Currently there are 3 hosts you can mirror:
|
|
||||||
# - github.com (for stack and some older HLS versions)
|
|
||||||
# - raw.githubusercontent.com (for the yaml metadata)
|
|
||||||
# - downloads.haskell.org (for everything else)
|
|
||||||
#
|
|
||||||
# E.g. when we have 'https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml'
|
|
||||||
# and the following mirror config
|
|
||||||
#
|
|
||||||
# "raw.githubusercontent.com":
|
|
||||||
# authority:
|
|
||||||
# host: "mirror.sjtu.edu.cn"
|
|
||||||
# pathPrefix: "ghcup/yaml"
|
|
||||||
#
|
|
||||||
# Then the resulting url will be 'https://mirror.sjtu.edu.cn/ghcup/yaml/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml'
|
|
||||||
mirrors:
|
|
||||||
"github.com":
|
|
||||||
authority:
|
|
||||||
host: "mirror.sjtu.edu.cn"
|
|
||||||
"raw.githubusercontent.com":
|
|
||||||
authority:
|
|
||||||
host: "mirror.sjtu.edu.cn"
|
|
||||||
pathPrefix: "ghcup/yaml"
|
|
||||||
"downloads.haskell.org":
|
|
||||||
authority:
|
|
||||||
host: "mirror.sjtu.edu.cn"
|
|
||||||
|
|
||||||
|
|||||||
Submodule data/metadata updated: c88802ea8c...8f0e82ef06
@@ -1,4 +1,4 @@
|
|||||||
FROM --platform=linux/i386 i386/alpine:3.12
|
FROM i386/alpine:3.12
|
||||||
|
|
||||||
ENV LANG C.UTF-8
|
ENV LANG C.UTF-8
|
||||||
|
|
||||||
@@ -37,8 +37,8 @@ RUN apk add --no-cache \
|
|||||||
xz-dev \
|
xz-dev \
|
||||||
ncurses-static
|
ncurses-static
|
||||||
|
|
||||||
ARG GHCUP_VERSION=0.1.19.4
|
ARG GHCUP_VERSION=0.1.18.0
|
||||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
# install ghcup
|
# install ghcup
|
||||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
|
|||||||
@@ -37,9 +37,8 @@ RUN apk add --no-cache \
|
|||||||
xz-dev \
|
xz-dev \
|
||||||
ncurses-static
|
ncurses-static
|
||||||
|
|
||||||
ARG GHCUP_VERSION=0.1.19.4
|
ARG GHCUP_VERSION=0.1.18.0
|
||||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
|
|
||||||
# install ghcup
|
# install ghcup
|
||||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ RUN apt-get update && \
|
|||||||
|
|
||||||
RUN update_opt.sh 9 1
|
RUN update_opt.sh 9 1
|
||||||
|
|
||||||
ARG GHCUP_VERSION=0.1.19.4
|
ARG GHCUP_VERSION=0.1.17.8
|
||||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
# install ghcup
|
# install ghcup
|
||||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
@@ -54,7 +54,10 @@ ENV NO_COLOR=1
|
|||||||
RUN ghcup config set gpg-setting GPGStrict && \
|
RUN ghcup config set gpg-setting GPGStrict && \
|
||||||
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||||
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||||
ghcup gc -s -c -t
|
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
|
||||||
|
|
||||||
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||||
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
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.19.4
|
|
||||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
|
||||||
|
|
||||||
# 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"]
|
|
||||||
@@ -29,8 +29,8 @@ RUN apt-get update && \
|
|||||||
|
|
||||||
RUN update_opt.sh 9 1
|
RUN update_opt.sh 9 1
|
||||||
|
|
||||||
ARG GHCUP_VERSION=0.1.19.4
|
ARG GHCUP_VERSION=0.1.18.0
|
||||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
# install ghcup
|
# install ghcup
|
||||||
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
@@ -54,7 +54,10 @@ ENV NO_COLOR=1
|
|||||||
RUN ghcup config set gpg-setting GPGStrict && \
|
RUN ghcup config set gpg-setting GPGStrict && \
|
||||||
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||||
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||||
ghcup gc -s -c -t
|
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
|
||||||
|
|
||||||
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||||
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
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.19.4
|
|
||||||
ARG GPG_KEY=7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
|
||||||
|
|
||||||
# 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"]
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#!/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}"
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#!/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}"
|
|
||||||
@@ -163,7 +163,6 @@ ghcup --url-source=https://some-url/ghcup-0.0.6.yaml list
|
|||||||
#### Known mirrors
|
#### Known mirrors
|
||||||
|
|
||||||
1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup)
|
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
|
### (Pre-)Release channels
|
||||||
|
|
||||||
@@ -203,34 +202,6 @@ url-source:
|
|||||||
- "https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml"
|
- "https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Nightlies
|
|
||||||
|
|
||||||
Nightlies are just a nother release channel. Currently, only GHC supports nightlies, which are binary releases
|
|
||||||
that are built every night from `master`.
|
|
||||||
|
|
||||||
To add the nightly channel, run:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
ghcup config add-release-channel https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
To list all nightlies from 2023, run:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
ghcup list --show-nightly --tool=ghc --since=2023-01-01
|
|
||||||
```
|
|
||||||
|
|
||||||
Ways to install a nightly:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# by date
|
|
||||||
ghcup install ghc 2023-06-20
|
|
||||||
# by version
|
|
||||||
ghcup install ghc 9.7.20230619
|
|
||||||
# by tag
|
|
||||||
ghcup install ghc latest-nightly
|
|
||||||
```
|
|
||||||
|
|
||||||
## Stack integration
|
## Stack integration
|
||||||
|
|
||||||
Stack manages GHC versions internally by default. In order to make it use ghcup installed
|
Stack manages GHC versions internally by default. In order to make it use ghcup installed
|
||||||
@@ -489,7 +460,7 @@ this is cryptographically secure.
|
|||||||
First, obtain the gpg keys:
|
First, obtain the gpg keys:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
gpg --batch --keyserver keys.openpgp.org --recv-keys 7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C
|
gpg --batch --keyserver keys.openpgp.org --recv-keys 7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01
|
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ hide:
|
|||||||
- toc
|
- 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">
|
<section class="index-ghcup-hero">
|
||||||
<img alt="haskell logo" src="./haskell_logo.png" />
|
<img alt="haskell logo" src="./haskell_logo.png" />
|
||||||
<h1>GHCup</h1>
|
<h1>GHCup</h1>
|
||||||
@@ -31,7 +35,7 @@ hide:
|
|||||||
<span>
|
<span>
|
||||||
</span>
|
</span>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-installation">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-install">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -47,7 +51,7 @@ hide:
|
|||||||
<button class="btn" onclick="copyToClipboardWin()" id="ghcup-windows-button"><i class="fa fa-copy"></i></button>
|
<button class="btn" onclick="copyToClipboardWin()" id="ghcup-windows-button"><i class="fa fa-copy"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell.ps1" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-installation">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell.ps1" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-install">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -80,6 +84,9 @@ hide:
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="javascripts/ghcup.js"></script>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
GHCup makes it easy to install specific versions of GHC on GNU/Linux,
|
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](./#supported-tools) from scratch.
|
macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh [Haskell developer environment](./install/#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).
|
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
|
## 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.
|
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-installation) 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-install) and GPG verify the binaries.
|
||||||
|
|
||||||
### Which versions get installed?
|
### Which versions get installed?
|
||||||
|
|
||||||
@@ -77,8 +77,6 @@ On Darwin M1 you might also need a working llvm installed (e.g. via brew) and ha
|
|||||||
|
|
||||||
The following distro packages are required: `curl gcc gmp gmake ncurses perl5 libffi libiconv`
|
The following distro packages are required: `curl gcc gmp gmake ncurses perl5 libffi libiconv`
|
||||||
|
|
||||||
Notice that only FreeBSD 13.x is supported. If the installation fails, complaining about `libncursesw.8.so`, you will need to install FreeBSD 12 compat package first, for example, `pkg install misc/compat12x`.
|
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
On Windows, msys2 should already have been set up during the installation, so most users should just proceed. If you are installing manually, make sure to have a working mingw64 toolchain and shell.
|
On Windows, msys2 should already have been set up during the installation, so most users should just proceed. If you are installing manually, make sure to have a working mingw64 toolchain and shell.
|
||||||
@@ -104,13 +102,9 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
|||||||
<table>
|
<table>
|
||||||
<thead><tr><th>GHC Version</th><th>Tags</th></tr></thead>
|
<thead><tr><th>GHC Version</th><th>Tags</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td>9.6.1</td><td><span style="color:blue">latest</span>, base-4.18.0.0</td></tr>
|
<tr><td>9.4.3</td><td><span style="color:blue">latest</span>, base-4.17.0.0</td></tr>
|
||||||
<tr><td>9.4.4</td><td>base-4.17.0.0</td></tr>
|
|
||||||
<tr><td>9.4.3</td><td>base-4.17.0.0</td></tr>
|
|
||||||
<tr><td>9.4.2</td><td>base-4.17.0.0</td></tr>
|
<tr><td>9.4.2</td><td>base-4.17.0.0</td></tr>
|
||||||
<tr><td>9.4.1</td><td>base-4.17.0.0</td></tr>
|
<tr><td>9.4.1</td><td>base-4.17.0.0</td></tr>
|
||||||
<tr><td>9.2.7</td><td>base-4.16.4.0</td></tr>
|
|
||||||
<tr><td>9.2.6</td><td>base-4.16.4.0</td></tr>
|
|
||||||
<tr><td>9.2.5</td><td><span style="color:green">recommended</span>, base-4.16.4.0</td></tr>
|
<tr><td>9.2.5</td><td><span style="color:green">recommended</span>, base-4.16.4.0</td></tr>
|
||||||
<tr><td>9.2.4</td><td>base-4.16.3.0</td></tr>
|
<tr><td>9.2.4</td><td>base-4.16.3.0</td></tr>
|
||||||
<tr><td>9.2.3</td><td>base-4.16.2.0</td></tr>
|
<tr><td>9.2.3</td><td>base-4.16.2.0</td></tr>
|
||||||
@@ -149,8 +143,7 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
|||||||
<table>
|
<table>
|
||||||
<thead><tr><th>Cabal Version</th><th>Tags</th></tr></thead>
|
<thead><tr><th>Cabal Version</th><th>Tags</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td>3.10.1.0</td><td><span style="color:blue">latest</span></td></tr>
|
<tr><td>3.8.1.0</td><td><span style="color:blue">latest</span></td></tr>
|
||||||
<tr><td>3.8.1.0</td><td></td></tr>
|
|
||||||
<tr><td>3.6.2.0</td><td><span style="color:green">recommended</span></td></tr>
|
<tr><td>3.6.2.0</td><td><span style="color:green">recommended</span></td></tr>
|
||||||
<tr><td>3.6.0.0</td><td></td></tr>
|
<tr><td>3.6.0.0</td><td></td></tr>
|
||||||
<tr><td>3.4.1.0</td><td></td></tr>
|
<tr><td>3.4.1.0</td><td></td></tr>
|
||||||
@@ -166,9 +159,7 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
|||||||
<table>
|
<table>
|
||||||
<thead><tr><th>HLS Version</th><th>Tags</th></tr></thead>
|
<thead><tr><th>HLS Version</th><th>Tags</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td>1.9.1.0</td><td><span style="color:blue">latest</span></td></tr>
|
<tr><td>1.8.0.0</td><td><span style="color:blue">latest</span>, <span style="color:green">recommended</span></td></tr>
|
||||||
<tr><td>1.9.0.0</td><td><span style="color:green">recommended</span></td></tr>
|
|
||||||
<tr><td>1.8.0.0</td><td></td></tr>
|
|
||||||
<tr><td>1.7.0.0</td><td></td></tr>
|
<tr><td>1.7.0.0</td><td></td></tr>
|
||||||
<tr><td>1.6.1.0</td><td></td></tr>
|
<tr><td>1.6.1.0</td><td></td></tr>
|
||||||
<tr><td>1.6.0.0</td><td></td></tr>
|
<tr><td>1.6.0.0</td><td></td></tr>
|
||||||
@@ -186,8 +177,7 @@ GHCup supports the following tools, which are also known as the **Haskell Toolch
|
|||||||
<table>
|
<table>
|
||||||
<thead><tr><th>Stack Version</th><th>Tags</th></tr></thead>
|
<thead><tr><th>Stack Version</th><th>Tags</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td>2.9.3</td><td><span style="color:blue">latest</span>, <span style="color:green">recommended</span></td></tr>
|
<tr><td>2.9.1</td><td><span style="color:blue">latest</span>, <span style="color:green">recommended</span></td></tr>
|
||||||
<tr><td>2.9.1</td><td></td></tr>
|
|
||||||
<tr><td>2.7.5</td><td></td></tr>
|
<tr><td>2.7.5</td><td></td></tr>
|
||||||
<tr><td>2.7.3</td><td></td></tr>
|
<tr><td>2.7.3</td><td></td></tr>
|
||||||
<tr><td>2.7.1</td><td></td></tr>
|
<tr><td>2.7.1</td><td></td></tr>
|
||||||
@@ -241,9 +231,8 @@ There are various issues with GHC itself.
|
|||||||
|
|
||||||
### FreeBSD
|
### FreeBSD
|
||||||
|
|
||||||
Lacks some upstream bindists and may need compat libs (such as `misc/compat12x`).
|
Lacks some upstream bindists and may need compat libs, since most bindists are built on FreeBSD-12.
|
||||||
HLS bindists are experimental.
|
HLS bindists are experimental.
|
||||||
Only latest FreeBSD is generally supported.
|
|
||||||
|
|
||||||
### Linux ARMv7/AARCH64
|
### Linux ARMv7/AARCH64
|
||||||
|
|
||||||
@@ -251,12 +240,10 @@ Lower availability of bindists. Stack and HLS binaries are experimental.
|
|||||||
|
|
||||||
## Manual installation
|
## Manual installation
|
||||||
|
|
||||||
### Unix
|
|
||||||
|
|
||||||
Download the binary for your platform at [https://downloads.haskell.org/~ghcup/](https://downloads.haskell.org/~ghcup/)
|
Download the binary for your platform at [https://downloads.haskell.org/~ghcup/](https://downloads.haskell.org/~ghcup/)
|
||||||
and place it into your `PATH` anywhere.
|
and place it into your `PATH` anywhere.
|
||||||
|
|
||||||
If you want to GPG verify the binaries, import the following keys first: `7D1E8AFD1D4A16D71FADA2F2CCC85C0E40C06A8C` and `FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01`.
|
If you want to GPG verify the binaries, import the following keys first: `7784930957807690A66EBDBE3786C5262ECB4A3F` and `FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01`.
|
||||||
|
|
||||||
Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) like so:
|
Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) like so:
|
||||||
|
|
||||||
@@ -264,60 +251,6 @@ Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) lik
|
|||||||
export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
|
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
|
## Vim integration
|
||||||
|
|
||||||
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).
|
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).
|
||||||
|
|||||||
201
docs/overrides/base.html
Normal file
201
docs/overrides/base.html
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
<!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.
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,4 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
<!-- Get rid of the next/prev buttons -->
|
|
||||||
{% block next_prev %}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -328,7 +328,7 @@ see the [Cabal user guide](https://cabal.readthedocs.io/en/stable/getting-starte
|
|||||||
<a href="https://hackage.haskell.org/" class="btn btn-primary" role="button">Discover Haskell packages</a>
|
<a href="https://hackage.haskell.org/" class="btn btn-primary" role="button">Discover Haskell packages</a>
|
||||||
<a href="https://hackage.haskell.org/package/base" class="btn btn-primary" role="button">The standard library</a>
|
<a href="https://hackage.haskell.org/package/base" class="btn btn-primary" role="button">The standard library</a>
|
||||||
<a href="https://haskell-language-server.readthedocs.io/en/stable/installation.html" class="btn btn-primary" role="button">Editor setup with HLS</a>
|
<a href="https://haskell-language-server.readthedocs.io/en/stable/installation.html" class="btn btn-primary" role="button">Editor setup with HLS</a>
|
||||||
<a href="https://play.haskell.org/" class="btn btn-primary" role="button">Online playground</a>
|
<a href="https://play-haskell.tomsmeding.com/play" class="btn btn-primary" role="button">Online playground</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## How to learn Haskell proper
|
## How to learn Haskell proper
|
||||||
|
|||||||
124
ghcup.cabal
124
ghcup.cabal
@@ -1,6 +1,6 @@
|
|||||||
cabal-version: 2.4
|
cabal-version: 3.0
|
||||||
name: ghcup
|
name: ghcup
|
||||||
version: 0.1.19.4
|
version: 0.1.18.1
|
||||||
license: LGPL-3.0-only
|
license: LGPL-3.0-only
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
copyright: Julian Ospald 2020
|
copyright: Julian Ospald 2020
|
||||||
@@ -25,10 +25,10 @@ extra-source-files:
|
|||||||
cbits/dirutils.h
|
cbits/dirutils.h
|
||||||
data/build_mk/cross
|
data/build_mk/cross
|
||||||
data/build_mk/default
|
data/build_mk/default
|
||||||
test/data/dir/.keep
|
|
||||||
test/data/file
|
|
||||||
test/golden/unix/GHCupInfo.json
|
test/golden/unix/GHCupInfo.json
|
||||||
test/golden/windows/GHCupInfo.json
|
test/golden/windows/GHCupInfo.json
|
||||||
|
test/data/file
|
||||||
|
test/data/dir/.keep
|
||||||
|
|
||||||
source-repository head
|
source-repository head
|
||||||
type: git
|
type: git
|
||||||
@@ -41,6 +41,11 @@ flag tui
|
|||||||
default: False
|
default: False
|
||||||
manual: True
|
manual: True
|
||||||
|
|
||||||
|
flag tui-ansi
|
||||||
|
description: Build the ansi-terminal powered tui (ghcup tui-ansi).
|
||||||
|
default: False
|
||||||
|
manual: True
|
||||||
|
|
||||||
flag internal-downloader
|
flag internal-downloader
|
||||||
description:
|
description:
|
||||||
Compile the internal downloader, which links against OpenSSL. This is disabled on windows.
|
Compile the internal downloader, which links against OpenSSL. This is disabled on windows.
|
||||||
@@ -65,6 +70,7 @@ library
|
|||||||
GHCup.List
|
GHCup.List
|
||||||
GHCup.Platform
|
GHCup.Platform
|
||||||
GHCup.Prelude
|
GHCup.Prelude
|
||||||
|
GHCup.Prelude.Ansi
|
||||||
GHCup.Prelude.File
|
GHCup.Prelude.File
|
||||||
GHCup.Prelude.File.Search
|
GHCup.Prelude.File.Search
|
||||||
GHCup.Prelude.Internal
|
GHCup.Prelude.Internal
|
||||||
@@ -124,7 +130,7 @@ library
|
|||||||
, directory ^>=1.3.6.0
|
, directory ^>=1.3.6.0
|
||||||
, disk-free-space ^>=0.1.0.1
|
, disk-free-space ^>=0.1.0.1
|
||||||
, exceptions ^>=0.10
|
, exceptions ^>=0.10
|
||||||
, filepath ^>=1.4.2.1
|
, filepath ==1.4.2.1
|
||||||
, haskus-utils-types ^>=1.5
|
, haskus-utils-types ^>=1.5
|
||||||
, haskus-utils-variant ^>=3.2.1
|
, haskus-utils-variant ^>=3.2.1
|
||||||
, libarchive ^>=3.0.3.0
|
, libarchive ^>=3.0.3.0
|
||||||
@@ -137,16 +143,16 @@ library
|
|||||||
, pretty-terminal ^>=0.1.0.0
|
, pretty-terminal ^>=0.1.0.0
|
||||||
, regex-posix ^>=0.96
|
, regex-posix ^>=0.96
|
||||||
, resourcet ^>=1.2.2
|
, resourcet ^>=1.2.2
|
||||||
, retry ^>=0.8.1.2 || ^>=0.9
|
, retry ^>=0.8.1.2
|
||||||
, safe ^>=0.3.18
|
, safe ^>=0.3.18
|
||||||
, safe-exceptions ^>=0.1
|
, safe-exceptions ^>=0.1
|
||||||
, split ^>=0.2.3.4
|
, split ^>=0.2.3.4
|
||||||
, streamly ^>=0.8.2
|
, streamly ^>=0.8.2
|
||||||
, strict-base ^>=0.4
|
, strict-base ^>=0.4
|
||||||
, template-haskell >=2.7 && <2.20
|
, template-haskell >=2.7 && <2.18
|
||||||
, temporary ^>=1.3
|
, temporary ^>=1.3
|
||||||
, text ^>=2.0
|
, text ^>=1.2.4.0
|
||||||
, time ^>=1.9.3 || ^>=1.10 || ^>=1.11
|
, time ^>=1.9.3
|
||||||
, transformers ^>=0.5
|
, transformers ^>=0.5
|
||||||
, unliftio-core ^>=0.2.0.1
|
, unliftio-core ^>=0.2.0.1
|
||||||
, unordered-containers ^>=0.2.10.0
|
, unordered-containers ^>=0.2.10.0
|
||||||
@@ -161,7 +167,7 @@ library
|
|||||||
exposed-modules: GHCup.Download.IOStreams
|
exposed-modules: GHCup.Download.IOStreams
|
||||||
cpp-options: -DINTERNAL_DOWNLOADER
|
cpp-options: -DINTERNAL_DOWNLOADER
|
||||||
build-depends:
|
build-depends:
|
||||||
, HsOpenSSL >=0.11.7.2
|
, HsOpenSSL >=0.11.4.18
|
||||||
, http-io-streams >=0.1.2.0
|
, http-io-streams >=0.1.2.0
|
||||||
, io-streams >=1.5.2.1
|
, io-streams >=1.5.2.1
|
||||||
, terminal-progress-bar >=0.4.1
|
, terminal-progress-bar >=0.4.1
|
||||||
@@ -185,21 +191,22 @@ library
|
|||||||
GHCup.Prelude.File.Posix.Foreign
|
GHCup.Prelude.File.Posix.Foreign
|
||||||
GHCup.Prelude.Posix
|
GHCup.Prelude.Posix
|
||||||
GHCup.Prelude.Process.Posix
|
GHCup.Prelude.Process.Posix
|
||||||
|
exposed-modules:
|
||||||
|
GHCup.Prelude.File.Posix.Traversals
|
||||||
|
|
||||||
exposed-modules: GHCup.Prelude.File.Posix.Traversals
|
|
||||||
include-dirs: cbits
|
include-dirs: cbits
|
||||||
includes: dirutils.h
|
includes: dirutils.h
|
||||||
install-includes: dirutils.h
|
install-includes: dirutils.h
|
||||||
c-sources: cbits/dirutils.c
|
c-sources: cbits/dirutils.c
|
||||||
build-depends:
|
build-depends:
|
||||||
, bz2 >=0.5.0.5 && <1.1
|
, bz2 >=0.5.0.5 && <1.1
|
||||||
, terminal-size ^>=0.3.3
|
, terminal-size ^>=0.3.2.1
|
||||||
, unix ^>=2.7
|
, unix ^>=2.7
|
||||||
, unix-bytestring ^>=0.3.7.3
|
, unix-bytestring ^>=0.3.7.3
|
||||||
|
|
||||||
if (flag(tui) && !os(windows))
|
if (flag(tui) && !os(windows))
|
||||||
cpp-options: -DBRICK
|
cpp-options: -DBRICK
|
||||||
build-depends: vty ^>=5.37
|
build-depends: vty >=5.28.2 && <5.34
|
||||||
|
|
||||||
executable ghcup
|
executable ghcup
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
@@ -218,7 +225,6 @@ executable ghcup
|
|||||||
GHCup.OptParse.Rm
|
GHCup.OptParse.Rm
|
||||||
GHCup.OptParse.Run
|
GHCup.OptParse.Run
|
||||||
GHCup.OptParse.Set
|
GHCup.OptParse.Set
|
||||||
GHCup.OptParse.Test
|
|
||||||
GHCup.OptParse.ToolRequirements
|
GHCup.OptParse.ToolRequirements
|
||||||
GHCup.OptParse.UnSet
|
GHCup.OptParse.UnSet
|
||||||
GHCup.OptParse.Upgrade
|
GHCup.OptParse.Upgrade
|
||||||
@@ -241,53 +247,60 @@ executable ghcup
|
|||||||
-fwarn-incomplete-record-updates -threaded
|
-fwarn-incomplete-record-updates -threaded
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
, aeson >=1.4
|
, aeson >=1.4
|
||||||
, aeson-pretty ^>=0.8.8
|
, aeson-pretty ^>=0.8.8
|
||||||
, async ^>=2.2.3
|
, async ^>=2.2.3
|
||||||
, base >=4.12 && <5
|
, base >=4.12 && <5
|
||||||
, bytestring >=0.10 && <0.12
|
, bytestring >=0.10 && <0.12
|
||||||
, cabal-install-parsers >=0.4.5
|
, cabal-plan ^>=0.7.2
|
||||||
, cabal-plan ^>=0.7.2
|
, cabal-install-parsers >=0.4.5
|
||||||
, containers ^>=0.6
|
, containers ^>=0.6
|
||||||
, deepseq ^>=1.4
|
, deepseq ^>=1.4
|
||||||
, directory ^>=1.3.6.0
|
, directory ^>=1.3.6.0
|
||||||
, filepath ^>=1.4.2.1
|
, filepath ==1.4.2.1
|
||||||
, ghcup
|
, ghcup
|
||||||
, haskus-utils-types ^>=1.5
|
, haskus-utils-types ^>=1.5
|
||||||
, haskus-utils-variant ^>=3.2.1
|
, haskus-utils-variant ^>=3.2.1
|
||||||
, libarchive ^>=3.0.3.0
|
, libarchive ^>=3.0.3.0
|
||||||
, megaparsec >=8.0.0 && <9.3
|
, megaparsec >=8.0.0 && <9.3
|
||||||
, mtl ^>=2.2
|
, mtl ^>=2.2
|
||||||
, optparse-applicative >=0.15.1.0 && <0.18
|
, optparse-applicative >=0.15.1.0 && <0.18
|
||||||
, pretty ^>=1.1.3.1
|
, pretty ^>=1.1.3.1
|
||||||
, pretty-terminal ^>=0.1.0.0
|
, pretty-terminal ^>=0.1.0.0
|
||||||
, process ^>=1.6.11.0
|
, process ^>=1.6.11.0
|
||||||
, resourcet ^>=1.2.2
|
, resourcet ^>=1.2.2
|
||||||
, safe ^>=0.3.18
|
, safe ^>=0.3.18
|
||||||
, safe-exceptions ^>=0.1
|
, safe-exceptions ^>=0.1
|
||||||
, tagsoup ^>=0.14
|
, tagsoup ^>=0.14
|
||||||
, template-haskell >=2.7 && <2.20
|
, template-haskell >=2.7 && <2.18
|
||||||
, temporary ^>=1.3
|
, temporary ^>=1.3
|
||||||
, text ^>=2.0
|
, text ^>=1.2.4.0
|
||||||
, time ^>=1.9.3 || ^>=1.10 || ^>=1.11
|
, unordered-containers ^>=0.2
|
||||||
, unordered-containers ^>=0.2
|
, uri-bytestring ^>=0.3.2.2
|
||||||
, uri-bytestring ^>=0.3.2.2
|
, utf8-string ^>=1.0
|
||||||
, utf8-string ^>=1.0
|
, vector ^>=0.12
|
||||||
, vector ^>=0.12
|
, versions >=4.0.1 && <5.1
|
||||||
, versions >=4.0.1 && <5.1
|
, yaml-streamly ^>=0.12.0
|
||||||
, yaml-streamly ^>=0.12.0
|
|
||||||
|
|
||||||
if flag(internal-downloader)
|
if flag(internal-downloader)
|
||||||
cpp-options: -DINTERNAL_DOWNLOADER
|
cpp-options: -DINTERNAL_DOWNLOADER
|
||||||
|
|
||||||
|
if flag(tui-ansi)
|
||||||
|
cpp-options: -DANSI
|
||||||
|
other-modules: AnsiMain
|
||||||
|
build-depends:
|
||||||
|
, ansi-terminal
|
||||||
|
, ansi-terminal-game
|
||||||
|
, transformers ^>=0.5
|
||||||
|
|
||||||
if (flag(tui) && !os(windows))
|
if (flag(tui) && !os(windows))
|
||||||
cpp-options: -DBRICK
|
cpp-options: -DBRICK
|
||||||
other-modules: BrickMain
|
other-modules: BrickMain
|
||||||
build-depends:
|
build-depends:
|
||||||
, brick ^>=1.5
|
, brick ^>=0.64
|
||||||
, transformers ^>=0.5
|
, transformers ^>=0.5
|
||||||
, unix ^>=2.7
|
, unix ^>=2.7
|
||||||
, vty ^>=5.37
|
, vty >=5.28.2 && <5.34
|
||||||
|
|
||||||
if os(windows)
|
if os(windows)
|
||||||
cpp-options: -DIS_WINDOWS
|
cpp-options: -DIS_WINDOWS
|
||||||
@@ -305,9 +318,9 @@ test-suite ghcup-test
|
|||||||
hs-source-dirs: test
|
hs-source-dirs: test
|
||||||
other-modules:
|
other-modules:
|
||||||
GHCup.ArbitraryTypes
|
GHCup.ArbitraryTypes
|
||||||
GHCup.Prelude.File.Posix.TraversalsSpec
|
|
||||||
GHCup.Types.JSONSpec
|
GHCup.Types.JSONSpec
|
||||||
GHCup.Utils.FileSpec
|
GHCup.Utils.FileSpec
|
||||||
|
GHCup.Prelude.File.Posix.TraversalsSpec
|
||||||
Spec
|
Spec
|
||||||
|
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
@@ -328,7 +341,7 @@ test-suite ghcup-test
|
|||||||
, bytestring >=0.10 && <0.12
|
, bytestring >=0.10 && <0.12
|
||||||
, containers ^>=0.6
|
, containers ^>=0.6
|
||||||
, directory ^>=1.3.6.0
|
, directory ^>=1.3.6.0
|
||||||
, filepath ^>=1.4.2.1
|
, filepath ==1.4.2.1
|
||||||
, generic-arbitrary >=0.1.0 && <0.2.1 || >=0.2.2 && <0.3
|
, generic-arbitrary >=0.1.0 && <0.2.1 || >=0.2.2 && <0.3
|
||||||
, ghcup
|
, ghcup
|
||||||
, hspec >=2.7.10 && <2.11
|
, hspec >=2.7.10 && <2.11
|
||||||
@@ -336,13 +349,12 @@ test-suite ghcup-test
|
|||||||
, QuickCheck ^>=2.14.1
|
, QuickCheck ^>=2.14.1
|
||||||
, quickcheck-arbitrary-adt ^>=0.3.1.0
|
, quickcheck-arbitrary-adt ^>=0.3.1.0
|
||||||
, streamly ^>=0.8.2
|
, streamly ^>=0.8.2
|
||||||
, time ^>=1.9.3 || ^>=1.10 || ^>=1.11
|
, text ^>=1.2.4.0
|
||||||
, text ^>=2.0
|
|
||||||
, uri-bytestring ^>=0.3.2.2
|
, uri-bytestring ^>=0.3.2.2
|
||||||
, versions >=4.0.1 && <5.1
|
, versions >=4.0.1 && <5.1
|
||||||
|
|
||||||
if os(windows)
|
if os(windows)
|
||||||
cpp-options: -DIS_WINDOWS
|
cpp-options: -DIS_WINDOWS
|
||||||
|
|
||||||
else
|
else
|
||||||
build-depends: unix ^>=2.7
|
build-depends:
|
||||||
|
, unix ^>=2.7
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ upgradeGHCup mtarget force' fatal = do
|
|||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
|
|
||||||
lift $ logInfo "Upgrading GHCup..."
|
lift $ logInfo "Upgrading GHCup..."
|
||||||
let latestVer = _tvVersion $ fst (fromJust (getLatest dls GHCup))
|
let latestVer = fst (fromJust (getLatest dls GHCup))
|
||||||
(Just ghcupPVPVer) <- pure $ pvpToVersion ghcUpVer ""
|
(Just ghcupPVPVer) <- pure $ pvpToVersion ghcUpVer ""
|
||||||
when (not force' && (latestVer <= ghcupPVPVer)) $ throwE NoUpdate
|
when (not force' && (latestVer <= ghcupPVPVer)) $ throwE NoUpdate
|
||||||
dli <- liftE $ getDownloadInfo GHCup latestVer
|
dli <- liftE $ getDownloadInfo GHCup latestVer
|
||||||
@@ -492,7 +492,7 @@ rmOldGHC :: ( MonadReader env m
|
|||||||
=> Excepts '[NotInstalled, UninstallFailed] m ()
|
=> Excepts '[NotInstalled, UninstallFailed] m ()
|
||||||
rmOldGHC = do
|
rmOldGHC = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let oldGHCs = toListOf (ix GHC % getTagged Old % to fst) dls
|
let oldGHCs = mkTVer <$> toListOf (ix GHC % getTagged Old % to fst) dls
|
||||||
ghcs <- lift $ fmap rights getInstalledGHCs
|
ghcs <- lift $ fmap rights getInstalledGHCs
|
||||||
forM_ ghcs $ \ghc -> when (ghc `elem` oldGHCs) $ rmGHCVer ghc
|
forM_ ghcs $ \ghc -> when (ghc `elem` oldGHCs) $ rmGHCVer ghc
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import Control.Monad.Trans.Resource
|
|||||||
hiding ( throwM )
|
hiding ( throwM )
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Ord
|
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Versions hiding ( patch )
|
import Data.Versions hiding ( patch )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
@@ -281,6 +280,6 @@ rmCabalVer ver = do
|
|||||||
|
|
||||||
when (Just ver == cSet) $ do
|
when (Just ver == cSet) $ do
|
||||||
cVers <- lift $ fmap rights getInstalledCabals
|
cVers <- lift $ fmap rights getInstalledCabals
|
||||||
case headMay . sortBy (comparing Down) $ cVers of
|
case headMay . reverse . sort $ cVers of
|
||||||
Just latestver -> setCabal latestver
|
Just latestver -> setCabal latestver
|
||||||
Nothing -> lift $ rmLink (binDir </> "cabal" <> exeExt)
|
Nothing -> lift $ rmLink (binDir </> "cabal" <> exeExt)
|
||||||
|
|||||||
@@ -263,14 +263,11 @@ getBase uri = do
|
|||||||
dlWithMod modTime json_file = do
|
dlWithMod modTime json_file = do
|
||||||
let (dir, fn) = splitFileName json_file
|
let (dir, fn) = splitFileName json_file
|
||||||
f <- liftE $ download uri' (Just $ over pathL' (<> ".sig") uri') Nothing Nothing dir (Just fn) True
|
f <- liftE $ download uri' (Just $ over pathL' (<> ".sig") uri') Nothing Nothing dir (Just fn) True
|
||||||
|
liftIO $ setModificationTime f modTime
|
||||||
-- make these failures non-fatal, also see:
|
liftIO $ setAccessTime f modTime
|
||||||
-- 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
|
pure f
|
||||||
|
|
||||||
|
|
||||||
getDownloadInfo :: ( MonadReader env m
|
getDownloadInfo :: ( MonadReader env m
|
||||||
, HasPlatformReq env
|
, HasPlatformReq env
|
||||||
, HasGHCupInfo env
|
, HasGHCupInfo env
|
||||||
@@ -282,20 +279,7 @@ getDownloadInfo :: ( MonadReader env m
|
|||||||
'[NoDownload]
|
'[NoDownload]
|
||||||
m
|
m
|
||||||
DownloadInfo
|
DownloadInfo
|
||||||
getDownloadInfo t v = getDownloadInfo' t (mkTVer v)
|
getDownloadInfo t v = do
|
||||||
|
|
||||||
getDownloadInfo' :: ( MonadReader env m
|
|
||||||
, HasPlatformReq env
|
|
||||||
, HasGHCupInfo env
|
|
||||||
)
|
|
||||||
=> Tool
|
|
||||||
-> GHCTargetVersion
|
|
||||||
-- ^ tool version
|
|
||||||
-> Excepts
|
|
||||||
'[NoDownload]
|
|
||||||
m
|
|
||||||
DownloadInfo
|
|
||||||
getDownloadInfo' t v = do
|
|
||||||
(PlatformRequest a p mv) <- lift getPlatformReq
|
(PlatformRequest a p mv) <- lift getPlatformReq
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
|
|
||||||
@@ -349,21 +333,19 @@ download :: ( MonadReader env m
|
|||||||
-> Maybe FilePath -- ^ optional filename
|
-> Maybe FilePath -- ^ optional filename
|
||||||
-> Bool -- ^ whether to read an write etags
|
-> Bool -- ^ whether to read an write etags
|
||||||
-> Excepts '[DigestError, ContentLengthError, DownloadFailed, GPGError] m FilePath
|
-> Excepts '[DigestError, ContentLengthError, DownloadFailed, GPGError] m FilePath
|
||||||
download rawUri gpgUri eDigest eCSize dest mfn etags
|
download uri gpgUri eDigest eCSize dest mfn etags
|
||||||
| scheme == "https" = liftE dl
|
| scheme == "https" = liftE dl
|
||||||
| scheme == "http" = liftE dl
|
| scheme == "http" = liftE dl
|
||||||
| scheme == "file" = do
|
| scheme == "file" = do
|
||||||
let destFile' = T.unpack . decUTF8Safe $ view pathL' rawUri
|
let destFile' = T.unpack . decUTF8Safe $ view pathL' uri
|
||||||
lift $ logDebug $ "using local file: " <> T.pack destFile'
|
lift $ logDebug $ "using local file: " <> T.pack destFile'
|
||||||
forM_ eDigest (liftE . flip checkDigest destFile')
|
forM_ eDigest (liftE . flip checkDigest destFile')
|
||||||
pure destFile'
|
pure destFile'
|
||||||
| otherwise = throwE $ DownloadFailed (variantFromValue UnsupportedScheme)
|
| otherwise = throwE $ DownloadFailed (variantFromValue UnsupportedScheme)
|
||||||
|
|
||||||
where
|
where
|
||||||
scheme = view (uriSchemeL' % schemeBSL') rawUri
|
scheme = view (uriSchemeL' % schemeBSL') uri
|
||||||
dl = do
|
dl = do
|
||||||
Settings{ mirrors } <- lift getSettings
|
|
||||||
let uri = applyMirrors mirrors rawUri
|
|
||||||
baseDestFile <- liftE . reThrowAll @_ @_ @'[DownloadFailed] DownloadFailed $ getDestFile uri mfn
|
baseDestFile <- liftE . reThrowAll @_ @_ @'[DownloadFailed] DownloadFailed $ getDestFile uri mfn
|
||||||
lift $ logInfo $ "downloading: " <> (decUTF8Safe . serializeURIRef') uri <> " as file " <> T.pack baseDestFile
|
lift $ logInfo $ "downloading: " <> (decUTF8Safe . serializeURIRef') uri <> " as file " <> T.pack baseDestFile
|
||||||
|
|
||||||
@@ -645,9 +627,7 @@ downloadCached dli mfn = do
|
|||||||
True -> downloadCached' dli mfn Nothing
|
True -> downloadCached' dli mfn Nothing
|
||||||
False -> do
|
False -> do
|
||||||
tmp <- lift withGHCupTmpDir
|
tmp <- lift withGHCupTmpDir
|
||||||
liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) (fromGHCupPath tmp) outputFileName False
|
liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) (fromGHCupPath tmp) mfn False
|
||||||
where
|
|
||||||
outputFileName = mfn <|> _dlOutput dli
|
|
||||||
|
|
||||||
|
|
||||||
downloadCached' :: ( MonadReader env m
|
downloadCached' :: ( MonadReader env m
|
||||||
@@ -666,7 +646,7 @@ downloadCached' :: ( MonadReader env m
|
|||||||
downloadCached' dli mfn mDestDir = do
|
downloadCached' dli mfn mDestDir = do
|
||||||
Dirs { cacheDir } <- lift getDirs
|
Dirs { cacheDir } <- lift getDirs
|
||||||
let destDir = fromMaybe (fromGHCupPath cacheDir) mDestDir
|
let destDir = fromMaybe (fromGHCupPath cacheDir) mDestDir
|
||||||
let fn = fromMaybe ((T.unpack . decUTF8Safe) $ urlBaseName $ view (dlUri % pathL') dli) outputFileName
|
let fn = fromMaybe ((T.unpack . decUTF8Safe) $ urlBaseName $ view (dlUri % pathL') dli) mfn
|
||||||
let cachfile = destDir </> fn
|
let cachfile = destDir </> fn
|
||||||
fileExists <- liftIO $ doesFileExist cachfile
|
fileExists <- liftIO $ doesFileExist cachfile
|
||||||
if
|
if
|
||||||
@@ -674,9 +654,7 @@ downloadCached' dli mfn mDestDir = do
|
|||||||
forM_ (view dlCSize dli) $ \s -> liftE $ checkCSize s cachfile
|
forM_ (view dlCSize dli) $ \s -> liftE $ checkCSize s cachfile
|
||||||
liftE $ checkDigest (view dlHash dli) cachfile
|
liftE $ checkDigest (view dlHash dli) cachfile
|
||||||
pure cachfile
|
pure cachfile
|
||||||
| otherwise -> liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) destDir outputFileName False
|
| otherwise -> liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) (_dlCSize dli) destDir mfn False
|
||||||
where
|
|
||||||
outputFileName = mfn <|> _dlOutput dli
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -773,17 +751,3 @@ getLastHeader = T.unlines . lastDef [] . filter (\x -> not (null x)) . splitOn [
|
|||||||
|
|
||||||
tmpFile :: FilePath -> FilePath
|
tmpFile :: FilePath -> FilePath
|
||||||
tmpFile = (<.> "tmp")
|
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
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,10 +35,7 @@ import URI.ByteString
|
|||||||
|
|
||||||
import qualified Data.Map.Strict as M
|
import qualified Data.Map.Strict as M
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Encoding as E
|
|
||||||
import qualified Data.Text.Encoding.Error as E
|
|
||||||
import Data.Data (Proxy(..))
|
import Data.Data (Proxy(..))
|
||||||
import Data.Time (Day)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -60,7 +57,6 @@ allHFError = unlines allErrors
|
|||||||
, let proxy = Proxy :: Proxy CopyError in format proxy
|
, let proxy = Proxy :: Proxy CopyError in format proxy
|
||||||
, let proxy = Proxy :: Proxy MergeFileTreeError in format proxy
|
, let proxy = Proxy :: Proxy MergeFileTreeError in format proxy
|
||||||
, let proxy = Proxy :: Proxy TagNotFound in format proxy
|
, let proxy = Proxy :: Proxy TagNotFound in format proxy
|
||||||
, let proxy = Proxy :: Proxy DayNotFound in format proxy
|
|
||||||
, let proxy = Proxy :: Proxy NextVerNotFound in format proxy
|
, let proxy = Proxy :: Proxy NextVerNotFound in format proxy
|
||||||
, let proxy = Proxy :: Proxy AlreadyInstalled in format proxy
|
, let proxy = Proxy :: Proxy AlreadyInstalled in format proxy
|
||||||
, let proxy = Proxy :: Proxy DirNotEmpty in format proxy
|
, let proxy = Proxy :: Proxy DirNotEmpty in format proxy
|
||||||
@@ -86,12 +82,10 @@ allHFError = unlines allErrors
|
|||||||
, let proxy = Proxy :: Proxy HadrianNotFound in format proxy
|
, let proxy = Proxy :: Proxy HadrianNotFound in format proxy
|
||||||
, let proxy = Proxy :: Proxy ToolShadowed in format proxy
|
, let proxy = Proxy :: Proxy ToolShadowed in format proxy
|
||||||
, let proxy = Proxy :: Proxy ContentLengthError in format proxy
|
, let proxy = Proxy :: Proxy ContentLengthError in format proxy
|
||||||
, let proxy = Proxy :: Proxy DuplicateReleaseChannel in format proxy
|
|
||||||
, ""
|
, ""
|
||||||
, "# high level errors (4000+)"
|
, "# high level errors (5000+)"
|
||||||
, let proxy = Proxy :: Proxy DownloadFailed in format proxy
|
, let proxy = Proxy :: Proxy DownloadFailed in format proxy
|
||||||
, let proxy = Proxy :: Proxy InstallSetError 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 BuildFailed in format proxy
|
||||||
, let proxy = Proxy :: Proxy GHCupSetError in format proxy
|
, let proxy = Proxy :: Proxy GHCupSetError in format proxy
|
||||||
, ""
|
, ""
|
||||||
@@ -167,6 +161,7 @@ prettyHFError e =
|
|||||||
let errorCode = "GHCup-" <> padIntAndShow (eNum e)
|
let errorCode = "GHCup-" <> padIntAndShow (eNum e)
|
||||||
in ("[" <> linkEscapeCode errorCode (hfErrorLink errorCode) <> "] ") <> prettyShow e
|
in ("[" <> linkEscapeCode errorCode (hfErrorLink errorCode) <> "] ") <> prettyShow e
|
||||||
where
|
where
|
||||||
|
linkEscapeCode linkText link = "\ESC]8;;" <> link <> "\ESC\\" <> linkText <> "\ESC]8;;\ESC\\"
|
||||||
hfErrorLink errorCode = "https://errors.haskell.org/messages/" <> errorCode
|
hfErrorLink errorCode = "https://errors.haskell.org/messages/" <> errorCode
|
||||||
padIntAndShow i
|
padIntAndShow i
|
||||||
| i < 10 = "0000" <> show i
|
| i < 10 = "0000" <> show i
|
||||||
@@ -183,9 +178,6 @@ class HFErrorProject a where
|
|||||||
|
|
||||||
eDesc :: Proxy a -> String
|
eDesc :: Proxy a -> String
|
||||||
|
|
||||||
linkEscapeCode :: String -> String -> String
|
|
||||||
linkEscapeCode linkText link = "\ESC]8;;" <> link <> "\ESC\\" <> linkText <> "\ESC]8;;\ESC\\"
|
|
||||||
|
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
--[ Low-level errors ]--
|
--[ Low-level errors ]--
|
||||||
@@ -313,21 +305,6 @@ instance HFErrorProject TagNotFound where
|
|||||||
eBase _ = 90
|
eBase _ = 90
|
||||||
eDesc _ = "Unable to find a tag of a tool"
|
eDesc _ = "Unable to find a tag of a tool"
|
||||||
|
|
||||||
-- | Unable to find a release day of a tool
|
|
||||||
data DayNotFound = DayNotFound Day Tool (Maybe Day)
|
|
||||||
deriving Show
|
|
||||||
|
|
||||||
instance Pretty DayNotFound where
|
|
||||||
pPrint (DayNotFound day tool Nothing) =
|
|
||||||
text "Unable to find release date" <+> text (show day) <+> text "of tool" <+> pPrint tool
|
|
||||||
pPrint (DayNotFound day tool (Just alternateDay)) =
|
|
||||||
text "Unable to find release date" <+> text (show day) <+> text "of tool" <+> pPrint tool <+>
|
|
||||||
text "but found an alternative date" <+> text (show alternateDay)
|
|
||||||
|
|
||||||
instance HFErrorProject DayNotFound where
|
|
||||||
eBase _ = 95
|
|
||||||
eDesc _ = "Unable to find a release date of a tool"
|
|
||||||
|
|
||||||
-- | Unable to find the next version of a tool (the one after the currently
|
-- | Unable to find the next version of a tool (the one after the currently
|
||||||
-- set one).
|
-- set one).
|
||||||
data NextVerNotFound = NextVerNotFound Tool
|
data NextVerNotFound = NextVerNotFound Tool
|
||||||
@@ -660,19 +637,6 @@ instance HFErrorProject ContentLengthError where
|
|||||||
eBase _ = 340
|
eBase _ = 340
|
||||||
eDesc _ = "File content length verification failed"
|
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 ]--
|
--[ High-level errors ]--
|
||||||
-------------------------
|
-------------------------
|
||||||
@@ -711,22 +675,6 @@ instance HFErrorProject InstallSetError where
|
|||||||
eDesc _ = "Installation or setting the tool failed."
|
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.
|
-- | A build failed.
|
||||||
data BuildFailed = forall es . (ToVariantMaybe BuildFailed es, PopVariant BuildFailed es, Pretty (V es), Show (V es), HFErrorProject (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)
|
||||||
|
|
||||||
|
|||||||
217
lib/GHCup/GHC.hs
217
lib/GHCup/GHC.hs
@@ -80,152 +80,12 @@ import qualified Data.Text.Encoding as E
|
|||||||
import qualified Text.Megaparsec as MP
|
import qualified Text.Megaparsec as MP
|
||||||
|
|
||||||
|
|
||||||
data GHCVer = SourceDist Version
|
data GHCVer v = SourceDist v
|
||||||
| GitDist GitBranch
|
| GitDist GitBranch
|
||||||
| RemoteDist URI
|
| RemoteDist URI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------------
|
|
||||||
--[ Tool testing ]--
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
testGHCVer :: ( MonadFail m
|
|
||||||
, MonadMask m
|
|
||||||
, MonadCatch m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, HasPlatformReq env
|
|
||||||
, HasGHCupInfo env
|
|
||||||
, HasLog env
|
|
||||||
, MonadResource m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadUnliftIO m
|
|
||||||
)
|
|
||||||
=> GHCTargetVersion
|
|
||||||
-> [T.Text]
|
|
||||||
-> Excepts
|
|
||||||
'[ DigestError
|
|
||||||
, ContentLengthError
|
|
||||||
, GPGError
|
|
||||||
, DownloadFailed
|
|
||||||
, NoDownload
|
|
||||||
, ArchiveResult
|
|
||||||
, TarDirDoesNotExist
|
|
||||||
, UnknownArchive
|
|
||||||
, TestFailed
|
|
||||||
]
|
|
||||||
m
|
|
||||||
()
|
|
||||||
testGHCVer ver addMakeArgs = do
|
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
|
||||||
|
|
||||||
dlInfo <-
|
|
||||||
preview (ix GHC % ix ver % viTestDL % _Just) dls
|
|
||||||
?? NoDownload
|
|
||||||
|
|
||||||
liftE $ testGHCBindist dlInfo ver addMakeArgs
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
testGHCBindist :: ( MonadFail m
|
|
||||||
, MonadMask m
|
|
||||||
, MonadCatch m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, HasPlatformReq env
|
|
||||||
, HasGHCupInfo env
|
|
||||||
, HasLog env
|
|
||||||
, MonadResource m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadUnliftIO m
|
|
||||||
)
|
|
||||||
=> DownloadInfo
|
|
||||||
-> GHCTargetVersion
|
|
||||||
-> [T.Text]
|
|
||||||
-> Excepts
|
|
||||||
'[ DigestError
|
|
||||||
, ContentLengthError
|
|
||||||
, GPGError
|
|
||||||
, DownloadFailed
|
|
||||||
, NoDownload
|
|
||||||
, ArchiveResult
|
|
||||||
, TarDirDoesNotExist
|
|
||||||
, UnknownArchive
|
|
||||||
, TestFailed
|
|
||||||
]
|
|
||||||
m
|
|
||||||
()
|
|
||||||
testGHCBindist dlinfo ver addMakeArgs = do
|
|
||||||
-- download (or use cached version)
|
|
||||||
dl <- liftE $ downloadCached dlinfo Nothing
|
|
||||||
|
|
||||||
liftE $ testPackedGHC dl (view dlSubdir dlinfo) ver addMakeArgs
|
|
||||||
|
|
||||||
|
|
||||||
testPackedGHC :: ( MonadMask m
|
|
||||||
, MonadCatch m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, HasPlatformReq env
|
|
||||||
, HasSettings env
|
|
||||||
, MonadThrow m
|
|
||||||
, HasLog env
|
|
||||||
, MonadIO m
|
|
||||||
, MonadUnliftIO m
|
|
||||||
, MonadFail m
|
|
||||||
, MonadResource m
|
|
||||||
)
|
|
||||||
=> FilePath -- ^ Path to the packed GHC bindist
|
|
||||||
-> Maybe TarDir -- ^ Subdir of the archive
|
|
||||||
-> GHCTargetVersion -- ^ The GHC version
|
|
||||||
-> [T.Text] -- ^ additional make args
|
|
||||||
-> Excepts
|
|
||||||
'[ ArchiveResult, UnknownArchive, TarDirDoesNotExist, TestFailed ] m ()
|
|
||||||
testPackedGHC dl msubdir ver addMakeArgs = do
|
|
||||||
-- unpack
|
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
|
||||||
liftE $ cleanUpOnError tmpUnpack (unpackToDir (fromGHCupPath tmpUnpack) dl)
|
|
||||||
|
|
||||||
-- the subdir of the archive where we do the work
|
|
||||||
workdir <- maybe (pure tmpUnpack)
|
|
||||||
(liftE . intoSubdir tmpUnpack)
|
|
||||||
msubdir
|
|
||||||
|
|
||||||
reThrowAll @_ @'[ArchiveResult, UnknownArchive, TarDirDoesNotExist, ProcessError]
|
|
||||||
(TestFailed (fromGHCupPath workdir)) $ liftE $ runBuildAction tmpUnpack
|
|
||||||
(testUnpackedGHC workdir ver addMakeArgs)
|
|
||||||
|
|
||||||
testUnpackedGHC :: ( MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, MonadThrow m
|
|
||||||
, HasLog env
|
|
||||||
, MonadIO m
|
|
||||||
)
|
|
||||||
=> GHCupPath -- ^ Path to the unpacked GHC bindist (where the make file resides)
|
|
||||||
-> GHCTargetVersion -- ^ The GHC version
|
|
||||||
-> [T.Text] -- ^ additional configure args for bindist
|
|
||||||
-> Excepts '[ProcessError] m ()
|
|
||||||
testUnpackedGHC path tver addMakeArgs = do
|
|
||||||
lift $ logInfo $ "Testing GHC version " <> tVerToText tver <> "!"
|
|
||||||
ghcDir <- lift $ ghcupGHCDir tver
|
|
||||||
let ghcBinDir = fromGHCupPath ghcDir </> "bin"
|
|
||||||
env <- liftIO $ addToPath ghcBinDir False
|
|
||||||
|
|
||||||
lEM $ make' (fmap T.unpack addMakeArgs)
|
|
||||||
(Just $ fromGHCupPath path)
|
|
||||||
"ghc-test"
|
|
||||||
(Just $ ("STAGE1_GHC", maybe "" (T.unpack . (<> "-")) (_tvTarget tver)
|
|
||||||
<> "ghc-"
|
|
||||||
<> T.unpack (prettyVer $ _tvVersion tver)) : env)
|
|
||||||
pure ()
|
|
||||||
|
|
||||||
|
|
||||||
---------------------
|
---------------------
|
||||||
--[ Tool fetching ]--
|
--[ Tool fetching ]--
|
||||||
---------------------
|
---------------------
|
||||||
@@ -245,7 +105,7 @@ fetchGHCSrc :: ( MonadFail m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
)
|
)
|
||||||
=> GHCTargetVersion
|
=> Version
|
||||||
-> Maybe FilePath
|
-> Maybe FilePath
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ DigestError
|
'[ DigestError
|
||||||
@@ -285,7 +145,7 @@ installGHCBindist :: ( MonadFail m
|
|||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
)
|
)
|
||||||
=> DownloadInfo -- ^ where/how to download
|
=> DownloadInfo -- ^ where/how to download
|
||||||
-> GHCTargetVersion -- ^ the version to install
|
-> Version -- ^ the version to install
|
||||||
-> InstallDir
|
-> InstallDir
|
||||||
-> Bool -- ^ Force install
|
-> Bool -- ^ Force install
|
||||||
-> [T.Text] -- ^ additional configure args for bindist
|
-> [T.Text] -- ^ additional configure args for bindist
|
||||||
@@ -308,8 +168,10 @@ installGHCBindist :: ( MonadFail m
|
|||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
installGHCBindist dlinfo tver installDir forceInstall addConfArgs = do
|
installGHCBindist dlinfo ver installDir forceInstall addConfArgs = do
|
||||||
lift $ logDebug $ "Requested to install GHC with " <> tVerToText tver
|
let tver = mkTVer ver
|
||||||
|
|
||||||
|
lift $ logDebug $ "Requested to install GHC with " <> prettyVer ver
|
||||||
|
|
||||||
regularGHCInstalled <- lift $ ghcInstalled tver
|
regularGHCInstalled <- lift $ ghcInstalled tver
|
||||||
|
|
||||||
@@ -317,7 +179,7 @@ installGHCBindist dlinfo tver installDir forceInstall addConfArgs = do
|
|||||||
| not forceInstall
|
| not forceInstall
|
||||||
, regularGHCInstalled
|
, regularGHCInstalled
|
||||||
, GHCupInternal <- installDir -> do
|
, GHCupInternal <- installDir -> do
|
||||||
throwE $ AlreadyInstalled GHC (_tvVersion tver)
|
throwE $ AlreadyInstalled GHC ver
|
||||||
|
|
||||||
| forceInstall
|
| forceInstall
|
||||||
, regularGHCInstalled
|
, regularGHCInstalled
|
||||||
@@ -336,12 +198,12 @@ installGHCBindist dlinfo tver installDir forceInstall addConfArgs = do
|
|||||||
case installDir of
|
case installDir of
|
||||||
IsolateDir isoDir -> do -- isolated install
|
IsolateDir isoDir -> do -- isolated install
|
||||||
lift $ logInfo $ "isolated installing GHC to " <> T.pack isoDir
|
lift $ logInfo $ "isolated installing GHC to " <> T.pack isoDir
|
||||||
liftE $ installPackedGHC dl (view dlSubdir dlinfo) (IsolateDirResolved isoDir) tver forceInstall addConfArgs
|
liftE $ installPackedGHC dl (view dlSubdir dlinfo) (IsolateDirResolved isoDir) ver forceInstall addConfArgs
|
||||||
GHCupInternal -> do -- regular install
|
GHCupInternal -> do -- regular install
|
||||||
-- prepare paths
|
-- prepare paths
|
||||||
ghcdir <- lift $ ghcupGHCDir tver
|
ghcdir <- lift $ ghcupGHCDir tver
|
||||||
|
|
||||||
liftE $ installPackedGHC dl (view dlSubdir dlinfo) (GHCupDir ghcdir) tver forceInstall addConfArgs
|
liftE $ installPackedGHC dl (view dlSubdir dlinfo) (GHCupDir ghcdir) ver forceInstall addConfArgs
|
||||||
|
|
||||||
-- make symlinks & stuff when regular install,
|
-- make symlinks & stuff when regular install,
|
||||||
liftE $ postGHCInstall tver
|
liftE $ postGHCInstall tver
|
||||||
@@ -375,7 +237,7 @@ installPackedGHC :: ( MonadMask m
|
|||||||
=> FilePath -- ^ Path to the packed GHC bindist
|
=> FilePath -- ^ Path to the packed GHC bindist
|
||||||
-> Maybe TarDir -- ^ Subdir of the archive
|
-> Maybe TarDir -- ^ Subdir of the archive
|
||||||
-> InstallDirResolved
|
-> InstallDirResolved
|
||||||
-> GHCTargetVersion -- ^ The GHC version
|
-> Version -- ^ The GHC version
|
||||||
-> Bool -- ^ Force install
|
-> Bool -- ^ Force install
|
||||||
-> [T.Text] -- ^ additional configure args for bindist
|
-> [T.Text] -- ^ additional configure args for bindist
|
||||||
-> Excepts
|
-> Excepts
|
||||||
@@ -423,17 +285,17 @@ installUnpackedGHC :: ( MonadReader env m
|
|||||||
)
|
)
|
||||||
=> GHCupPath -- ^ Path to the unpacked GHC bindist (where the configure script resides)
|
=> GHCupPath -- ^ Path to the unpacked GHC bindist (where the configure script resides)
|
||||||
-> InstallDirResolved -- ^ Path to install to
|
-> InstallDirResolved -- ^ Path to install to
|
||||||
-> GHCTargetVersion -- ^ The GHC version
|
-> Version -- ^ The GHC version
|
||||||
-> Bool -- ^ Force install
|
-> Bool -- ^ Force install
|
||||||
-> [T.Text] -- ^ additional configure args for bindist
|
-> [T.Text] -- ^ additional configure args for bindist
|
||||||
-> Excepts '[ProcessError, MergeFileTreeError] m ()
|
-> Excepts '[ProcessError, MergeFileTreeError] m ()
|
||||||
installUnpackedGHC path inst tver forceInstall addConfArgs
|
installUnpackedGHC path inst ver forceInstall addConfArgs
|
||||||
| isWindows = do
|
| isWindows = do
|
||||||
lift $ logInfo "Installing GHC (this may take a while)"
|
lift $ logInfo "Installing GHC (this may take a while)"
|
||||||
-- Windows bindists are relocatable and don't need
|
-- Windows bindists are relocatable and don't need
|
||||||
-- to run configure.
|
-- to run configure.
|
||||||
-- We also must make sure to preserve mtime to not confuse ghc-pkg.
|
-- We also must make sure to preserve mtime to not confuse ghc-pkg.
|
||||||
liftE $ mergeFileTree path inst GHC tver $ \source dest -> do
|
liftE $ mergeFileTree path inst GHC (mkTVer ver) $ \source dest -> do
|
||||||
mtime <- liftIO $ ifM (pathIsSymbolicLink source) (pure Nothing) (Just <$> getModificationTime source)
|
mtime <- liftIO $ ifM (pathIsSymbolicLink source) (pure Nothing) (Just <$> getModificationTime source)
|
||||||
when forceInstall $ hideError doesNotExistErrorType $ hideError InappropriateType $ recycleFile dest
|
when forceInstall $ hideError doesNotExistErrorType $ hideError InappropriateType $ recycleFile dest
|
||||||
liftIO $ moveFilePortable source dest
|
liftIO $ moveFilePortable source dest
|
||||||
@@ -442,7 +304,7 @@ installUnpackedGHC path inst tver forceInstall addConfArgs
|
|||||||
PlatformRequest {..} <- lift getPlatformReq
|
PlatformRequest {..} <- lift getPlatformReq
|
||||||
|
|
||||||
let ldOverride
|
let ldOverride
|
||||||
| _tvVersion tver >= [vver|8.2.2|]
|
| ver >= [vver|8.2.2|]
|
||||||
, _rPlatform `elem` [Linux Alpine, Darwin]
|
, _rPlatform `elem` [Linux Alpine, Darwin]
|
||||||
= ["--disable-ld-override"]
|
= ["--disable-ld-override"]
|
||||||
| otherwise
|
| otherwise
|
||||||
@@ -451,7 +313,7 @@ installUnpackedGHC path inst tver forceInstall addConfArgs
|
|||||||
lift $ logInfo "Installing GHC (this may take a while)"
|
lift $ logInfo "Installing GHC (this may take a while)"
|
||||||
lEM $ execLogged "sh"
|
lEM $ execLogged "sh"
|
||||||
("./configure" : ("--prefix=" <> fromInstallDir inst)
|
("./configure" : ("--prefix=" <> fromInstallDir inst)
|
||||||
: (maybe mempty (\x -> ["--target=" <> T.unpack x]) (_tvTarget tver) <> ldOverride <> (T.unpack <$> addConfArgs))
|
: (ldOverride <> (T.unpack <$> addConfArgs))
|
||||||
)
|
)
|
||||||
(Just $ fromGHCupPath path)
|
(Just $ fromGHCupPath path)
|
||||||
"ghc-configure"
|
"ghc-configure"
|
||||||
@@ -462,7 +324,7 @@ installUnpackedGHC path inst tver forceInstall addConfArgs
|
|||||||
liftE $ mergeFileTree (tmpInstallDest `appendGHCupPath` dropDrive (fromInstallDir inst))
|
liftE $ mergeFileTree (tmpInstallDest `appendGHCupPath` dropDrive (fromInstallDir inst))
|
||||||
inst
|
inst
|
||||||
GHC
|
GHC
|
||||||
tver
|
(mkTVer ver)
|
||||||
(\f t -> liftIO $ do
|
(\f t -> liftIO $ do
|
||||||
mtime <- ifM (pathIsSymbolicLink f) (pure Nothing) (Just <$> getModificationTime f)
|
mtime <- ifM (pathIsSymbolicLink f) (pure Nothing) (Just <$> getModificationTime f)
|
||||||
install f t (not forceInstall)
|
install f t (not forceInstall)
|
||||||
@@ -489,7 +351,7 @@ installGHCBin :: ( MonadFail m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
)
|
)
|
||||||
=> GHCTargetVersion -- ^ the version to install
|
=> Version -- ^ the version to install
|
||||||
-> InstallDir
|
-> InstallDir
|
||||||
-> Bool -- ^ force install
|
-> Bool -- ^ force install
|
||||||
-> [T.Text] -- ^ additional configure args for bindist
|
-> [T.Text] -- ^ additional configure args for bindist
|
||||||
@@ -512,9 +374,9 @@ installGHCBin :: ( MonadFail m
|
|||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
installGHCBin tver installDir forceInstall addConfArgs = do
|
installGHCBin ver installDir forceInstall addConfArgs = do
|
||||||
dlinfo <- liftE $ getDownloadInfo' GHC tver
|
dlinfo <- liftE $ getDownloadInfo GHC ver
|
||||||
liftE $ installGHCBindist dlinfo tver installDir forceInstall addConfArgs
|
liftE $ installGHCBindist dlinfo ver installDir forceInstall addConfArgs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -755,8 +617,7 @@ compileGHC :: ( MonadMask m
|
|||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> GHCVer
|
=> GHCVer GHCTargetVersion
|
||||||
-> Maybe Text -- ^ cross target
|
|
||||||
-> Maybe Version -- ^ overwrite version
|
-> Maybe Version -- ^ overwrite version
|
||||||
-> Either Version FilePath -- ^ version to bootstrap with
|
-> Either Version FilePath -- ^ version to bootstrap with
|
||||||
-> Maybe Int -- ^ jobs
|
-> Maybe Int -- ^ jobs
|
||||||
@@ -793,19 +654,19 @@ compileGHC :: ( MonadMask m
|
|||||||
]
|
]
|
||||||
m
|
m
|
||||||
GHCTargetVersion
|
GHCTargetVersion
|
||||||
compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs buildFlavour hadrian installDir
|
compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadrian installDir
|
||||||
= do
|
= do
|
||||||
PlatformRequest { .. } <- lift getPlatformReq
|
PlatformRequest { .. } <- lift getPlatformReq
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
|
|
||||||
(workdir, tmpUnpack, tver) <- case targetGhc of
|
(workdir, tmpUnpack, tver) <- case targetGhc of
|
||||||
-- unpack from version tarball
|
-- unpack from version tarball
|
||||||
SourceDist ver -> do
|
SourceDist tver -> do
|
||||||
lift $ logDebug $ "Requested to compile: " <> prettyVer ver <> " with " <> either prettyVer T.pack bstrap
|
lift $ logDebug $ "Requested to compile: " <> tVerToText tver <> " with " <> either prettyVer T.pack bstrap
|
||||||
|
|
||||||
-- download source tarball
|
-- download source tarball
|
||||||
dlInfo <-
|
dlInfo <-
|
||||||
preview (ix GHC % ix (mkTVer ver) % viSourceDL % _Just) dls
|
preview (ix GHC % ix (tver ^. tvVersion) % viSourceDL % _Just) dls
|
||||||
?? NoDownload
|
?? NoDownload
|
||||||
dl <- liftE $ downloadCached dlInfo Nothing
|
dl <- liftE $ downloadCached dlInfo Nothing
|
||||||
|
|
||||||
@@ -819,7 +680,7 @@ compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs build
|
|||||||
(view dlSubdir dlInfo)
|
(view dlSubdir dlInfo)
|
||||||
liftE $ applyAnyPatch patches (fromGHCupPath workdir)
|
liftE $ applyAnyPatch patches (fromGHCupPath workdir)
|
||||||
|
|
||||||
pure (workdir, tmpUnpack, Just (GHCTargetVersion crossTarget ver))
|
pure (workdir, tmpUnpack, Just tver)
|
||||||
|
|
||||||
RemoteDist uri -> do
|
RemoteDist uri -> do
|
||||||
lift $ logDebug $ "Requested to compile (from uri): " <> T.pack (show uri)
|
lift $ logDebug $ "Requested to compile (from uri): " <> T.pack (show uri)
|
||||||
@@ -843,7 +704,7 @@ compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs build
|
|||||||
|
|
||||||
let workdir = appendGHCupPath tmpUnpack (takeDirectory bf)
|
let workdir = appendGHCupPath tmpUnpack (takeDirectory bf)
|
||||||
|
|
||||||
pure (workdir, tmpUnpack, GHCTargetVersion crossTarget <$> tver)
|
pure (workdir, tmpUnpack, mkTVer <$> tver)
|
||||||
|
|
||||||
-- clone from git
|
-- clone from git
|
||||||
GitDist GitBranch{..} -> do
|
GitDist GitBranch{..} -> do
|
||||||
@@ -900,10 +761,10 @@ compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs build
|
|||||||
|
|
||||||
pure tver
|
pure tver
|
||||||
|
|
||||||
pure (tmpUnpack, tmpUnpack, GHCTargetVersion crossTarget <$> tver)
|
pure (tmpUnpack, tmpUnpack, mkTVer <$> tver)
|
||||||
-- the version that's installed may differ from the
|
-- the version that's installed may differ from the
|
||||||
-- compiled version, so the user can overwrite it
|
-- compiled version, so the user can overwrite it
|
||||||
installVer <- if | Just ov' <- ov -> pure (GHCTargetVersion crossTarget ov')
|
installVer <- if | Just ov' <- ov -> pure (mkTVer ov')
|
||||||
| Just tver' <- tver -> pure tver'
|
| Just tver' <- tver -> pure tver'
|
||||||
| otherwise -> fail "Newer GHCs don't support discovering the version in git. Complain to GHC devs: https://gitlab.haskell.org/ghc/ghc/-/issues/22322"
|
| otherwise -> fail "Newer GHCs don't support discovering the version in git. Complain to GHC devs: https://gitlab.haskell.org/ghc/ghc/-/issues/22322"
|
||||||
|
|
||||||
@@ -949,7 +810,7 @@ compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs build
|
|||||||
liftE $ installPackedGHC bindist
|
liftE $ installPackedGHC bindist
|
||||||
(Just $ RegexDir "ghc-.*")
|
(Just $ RegexDir "ghc-.*")
|
||||||
ghcdir
|
ghcdir
|
||||||
installVer
|
(installVer ^. tvVersion)
|
||||||
False -- not a force install, since we already overwrite when compiling.
|
False -- not a force install, since we already overwrite when compiling.
|
||||||
[]
|
[]
|
||||||
|
|
||||||
@@ -988,9 +849,9 @@ compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs build
|
|||||||
defaultConf =
|
defaultConf =
|
||||||
let cross_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/cross" >> runIO (readFile "data/build_mk/cross")))
|
let cross_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/cross" >> runIO (readFile "data/build_mk/cross")))
|
||||||
default_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/default" >> runIO (readFile "data/build_mk/default")))
|
default_mk = $(LitE . StringL <$> (qAddDependentFile "data/build_mk/default" >> runIO (readFile "data/build_mk/default")))
|
||||||
in case crossTarget of
|
in case targetGhc of
|
||||||
Just _ -> cross_mk
|
SourceDist (GHCTargetVersion (Just _) _) -> cross_mk
|
||||||
_ -> default_mk
|
_ -> default_mk
|
||||||
|
|
||||||
compileHadrianBindist :: ( MonadReader env m
|
compileHadrianBindist :: ( MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
@@ -1016,6 +877,8 @@ compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs build
|
|||||||
m
|
m
|
||||||
(Maybe FilePath) -- ^ output path of bindist, None for cross
|
(Maybe FilePath) -- ^ output path of bindist, None for cross
|
||||||
compileHadrianBindist tver workdir ghcdir = do
|
compileHadrianBindist tver workdir ghcdir = do
|
||||||
|
lEM $ execWithGhcEnv "python3" ["./boot"] (Just workdir) "ghc-bootstrap"
|
||||||
|
|
||||||
liftE $ configureBindist tver workdir ghcdir
|
liftE $ configureBindist tver workdir ghcdir
|
||||||
|
|
||||||
lift $ logInfo "Building (this may take a while)..."
|
lift $ logInfo "Building (this may take a while)..."
|
||||||
@@ -1163,8 +1026,8 @@ compileGHC targetGhc crossTarget ov bstrap jobs mbuildConfig patches aargs build
|
|||||||
let lines' = fmap T.strip . T.lines $ decUTF8Safe c
|
let lines' = fmap T.strip . T.lines $ decUTF8Safe c
|
||||||
|
|
||||||
-- for cross, we need Stage1Only
|
-- for cross, we need Stage1Only
|
||||||
case crossTarget of
|
case targetGhc of
|
||||||
Just _ -> when ("Stage1Only = YES" `notElem` lines') $ throwE
|
SourceDist (GHCTargetVersion (Just _) _) -> when ("Stage1Only = YES" `notElem` lines') $ throwE
|
||||||
(InvalidBuildConfig
|
(InvalidBuildConfig
|
||||||
[s|Cross compiling needs to be a Stage1 build, add "Stage1Only = YES" to your config!|]
|
[s|Cross compiling needs to be a Stage1 build, add "Stage1Only = YES" to your config!|]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ import Control.Monad.Trans.Resource
|
|||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Ord
|
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.String ( fromString )
|
import Data.String ( fromString )
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
@@ -369,7 +368,7 @@ compileHLS targetHLS ghcs jobs ov installDir cabalProject cabalProjectLocal upda
|
|||||||
|
|
||||||
-- download source tarball
|
-- download source tarball
|
||||||
dlInfo <-
|
dlInfo <-
|
||||||
preview (ix HLS % ix (mkTVer tver) % viSourceDL % _Just) dls
|
preview (ix HLS % ix tver % viSourceDL % _Just) dls
|
||||||
?? NoDownload
|
?? NoDownload
|
||||||
dl <- liftE $ downloadCached dlInfo Nothing
|
dl <- liftE $ downloadCached dlInfo Nothing
|
||||||
|
|
||||||
@@ -705,7 +704,7 @@ rmHLSVer ver = do
|
|||||||
when (Just ver == isHlsSet) $ do
|
when (Just ver == isHlsSet) $ do
|
||||||
-- set latest hls
|
-- set latest hls
|
||||||
hlsVers <- lift $ fmap rights getInstalledHLSs
|
hlsVers <- lift $ fmap rights getInstalledHLSs
|
||||||
case headMay . sortBy (comparing Down) $ hlsVers of
|
case headMay . reverse . sort $ hlsVers of
|
||||||
Just latestver -> liftE $ setHLS latestver SetHLSOnly Nothing
|
Just latestver -> liftE $ setHLS latestver SetHLSOnly Nothing
|
||||||
Nothing -> pure ()
|
Nothing -> pure ()
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import Data.Either
|
|||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Time.Calendar ( Day )
|
|
||||||
import Data.Versions hiding ( patch )
|
import Data.Versions hiding ( patch )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Optics
|
import Optics
|
||||||
@@ -62,9 +61,9 @@ import qualified Data.Text as T
|
|||||||
|
|
||||||
|
|
||||||
-- | Filter data type for 'listVersions'.
|
-- | Filter data type for 'listVersions'.
|
||||||
data ListCriteria = ListInstalled Bool
|
data ListCriteria = ListInstalled
|
||||||
| ListSet Bool
|
| ListSet
|
||||||
| ListAvailable Bool
|
| ListAvailable
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
-- | A list result describes a single tool version
|
-- | A list result describes a single tool version
|
||||||
@@ -80,13 +79,12 @@ data ListResult = ListResult
|
|||||||
, lStray :: Bool -- ^ not in download info
|
, lStray :: Bool -- ^ not in download info
|
||||||
, lNoBindist :: Bool -- ^ whether the version is available for this platform/arch
|
, lNoBindist :: Bool -- ^ whether the version is available for this platform/arch
|
||||||
, hlsPowered :: Bool
|
, hlsPowered :: Bool
|
||||||
, lReleaseDay :: Maybe Day
|
|
||||||
}
|
}
|
||||||
deriving (Eq, Ord, Show)
|
deriving (Eq, Ord, Show)
|
||||||
|
|
||||||
|
|
||||||
-- | Extract all available tool versions and their tags.
|
-- | Extract all available tool versions and their tags.
|
||||||
availableToolVersions :: GHCupDownloads -> Tool -> Map.Map GHCTargetVersion VersionInfo
|
availableToolVersions :: GHCupDownloads -> Tool -> Map.Map Version VersionInfo
|
||||||
availableToolVersions av tool = view
|
availableToolVersions av tool = view
|
||||||
(at tool % non Map.empty)
|
(at tool % non Map.empty)
|
||||||
av
|
av
|
||||||
@@ -95,22 +93,19 @@ availableToolVersions av tool = view
|
|||||||
-- | List all versions from the download info, as well as stray
|
-- | List all versions from the download info, as well as stray
|
||||||
-- versions.
|
-- versions.
|
||||||
listVersions :: ( MonadCatch m
|
listVersions :: ( MonadCatch m
|
||||||
, HasLog env
|
, HasLog env
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, HasLog env
|
, HasLog env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadReader env m
|
, MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
, HasPlatformReq env
|
, HasPlatformReq env
|
||||||
, HasGHCupInfo env
|
, HasGHCupInfo env
|
||||||
)
|
)
|
||||||
=> Maybe Tool
|
=> Maybe Tool
|
||||||
-> [ListCriteria]
|
-> Maybe ListCriteria
|
||||||
-> Bool
|
-> m [ListResult]
|
||||||
-> Bool
|
listVersions lt' criteria = do
|
||||||
-> (Maybe Day, Maybe Day)
|
|
||||||
-> m [ListResult]
|
|
||||||
listVersions lt' criteria hideOld showNightly days = do
|
|
||||||
-- some annoying work to avoid too much repeated IO
|
-- some annoying work to avoid too much repeated IO
|
||||||
cSet <- cabalSet
|
cSet <- cabalSet
|
||||||
cabals <- getInstalledCabals
|
cabals <- getInstalledCabals
|
||||||
@@ -134,13 +129,13 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
slr <- strayGHCs avTools
|
slr <- strayGHCs avTools
|
||||||
pure (sort (slr ++ lr))
|
pure (sort (slr ++ lr))
|
||||||
Cabal -> do
|
Cabal -> do
|
||||||
slr <- strayCabals (Map.mapKeys _tvVersion avTools) cSet cabals
|
slr <- strayCabals avTools cSet cabals
|
||||||
pure (sort (slr ++ lr))
|
pure (sort (slr ++ lr))
|
||||||
HLS -> do
|
HLS -> do
|
||||||
slr <- strayHLS (Map.mapKeys _tvVersion avTools) hlsSet' hlses
|
slr <- strayHLS avTools hlsSet' hlses
|
||||||
pure (sort (slr ++ lr))
|
pure (sort (slr ++ lr))
|
||||||
Stack -> do
|
Stack -> do
|
||||||
slr <- strayStacks (Map.mapKeys _tvVersion avTools) sSet stacks
|
slr <- strayStacks avTools sSet stacks
|
||||||
pure (sort (slr ++ lr))
|
pure (sort (slr ++ lr))
|
||||||
GHCup -> do
|
GHCup -> do
|
||||||
let cg = maybeToList $ currentGHCup avTools
|
let cg = maybeToList $ currentGHCup avTools
|
||||||
@@ -159,29 +154,42 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
, HasLog env
|
, HasLog env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
)
|
)
|
||||||
=> Map.Map GHCTargetVersion VersionInfo
|
=> Map.Map Version VersionInfo
|
||||||
-> m [ListResult]
|
-> m [ListResult]
|
||||||
strayGHCs avTools = do
|
strayGHCs avTools = do
|
||||||
ghcs <- getInstalledGHCs
|
ghcs <- getInstalledGHCs
|
||||||
fmap catMaybes $ forM ghcs $ \case
|
fmap catMaybes $ forM ghcs $ \case
|
||||||
Right tver@GHCTargetVersion{ .. } -> do
|
Right tver@GHCTargetVersion{ _tvTarget = Nothing, .. } -> do
|
||||||
case Map.lookup tver avTools of
|
case Map.lookup _tvVersion avTools of
|
||||||
Just _ -> pure Nothing
|
Just _ -> pure Nothing
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
lSet <- fmap (maybe False (\(GHCTargetVersion _ v ) -> v == _tvVersion)) $ ghcSet _tvTarget
|
lSet <- fmap (maybe False (\(GHCTargetVersion _ v ) -> v == _tvVersion)) $ ghcSet Nothing
|
||||||
fromSrc <- ghcSrcInstalled tver
|
fromSrc <- ghcSrcInstalled tver
|
||||||
hlsPowered <- fmap (elem _tvVersion) hlsGHCVersions
|
hlsPowered <- fmap (elem _tvVersion) hlsGHCVersions
|
||||||
pure $ Just $ ListResult
|
pure $ Just $ ListResult
|
||||||
{ lTool = GHC
|
{ lTool = GHC
|
||||||
, lVer = _tvVersion
|
, lVer = _tvVersion
|
||||||
, lCross = _tvTarget
|
, lCross = Nothing
|
||||||
, lTag = []
|
, lTag = []
|
||||||
, lInstalled = True
|
, lInstalled = True
|
||||||
, lStray = isNothing (Map.lookup tver avTools)
|
, lStray = isNothing (Map.lookup _tvVersion avTools)
|
||||||
, lNoBindist = False
|
, lNoBindist = False
|
||||||
, lReleaseDay = Nothing
|
|
||||||
, ..
|
, ..
|
||||||
}
|
}
|
||||||
|
Right tver@GHCTargetVersion{ .. } -> do
|
||||||
|
lSet <- fmap (maybe False (\(GHCTargetVersion _ v ) -> v == _tvVersion)) $ ghcSet _tvTarget
|
||||||
|
fromSrc <- ghcSrcInstalled tver
|
||||||
|
hlsPowered <- fmap (elem _tvVersion) hlsGHCVersions
|
||||||
|
pure $ Just $ ListResult
|
||||||
|
{ lTool = GHC
|
||||||
|
, lVer = _tvVersion
|
||||||
|
, lCross = _tvTarget
|
||||||
|
, lTag = []
|
||||||
|
, lInstalled = True
|
||||||
|
, lStray = True -- NOTE: cross currently cannot be installed via bindist
|
||||||
|
, lNoBindist = False
|
||||||
|
, ..
|
||||||
|
}
|
||||||
Left e -> do
|
Left e -> do
|
||||||
logWarn
|
logWarn
|
||||||
$ "Could not parse version of stray directory" <> T.pack e
|
$ "Could not parse version of stray directory" <> T.pack e
|
||||||
@@ -215,7 +223,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
, lNoBindist = False
|
, lNoBindist = False
|
||||||
, fromSrc = False -- actually, we don't know :>
|
, fromSrc = False -- actually, we don't know :>
|
||||||
, hlsPowered = False
|
, hlsPowered = False
|
||||||
, lReleaseDay = Nothing
|
|
||||||
, ..
|
, ..
|
||||||
}
|
}
|
||||||
Left e -> do
|
Left e -> do
|
||||||
@@ -250,7 +257,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
, lNoBindist = False
|
, lNoBindist = False
|
||||||
, fromSrc = False -- actually, we don't know :>
|
, fromSrc = False -- actually, we don't know :>
|
||||||
, hlsPowered = False
|
, hlsPowered = False
|
||||||
, lReleaseDay = Nothing
|
|
||||||
, ..
|
, ..
|
||||||
}
|
}
|
||||||
Left e -> do
|
Left e -> do
|
||||||
@@ -286,7 +292,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
, lNoBindist = False
|
, lNoBindist = False
|
||||||
, fromSrc = False -- actually, we don't know :>
|
, fromSrc = False -- actually, we don't know :>
|
||||||
, hlsPowered = False
|
, hlsPowered = False
|
||||||
, lReleaseDay = Nothing
|
|
||||||
, ..
|
, ..
|
||||||
}
|
}
|
||||||
Left e -> do
|
Left e -> do
|
||||||
@@ -294,15 +299,15 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
$ "Could not parse version of stray directory" <> T.pack e
|
$ "Could not parse version of stray directory" <> T.pack e
|
||||||
pure Nothing
|
pure Nothing
|
||||||
|
|
||||||
currentGHCup :: Map.Map GHCTargetVersion VersionInfo -> Maybe ListResult
|
currentGHCup :: Map.Map Version VersionInfo -> Maybe ListResult
|
||||||
currentGHCup av =
|
currentGHCup av =
|
||||||
let currentVer = mkTVer $ fromJust $ pvpToVersion ghcUpVer ""
|
let currentVer = fromJust $ pvpToVersion ghcUpVer ""
|
||||||
listVer = Map.lookup currentVer av
|
listVer = Map.lookup currentVer av
|
||||||
latestVer = fst <$> headOf (getTagged Latest) av
|
latestVer = fst <$> headOf (getTagged Latest) av
|
||||||
recommendedVer = fst <$> headOf (getTagged Latest) av
|
recommendedVer = fst <$> headOf (getTagged Latest) av
|
||||||
isOld = maybe True (> currentVer) latestVer && maybe True (> currentVer) recommendedVer
|
isOld = maybe True (> currentVer) latestVer && maybe True (> currentVer) recommendedVer
|
||||||
in if | Map.member currentVer av -> Nothing
|
in if | Map.member currentVer av -> Nothing
|
||||||
| otherwise -> Just $ ListResult { lVer = _tvVersion currentVer
|
| otherwise -> Just $ ListResult { lVer = currentVer
|
||||||
, lTag = maybe (if isOld then [Old] else []) _viTags listVer
|
, lTag = maybe (if isOld then [Old] else []) _viTags listVer
|
||||||
, lCross = Nothing
|
, lCross = Nothing
|
||||||
, lTool = GHCup
|
, lTool = GHCup
|
||||||
@@ -312,7 +317,6 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
, lInstalled = True
|
, lInstalled = True
|
||||||
, lNoBindist = False
|
, lNoBindist = False
|
||||||
, hlsPowered = False
|
, hlsPowered = False
|
||||||
, lReleaseDay = Nothing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- NOTE: this are not cross ones, because no bindists
|
-- NOTE: this are not cross ones, because no bindists
|
||||||
@@ -331,44 +335,42 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
-> [Either FilePath Version]
|
-> [Either FilePath Version]
|
||||||
-> Maybe Version
|
-> Maybe Version
|
||||||
-> [Either FilePath Version]
|
-> [Either FilePath Version]
|
||||||
-> (GHCTargetVersion, VersionInfo)
|
-> (Version, VersionInfo)
|
||||||
-> m ListResult
|
-> m ListResult
|
||||||
toListResult t cSet cabals hlsSet' hlses stackSet' stacks (tver, VersionInfo{..}) = do
|
toListResult t cSet cabals hlsSet' hlses stackSet' stacks (v, _viTags -> tags) = do
|
||||||
let v = _tvVersion tver
|
|
||||||
case t of
|
case t of
|
||||||
GHC -> do
|
GHC -> do
|
||||||
lNoBindist <- fmap (isLeft . veitherToEither) $ runE @'[NoDownload] $ getDownloadInfo' GHC tver
|
lNoBindist <- fmap (isLeft . veitherToEither) $ runE @'[NoDownload] $ getDownloadInfo GHC v
|
||||||
lSet <- fmap (== Just tver) $ ghcSet (_tvTarget tver)
|
let tver = mkTVer v
|
||||||
|
lSet <- fmap (maybe False (\(GHCTargetVersion _ v') -> v' == v)) $ ghcSet Nothing
|
||||||
lInstalled <- ghcInstalled tver
|
lInstalled <- ghcInstalled tver
|
||||||
fromSrc <- ghcSrcInstalled tver
|
fromSrc <- ghcSrcInstalled tver
|
||||||
hlsPowered <- fmap (elem tver) (fmap mkTVer <$> hlsGHCVersions)
|
hlsPowered <- fmap (elem v) hlsGHCVersions
|
||||||
pure ListResult { lVer = _tvVersion tver , lCross = _tvTarget tver , lTag = _viTags, lTool = t, lStray = False, lReleaseDay = _viReleaseDay, .. }
|
pure ListResult { lVer = v, lCross = Nothing , lTag = tags, lTool = t, lStray = False, .. }
|
||||||
Cabal -> do
|
Cabal -> do
|
||||||
lNoBindist <- fmap (isLeft . veitherToEither) $ runE @'[NoDownload] $ getDownloadInfo Cabal v
|
lNoBindist <- fmap (isLeft . veitherToEither) $ runE @'[NoDownload] $ getDownloadInfo Cabal v
|
||||||
let lSet = cSet == Just v
|
let lSet = cSet == Just v
|
||||||
let lInstalled = elem v $ rights cabals
|
let lInstalled = elem v $ rights cabals
|
||||||
pure ListResult { lVer = v
|
pure ListResult { lVer = v
|
||||||
, lCross = Nothing
|
, lCross = Nothing
|
||||||
, lTag = _viTags
|
, lTag = tags
|
||||||
, lTool = t
|
, lTool = t
|
||||||
, fromSrc = False
|
, fromSrc = False
|
||||||
, lStray = False
|
, lStray = False
|
||||||
, hlsPowered = False
|
, hlsPowered = False
|
||||||
, lReleaseDay = _viReleaseDay
|
|
||||||
, ..
|
, ..
|
||||||
}
|
}
|
||||||
GHCup -> do
|
GHCup -> do
|
||||||
let lSet = prettyPVP ghcUpVer == prettyVer v
|
let lSet = prettyPVP ghcUpVer == prettyVer v
|
||||||
let lInstalled = lSet
|
let lInstalled = lSet
|
||||||
pure ListResult { lVer = v
|
pure ListResult { lVer = v
|
||||||
, lTag = _viTags
|
, lTag = tags
|
||||||
, lCross = Nothing
|
, lCross = Nothing
|
||||||
, lTool = t
|
, lTool = t
|
||||||
, fromSrc = False
|
, fromSrc = False
|
||||||
, lStray = False
|
, lStray = False
|
||||||
, lNoBindist = False
|
, lNoBindist = False
|
||||||
, hlsPowered = False
|
, hlsPowered = False
|
||||||
, lReleaseDay = _viReleaseDay
|
|
||||||
, ..
|
, ..
|
||||||
}
|
}
|
||||||
HLS -> do
|
HLS -> do
|
||||||
@@ -377,12 +379,11 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
let lInstalled = elem v $ rights hlses
|
let lInstalled = elem v $ rights hlses
|
||||||
pure ListResult { lVer = v
|
pure ListResult { lVer = v
|
||||||
, lCross = Nothing
|
, lCross = Nothing
|
||||||
, lTag = _viTags
|
, lTag = tags
|
||||||
, lTool = t
|
, lTool = t
|
||||||
, fromSrc = False
|
, fromSrc = False
|
||||||
, lStray = False
|
, lStray = False
|
||||||
, hlsPowered = False
|
, hlsPowered = False
|
||||||
, lReleaseDay = _viReleaseDay
|
|
||||||
, ..
|
, ..
|
||||||
}
|
}
|
||||||
Stack -> do
|
Stack -> do
|
||||||
@@ -391,43 +392,19 @@ listVersions lt' criteria hideOld showNightly days = do
|
|||||||
let lInstalled = elem v $ rights stacks
|
let lInstalled = elem v $ rights stacks
|
||||||
pure ListResult { lVer = v
|
pure ListResult { lVer = v
|
||||||
, lCross = Nothing
|
, lCross = Nothing
|
||||||
, lTag = _viTags
|
, lTag = tags
|
||||||
, lTool = t
|
, lTool = t
|
||||||
, fromSrc = False
|
, fromSrc = False
|
||||||
, lStray = False
|
, lStray = False
|
||||||
, hlsPowered = False
|
, hlsPowered = False
|
||||||
, lReleaseDay = _viReleaseDay
|
|
||||||
, ..
|
, ..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
filter' :: [ListResult] -> [ListResult]
|
filter' :: [ListResult] -> [ListResult]
|
||||||
filter' = filterNightly . filterOld . filter (\lr -> foldr (\a b -> fromCriteria a lr && b) True criteria) . filterDays
|
filter' lr = case criteria of
|
||||||
|
Nothing -> lr
|
||||||
filterDays :: [ListResult] -> [ListResult]
|
Just ListInstalled -> filter (\ListResult {..} -> lInstalled) lr
|
||||||
filterDays lrs = case days of
|
Just ListSet -> filter (\ListResult {..} -> lSet) lr
|
||||||
(Nothing, Nothing) -> lrs
|
Just ListAvailable -> filter (\ListResult {..} -> not lNoBindist) lr
|
||||||
(Just from, Just to') -> filter (\ListResult{..} -> maybe False (\d -> d >= from && d <= to') lReleaseDay) lrs
|
|
||||||
(Nothing, Just to') -> filter (\ListResult{..} -> maybe False (<= to') lReleaseDay) lrs
|
|
||||||
(Just from, Nothing) -> filter (\ListResult{..} -> maybe False (>= from) lReleaseDay) lrs
|
|
||||||
|
|
||||||
fromCriteria :: ListCriteria -> ListResult -> Bool
|
|
||||||
fromCriteria lc ListResult{..} = case lc of
|
|
||||||
ListInstalled b -> f b lInstalled
|
|
||||||
ListSet b -> f b lSet
|
|
||||||
ListAvailable b -> f b $ not lNoBindist
|
|
||||||
where
|
|
||||||
f b
|
|
||||||
| b = id
|
|
||||||
| otherwise = not
|
|
||||||
|
|
||||||
filterOld :: [ListResult] -> [ListResult]
|
|
||||||
filterOld lr
|
|
||||||
| hideOld = filter (\ListResult {..} -> lInstalled || Old `notElem` lTag) lr
|
|
||||||
| otherwise = lr
|
|
||||||
|
|
||||||
filterNightly :: [ListResult] -> [ListResult]
|
|
||||||
filterNightly lr
|
|
||||||
| showNightly = lr
|
|
||||||
| otherwise = filter (\ListResult {..} -> lInstalled || (Nightly `notElem` lTag && LatestNightly `notElem` lTag)) lr
|
|
||||||
|
|
||||||
|
|||||||
@@ -77,14 +77,8 @@ runBothE' a1 a2 = do
|
|||||||
(_ , VLeft e ) -> throwSomeE e
|
(_ , VLeft e ) -> throwSomeE e
|
||||||
(VRight _, VRight _) -> pure ()
|
(VRight _, VRight _) -> pure ()
|
||||||
|
|
||||||
-- "throwSomeE" function has been upstreamed in haskus-utils-variant-3.3
|
|
||||||
-- So, only conditionally include this shim if
|
|
||||||
-- haskus-utils-variant version is < 3.3
|
|
||||||
|
|
||||||
#if MIN_VERSION_haskus_utils_variant(3,3,0)
|
|
||||||
#else
|
|
||||||
-- | Throw some exception
|
-- | Throw some exception
|
||||||
throwSomeE :: forall es' es a m. (Monad m, LiftVariant es' es) => V es' -> Excepts es m a
|
throwSomeE :: forall es' es a m. (Monad m, LiftVariant es' es) => V es' -> Excepts es m a
|
||||||
{-# INLINABLE throwSomeE #-}
|
{-# INLINABLE throwSomeE #-}
|
||||||
throwSomeE = Excepts . pure . VLeft . liftVariant
|
throwSomeE = Excepts . pure . VLeft . liftVariant
|
||||||
#endif
|
|
||||||
|
|||||||
92
lib/GHCup/Prelude/Ansi.hs
Normal file
92
lib/GHCup/Prelude/Ansi.hs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
module GHCup.Prelude.Ansi where
|
||||||
|
|
||||||
|
import Control.Applicative
|
||||||
|
import Data.Char
|
||||||
|
import Data.Void
|
||||||
|
|
||||||
|
import qualified Text.Megaparsec as MP
|
||||||
|
import qualified Text.Megaparsec.Char as MPC
|
||||||
|
|
||||||
|
|
||||||
|
-- | Calculate the render width of a string, considering
|
||||||
|
-- wide characters (counted as double width), ANSI escape codes
|
||||||
|
-- (not counted), and line breaks (in a multi-line string, the longest
|
||||||
|
-- line determines the width).
|
||||||
|
strWidth :: String -> Int
|
||||||
|
strWidth =
|
||||||
|
maximum
|
||||||
|
. (0 :)
|
||||||
|
. map (foldr (\a b -> charWidth a + b) 0)
|
||||||
|
. lines
|
||||||
|
. stripAnsi
|
||||||
|
|
||||||
|
-- | Strip ANSI escape sequences from a string.
|
||||||
|
--
|
||||||
|
-- >>> stripAnsi "\ESC[31m-1\ESC[m"
|
||||||
|
-- "-1"
|
||||||
|
stripAnsi :: String -> String
|
||||||
|
stripAnsi s' =
|
||||||
|
case
|
||||||
|
MP.parseMaybe (many $ "" <$ MP.try ansi <|> pure <$> MP.anySingle) s'
|
||||||
|
of
|
||||||
|
Nothing -> error "Bad ansi escape" -- PARTIAL: should not happen
|
||||||
|
Just xs -> concat xs
|
||||||
|
where
|
||||||
|
-- This parses lots of invalid ANSI escape codes, but that should be fine
|
||||||
|
ansi =
|
||||||
|
MPC.string "\ESC[" *> digitSemicolons *> suffix MP.<?> "ansi" :: MP.Parsec
|
||||||
|
Void
|
||||||
|
String
|
||||||
|
Char
|
||||||
|
digitSemicolons = MP.takeWhileP Nothing (\c -> isDigit c || c == ';')
|
||||||
|
suffix = MP.oneOf ['A', 'B', 'C', 'D', 'H', 'J', 'K', 'f', 'm', 's', 'u']
|
||||||
|
|
||||||
|
-- | Get the designated render width of a character: 0 for a combining
|
||||||
|
-- character, 1 for a regular character, 2 for a wide character.
|
||||||
|
-- (Wide characters are rendered as exactly double width in apps and
|
||||||
|
-- fonts that support it.) (From Pandoc.)
|
||||||
|
charWidth :: Char -> Int
|
||||||
|
charWidth c = case c of
|
||||||
|
_ | c < '\x0300' -> 1
|
||||||
|
| c >= '\x0300' && c <= '\x036F' -> 0
|
||||||
|
| -- combining
|
||||||
|
c >= '\x0370' && c <= '\x10FC' -> 1
|
||||||
|
| c >= '\x1100' && c <= '\x115F' -> 2
|
||||||
|
| c >= '\x1160' && c <= '\x11A2' -> 1
|
||||||
|
| c >= '\x11A3' && c <= '\x11A7' -> 2
|
||||||
|
| c >= '\x11A8' && c <= '\x11F9' -> 1
|
||||||
|
| c >= '\x11FA' && c <= '\x11FF' -> 2
|
||||||
|
| c >= '\x1200' && c <= '\x2328' -> 1
|
||||||
|
| c >= '\x2329' && c <= '\x232A' -> 2
|
||||||
|
| c >= '\x232B' && c <= '\x2E31' -> 1
|
||||||
|
| c >= '\x2E80' && c <= '\x303E' -> 2
|
||||||
|
| c == '\x303F' -> 1
|
||||||
|
| c >= '\x3041' && c <= '\x3247' -> 2
|
||||||
|
| c >= '\x3248' && c <= '\x324F' -> 1
|
||||||
|
| -- ambiguous
|
||||||
|
c >= '\x3250' && c <= '\x4DBF' -> 2
|
||||||
|
| c >= '\x4DC0' && c <= '\x4DFF' -> 1
|
||||||
|
| c >= '\x4E00' && c <= '\xA4C6' -> 2
|
||||||
|
| c >= '\xA4D0' && c <= '\xA95F' -> 1
|
||||||
|
| c >= '\xA960' && c <= '\xA97C' -> 2
|
||||||
|
| c >= '\xA980' && c <= '\xABF9' -> 1
|
||||||
|
| c >= '\xAC00' && c <= '\xD7FB' -> 2
|
||||||
|
| c >= '\xD800' && c <= '\xDFFF' -> 1
|
||||||
|
| c >= '\xE000' && c <= '\xF8FF' -> 1
|
||||||
|
| -- ambiguous
|
||||||
|
c >= '\xF900' && c <= '\xFAFF' -> 2
|
||||||
|
| c >= '\xFB00' && c <= '\xFDFD' -> 1
|
||||||
|
| c >= '\xFE00' && c <= '\xFE0F' -> 1
|
||||||
|
| -- ambiguous
|
||||||
|
c >= '\xFE10' && c <= '\xFE19' -> 2
|
||||||
|
| c >= '\xFE20' && c <= '\xFE26' -> 1
|
||||||
|
| c >= '\xFE30' && c <= '\xFE6B' -> 2
|
||||||
|
| c >= '\xFE70' && c <= '\xFEFF' -> 1
|
||||||
|
| c >= '\xFF01' && c <= '\xFF60' -> 2
|
||||||
|
| c >= '\xFF61' && c <= '\x16A38' -> 1
|
||||||
|
| c >= '\x1B000' && c <= '\x1B001' -> 2
|
||||||
|
| c >= '\x1D000' && c <= '\x1F1FF' -> 1
|
||||||
|
| c >= '\x1F200' && c <= '\x1F251' -> 2
|
||||||
|
| c >= '\x1F300' && c <= '\x1F773' -> 1
|
||||||
|
| c >= '\x20000' && c <= '\x3FFFD' -> 2
|
||||||
|
| otherwise -> 1
|
||||||
@@ -279,11 +279,11 @@ removeEmptyDirectory = PD.removeDirectory
|
|||||||
|
|
||||||
-- | Create an 'Unfold' of directory contents.
|
-- | Create an 'Unfold' of directory contents.
|
||||||
unfoldDirContents :: (MonadMask m, MonadIO m, S.MonadAsync m) => Unfold m FilePath (FD.DirType, FilePath)
|
unfoldDirContents :: (MonadMask m, MonadIO m, S.MonadAsync m) => Unfold m FilePath (FD.DirType, FilePath)
|
||||||
unfoldDirContents = U.bracket (liftIO . openDirStreamPortable) (liftIO . closeDirStreamPortable) (Unfold step return)
|
unfoldDirContents = U.bracket (liftIO . openDirStream) (liftIO . closeDirStream) (Unfold step return)
|
||||||
where
|
where
|
||||||
{-# INLINE [0] step #-}
|
{-# INLINE [0] step #-}
|
||||||
step dirstream = do
|
step dirstream = do
|
||||||
(typ, e) <- liftIO $ readDirEntPortable dirstream
|
(typ, e) <- liftIO $ readDirEnt dirstream
|
||||||
return $ if
|
return $ if
|
||||||
| null e -> D.Stop
|
| null e -> D.Stop
|
||||||
| "." == e -> D.Skip dirstream
|
| "." == e -> D.Skip dirstream
|
||||||
@@ -308,8 +308,8 @@ getDirectoryContentsRecursiveUnfold = Unfold step (\s -> return (s, Nothing, [""
|
|||||||
step (_, Nothing, []) = return D.Stop
|
step (_, Nothing, []) = return D.Stop
|
||||||
|
|
||||||
step (topdir, Just (cdir, dirstream, finalizer), dirs) = flip onException (runIOFinalizer finalizer) $ do
|
step (topdir, Just (cdir, dirstream, finalizer), dirs) = flip onException (runIOFinalizer finalizer) $ do
|
||||||
(dt, f) <- liftIO $ readDirEntPortable dirstream
|
(dt, f) <- liftIO $ readDirEnt dirstream
|
||||||
if | f == "" -> do
|
if | FD.dtUnknown == dt -> do
|
||||||
runIOFinalizer finalizer
|
runIOFinalizer finalizer
|
||||||
return $ D.Skip (topdir, Nothing, dirs)
|
return $ D.Skip (topdir, Nothing, dirs)
|
||||||
| f == "." || f == ".."
|
| f == "." || f == ".."
|
||||||
@@ -323,8 +323,8 @@ getDirectoryContentsRecursiveUnfold = Unfold step (\s -> return (s, Nothing, [""
|
|||||||
|
|
||||||
acquire dir =
|
acquire dir =
|
||||||
withRunInIO $ \run -> mask_ $ run $ do
|
withRunInIO $ \run -> mask_ $ run $ do
|
||||||
dirstream <- liftIO $ openDirStreamPortable dir
|
dirstream <- liftIO $ openDirStream dir
|
||||||
ref <- newIOFinalizer (liftIO $ closeDirStreamPortable dirstream)
|
ref <- newIOFinalizer (liftIO $ closeDirStream dirstream)
|
||||||
return (dirstream, ref)
|
return (dirstream, ref)
|
||||||
|
|
||||||
getDirectoryContentsRecursiveBFSUnsafe :: (MonadMask m, MonadIO m, S.MonadAsync m)
|
getDirectoryContentsRecursiveBFSUnsafe :: (MonadMask m, MonadIO m, S.MonadAsync m)
|
||||||
|
|||||||
@@ -10,20 +10,9 @@
|
|||||||
module GHCup.Prelude.File.Posix.Traversals (
|
module GHCup.Prelude.File.Posix.Traversals (
|
||||||
-- lower-level stuff
|
-- lower-level stuff
|
||||||
readDirEnt
|
readDirEnt
|
||||||
, readDirEntPortable
|
|
||||||
, openDirStreamPortable
|
|
||||||
, closeDirStreamPortable
|
|
||||||
, unpackDirStream
|
, unpackDirStream
|
||||||
, DirStreamPortable
|
|
||||||
) where
|
) 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
|
#if __GLASGOW_HASKELL__ < 710
|
||||||
import Control.Applicative ((<$>))
|
import Control.Applicative ((<$>))
|
||||||
@@ -39,7 +28,6 @@ import Foreign.Storable
|
|||||||
import System.Posix
|
import System.Posix
|
||||||
import Foreign (alloca)
|
import Foreign (alloca)
|
||||||
import System.Posix.Internals (peekFilePath)
|
import System.Posix.Internals (peekFilePath)
|
||||||
import System.FilePath
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -102,38 +90,3 @@ readDirEnt (unpackDirStream -> dirp) =
|
|||||||
then return (dtUnknown, mempty)
|
then return (dtUnknown, mempty)
|
||||||
else throwErrno "readDirEnt"
|
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)
|
|
||||||
|
|
||||||
@@ -38,7 +38,6 @@ import Control.Monad.Trans.Resource
|
|||||||
hiding ( throwM )
|
hiding ( throwM )
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Ord
|
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Versions hiding ( patch )
|
import Data.Versions hiding ( patch )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
@@ -280,6 +279,6 @@ rmStackVer ver = do
|
|||||||
|
|
||||||
when (Just ver == sSet) $ do
|
when (Just ver == sSet) $ do
|
||||||
sVers <- lift $ fmap rights getInstalledStacks
|
sVers <- lift $ fmap rights getInstalledStacks
|
||||||
case headMay . sortBy (comparing Down) $ sVers of
|
case headMay . reverse . sort $ sVers of
|
||||||
Just latestver -> setStack latestver
|
Just latestver -> setStack latestver
|
||||||
Nothing -> lift $ rmLink (binDir </> "stack" <> exeExt)
|
Nothing -> lift $ rmLink (binDir </> "stack" <> exeExt)
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import {-# SOURCE #-} GHCup.Utils.Dirs ( fromGHCupPath, GHCupPath )
|
|||||||
import Control.DeepSeq ( NFData, rnf )
|
import Control.DeepSeq ( NFData, rnf )
|
||||||
import Data.Map.Strict ( Map )
|
import Data.Map.Strict ( Map )
|
||||||
import Data.List.NonEmpty ( NonEmpty (..) )
|
import Data.List.NonEmpty ( NonEmpty (..) )
|
||||||
import Data.Time.Calendar ( Day )
|
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
import GHC.IO.Exception ( ExitCode )
|
import GHC.IO.Exception ( ExitCode )
|
||||||
@@ -67,7 +66,7 @@ data GHCupInfo = GHCupInfo
|
|||||||
, _ghcupDownloads :: GHCupDownloads
|
, _ghcupDownloads :: GHCupDownloads
|
||||||
, _globalTools :: Map GlobalTool DownloadInfo
|
, _globalTools :: Map GlobalTool DownloadInfo
|
||||||
}
|
}
|
||||||
deriving (Show, GHC.Generic, Eq)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
instance NFData GHCupInfo
|
instance NFData GHCupInfo
|
||||||
|
|
||||||
@@ -88,7 +87,7 @@ data Requirements = Requirements
|
|||||||
{ _distroPKGs :: [Text]
|
{ _distroPKGs :: [Text]
|
||||||
, _notes :: Text
|
, _notes :: Text
|
||||||
}
|
}
|
||||||
deriving (Show, GHC.Generic, Eq)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
instance NFData Requirements
|
instance NFData Requirements
|
||||||
|
|
||||||
@@ -104,7 +103,7 @@ instance NFData Requirements
|
|||||||
-- | Description of all binary and source downloads. This is a tree
|
-- | Description of all binary and source downloads. This is a tree
|
||||||
-- of nested maps.
|
-- of nested maps.
|
||||||
type GHCupDownloads = Map Tool ToolVersionSpec
|
type GHCupDownloads = Map Tool ToolVersionSpec
|
||||||
type ToolVersionSpec = Map GHCTargetVersion VersionInfo
|
type ToolVersionSpec = Map Version VersionInfo
|
||||||
type ArchitectureSpec = Map Architecture PlatformSpec
|
type ArchitectureSpec = Map Architecture PlatformSpec
|
||||||
type PlatformSpec = Map Platform PlatformVersionSpec
|
type PlatformSpec = Map Platform PlatformVersionSpec
|
||||||
type PlatformVersionSpec = Map (Maybe VersionRange) DownloadInfo
|
type PlatformVersionSpec = Map (Maybe VersionRange) DownloadInfo
|
||||||
@@ -137,10 +136,8 @@ instance NFData GlobalTool
|
|||||||
-- source download and per-architecture downloads.
|
-- source download and per-architecture downloads.
|
||||||
data VersionInfo = VersionInfo
|
data VersionInfo = VersionInfo
|
||||||
{ _viTags :: [Tag] -- ^ version specific tag
|
{ _viTags :: [Tag] -- ^ version specific tag
|
||||||
, _viReleaseDay :: Maybe Day
|
|
||||||
, _viChangeLog :: Maybe URI
|
, _viChangeLog :: Maybe URI
|
||||||
, _viSourceDL :: Maybe DownloadInfo -- ^ source tarball
|
, _viSourceDL :: Maybe DownloadInfo -- ^ source tarball
|
||||||
, _viTestDL :: Maybe DownloadInfo -- ^ test tarball
|
|
||||||
, _viArch :: ArchitectureSpec -- ^ descend for binary downloads per arch
|
, _viArch :: ArchitectureSpec -- ^ descend for binary downloads per arch
|
||||||
-- informative messages
|
-- informative messages
|
||||||
, _viPostInstall :: Maybe Text
|
, _viPostInstall :: Maybe Text
|
||||||
@@ -156,9 +153,6 @@ instance NFData VersionInfo
|
|||||||
data Tag = Latest
|
data Tag = Latest
|
||||||
| Recommended
|
| Recommended
|
||||||
| Prerelease
|
| Prerelease
|
||||||
| LatestPrerelease
|
|
||||||
| Nightly
|
|
||||||
| LatestNightly
|
|
||||||
| Base PVP
|
| Base PVP
|
||||||
| Old -- ^ old versions are hidden by default in TUI
|
| Old -- ^ old versions are hidden by default in TUI
|
||||||
| UnknownTag String -- ^ used for upwardscompat
|
| UnknownTag String -- ^ used for upwardscompat
|
||||||
@@ -170,22 +164,16 @@ tagToString :: Tag -> String
|
|||||||
tagToString Recommended = "recommended"
|
tagToString Recommended = "recommended"
|
||||||
tagToString Latest = "latest"
|
tagToString Latest = "latest"
|
||||||
tagToString Prerelease = "prerelease"
|
tagToString Prerelease = "prerelease"
|
||||||
tagToString Nightly = "nightly"
|
|
||||||
tagToString (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
|
tagToString (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
|
||||||
tagToString (UnknownTag t ) = t
|
tagToString (UnknownTag t ) = t
|
||||||
tagToString LatestPrerelease = "latest-prerelease"
|
|
||||||
tagToString LatestNightly = "latest-nightly"
|
|
||||||
tagToString Old = ""
|
tagToString Old = ""
|
||||||
|
|
||||||
instance Pretty Tag where
|
instance Pretty Tag where
|
||||||
pPrint Recommended = text "recommended"
|
pPrint Recommended = text "recommended"
|
||||||
pPrint Latest = text "latest"
|
pPrint Latest = text "latest"
|
||||||
pPrint Prerelease = text "prerelease"
|
pPrint Prerelease = text "prerelease"
|
||||||
pPrint Nightly = text "nightly"
|
|
||||||
pPrint (Base pvp'') = text ("base-" ++ T.unpack (prettyPVP pvp''))
|
pPrint (Base pvp'') = text ("base-" ++ T.unpack (prettyPVP pvp''))
|
||||||
pPrint (UnknownTag t ) = text t
|
pPrint (UnknownTag t ) = text t
|
||||||
pPrint LatestPrerelease = text "latest-prerelease"
|
|
||||||
pPrint LatestNightly = text "latest-prerelease"
|
|
||||||
pPrint Old = mempty
|
pPrint Old = mempty
|
||||||
|
|
||||||
data Architecture = A_64
|
data Architecture = A_64
|
||||||
@@ -275,7 +263,6 @@ data DownloadInfo = DownloadInfo
|
|||||||
, _dlSubdir :: Maybe TarDir
|
, _dlSubdir :: Maybe TarDir
|
||||||
, _dlHash :: Text
|
, _dlHash :: Text
|
||||||
, _dlCSize :: Maybe Integer
|
, _dlCSize :: Maybe Integer
|
||||||
, _dlOutput :: Maybe FilePath
|
|
||||||
}
|
}
|
||||||
deriving (Eq, Ord, GHC.Generic, Show)
|
deriving (Eq, Ord, GHC.Generic, Show)
|
||||||
|
|
||||||
@@ -287,23 +274,6 @@ instance NFData DownloadInfo
|
|||||||
--[ Others ]--
|
--[ 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.
|
-- | How to descend into a tar archive.
|
||||||
data TarDir = RealDir FilePath
|
data TarDir = RealDir FilePath
|
||||||
@@ -346,13 +316,12 @@ data UserSettings = UserSettings
|
|||||||
, uUrlSource :: Maybe URLSource
|
, uUrlSource :: Maybe URLSource
|
||||||
, uNoNetwork :: Maybe Bool
|
, uNoNetwork :: Maybe Bool
|
||||||
, uGPGSetting :: Maybe GPGSetting
|
, uGPGSetting :: Maybe GPGSetting
|
||||||
, uPlatformOverride :: Maybe PlatformRequest
|
, uPlatformOverride :: Maybe PlatformRequest
|
||||||
, uMirrors :: Maybe DownloadMirrors
|
|
||||||
}
|
}
|
||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
defaultUserSettings :: UserSettings
|
defaultUserSettings :: UserSettings
|
||||||
defaultUserSettings = UserSettings Nothing Nothing 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
|
||||||
|
|
||||||
fromSettings :: Settings -> Maybe KeyBindings -> UserSettings
|
fromSettings :: Settings -> Maybe KeyBindings -> UserSettings
|
||||||
fromSettings Settings{..} Nothing =
|
fromSettings Settings{..} Nothing =
|
||||||
@@ -369,7 +338,6 @@ fromSettings Settings{..} Nothing =
|
|||||||
, uUrlSource = Just urlSource
|
, uUrlSource = Just urlSource
|
||||||
, uGPGSetting = Just gpgSetting
|
, uGPGSetting = Just gpgSetting
|
||||||
, uPlatformOverride = platformOverride
|
, uPlatformOverride = platformOverride
|
||||||
, uMirrors = Just mirrors
|
|
||||||
}
|
}
|
||||||
fromSettings Settings{..} (Just KeyBindings{..}) =
|
fromSettings Settings{..} (Just KeyBindings{..}) =
|
||||||
let ukb = UserKeyBindings
|
let ukb = UserKeyBindings
|
||||||
@@ -396,7 +364,6 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
|
|||||||
, uUrlSource = Just urlSource
|
, uUrlSource = Just urlSource
|
||||||
, uGPGSetting = Just gpgSetting
|
, uGPGSetting = Just gpgSetting
|
||||||
, uPlatformOverride = platformOverride
|
, uPlatformOverride = platformOverride
|
||||||
, uMirrors = Just mirrors
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data UserKeyBindings = UserKeyBindings
|
data UserKeyBindings = UserKeyBindings
|
||||||
@@ -426,9 +393,7 @@ data KeyBindings = KeyBindings
|
|||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
instance NFData KeyBindings
|
instance NFData KeyBindings
|
||||||
#if defined(IS_WINDOWS) || !defined(BRICK)
|
|
||||||
instance NFData Key
|
instance NFData Key
|
||||||
#endif
|
|
||||||
|
|
||||||
defaultKeyBindings :: KeyBindings
|
defaultKeyBindings :: KeyBindings
|
||||||
defaultKeyBindings = KeyBindings
|
defaultKeyBindings = KeyBindings
|
||||||
@@ -480,7 +445,6 @@ data Settings = Settings
|
|||||||
, gpgSetting :: GPGSetting
|
, gpgSetting :: GPGSetting
|
||||||
, noColor :: Bool -- this also exists in LoggerConfig
|
, noColor :: Bool -- this also exists in LoggerConfig
|
||||||
, platformOverride :: Maybe PlatformRequest
|
, platformOverride :: Maybe PlatformRequest
|
||||||
, mirrors :: DownloadMirrors
|
|
||||||
}
|
}
|
||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
@@ -488,7 +452,7 @@ defaultMetaCache :: Integer
|
|||||||
defaultMetaCache = 300 -- 5 minutes
|
defaultMetaCache = 300 -- 5 minutes
|
||||||
|
|
||||||
defaultSettings :: Settings
|
defaultSettings :: Settings
|
||||||
defaultSettings = Settings False defaultMetaCache Lax False Never Curl False GHCupURL False GPGNone False Nothing (DM mempty)
|
defaultSettings = Settings False defaultMetaCache Lax False Never Curl False GHCupURL False GPGNone False Nothing
|
||||||
|
|
||||||
instance NFData Settings
|
instance NFData Settings
|
||||||
|
|
||||||
@@ -593,9 +557,7 @@ data GHCTargetVersion = GHCTargetVersion
|
|||||||
{ _tvTarget :: Maybe Text
|
{ _tvTarget :: Maybe Text
|
||||||
, _tvVersion :: Version
|
, _tvVersion :: Version
|
||||||
}
|
}
|
||||||
deriving (Ord, Eq, Show, GHC.Generic)
|
deriving (Ord, Eq, Show)
|
||||||
|
|
||||||
instance NFData GHCTargetVersion
|
|
||||||
|
|
||||||
data GitBranch = GitBranch
|
data GitBranch = GitBranch
|
||||||
{ ref :: String
|
{ ref :: String
|
||||||
@@ -705,18 +667,3 @@ type PromptQuestion = Text
|
|||||||
|
|
||||||
data PromptResponse = PromptYes | PromptNo
|
data PromptResponse = PromptYes | PromptNo
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
data ToolVersion = GHCVersion GHCTargetVersion
|
|
||||||
| ToolVersion Version
|
|
||||||
| ToolTag Tag
|
|
||||||
| ToolDay Day
|
|
||||||
|
|
||||||
instance Pretty ToolVersion where
|
|
||||||
pPrint (GHCVersion v) = pPrint v
|
|
||||||
pPrint (ToolVersion v) = pPrint v
|
|
||||||
pPrint (ToolTag t) = pPrint t
|
|
||||||
pPrint (ToolDay d) = text (show d)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import Control.Applicative ( (<|>) )
|
|||||||
import Data.Aeson hiding (Key)
|
import Data.Aeson hiding (Key)
|
||||||
import Data.Aeson.TH
|
import Data.Aeson.TH
|
||||||
import Data.Aeson.Types hiding (Key)
|
import Data.Aeson.Types hiding (Key)
|
||||||
import Data.ByteString ( ByteString )
|
|
||||||
import Data.List.NonEmpty ( NonEmpty(..) )
|
import Data.List.NonEmpty ( NonEmpty(..) )
|
||||||
import Data.Text.Encoding as E
|
import Data.Text.Encoding as E
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
@@ -64,11 +63,8 @@ instance ToJSON Tag where
|
|||||||
toJSON Latest = String "Latest"
|
toJSON Latest = String "Latest"
|
||||||
toJSON Recommended = String "Recommended"
|
toJSON Recommended = String "Recommended"
|
||||||
toJSON Prerelease = String "Prerelease"
|
toJSON Prerelease = String "Prerelease"
|
||||||
toJSON Nightly = String "Nightly"
|
|
||||||
toJSON Old = String "old"
|
toJSON Old = String "old"
|
||||||
toJSON (Base pvp'') = String ("base-" <> prettyPVP pvp'')
|
toJSON (Base pvp'') = String ("base-" <> prettyPVP pvp'')
|
||||||
toJSON LatestPrerelease = String "LatestPrerelease"
|
|
||||||
toJSON LatestNightly = String "LatestNightly"
|
|
||||||
toJSON (UnknownTag x ) = String (T.pack x)
|
toJSON (UnknownTag x ) = String (T.pack x)
|
||||||
|
|
||||||
instance FromJSON Tag where
|
instance FromJSON Tag where
|
||||||
@@ -76,9 +72,6 @@ instance FromJSON Tag where
|
|||||||
"Latest" -> pure Latest
|
"Latest" -> pure Latest
|
||||||
"Recommended" -> pure Recommended
|
"Recommended" -> pure Recommended
|
||||||
"Prerelease" -> pure Prerelease
|
"Prerelease" -> pure Prerelease
|
||||||
"Nightly" -> pure Nightly
|
|
||||||
"LatestPrerelease" -> pure LatestPrerelease
|
|
||||||
"LatestNightly" -> pure LatestNightly
|
|
||||||
"old" -> pure Old
|
"old" -> pure Old
|
||||||
('b' : 'a' : 's' : 'e' : '-' : ver') -> case pvp (T.pack ver') of
|
('b' : 'a' : 's' : 'e' : '-' : ver') -> case pvp (T.pack ver') of
|
||||||
Right x -> pure $ Base x
|
Right x -> pure $ Base x
|
||||||
@@ -95,29 +88,13 @@ instance FromJSON URI where
|
|||||||
Right x -> pure x
|
Right x -> pure x
|
||||||
Left e -> fail . show $ e
|
Left e -> fail . show $ e
|
||||||
|
|
||||||
instance ToJSON GHCTargetVersion where
|
|
||||||
toJSON = toJSON . tVerToText
|
|
||||||
|
|
||||||
instance FromJSON GHCTargetVersion where
|
|
||||||
parseJSON = withText "GHCTargetVersion" $ \t -> case MP.parse ghcTargetVerP "" t of
|
|
||||||
Right x -> pure x
|
|
||||||
Left e -> fail $ "Failure in GHCTargetVersion (FromJSON)" <> show e
|
|
||||||
|
|
||||||
instance ToJSONKey GHCTargetVersion where
|
|
||||||
toJSONKey = toJSONKeyText $ \x -> tVerToText x
|
|
||||||
|
|
||||||
instance FromJSONKey GHCTargetVersion where
|
|
||||||
fromJSONKey = FromJSONKeyTextParser $ \t -> case MP.parse ghcTargetVerP "" t of
|
|
||||||
Right x -> pure x
|
|
||||||
Left e -> fail $ "Failure in GHCTargetVersion (FromJSONKey)" <> show e
|
|
||||||
|
|
||||||
instance ToJSON Versioning where
|
instance ToJSON Versioning where
|
||||||
toJSON = toJSON . prettyV
|
toJSON = toJSON . prettyV
|
||||||
|
|
||||||
instance FromJSON Versioning where
|
instance FromJSON Versioning where
|
||||||
parseJSON = withText "Versioning" $ \t -> case versioning t of
|
parseJSON = withText "Versioning" $ \t -> case versioning t of
|
||||||
Right x -> pure x
|
Right x -> pure x
|
||||||
Left e -> fail $ "Failure in GHCTargetVersion (FromJSON)" <> show e
|
Left e -> fail $ "Failure in Version (FromJSON)" <> show e
|
||||||
|
|
||||||
instance ToJSONKey Versioning where
|
instance ToJSONKey Versioning where
|
||||||
toJSONKey = toJSONKeyText $ \x -> prettyV x
|
toJSONKey = toJSONKeyText $ \x -> prettyV x
|
||||||
@@ -248,12 +225,6 @@ instance FromJSON VersionCmp where
|
|||||||
Right r -> pure r
|
Right r -> pure r
|
||||||
Left e -> fail (MP.errorBundlePretty e)
|
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 :: VersionCmp -> T.Text
|
||||||
versionCmpToText (VR_gt ver') = "> " <> prettyV ver'
|
versionCmpToText (VR_gt ver') = "> " <> prettyV ver'
|
||||||
versionCmpToText (VR_gteq ver') = ">= " <> prettyV ver'
|
versionCmpToText (VR_gteq ver') = ">= " <> prettyV ver'
|
||||||
@@ -349,12 +320,6 @@ deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''GHCupI
|
|||||||
deriveToJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''URLSource
|
deriveToJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''URLSource
|
||||||
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''Key
|
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 = \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 = kebab } ''Settings
|
||||||
deriveToJSON defaultOptions { fieldLabelModifier = drop 2 . kebab } ''KeyBindings -- move under key-bindings key
|
deriveToJSON defaultOptions { fieldLabelModifier = drop 2 . kebab } ''KeyBindings -- move under key-bindings key
|
||||||
|
|
||||||
@@ -391,3 +356,4 @@ instance FromJSON URLSource where
|
|||||||
pure (AddSource r)
|
pure (AddSource r)
|
||||||
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "u-") . T.pack . kebab $ str' } ''UserSettings
|
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "u-") . T.pack . kebab $ str' } ''UserSettings
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ import Control.Monad.Trans.Resource
|
|||||||
hiding ( throwM )
|
hiding ( throwM )
|
||||||
import Control.Monad.IO.Unlift ( MonadUnliftIO( withRunInIO ) )
|
import Control.Monad.IO.Unlift ( MonadUnliftIO( withRunInIO ) )
|
||||||
import Data.Char ( isHexDigit )
|
import Data.Char ( isHexDigit )
|
||||||
|
import Data.Bifunctor ( first )
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Foldable
|
import Data.Foldable
|
||||||
@@ -92,8 +93,6 @@ import qualified Data.List.NonEmpty as NE
|
|||||||
import qualified Streamly.Prelude as S
|
import qualified Streamly.Prelude as S
|
||||||
import Control.DeepSeq (force)
|
import Control.DeepSeq (force)
|
||||||
import GHC.IO (evaluate)
|
import GHC.IO (evaluate)
|
||||||
import System.Environment (getEnvironment, setEnv)
|
|
||||||
import Data.Time (Day(..), diffDays, addDays)
|
|
||||||
|
|
||||||
|
|
||||||
-- $setup
|
-- $setup
|
||||||
@@ -335,7 +334,7 @@ ghcSet mtarget = do
|
|||||||
getInstalledGHCs :: (MonadReader env m, HasDirs env, MonadIO m) => m [Either FilePath GHCTargetVersion]
|
getInstalledGHCs :: (MonadReader env m, HasDirs env, MonadIO m) => m [Either FilePath GHCTargetVersion]
|
||||||
getInstalledGHCs = do
|
getInstalledGHCs = do
|
||||||
ghcdir <- ghcupGHCBaseDir
|
ghcdir <- ghcupGHCBaseDir
|
||||||
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectoryDirs (fromGHCupPath ghcdir)
|
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectory (fromGHCupPath ghcdir)
|
||||||
forM fs $ \f -> case parseGHCupGHCDir f of
|
forM fs $ \f -> case parseGHCupGHCDir f of
|
||||||
Right r -> pure $ Right r
|
Right r -> pure $ Right r
|
||||||
Left _ -> pure $ Left f
|
Left _ -> pure $ Left f
|
||||||
@@ -438,7 +437,7 @@ getInstalledHLSs = do
|
|||||||
Nothing -> pure $ Left f
|
Nothing -> pure $ Left f
|
||||||
|
|
||||||
hlsdir <- ghcupHLSBaseDir
|
hlsdir <- ghcupHLSBaseDir
|
||||||
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectoryDirs (fromGHCupPath hlsdir)
|
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectory (fromGHCupPath hlsdir)
|
||||||
new <- forM fs $ \f -> case parseGHCupHLSDir f of
|
new <- forM fs $ \f -> case parseGHCupHLSDir f of
|
||||||
Right r -> pure $ Right r
|
Right r -> pure $ Right r
|
||||||
Left _ -> pure $ Left f
|
Left _ -> pure $ Left f
|
||||||
@@ -626,7 +625,7 @@ hlsInternalServerScripts ver mghcVer = do
|
|||||||
dir <- ghcupHLSDir ver
|
dir <- ghcupHLSDir ver
|
||||||
let bdir = fromGHCupPath dir </> "bin"
|
let bdir = fromGHCupPath dir </> "bin"
|
||||||
fmap (bdir </>) . filter (\f -> maybe True (\gv -> ("-" <> T.unpack (prettyVer gv)) `isSuffixOf` f) mghcVer)
|
fmap (bdir </>) . filter (\f -> maybe True (\gv -> ("-" <> T.unpack (prettyVer gv)) `isSuffixOf` f) mghcVer)
|
||||||
<$> liftIO (listDirectoryFiles bdir)
|
<$> liftIO (listDirectory bdir)
|
||||||
|
|
||||||
-- | Get all binaries for a hls version from the ~/.ghcup/hls/<ver>/lib/haskell-language-server-<ver>/bin directory, if any.
|
-- | 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.
|
-- Returns the full path.
|
||||||
@@ -639,7 +638,7 @@ hlsInternalServerBinaries ver mghcVer = do
|
|||||||
let regex = makeRegexOpts compExtended execBlank ([s|^haskell-language-server-.*$|] :: ByteString)
|
let regex = makeRegexOpts compExtended execBlank ([s|^haskell-language-server-.*$|] :: ByteString)
|
||||||
(Just bdir) <- fmap headMay $ liftIO $ expandFilePath [Left (dir </> "lib"), Right regex, Left "bin"]
|
(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)
|
fmap (bdir </>) . filter (\f -> maybe True (\gv -> ("-" <> T.unpack (prettyVer gv)) `isSuffixOf` f) mghcVer)
|
||||||
<$> liftIO (listDirectoryFiles bdir)
|
<$> liftIO (listDirectory bdir)
|
||||||
|
|
||||||
-- | Get all libraries for a hls version from the ~/.ghcup/hls/<ver>/lib/haskell-language-server-<ver>/lib/<ghc-ver>/
|
-- | Get all libraries for a hls version from the ~/.ghcup/hls/<ver>/lib/haskell-language-server-<ver>/lib/<ghc-ver>/
|
||||||
-- directory, if any.
|
-- directory, if any.
|
||||||
@@ -652,7 +651,7 @@ hlsInternalServerLibs ver ghcVer = do
|
|||||||
dir <- fromGHCupPath <$> ghcupHLSDir ver
|
dir <- fromGHCupPath <$> ghcupHLSDir ver
|
||||||
let regex = makeRegexOpts compExtended execBlank ([s|^haskell-language-server-.*$|] :: ByteString)
|
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))]
|
(Just bdir) <- fmap headMay $ liftIO $ expandFilePath [Left (dir </> "lib"), Right regex, Left ("lib" </> T.unpack (prettyVer ghcVer))]
|
||||||
fmap (bdir </>) <$> liftIO (listDirectoryFiles bdir)
|
fmap (bdir </>) <$> liftIO (listDirectory bdir)
|
||||||
|
|
||||||
|
|
||||||
-- | Get the wrapper binary for an hls version, if any.
|
-- | Get the wrapper binary for an hls version, if any.
|
||||||
@@ -773,16 +772,13 @@ getGHCForPVP' pvpIn ghcs' mt = do
|
|||||||
-- Just (PVP {_pComponents = 8 :| [8,4]})
|
-- Just (PVP {_pComponents = 8 :| [8,4]})
|
||||||
getLatestToolFor :: MonadThrow m
|
getLatestToolFor :: MonadThrow m
|
||||||
=> Tool
|
=> Tool
|
||||||
-> Maybe Text
|
|
||||||
-> PVP
|
-> PVP
|
||||||
-> GHCupDownloads
|
-> GHCupDownloads
|
||||||
-> m (Maybe (PVP, VersionInfo, Maybe Text))
|
-> m (Maybe (PVP, VersionInfo))
|
||||||
getLatestToolFor tool target pvpIn dls = do
|
getLatestToolFor tool pvpIn dls = do
|
||||||
let ls :: [(GHCTargetVersion, VersionInfo)]
|
let ls = fromMaybe [] $ preview (ix tool % to Map.toDescList) dls
|
||||||
ls = fromMaybe [] $ preview (ix tool % to Map.toDescList) dls
|
let ps = catMaybes $ fmap (\(v, vi) -> (,vi) <$> versionToPVP v) ls
|
||||||
let ps :: [((PVP, Text), VersionInfo, Maybe Text)]
|
pure . fmap (first fst) . headMay . filter (\((v, _), _) -> matchPVPrefix pvpIn v) $ ps
|
||||||
ps = catMaybes $ fmap (\(v, vi) -> (,vi, _tvTarget v) <$> versionToPVP (_tvVersion v)) ls
|
|
||||||
pure . fmap (\((pv', _), vi, mt) -> (pv', vi, mt)) . headMay . filter (\((v, _), _, t) -> matchPVPrefix pvpIn v && t == target) $ ps
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -887,41 +883,20 @@ intoSubdir bdir tardir = case tardir of
|
|||||||
-- | Get the tool version that has this tag. If multiple have it,
|
-- | Get the tool version that has this tag. If multiple have it,
|
||||||
-- picks the greatest version.
|
-- picks the greatest version.
|
||||||
getTagged :: Tag
|
getTagged :: Tag
|
||||||
-> Fold (Map.Map GHCTargetVersion VersionInfo) (GHCTargetVersion, VersionInfo)
|
-> Fold (Map.Map Version VersionInfo) (Version, VersionInfo)
|
||||||
getTagged tag =
|
getTagged tag =
|
||||||
to (Map.toDescList . Map.filter (\VersionInfo {..} -> tag `elem` _viTags))
|
to (Map.toDescList . Map.filter (\VersionInfo {..} -> tag `elem` _viTags))
|
||||||
% folding id
|
% folding id
|
||||||
|
|
||||||
getByReleaseDay :: GHCupDownloads -> Tool -> Day -> Either (Maybe Day) (GHCTargetVersion, VersionInfo)
|
getLatest :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
|
||||||
getByReleaseDay av tool day = let mvv = fromMaybe mempty $ headOf (ix tool) av
|
|
||||||
mdv = Map.foldrWithKey (\k vi@VersionInfo{..} m ->
|
|
||||||
maybe m (\d -> let diff = diffDays d day
|
|
||||||
in Map.insert (abs diff) (diff, (k, vi)) m) _viReleaseDay)
|
|
||||||
Map.empty mvv
|
|
||||||
in case headMay (Map.toAscList mdv) of
|
|
||||||
Nothing -> Left Nothing
|
|
||||||
Just (absDiff, (diff, (k, vi)))
|
|
||||||
| absDiff == 0 -> Right (k, vi)
|
|
||||||
| otherwise -> Left (Just (addDays diff day))
|
|
||||||
|
|
||||||
getByReleaseDayFold :: Day -> Fold (Map.Map GHCTargetVersion VersionInfo) (GHCTargetVersion, VersionInfo)
|
|
||||||
getByReleaseDayFold day = to (Map.toDescList . Map.filter (\VersionInfo {..} -> Just day == _viReleaseDay)) % folding id
|
|
||||||
|
|
||||||
getLatest :: GHCupDownloads -> Tool -> Maybe (GHCTargetVersion, VersionInfo)
|
|
||||||
getLatest av tool = headOf (ix tool % getTagged Latest) av
|
getLatest av tool = headOf (ix tool % getTagged Latest) av
|
||||||
|
|
||||||
getLatestPrerelease :: GHCupDownloads -> Tool -> Maybe (GHCTargetVersion, VersionInfo)
|
getRecommended :: GHCupDownloads -> Tool -> Maybe (Version, VersionInfo)
|
||||||
getLatestPrerelease av tool = headOf (ix tool % getTagged LatestPrerelease) av
|
|
||||||
|
|
||||||
getLatestNightly :: GHCupDownloads -> Tool -> Maybe (GHCTargetVersion, VersionInfo)
|
|
||||||
getLatestNightly av tool = headOf (ix tool % getTagged LatestNightly) av
|
|
||||||
|
|
||||||
getRecommended :: GHCupDownloads -> Tool -> Maybe (GHCTargetVersion, VersionInfo)
|
|
||||||
getRecommended av tool = headOf (ix tool % getTagged Recommended) av
|
getRecommended av tool = headOf (ix tool % getTagged Recommended) av
|
||||||
|
|
||||||
|
|
||||||
-- | Gets the latest GHC with a given base version.
|
-- | Gets the latest GHC with a given base version.
|
||||||
getLatestBaseVersion :: GHCupDownloads -> PVP -> Maybe (GHCTargetVersion, VersionInfo)
|
getLatestBaseVersion :: GHCupDownloads -> PVP -> Maybe (Version, VersionInfo)
|
||||||
getLatestBaseVersion av pvpVer =
|
getLatestBaseVersion av pvpVer =
|
||||||
headOf (ix GHC % getTagged (Base pvpVer)) av
|
headOf (ix GHC % getTagged (Base pvpVer)) av
|
||||||
|
|
||||||
@@ -957,7 +932,7 @@ ghcToolFiles ver = do
|
|||||||
whenM (fmap not $ ghcInstalled ver)
|
whenM (fmap not $ ghcInstalled ver)
|
||||||
(throwE (NotInstalled GHC ver))
|
(throwE (NotInstalled GHC ver))
|
||||||
|
|
||||||
files <- liftIO (listDirectoryFiles bindir >>= filterM (doesFileExist . (bindir </>)))
|
files <- liftIO (listDirectory bindir >>= filterM (doesFileExist . (bindir </>)))
|
||||||
pure (getUniqueTools . groupToolFiles . fmap (dropSuffix exeExt) $ files)
|
pure (getUniqueTools . groupToolFiles . fmap (dropSuffix exeExt) $ files)
|
||||||
|
|
||||||
where
|
where
|
||||||
@@ -992,28 +967,11 @@ make :: ( MonadThrow m
|
|||||||
=> [String]
|
=> [String]
|
||||||
-> Maybe FilePath
|
-> Maybe FilePath
|
||||||
-> m (Either ProcessError ())
|
-> m (Either ProcessError ())
|
||||||
make args workdir = make' args workdir "ghc-make" Nothing
|
make args workdir = do
|
||||||
|
|
||||||
|
|
||||||
-- | 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
|
spaths <- liftIO getSearchPath
|
||||||
has_gmake <- isJust <$> liftIO (searchPath spaths "gmake")
|
has_gmake <- isJust <$> liftIO (searchPath spaths "gmake")
|
||||||
let mymake = if has_gmake then "gmake" else "make"
|
let mymake = if has_gmake then "gmake" else "make"
|
||||||
execLogged mymake args workdir logfile menv
|
execLogged mymake args workdir "ghc-make" Nothing
|
||||||
|
|
||||||
|
|
||||||
makeOut :: (MonadReader env m, HasDirs env, MonadIO m)
|
makeOut :: (MonadReader env m, HasDirs env, MonadIO m)
|
||||||
=> [String]
|
=> [String]
|
||||||
@@ -1102,15 +1060,11 @@ darwinNotarization _ _ = pure $ Right ()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
getChangeLog :: GHCupDownloads -> Tool -> ToolVersion -> Maybe URI
|
getChangeLog :: GHCupDownloads -> Tool -> Either Version Tag -> Maybe URI
|
||||||
getChangeLog dls tool (GHCVersion v') =
|
getChangeLog dls tool (Left v') =
|
||||||
preview (ix tool % ix v' % viChangeLog % _Just) dls
|
preview (ix tool % ix v' % viChangeLog % _Just) dls
|
||||||
getChangeLog dls tool (ToolVersion (mkTVer -> v')) =
|
getChangeLog dls tool (Right tag) =
|
||||||
preview (ix tool % ix v' % viChangeLog % _Just) dls
|
|
||||||
getChangeLog dls tool (ToolTag tag) =
|
|
||||||
preview (ix tool % pre (getTagged tag) % to snd % viChangeLog % _Just) dls
|
preview (ix tool % pre (getTagged tag) % to snd % viChangeLog % _Just) dls
|
||||||
getChangeLog dls tool (ToolDay day) =
|
|
||||||
preview (ix tool % pre (getByReleaseDayFold day) % to snd % viChangeLog % _Just) dls
|
|
||||||
|
|
||||||
|
|
||||||
-- | Execute a build action while potentially cleaning up:
|
-- | Execute a build action while potentially cleaning up:
|
||||||
@@ -1194,7 +1148,7 @@ rmBDir dir = withRunInIO (\run -> run $
|
|||||||
$ rmPathForcibly dir)
|
$ rmPathForcibly dir)
|
||||||
|
|
||||||
|
|
||||||
getVersionInfo :: GHCTargetVersion
|
getVersionInfo :: Version
|
||||||
-> Tool
|
-> Tool
|
||||||
-> GHCupDownloads
|
-> GHCupDownloads
|
||||||
-> Maybe VersionInfo
|
-> Maybe VersionInfo
|
||||||
@@ -1328,22 +1282,6 @@ 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 ]--
|
--[ Git ]--
|
||||||
-----------
|
-----------
|
||||||
|
|||||||
@@ -42,9 +42,6 @@ module GHCup.Utils.Dirs
|
|||||||
, removeDirectoryRecursive
|
, removeDirectoryRecursive
|
||||||
, removePathForcibly
|
, removePathForcibly
|
||||||
|
|
||||||
, listDirectoryFiles
|
|
||||||
, listDirectoryDirs
|
|
||||||
|
|
||||||
-- System.Directory re-exports
|
-- System.Directory re-exports
|
||||||
, createDirectory
|
, createDirectory
|
||||||
, createDirectoryIfMissing
|
, createDirectoryIfMissing
|
||||||
@@ -133,7 +130,7 @@ import Data.Maybe
|
|||||||
import Data.Versions
|
import Data.Versions
|
||||||
import GHC.IO.Exception ( IOErrorType(NoSuchThing) )
|
import GHC.IO.Exception ( IOErrorType(NoSuchThing) )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Optics hiding ( uncons )
|
import Optics
|
||||||
import Safe
|
import Safe
|
||||||
import System.Directory hiding ( removeDirectory
|
import System.Directory hiding ( removeDirectory
|
||||||
, removeDirectoryRecursive
|
, removeDirectoryRecursive
|
||||||
@@ -279,7 +276,7 @@ ghcupCacheDir
|
|||||||
Nothing -> do
|
Nothing -> do
|
||||||
home <- liftIO getHomeDirectory
|
home <- liftIO getHomeDirectory
|
||||||
pure (home </> ".cache")
|
pure (home </> ".cache")
|
||||||
pure (GHCupPath (bdir </> "ghcup" </> "cache"))
|
pure (GHCupPath (bdir </> "ghcup"))
|
||||||
else ghcupBaseDir <&> (\(GHCupPath gp) -> GHCupPath (gp </> "cache"))
|
else ghcupBaseDir <&> (\(GHCupPath gp) -> GHCupPath (gp </> "cache"))
|
||||||
|
|
||||||
|
|
||||||
@@ -308,7 +305,19 @@ ghcupLogsDir
|
|||||||
-- If 'GHCUP_USE_XDG_DIRS' is set (to anything),
|
-- If 'GHCUP_USE_XDG_DIRS' is set (to anything),
|
||||||
-- then uses 'XDG_CACHE_HOME/ghcup/db as per xdg spec.
|
-- then uses 'XDG_CACHE_HOME/ghcup/db as per xdg spec.
|
||||||
ghcupDbDir :: IO GHCupPath
|
ghcupDbDir :: IO GHCupPath
|
||||||
ghcupDbDir = ghcupBaseDir <&> (\(GHCupPath gp) -> GHCupPath (gp </> "db"))
|
ghcupDbDir
|
||||||
|
| isWindows = ghcupBaseDir <&> (\(GHCupPath gp) -> GHCupPath (gp </> "db"))
|
||||||
|
| otherwise = do
|
||||||
|
xdg <- useXDG
|
||||||
|
if xdg
|
||||||
|
then do
|
||||||
|
bdir <- lookupEnv "XDG_CACHE_HOME" >>= \case
|
||||||
|
Just r -> pure r
|
||||||
|
Nothing -> do
|
||||||
|
home <- liftIO getHomeDirectory
|
||||||
|
pure (home </> ".cache")
|
||||||
|
pure (GHCupPath (bdir </> "ghcup" </> "db"))
|
||||||
|
else ghcupBaseDir <&> (\(GHCupPath gp) -> GHCupPath (gp </> "db"))
|
||||||
|
|
||||||
|
|
||||||
-- | '~/.ghcup/trash'.
|
-- | '~/.ghcup/trash'.
|
||||||
@@ -520,29 +529,6 @@ cleanupTrash = do
|
|||||||
) $ liftIO $ removePathForcibly (recycleDir `appendGHCupPath` fp))
|
) $ 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
|
-- System.Directory re-exports with GHCupPath
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ versionCmp ver1 (VR_lteq ver2) = ver1 <= ver2
|
|||||||
versionCmp ver1 (VR_eq ver2) = ver1 == ver2
|
versionCmp ver1 (VR_eq ver2) = ver1 == ver2
|
||||||
|
|
||||||
versionRange :: V.Versioning -> VersionRange -> Bool
|
versionRange :: V.Versioning -> VersionRange -> Bool
|
||||||
versionRange ver' (SimpleRange cmps) = all (versionCmp ver') cmps
|
versionRange ver' (SimpleRange cmps) = and $ fmap (versionCmp ver') cmps
|
||||||
versionRange ver' (OrRange cmps range) =
|
versionRange ver' (OrRange cmps range) =
|
||||||
versionRange ver' (SimpleRange cmps) || versionRange ver' range
|
versionRange ver' (SimpleRange cmps) || versionRange ver' range
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ site_name: GHCup
|
|||||||
site_url: https://www.haskell.org/ghcup
|
site_url: https://www.haskell.org/ghcup
|
||||||
site_description: GHCup is the main installer for the general purpose language Haskell.
|
site_description: GHCup is the main installer for the general purpose language Haskell.
|
||||||
site_author: GHCup Team
|
site_author: GHCup Team
|
||||||
|
site_favicon: haskell_logo.png
|
||||||
|
|
||||||
repo_url: https://github.com/haskell/ghcup-hs
|
repo_url: https://github.com/haskell/ghcup-hs
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
plat="$(uname -s)"
|
plat="$(uname -s)"
|
||||||
arch=$(uname -m)
|
arch=$(uname -m)
|
||||||
ghver="0.1.19.4"
|
ghver="0.1.18.0"
|
||||||
: "${GHCUP_BASE_URL:=https://downloads.haskell.org/~ghcup}"
|
: "${GHCUP_BASE_URL:=https://downloads.haskell.org/~ghcup}"
|
||||||
|
|
||||||
export GHCUP_SKIP_UPDATE_CHECK=yes
|
export GHCUP_SKIP_UPDATE_CHECK=yes
|
||||||
@@ -119,26 +119,20 @@ edo() {
|
|||||||
"$@" || die "\"$*\" failed!"
|
"$@" || die "\"$*\" failed!"
|
||||||
}
|
}
|
||||||
|
|
||||||
eghcup_raw() {
|
|
||||||
"${GHCUP_BIN}/ghcup" "$@" || die "\"ghcup $*\" failed!"
|
|
||||||
}
|
|
||||||
|
|
||||||
eghcup() {
|
eghcup() {
|
||||||
_eghcup "$@"
|
edo _eghcup "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
_eghcup() {
|
_eghcup() {
|
||||||
if [ -n "${BOOTSTRAP_HASKELL_YAML}" ] ; then
|
if [ -n "${BOOTSTRAP_HASKELL_YAML}" ] ; then
|
||||||
args="-s ${BOOTSTRAP_HASKELL_YAML} --metadata-fetching-mode=Strict"
|
args="-s ${BOOTSTRAP_HASKELL_YAML}"
|
||||||
else
|
|
||||||
args="--metadata-fetching-mode=Strict"
|
|
||||||
fi
|
fi
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_VERBOSE}" ] ; then
|
if [ -z "${BOOTSTRAP_HASKELL_VERBOSE}" ] ; then
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
"${GHCUP_BIN}/ghcup" ${args} "$@" || die "\"ghcup ${args} $*\" failed!"
|
"${GHCUP_BIN}/ghcup" ${args} "$@"
|
||||||
else
|
else
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
"${GHCUP_BIN}/ghcup" ${args} --verbose "$@" || die "\"ghcup ${args} --verbose $*\" failed!"
|
"${GHCUP_BIN}/ghcup" ${args} --verbose "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +147,7 @@ _ecabal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ecabal() {
|
ecabal() {
|
||||||
_ecabal "$@" || die "\"cabal $*\" failed!"
|
edo _ecabal "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
_done() {
|
_done() {
|
||||||
@@ -288,6 +282,14 @@ download_ghcup() {
|
|||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
"FreeBSD"|"freebsd")
|
"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
|
case "${arch}" in
|
||||||
x86_64|amd64)
|
x86_64|amd64)
|
||||||
;;
|
;;
|
||||||
@@ -297,7 +299,7 @@ download_ghcup() {
|
|||||||
*) die "Unknown architecture: ${arch}"
|
*) die "Unknown architecture: ${arch}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
_url=${GHCUP_BASE_URL}/${ghver}/x86_64-portbld-freebsd-ghcup-${ghver}
|
_url=${GHCUP_BASE_URL}/${ghver}/x86_64-freebsd${freebsd_ver}-ghcup-${ghver}
|
||||||
;;
|
;;
|
||||||
"Darwin"|"darwin")
|
"Darwin"|"darwin")
|
||||||
case "${arch}" in
|
case "${arch}" in
|
||||||
@@ -385,10 +387,10 @@ download_ghcup() {
|
|||||||
edo . "${GHCUP_DIR}"/env
|
edo . "${GHCUP_DIR}"/env
|
||||||
case "${BOOTSTRAP_HASKELL_DOWNLOADER}" in
|
case "${BOOTSTRAP_HASKELL_DOWNLOADER}" in
|
||||||
"curl")
|
"curl")
|
||||||
eghcup_raw config set downloader Curl
|
eghcup config set downloader Curl
|
||||||
;;
|
;;
|
||||||
"wget")
|
"wget")
|
||||||
eghcup_raw config set downloader Wget
|
eghcup config set downloader Wget
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
die "Unknown downloader: ${BOOTSTRAP_HASKELL_DOWNLOADER}"
|
die "Unknown downloader: ${BOOTSTRAP_HASKELL_DOWNLOADER}"
|
||||||
@@ -793,7 +795,7 @@ edo mkdir -p "${GHCUP_BIN}"
|
|||||||
|
|
||||||
if command -V "ghcup" >/dev/null 2>&1 ; then
|
if command -V "ghcup" >/dev/null 2>&1 ; then
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_NO_UPGRADE}" ] ; then
|
if [ -z "${BOOTSTRAP_HASKELL_NO_UPGRADE}" ] ; then
|
||||||
( _eghcup upgrade ) || download_ghcup
|
_eghcup upgrade || download_ghcup
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
download_ghcup
|
download_ghcup
|
||||||
@@ -840,19 +842,19 @@ fi
|
|||||||
|
|
||||||
case $ask_hls_answer in
|
case $ask_hls_answer in
|
||||||
1)
|
1)
|
||||||
(_eghcup --cache install hls) || warn "HLS installation failed, continuing anyway"
|
_eghcup --cache install hls || warn "HLS installation failed, continuing anyway"
|
||||||
;;
|
;;
|
||||||
*) ;;
|
*) ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case $ask_stack_answer in
|
case $ask_stack_answer in
|
||||||
1)
|
1)
|
||||||
(_eghcup --cache install stack) || die "Stack installation failed"
|
_eghcup --cache install stack || die "Stack installation failed"
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
(_eghcup --cache install stack) || die "Stack installation failed"
|
_eghcup --cache install stack || die "Stack installation failed"
|
||||||
edo mkdir -p "${STACK_ROOT:-$HOME/.stack}"/hooks
|
edo mkdir -p "${STACK_ROOOT:-$HOME/.stack}"/hooks
|
||||||
hook_exe="${STACK_ROOT:-$HOME/.stack}"/hooks/ghc-install.sh
|
hook_exe="${STACK_ROOOT:-$HOME/.stack}"/hooks/ghc-install.sh
|
||||||
hook_url="https://www.haskell.org/ghcup/sh/hooks/stack/ghc-install.sh"
|
hook_url="https://www.haskell.org/ghcup/sh/hooks/stack/ghc-install.sh"
|
||||||
|
|
||||||
if [ -e "${hook_exe}" ] ; then
|
if [ -e "${hook_exe}" ] ; then
|
||||||
|
|||||||
@@ -432,13 +432,12 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
|
|||||||
}
|
}
|
||||||
Print-Msg -msg ('Downloading Msys2 archive {0}...' -f $Msys2Version)
|
Print-Msg -msg ('Downloading Msys2 archive {0}...' -f $Msys2Version)
|
||||||
$archive = ('msys2-base-x86_64-{0}.sfx.exe' -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")
|
$archivePath = ('{0}\{1}' -f ([IO.Path]::GetTempPath()), "$archive")
|
||||||
|
|
||||||
if ((Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) -and !($DisableCurl)) {
|
if ((Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) -and !($DisableCurl)) {
|
||||||
Exec "curl.exe" '-o' "$archivePath" "$msysUrl"
|
Exec "curl.exe" '-o' "$archivePath" ('https://repo.msys2.org/distrib/x86_64/{0}' -f "$archive")
|
||||||
} else {
|
} else {
|
||||||
Get-FileWCSynchronous -url "$msysUrl" -destinationFolder ([IO.Path]::GetTempPath()) -includeStats
|
Get-FileWCSynchronous -url ('https://repo.msys2.org/distrib/{0}' -f $archive) -destinationFolder ([IO.Path]::GetTempPath()) -includeStats
|
||||||
}
|
}
|
||||||
|
|
||||||
Print-Msg -msg 'Extracting Msys2 archive...'
|
Print-Msg -msg 'Extracting Msys2 archive...'
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
RELEASE=$1
|
|
||||||
|
|
||||||
get_sha() {
|
|
||||||
sha256sum "$1" | awk '{ print $1 }'
|
|
||||||
}
|
|
||||||
|
|
||||||
cd "gh-release-artifacts/v${RELEASE}"
|
|
||||||
|
|
||||||
cat <<EOF > /dev/stdout
|
|
||||||
GHCup:
|
|
||||||
${RELEASE}:
|
|
||||||
viTags:
|
|
||||||
- Recommended
|
|
||||||
- Latest
|
|
||||||
viChangeLog: https://github.com/haskell/ghcup-hs/blob/master/CHANGELOG.md
|
|
||||||
viSourceDL:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/ghcup-${RELEASE}-src.tar.gz
|
|
||||||
dlSubdir: ghcup-${RELEASE}
|
|
||||||
dlHash: $(get_sha "ghcup-${RELEASE}-src.tar.gz")
|
|
||||||
viArch:
|
|
||||||
A_64:
|
|
||||||
Linux_UnknownLinux:
|
|
||||||
unknown_versioning: &ghcup-64
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/x86_64-linux-ghcup-${RELEASE}
|
|
||||||
dlHash: $(get_sha "x86_64-linux-ghcup-${RELEASE}")
|
|
||||||
Darwin:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/x86_64-apple-darwin-ghcup-${RELEASE}
|
|
||||||
dlHash: $(get_sha "x86_64-apple-darwin-ghcup-${RELEASE}")
|
|
||||||
FreeBSD:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/x86_64-portbld-freebsd-ghcup-${RELEASE}
|
|
||||||
dlHash: $(get_sha "x86_64-portbld-freebsd-ghcup-${RELEASE}")
|
|
||||||
Windows:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/x86_64-mingw64-ghcup-${RELEASE}.exe
|
|
||||||
dlHash: $(get_sha "x86_64-mingw64-ghcup-${RELEASE}.exe")
|
|
||||||
Linux_Alpine:
|
|
||||||
unknown_versioning: *ghcup-64
|
|
||||||
A_32:
|
|
||||||
Linux_UnknownLinux:
|
|
||||||
unknown_versioning: &ghcup-32
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/i386-linux-ghcup-${RELEASE}
|
|
||||||
dlHash: $(get_sha "i386-linux-ghcup-${RELEASE}")
|
|
||||||
Linux_Alpine:
|
|
||||||
unknown_versioning: *ghcup-32
|
|
||||||
A_ARM64:
|
|
||||||
Linux_UnknownLinux:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/aarch64-linux-ghcup-${RELEASE}
|
|
||||||
dlHash: $(get_sha "aarch64-linux-ghcup-${RELEASE}")
|
|
||||||
Darwin:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/aarch64-apple-darwin-ghcup-${RELEASE}
|
|
||||||
dlHash: $(get_sha "aarch64-apple-darwin-ghcup-${RELEASE}")
|
|
||||||
A_ARM:
|
|
||||||
Linux_UnknownLinux:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/${RELEASE}/armv7-linux-ghcup-${RELEASE}
|
|
||||||
dlHash: $(get_sha "armv7-linux-ghcup-${RELEASE}")
|
|
||||||
EOF
|
|
||||||
|
|
||||||
@@ -1,37 +1,49 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
shopt -s extglob
|
tag=v$1
|
||||||
|
ver=$1
|
||||||
|
|
||||||
RELEASE=$1
|
dest=$2
|
||||||
SIGNER=$2
|
gpg_user=$3
|
||||||
TAG=${RELEASE/v/}
|
|
||||||
|
|
||||||
echo "RELEASE: $RELEASE"
|
mkdir -p "${dest}"
|
||||||
echo "SIGNER: $SIGNER"
|
|
||||||
|
|
||||||
for com in gh gpg curl sha256sum ; do
|
cd "${dest}"
|
||||||
command -V ${com} >/dev/null 2>&1
|
|
||||||
done
|
|
||||||
|
|
||||||
[ ! -e "gh-release-artifacts/${RELEASE}" ]
|
base_url="https://gitlab.haskell.org/api/v4/projects/618/jobs/artifacts/${tag}/raw"
|
||||||
|
|
||||||
mkdir -p "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"
|
||||||
|
|
||||||
git archive --format=tar.gz -o "gh-release-artifacts/${RELEASE}/ghcup-${TAG}-src.tar.gz" --prefix="ghcup-${TAG}/" HEAD
|
curl -f -o "aarch64-apple-darwin-ghcup-${ver}" \
|
||||||
|
"${base_url}/out/aarch64-apple-darwin-ghcup-${ver}?job=release:darwin:aarch64"
|
||||||
|
|
||||||
cd "gh-release-artifacts/${RELEASE}"
|
curl -f -o "x86_64-freebsd12-ghcup-${ver}" \
|
||||||
|
"${base_url}/out/x86_64-portbld-freebsd-ghcup-${ver}?job=release:freebsd12"
|
||||||
|
|
||||||
# github
|
curl -f -o "x86_64-freebsd13-ghcup-${ver}" \
|
||||||
gh release download "$RELEASE"
|
"${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
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|||||||
@@ -21,14 +21,16 @@ rm i386-linux-ghcup
|
|||||||
rm x86_64-apple-darwin-ghcup
|
rm x86_64-apple-darwin-ghcup
|
||||||
rm x86_64-linux-ghcup
|
rm x86_64-linux-ghcup
|
||||||
rm x86_64-mingw64-ghcup.exe
|
rm x86_64-mingw64-ghcup.exe
|
||||||
rm x86_64-portbld-freebsd-ghcup
|
rm x86_64-freebsd12-ghcup
|
||||||
|
rm x86_64-freebsd13-ghcup
|
||||||
|
|
||||||
symlink ${ver}/aarch64-apple-darwin-ghcup-${ver} aarch64-apple-darwin-ghcup
|
symlink ${ver}/aarch64-apple-darwin-ghcup-${ver} aarch64-apple-darwin-ghcup
|
||||||
symlink ${ver}/aarch64-linux-ghcup-${ver} aarch64-linux-ghcup
|
symlink ${ver}/aarch64-linux-ghcup-${ver} aarch64-linux-ghcup
|
||||||
symlink ${ver}/armv7-linux-ghcup-${ver} armv7-linux-ghcup
|
symlink ${ver}/armv7-linux-ghcup-${ver} armv7-linux-ghcup
|
||||||
symlink ${ver}/i386-linux-ghcup-${ver} i386-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-apple-darwin-ghcup-${ver} x86_64-apple-darwin-ghcup
|
||||||
symlink ${ver}/x86_64-portbld-freebsd-ghcup-${ver} x86_64-portbld-freebsd-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-linux-ghcup-${ver} x86_64-linux-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
|
symlink ${ver}/x86_64-mingw64-ghcup-${ver}.exe x86_64-mingw64-ghcup.exe
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@@ -25,28 +25,22 @@ put SHA256SUMS
|
|||||||
put SHA256SUMS.sig
|
put SHA256SUMS.sig
|
||||||
put aarch64-apple-darwin-ghcup-${ver}
|
put aarch64-apple-darwin-ghcup-${ver}
|
||||||
put aarch64-apple-darwin-ghcup-${ver}.sig
|
put aarch64-apple-darwin-ghcup-${ver}.sig
|
||||||
put aarch64-apple-darwin-ghcup.plan.json
|
|
||||||
put aarch64-linux-ghcup-${ver}
|
put aarch64-linux-ghcup-${ver}
|
||||||
put aarch64-linux-ghcup-${ver}.sig
|
put aarch64-linux-ghcup-${ver}.sig
|
||||||
put aarch64-linux-ghcup.plan.json
|
|
||||||
put armv7-linux-ghcup-${ver}
|
put armv7-linux-ghcup-${ver}
|
||||||
put armv7-linux-ghcup-${ver}.sig
|
put armv7-linux-ghcup-${ver}.sig
|
||||||
put armv7-linux-ghcup.plan.json
|
|
||||||
put i386-linux-ghcup-${ver}
|
put i386-linux-ghcup-${ver}
|
||||||
put i386-linux-ghcup-${ver}.sig
|
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}
|
||||||
put x86_64-apple-darwin-ghcup-${ver}.sig
|
put x86_64-apple-darwin-ghcup-${ver}.sig
|
||||||
put x86_64-apple-darwin-ghcup.plan.json
|
put x86_64-freebsd12-ghcup-${ver}
|
||||||
put x86_64-portbld-freebsd-ghcup-${ver}
|
put x86_64-freebsd12-ghcup-${ver}.sig
|
||||||
put x86_64-portbld-freebsd-ghcup-${ver}.sig
|
put x86_64-freebsd13-ghcup-${ver}
|
||||||
put x86_64-portbld-freebsd-ghcup.plan.json
|
put x86_64-freebsd13-ghcup-${ver}.sig
|
||||||
put x86_64-linux-ghcup-${ver}
|
put x86_64-linux-ghcup-${ver}
|
||||||
put x86_64-linux-ghcup-${ver}.sig
|
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
|
||||||
put x86_64-mingw64-ghcup-${ver}.exe.sig
|
put x86_64-mingw64-ghcup-${ver}.exe.sig
|
||||||
put x86_64-mingw64-ghcup.plan.json
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
curl -X PURGE https://downloads.haskell.org/~ghcup/${ver}/
|
curl -X PURGE https://downloads.haskell.org/~ghcup/${ver}/
|
||||||
|
|||||||
57
stack.yaml
57
stack.yaml
@@ -1,36 +1,56 @@
|
|||||||
resolver: lts-20.20
|
resolver: lts-18.28
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- .
|
- .
|
||||||
|
|
||||||
extra-deps:
|
extra-deps:
|
||||||
- Cabal-3.6.3.0
|
- Cabal-3.6.2.0@sha256:e2266e14758c1f799220fad7f0d4b0b4ec567d81b7ba3faea17ff76d4c31de95,12437
|
||||||
- Cabal-syntax-3.10.1.0
|
- IfElse-0.85@sha256:6939b94acc6a55f545f63a168a349dd2fbe4b9a7cca73bf60282db5cc6aa47d2,445
|
||||||
- aeson-2.1.2.1
|
- ansi-terminal-game-1.8.0.0@sha256:001cf786098d9f1056ac6055ff3f598054b5c231b7343e76abb686d4f485855d,6977
|
||||||
- cabal-install-parsers-0.6.1
|
- ascii-string-1.0.1.4@sha256:fa34f1d9ba57e8e89c0d4c9cef5e01ba32cb2d4373d13f92dcc0b531a6c6749b,2582
|
||||||
|
- base16-bytestring-0.1.1.7@sha256:0021256a9628971c08da95cb8f4d0d72192f3bb8a7b30b55c080562d17c43dd3,2231
|
||||||
|
- brick-0.64@sha256:f03fa14607c22cf48af99e24c44f79a0fb073f7ec229f15e969fed9ff73c93f6,16530
|
||||||
|
- brotli-0.0.0.0@sha256:2bf383a4cd308745740986be0b18381c5a0784393fe69b91456aacb2d603de46,2964
|
||||||
|
- brotli-streams-0.0.0.0@sha256:1af1e22f67b8bfd6ad0d05e61825e7a178d738f689ebbb21c1aab5f1bbcae176,2331
|
||||||
- chs-cabal-0.1.1.1
|
- chs-cabal-0.1.1.1
|
||||||
- chs-deps-0.1.0.0
|
- chs-deps-0.1.0.0@sha256:0cdada6d2c682c41b20331b8c63c2ecfc7e806928585195fd544c9d41f3074fd,2496
|
||||||
- generic-arbitrary-0.2.2@sha256:202ffbf2032672a51318f2e80d7e75b72f8950e690346b4314f38bc7e39215f7,1189
|
- composition-prelude-3.0.0.2@sha256:1ffed216bd28d810fce0b5be83a661e2a892696d73b3f8de5c0f5edb9b5f0090,1216
|
||||||
- generically-0.1.1
|
|
||||||
- haskus-utils-data-1.4@sha256:bfa94363b94b14779edd6834fbd59dbb847c3d7b8f48e3844f456ffdc077da4a,1466
|
- haskus-utils-data-1.4@sha256:bfa94363b94b14779edd6834fbd59dbb847c3d7b8f48e3844f456ffdc077da4a,1466
|
||||||
- haskus-utils-types-1.5.1@sha256:991c472f4e751e2f0d7aab6ad4220ef151d6160876dcf0511bbf876bbd432020,1298
|
- haskus-utils-types-1.5.1@sha256:991c472f4e751e2f0d7aab6ad4220ef151d6160876dcf0511bbf876bbd432020,1298
|
||||||
- haskus-utils-variant-3.2.1
|
- haskus-utils-variant-3.2.1@sha256:791f4cf1e786eb578f4d37aef60986641f84c36e130164321f7d01542584066a,2200
|
||||||
- libarchive-3.0.3.2
|
- heaps-0.3.6.1@sha256:7928b759ca5180d35722c45948c0bde264229f3c99c1888188a3d9285f13d3d2,1340
|
||||||
|
- hpath-filepath-0.10.4@sha256:e9e44fb5fdbade7f30b5b5451257dbee15b6ef1aae4060034d73008bb3b5d878,1269
|
||||||
|
- hpath-posix-0.13.3@sha256:abe472cf16bccd3a8b8814865ed3551a728fde0f3a2baea2acc03023bec6c565,1615
|
||||||
|
- hspec-2.7.10@sha256:c9e82c90086acebac576552a06f3cabd249bba048edd1667c7fae0b1313d5bce,1712
|
||||||
|
- hspec-core-2.7.10@sha256:2aba6ea126442b29e8183ab27f1c811706b19b1d83b02f193a896f6fc1589d13,4621
|
||||||
|
- hspec-discover-2.7.10@sha256:d08bf5dd785629f589571477d9beb7cd91529471bd89f39517c1cb4b9b38160f,2184
|
||||||
|
- hspec-golden-aeson-0.9.0.0@sha256:aa17274114026661ba4dfc9c60c230673c8f408bd86482fd611d2d5cb6aff996,2179
|
||||||
|
- http-io-streams-0.1.6.0@sha256:53f5bab177efb52cd65ec396fd04ed59b93e5f919fb3700cd7dacd6cfce6f06d,3582
|
||||||
|
- libarchive-3.0.3.0
|
||||||
- libyaml-streamly-0.2.1
|
- libyaml-streamly-0.2.1
|
||||||
- lzma-static-5.2.5.5
|
- linebreak-1.1.0.1@sha256:b253873c3f98189eb22a5a9f0405677cde125c09666b63c3117f497c01c95893,1397
|
||||||
- os-release-1.0.2.1
|
- lzma-static-5.2.5.3@sha256:2758ee58c35992fcf7db78e98684c357a16a82fa2a4e7c352a6c210c08c555d8,7308
|
||||||
- parsec-3.1.15.0
|
- optics-0.4@sha256:9fb69bf0195b8d8f1f8cd0098000946868b8a3c3ffb51e5b64f79fc600c3eb4c,6568
|
||||||
|
- optics-core-0.4@sha256:59e04aebca536bd011ae50c781937f45af4c1456af1eb9fb578f9a69eee293cd,4995
|
||||||
|
- optics-extra-0.4@sha256:b9914f38aa7d5c92f231060d9168447f9f5a367c07df9bf47a003e3e786d5e05,3432
|
||||||
|
- optics-th-0.4@sha256:7c838b5b1d6998133bf8f0641c36197ed6cb468dc69515e1952f33f0bbe8e11d,2009
|
||||||
|
- os-release-1.0.1@sha256:1281c62081f438fc3f0874d3bae6a4887d5964ac25261ba06e29d368ab173467,2716
|
||||||
|
- primitive-0.7.1.0@sha256:29de6bfd0cf8ba023ceb806203dfbec0e51e3524e75ffe41056f70b4229c6f0f,2728
|
||||||
|
- regex-posix-clib-2.7
|
||||||
- streamly-0.8.2@sha256:ec521b7c1c4db068501c35804af77f40b7d34232f5e29d9b99e722229040eb80,23500
|
- streamly-0.8.2@sha256:ec521b7c1c4db068501c35804af77f40b7d34232f5e29d9b99e722229040eb80,23500
|
||||||
- strict-base-0.4.0.0
|
- strict-base-0.4.0.0@sha256:2ff4e43cb95eedf2995558d7fc34d19362846413dd39e6aa6a5b3ea8228fef9f,1248
|
||||||
- text-2.0.2
|
- timers-tick-0.5.0.1@sha256:91d4b03266715c6969b82cb24e57a6b47191a4d2f95e9a92e0ad3f7301cc7c8b,1552
|
||||||
- yaml-streamly-0.12.2
|
- unicode-data-0.3.0@sha256:0545e079705a5381d0893f8fe8daaa08fc9174baeab269b9cf651817d8eadbc6,5123
|
||||||
|
- unidecode-0.1.0.4@sha256:99581ee1ea334a4596a09ae3642e007808457c66893b587e965b31f15cbf8c4d,1144
|
||||||
|
- xor-0.0.1.0@sha256:f8362b4a68562b9afbcd727ff64c1a303970df3a032e0033d2f4c094c3501df3,2243
|
||||||
|
- yaml-streamly-0.12.1
|
||||||
|
|
||||||
flags:
|
flags:
|
||||||
http-io-streams:
|
http-io-streams:
|
||||||
brotli: false
|
brotli: false
|
||||||
|
|
||||||
libarchive:
|
libarchive:
|
||||||
system-libarchive: true
|
system-libarchive: false
|
||||||
|
|
||||||
regex-posix:
|
regex-posix:
|
||||||
_regex-posix-clib: true
|
_regex-posix-clib: true
|
||||||
@@ -44,6 +64,9 @@ flags:
|
|||||||
streamly:
|
streamly:
|
||||||
use-unliftio: true
|
use-unliftio: true
|
||||||
|
|
||||||
|
ghcup:
|
||||||
|
tui-ansi: true
|
||||||
|
|
||||||
ghc-options:
|
ghc-options:
|
||||||
"$locals": -O2
|
"$locals": -O2
|
||||||
streamly: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
|
streamly: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import GHCup.Types
|
|||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
import Data.List.NonEmpty
|
import Data.List.NonEmpty
|
||||||
import Data.Time.Calendar ( Day(..) )
|
|
||||||
import Test.QuickCheck
|
import Test.QuickCheck
|
||||||
import Test.QuickCheck.Arbitrary.ADT ( ToADTArbitrary )
|
import Test.QuickCheck.Arbitrary.ADT ( ToADTArbitrary )
|
||||||
import Test.QuickCheck.Arbitrary.Generic
|
import Test.QuickCheck.Arbitrary.Generic
|
||||||
@@ -77,9 +76,6 @@ instance Arbitrary Port where
|
|||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
instance Arbitrary Day where
|
|
||||||
arbitrary = ModifiedJulianDay . fromIntegral <$> (chooseAny :: Gen Int)
|
|
||||||
|
|
||||||
instance Arbitrary (URIRef Absolute) where
|
instance Arbitrary (URIRef Absolute) where
|
||||||
arbitrary =
|
arbitrary =
|
||||||
URI <$> arbitrary <*> pure Nothing <*> arbitrary <*> pure (Query []) <*> pure Nothing
|
URI <$> arbitrary <*> pure Nothing <*> arbitrary <*> pure (Query []) <*> pure Nothing
|
||||||
@@ -183,10 +179,6 @@ instance Arbitrary GHCupInfo where
|
|||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
instance Arbitrary GHCTargetVersion where
|
|
||||||
arbitrary = GHCTargetVersion Nothing <$> arbitrary
|
|
||||||
shrink = genericShrink
|
|
||||||
|
|
||||||
|
|
||||||
-- our maps are nested... the default size easily blows up most ppls ram
|
-- our maps are nested... the default size easily blows up most ppls ram
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ spec = do
|
|||||||
-- https://github.com/haskell/ghcup-hs/issues/415
|
-- https://github.com/haskell/ghcup-hs/issues/415
|
||||||
describe "GHCup.Prelude.File.Posix.Traversals" $ do
|
describe "GHCup.Prelude.File.Posix.Traversals" $ do
|
||||||
it "readDirEnt" $ do
|
it "readDirEnt" $ do
|
||||||
dirstream <- liftIO $ openDirStreamPortable "test/data"
|
dirstream <- liftIO $ openDirStream "test/data"
|
||||||
(dt1, fp1) <- readDirEntPortable dirstream
|
(dt1, fp1) <- readDirEnt dirstream
|
||||||
(dt2, fp2) <- readDirEntPortable dirstream
|
(dt2, fp2) <- readDirEnt dirstream
|
||||||
(dt3, fp3) <- readDirEntPortable dirstream
|
(dt3, fp3) <- readDirEnt dirstream
|
||||||
(dt4, fp4) <- readDirEntPortable dirstream
|
(dt4, fp4) <- readDirEnt dirstream
|
||||||
let xs = sortOn snd [ (dt1, fp1), (dt2, fp2)
|
let xs = sortOn snd [ (dt1, fp1), (dt2, fp2)
|
||||||
, (dt3, fp3), (dt4, fp4)
|
, (dt3, fp3), (dt4, fp4)
|
||||||
]
|
]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
674
vendored/ansi-terminal-game-1.8.0.0/COPYING
Normal file
674
vendored/ansi-terminal-game-1.8.0.0/COPYING
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
275
vendored/ansi-terminal-game-1.8.0.0/NEWS
Normal file
275
vendored/ansi-terminal-game-1.8.0.0/NEWS
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
1.8.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Fixed testing facilities `recordGame`, `testGame`, `narrateGame` and
|
||||||
|
similar functions. `testGame` in particular is able to precisely
|
||||||
|
emulate recorded environment (so if your game has a bug only at a
|
||||||
|
specific size, `testGame` will now catch it).
|
||||||
|
Check `cabal run -f alone-playback examples ` to see a replay in action
|
||||||
|
and `test/Terminal/Game/Layer/ImperativeSpec.hs` for pure test ideas.
|
||||||
|
- Added information on how to have an hot-reload mode, albeit only for
|
||||||
|
non-interactive game replays. Check `example/MainHotReload.hs` if
|
||||||
|
interested.
|
||||||
|
- Added a new exception, `DisplayTooSmall`, which expands gracefully to
|
||||||
|
a “please resize your terminal” message to the player if uncaught.
|
||||||
|
Nothing changes if you do not already use `asserTermDims`.
|
||||||
|
- `assertTermDims` is now curries (`Width -> Height -> IO ()` instead
|
||||||
|
of `Dimensions -> IO ()`) to better fit the rest of the API.
|
||||||
|
- Modified behaviour of functions `vcat`, `hcat`, `stringPlane`,
|
||||||
|
`stringPlaneTrans`. They will not error on empty list, rather return
|
||||||
|
a transparent, 1×1 plane.
|
||||||
|
- Changed licence and changes files to COPYING and NEWS.
|
||||||
|
|
||||||
|
1.7.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- After some feedback from library users, I decided to eliminate
|
||||||
|
`simpleGame` from the API.
|
||||||
|
To reiterate hte migration guide, if your type was:
|
||||||
|
|
||||||
|
Game 80 24 13 initState logicFun drawFun quitFun
|
||||||
|
-- or
|
||||||
|
-- simpleGame (80, 24) 13 initState logicFun drawFun quitFun
|
||||||
|
|
||||||
|
You just need to modify it like this:
|
||||||
|
|
||||||
|
Game 13 initState
|
||||||
|
(const logicFun)
|
||||||
|
(\e s -> centerFull e $ drawFun s)
|
||||||
|
quitFun
|
||||||
|
-- notice how we lost `80 24`. You can still have a screen size
|
||||||
|
-- check with `assertTermDims`, as described below.
|
||||||
|
- Added `blankPlaneFull` and `centerFull` convenience functions (to work
|
||||||
|
with GEnv terminal dimensions).
|
||||||
|
- Added assertTermDims, a quick way to check your user terminal is big
|
||||||
|
enough at the start of the game.
|
||||||
|
- minimal blitting optimisation (you should be able to see a 1–2
|
||||||
|
FPS improvement).
|
||||||
|
- improved documentation on various functions.
|
||||||
|
|
||||||
|
1.6.0.2
|
||||||
|
-------
|
||||||
|
|
||||||
|
- lun 15 nov 2021, 02:21:08
|
||||||
|
- more doc tweaking
|
||||||
|
|
||||||
|
1.6.0.1
|
||||||
|
-------
|
||||||
|
|
||||||
|
- released lun 15 nov 2021, 00:35:41
|
||||||
|
- minor documentation / spelling fixes
|
||||||
|
|
||||||
|
1.6.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
Summary and tl;dr migration guide:
|
||||||
|
- This version introduces a breaking changes in the main way to make
|
||||||
|
a `Game`. I will detail the changes below, but first a three-lines
|
||||||
|
migration guide:
|
||||||
|
the only thing you should have to do is to replace your `Game`
|
||||||
|
data constructor with `simpleGame` smart constructor, and substitute
|
||||||
|
the first to `c` `r` arguments (col/row) with a `(c, r)` tuple.
|
||||||
|
And of course, if you are interested in displaying FPS and adapt to
|
||||||
|
screen size modifications at game-time (“liquid” layout), read along!
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- This version introduces GEnv, a structure that exposes current frame
|
||||||
|
rate (in FPS) and current terminal size (in Width, Height).
|
||||||
|
- `GEnv` is added as a parameter to logic and draw functions, which
|
||||||
|
now have these signatures:
|
||||||
|
gLogicFunction :: GEnv -> s -> Event -> slightly
|
||||||
|
gDrawFunction :: GEnv -> s -> plane
|
||||||
|
- If you do not want to dabble with GEnv, you can still use `simpleGame`
|
||||||
|
smart constructor, which mimicks the old `Game`. `simpleGame` has some
|
||||||
|
nice defaults:
|
||||||
|
- if the terminal is too small it will ask the player to resize it
|
||||||
|
(even in the middle of the game), blocking any input;
|
||||||
|
- if the terminal is bigger, it will paste `Plane` in the middle
|
||||||
|
of the screen.
|
||||||
|
- For this reason, `DisplayTooSmall` exception exists no more.
|
||||||
|
- the new `Game` does not have those defaults, but allows you to get
|
||||||
|
creative with screen resizes, e.g. accomodating as much gameworld
|
||||||
|
as possible etc. Check `cabal run -f examples balls` and resize the
|
||||||
|
screen to see it in action.
|
||||||
|
- Minor change: I have introduced a `Dimensions` alias for
|
||||||
|
`(Width, Height)`.
|
||||||
|
|
||||||
|
Future work:
|
||||||
|
- these changes lay the path for an even more general `Game` type,
|
||||||
|
adding effects like reading form a game configuration, writing to it
|
||||||
|
etc.
|
||||||
|
I would like to have these wrapped in a pure interface (maybe à la
|
||||||
|
Response/Request? Maybe callbacks?) and for sure want them to be
|
||||||
|
composable with current test scaffolding (testGame,
|
||||||
|
narrateGame, etc.). It will not be easy to design; if are reading
|
||||||
|
this and have any suggestion, please write to me.
|
||||||
|
|
||||||
|
Released dom 14 nov 2021, 20:25:19
|
||||||
|
|
||||||
|
1.5.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- `timers-tick` has released a new version: all timers function (creaTimer,
|
||||||
|
creaBoolTimer, creaTimerLoop, creaBoolTimerLoop, creaAnimation,
|
||||||
|
creaLoopAnimation, ticks) are slightly more robust now (will `error`
|
||||||
|
on nonsenical arguments, e.g. frame duration <1).
|
||||||
|
This should not impact any of your current projects, it just makes
|
||||||
|
catching bugs easier.
|
||||||
|
- Removed `getFrames` from Animation interface.
|
||||||
|
- Updated `Random` interface to fit the new `random`. This is a breaking
|
||||||
|
change but it should be easy to fix by updating your `Random` constraints
|
||||||
|
to `UniformRange`.
|
||||||
|
Be mindful that `recordGame` could play slightly differently, as the
|
||||||
|
update function for the StdGen in `random` has changed.
|
||||||
|
- Removed `getRandomList` from Random interface.
|
||||||
|
- Added `pickRandom` to Random interface.
|
||||||
|
- Removed unuseful `creaStaticAnimation` from Animation interface.
|
||||||
|
- Released mar 9 nov 2021, 15:56:14.
|
||||||
|
|
||||||
|
1.4.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Fixed an annoying bug that made a game run slower than expected on
|
||||||
|
low TPS. Now if you select 5 ticks per second, you can rest assured
|
||||||
|
that after 50 ticks, 5 seconds have elapsed.
|
||||||
|
- Renamed `FPS` to `TPS` (ticks per second); highlight logic speed is
|
||||||
|
constant timewise on all machines, while FPS might be different on
|
||||||
|
differently efficient terminals.
|
||||||
|
This will allow in future releases to provide a function to easily
|
||||||
|
calculate actual FPS of the game.
|
||||||
|
- Added alternative origin combinators `%^>`, `%.<`, `%.>`; they are
|
||||||
|
useful when you want to — e.g. — «paste a plane one row from
|
||||||
|
bottom-right corner».
|
||||||
|
|
||||||
|
1.3.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- `displaySize` and `playGame`/`playGameS` now throw an exception
|
||||||
|
(of type `ATGException`) instead of `error`ing. These exeptions are
|
||||||
|
`CannotGetDisplaySize` and `DisplayTooSmall`; they are synchronous,
|
||||||
|
for easier catching. (requested by sm)
|
||||||
|
- Released sab 16 ott 2021, 21:09:22
|
||||||
|
|
||||||
|
1.2.1.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Fixed textBox, textBoxHyphen bug (boxes were not transparent, contrary
|
||||||
|
to what stated in docs) (reported by sm).
|
||||||
|
- Released lun 11 ott 2021, 22:29:40
|
||||||
|
|
||||||
|
1.2.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Added textBoxHyphen and textBoxHyphenLiquid and a handful of `Hypenator`s.
|
||||||
|
This will allow you to have autohyphenation in textboxes. Compare:
|
||||||
|
(normal textbox) (hyphenated textbox)
|
||||||
|
Rimasi un po’ a meditare nel buio Rimasi un po’ a meditare nel buio
|
||||||
|
velato appena dal barlume azzurrino velato appena dal barlume azzurrino
|
||||||
|
del fornello a gas, su cui del fornello a gas, su cui sobbol-
|
||||||
|
sobbollliva quieta la pentola. liva quieta la pentola.
|
||||||
|
- Switched `Width`, `Height`, `Row`, `Col` from `Integer` to `Int`.
|
||||||
|
This is unfortunate, but will make playing with `base` simpler. I will
|
||||||
|
switch it back once `Prelude` handles both integers appropriately
|
||||||
|
or exports the relevant function. (request by sm)
|
||||||
|
- Changed signature for `box`, `textBox` and `textBoxLiquid`. Now
|
||||||
|
width/height parameters come *before* the character/string. E.g.:
|
||||||
|
textBoxLiquid :: String -> Width -> Plane -- this was before
|
||||||
|
textBoxLiquid :: Width -> String -> Plane -- this is now
|
||||||
|
This felt more ergonomic while writing games.
|
||||||
|
- `paperPlane` is now `planePaper` (to respect SVO order)
|
||||||
|
|
||||||
|
1.1.1.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Added (***) (centre blit) (request by sm)
|
||||||
|
- Released gio 30 set 2021, 12:29:22
|
||||||
|
|
||||||
|
1.1.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Added Plane justapoxition functions (===, |||, vcat, hcat).
|
||||||
|
- Added `word` and and `textBoxLiquid` drawing functions.
|
||||||
|
- Added `subPlane`, `displaySize` Plane functions.
|
||||||
|
- Removed unused `trimPlane`.
|
||||||
|
- Sanitized non-ASCII chars on Win32 console.
|
||||||
|
- Wed 03 Feb 2021 18:41:20 CET
|
||||||
|
|
||||||
|
1.0.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Milestone release.
|
||||||
|
- Beefed up documentation.
|
||||||
|
- Released Sun 08 Dec 2019 04:19:33 CET
|
||||||
|
|
||||||
|
0.7.2.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Fixed 0.7.1.0 unbumped dependency.
|
||||||
|
- Released Fri 22 Nov 2019 16:51:25 CET
|
||||||
|
|
||||||
|
0.7.1.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Fixed 0.7.0.0 (deprecated) interface.
|
||||||
|
- Released Fri 22 Nov 2019 14:51:40 CET
|
||||||
|
|
||||||
|
0.7.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Simplified Animation interface (breaking changes).
|
||||||
|
- Added `creaLoopAnimation` and `creaStaticAnimation`.
|
||||||
|
- Released Fri 22 Nov 2019 14:40:44 CET
|
||||||
|
|
||||||
|
0.6.1.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Reworked Timers/Animations interface and documentation.
|
||||||
|
- Added `lapse` (for Timers/Animations).
|
||||||
|
- Released Fri 22 Nov 2019 01:03:37 CET
|
||||||
|
|
||||||
|
0.6.0.1
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Add public repo (requested by sm).
|
||||||
|
- Released Tue 19 Nov 2019 22:38:34 CET
|
||||||
|
|
||||||
|
0.6.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Add random generation functions.
|
||||||
|
- Released Sun 10 Nov 2019 13:44:32 CET
|
||||||
|
|
||||||
|
0.5.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Add `setupGame` to setup games before playtesting (skip menus, etc.).
|
||||||
|
- Fixed screen corruption on Windows.
|
||||||
|
- Released Fri 08 Nov 2019 13:52:39 CET
|
||||||
|
|
||||||
|
0.4.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Exposed new functions in API.
|
||||||
|
- Greatly improved haddock documentation.
|
||||||
|
- Released Tue 25 Jun 2019 16:08:53 CEST
|
||||||
|
|
||||||
|
0.2.1.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Improved haddock documentation a bit.
|
||||||
|
- Cleanup runs regardless of exception.
|
||||||
|
- Released on Sun 18 Mar 2018 03:04:07 CET.
|
||||||
|
|
||||||
|
0.2.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Added dependencies constraints.
|
||||||
|
- Removed internal module.
|
||||||
|
- Fixed changelog.
|
||||||
|
- Released on Fri 16 Mar 2018 00:42:41 CET.
|
||||||
|
|
||||||
|
0.1.0.0
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Initial release.
|
||||||
|
- Released on Fri 16 Mar 2018 00:33:18 CET.
|
||||||
46
vendored/ansi-terminal-game-1.8.0.0/README
Normal file
46
vendored/ansi-terminal-game-1.8.0.0/README
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
==================
|
||||||
|
ansi-terminal-game
|
||||||
|
==================
|
||||||
|
|
||||||
|
`ansi-terminal-game` is a library for creating games in a terminal setting.
|
||||||
|
|
||||||
|
Goals
|
||||||
|
-----
|
||||||
|
|
||||||
|
- be cross platform (linux/win/mac). If you plan to have your executable
|
||||||
|
unix only, I invite you to check brick [1] or other, more expressive
|
||||||
|
libraries.
|
||||||
|
- be simple: no curses/ncurses/pdcurses/etc. dependencies, all
|
||||||
|
functionality built on a standard input / ANSI terminal base.
|
||||||
|
|
||||||
|
[1] http://hackage.haskell.org/package/brick
|
||||||
|
|
||||||
|
Learn
|
||||||
|
-----
|
||||||
|
|
||||||
|
- run the basic example with `cabal new-run -f examples alone`;
|
||||||
|
- check the source in `examples/Alone.hs`;
|
||||||
|
- open the 'Terminal.Game' haddock documentation (start reading from
|
||||||
|
`Data.Game`).
|
||||||
|
|
||||||
|
A full game can be found at:
|
||||||
|
|
||||||
|
http://www.ariis.it/static/articles/venzone/page.html
|
||||||
|
|
||||||
|
Other games made with a-t-g
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- caverunner:
|
||||||
|
https://github.com/simonmichael/games/blob/main/caverunner/caverunner.hs
|
||||||
|
- pigafetta: http://www.ariis.it/link/repos/pigafetta/
|
||||||
|
- avoidance: https://sabadev.xyz/avoidance_game
|
||||||
|
|
||||||
|
If you want yours to be added to this list, write to me.
|
||||||
|
|
||||||
|
Contact
|
||||||
|
-------
|
||||||
|
|
||||||
|
For any feedback or report, contact me at:
|
||||||
|
|
||||||
|
http://ariis.it/static/articles/mail/page.html
|
||||||
|
|
||||||
2
vendored/ansi-terminal-game-1.8.0.0/Setup.hs
Normal file
2
vendored/ansi-terminal-game-1.8.0.0/Setup.hs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import Distribution.Simple
|
||||||
|
main = defaultMain
|
||||||
188
vendored/ansi-terminal-game-1.8.0.0/ansi-terminal-game.cabal
Normal file
188
vendored/ansi-terminal-game-1.8.0.0/ansi-terminal-game.cabal
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
name: ansi-terminal-game
|
||||||
|
version: 1.8.0.0
|
||||||
|
synopsis: sdl-like functions for terminal applications, based on
|
||||||
|
ansi-terminal
|
||||||
|
description: Library which aims to replicate standard 2d game
|
||||||
|
functions (blit, ticks, timers, etc.) in a terminal
|
||||||
|
setting; features double buffering to optimise
|
||||||
|
performance.
|
||||||
|
Aims to be cross compatible (based on "ansi-terminal",
|
||||||
|
no unix-only dependencies), practical.
|
||||||
|
See @examples@ folder for some minimal programs. A
|
||||||
|
full game: <http://www.ariis.it/static/articles/venzone/page.html venzone>.
|
||||||
|
homepage: http://www.ariis.it/static/articles/ansi-terminal-game/page.html
|
||||||
|
license: GPL-3
|
||||||
|
license-file: COPYING
|
||||||
|
author: Francesco Ariis
|
||||||
|
maintainer: fa-ml@ariis.it
|
||||||
|
copyright: © 2017-2021 Francesco Ariis
|
||||||
|
category: Game
|
||||||
|
build-type: Simple
|
||||||
|
extra-source-files: README,
|
||||||
|
NEWS,
|
||||||
|
test/records/alone-record-test.gr
|
||||||
|
test/records/balls-dims.gr
|
||||||
|
test/records/balls-slow.gr
|
||||||
|
cabal-version: >=1.10
|
||||||
|
|
||||||
|
flag examples
|
||||||
|
description: builds examples
|
||||||
|
default: False
|
||||||
|
|
||||||
|
source-repository head
|
||||||
|
type: darcs
|
||||||
|
location: http://www.ariis.it/link/repos/ansi-terminal-game/
|
||||||
|
|
||||||
|
library
|
||||||
|
exposed-modules: Terminal.Game
|
||||||
|
other-modules: Terminal.Game.Animation,
|
||||||
|
Terminal.Game.Character,
|
||||||
|
Terminal.Game.Draw,
|
||||||
|
Terminal.Game.Layer.Imperative,
|
||||||
|
Terminal.Game.Layer.Object,
|
||||||
|
Terminal.Game.Layer.Object.GameIO,
|
||||||
|
Terminal.Game.Layer.Object.Interface,
|
||||||
|
Terminal.Game.Layer.Object.IO,
|
||||||
|
Terminal.Game.Layer.Object.Narrate,
|
||||||
|
Terminal.Game.Layer.Object.Primitive,
|
||||||
|
Terminal.Game.Layer.Object.Record,
|
||||||
|
Terminal.Game.Layer.Object.Test,
|
||||||
|
Terminal.Game.Utils,
|
||||||
|
Terminal.Game.Plane,
|
||||||
|
Terminal.Game.Random,
|
||||||
|
Terminal.Game.Timer
|
||||||
|
build-depends: base == 4.*,
|
||||||
|
ansi-terminal == 0.11.*,
|
||||||
|
array == 0.5.*,
|
||||||
|
bytestring >= 0.10 && < 0.12,
|
||||||
|
cereal == 0.5.*,
|
||||||
|
clock >= 0.7 && < 0.9,
|
||||||
|
containers == 0.6.*,
|
||||||
|
exceptions == 0.10.*,
|
||||||
|
linebreak == 1.1.*,
|
||||||
|
mintty == 0.1.*,
|
||||||
|
mtl == 2.2.*,
|
||||||
|
QuickCheck >= 2.13 && < 2.15,
|
||||||
|
random >= 1.2 && < 1.3,
|
||||||
|
split == 0.2.*,
|
||||||
|
terminal-size == 0.3.*,
|
||||||
|
unidecode >= 0.1.0 && < 0.2,
|
||||||
|
timers-tick > 0.5 && < 0.6
|
||||||
|
hs-source-dirs: src
|
||||||
|
default-language: Haskell2010
|
||||||
|
ghc-options: -Wall
|
||||||
|
|
||||||
|
if os(windows)
|
||||||
|
hs-source-dirs: platform-dep/windows
|
||||||
|
if !os(windows)
|
||||||
|
hs-source-dirs: platform-dep/non-win
|
||||||
|
|
||||||
|
test-suite test
|
||||||
|
default-language: Haskell2010
|
||||||
|
hs-Source-Dirs: test, src, example
|
||||||
|
main-is: Test.hs
|
||||||
|
other-modules: Alone,
|
||||||
|
Balls,
|
||||||
|
Terminal.Game,
|
||||||
|
Terminal.Game.Animation,
|
||||||
|
Terminal.Game.Character,
|
||||||
|
Terminal.Game.Draw,
|
||||||
|
Terminal.Game.DrawSpec,
|
||||||
|
Terminal.Game.Layer.Imperative,
|
||||||
|
Terminal.Game.Layer.ImperativeSpec,
|
||||||
|
Terminal.Game.Layer.Object,
|
||||||
|
Terminal.Game.Layer.Object.GameIO,
|
||||||
|
Terminal.Game.Layer.Object.Interface,
|
||||||
|
Terminal.Game.Layer.Object.IO,
|
||||||
|
Terminal.Game.Layer.Object.Narrate,
|
||||||
|
Terminal.Game.Layer.Object.Primitive,
|
||||||
|
Terminal.Game.Layer.Object.Record,
|
||||||
|
Terminal.Game.Layer.Object.Test,
|
||||||
|
Terminal.Game.Utils,
|
||||||
|
Terminal.Game.Plane,
|
||||||
|
Terminal.Game.PlaneSpec
|
||||||
|
Terminal.Game.Random,
|
||||||
|
Terminal.Game.RandomSpec
|
||||||
|
build-depends: base == 4.*,
|
||||||
|
ansi-terminal == 0.11.*,
|
||||||
|
array == 0.5.*,
|
||||||
|
bytestring >= 0.10 && < 0.12,
|
||||||
|
cereal == 0.5.*,
|
||||||
|
clock >= 0.7 && < 0.9,
|
||||||
|
containers == 0.6.*,
|
||||||
|
exceptions == 0.10.*,
|
||||||
|
linebreak == 1.1.*,
|
||||||
|
mintty == 0.1.*,
|
||||||
|
mtl == 2.2.*,
|
||||||
|
QuickCheck >= 2.13 && < 2.15,
|
||||||
|
random >= 1.2 && < 1.3,
|
||||||
|
split == 0.2.*,
|
||||||
|
terminal-size == 0.3.*,
|
||||||
|
unidecode >= 0.1.0 && < 0.2,
|
||||||
|
timers-tick > 0.5 && < 0.6
|
||||||
|
-- the above plus hspec
|
||||||
|
, hspec
|
||||||
|
type: exitcode-stdio-1.0
|
||||||
|
ghc-options: -Wall
|
||||||
|
|
||||||
|
if os(windows)
|
||||||
|
hs-source-dirs: platform-dep/windows
|
||||||
|
if !os(windows)
|
||||||
|
hs-source-dirs: platform-dep/non-win
|
||||||
|
|
||||||
|
executable alone
|
||||||
|
if flag(examples)
|
||||||
|
build-depends: base == 4.*,
|
||||||
|
ansi-terminal-game
|
||||||
|
else
|
||||||
|
buildable: False
|
||||||
|
|
||||||
|
hs-source-dirs: example
|
||||||
|
main-is: MainAlone.hs
|
||||||
|
other-modules: Alone
|
||||||
|
default-language: Haskell2010
|
||||||
|
ghc-options: -threaded
|
||||||
|
-Wall
|
||||||
|
|
||||||
|
executable alone-playback
|
||||||
|
if flag(examples)
|
||||||
|
build-depends: base == 4.*,
|
||||||
|
ansi-terminal-game,
|
||||||
|
temporary == 1.3.*
|
||||||
|
else
|
||||||
|
buildable: False
|
||||||
|
|
||||||
|
hs-source-dirs: example
|
||||||
|
main-is: MainPlayback.hs
|
||||||
|
other-modules: Alone
|
||||||
|
default-language: Haskell2010
|
||||||
|
ghc-options: -threaded
|
||||||
|
-Wall
|
||||||
|
|
||||||
|
executable balls
|
||||||
|
if flag(examples)
|
||||||
|
build-depends: base == 4.*,
|
||||||
|
ansi-terminal-game
|
||||||
|
else
|
||||||
|
buildable: False
|
||||||
|
|
||||||
|
hs-source-dirs: example
|
||||||
|
main-is: MainBalls.hs
|
||||||
|
other-modules: Balls
|
||||||
|
default-language: Haskell2010
|
||||||
|
ghc-options: -threaded
|
||||||
|
-Wall
|
||||||
|
|
||||||
|
executable hot-reload
|
||||||
|
if flag(examples)
|
||||||
|
build-depends: base == 4.*,
|
||||||
|
ansi-terminal-game
|
||||||
|
else
|
||||||
|
buildable: False
|
||||||
|
|
||||||
|
hs-source-dirs: example
|
||||||
|
main-is: MainHotReload.hs
|
||||||
|
other-modules: Alone
|
||||||
|
default-language: Haskell2010
|
||||||
|
ghc-options: -threaded
|
||||||
|
-Wall
|
||||||
90
vendored/ansi-terminal-game-1.8.0.0/example/Alone.hs
Normal file
90
vendored/ansi-terminal-game-1.8.0.0/example/Alone.hs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
module Alone where
|
||||||
|
|
||||||
|
-- Alone in a room, game definition (logic & draw)
|
||||||
|
-- run with: cabal new-run -f examples alone
|
||||||
|
|
||||||
|
import Terminal.Game
|
||||||
|
|
||||||
|
import qualified Data.Tuple as T
|
||||||
|
|
||||||
|
-- game specification
|
||||||
|
aloneInARoom :: Game MyState
|
||||||
|
aloneInARoom = Game 13 -- ticks per second
|
||||||
|
(MyState (10, 10)
|
||||||
|
Stop False) -- init state
|
||||||
|
(\_ s e -> logicFun s e) -- logic function
|
||||||
|
(\r s -> centerFull r $
|
||||||
|
drawFun s) -- draw function
|
||||||
|
gsQuit -- quit function
|
||||||
|
|
||||||
|
sizeCheck :: IO ()
|
||||||
|
sizeCheck = let (w, h) = T.swap . snd $ boundaries
|
||||||
|
in assertTermDims w h
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Types
|
||||||
|
|
||||||
|
data MyState = MyState { gsCoord :: Coords,
|
||||||
|
gsMove :: Move,
|
||||||
|
gsQuit :: Bool }
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data Move = N | S | E | W | Stop
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
boundaries :: (Coords, Coords)
|
||||||
|
boundaries = ((1, 1), (24, 80))
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Logic
|
||||||
|
|
||||||
|
logicFun :: MyState -> Event -> MyState
|
||||||
|
logicFun gs (KeyPress 'q') = gs { gsQuit = True }
|
||||||
|
logicFun gs Tick = gs { gsCoord = pos (gsMove gs) (gsCoord gs) }
|
||||||
|
logicFun gs (KeyPress c) = gs { gsMove = move (gsMove gs) c }
|
||||||
|
|
||||||
|
-- SCI movement
|
||||||
|
move :: Move -> Char -> Move
|
||||||
|
move N 'w' = Stop
|
||||||
|
move S 's' = Stop
|
||||||
|
move W 'a' = Stop
|
||||||
|
move E 'd' = Stop
|
||||||
|
move _ 'w' = N
|
||||||
|
move _ 's' = S
|
||||||
|
move _ 'a' = W
|
||||||
|
move _ 'd' = E
|
||||||
|
move m _ = m
|
||||||
|
|
||||||
|
pos :: Move -> (Width, Height) -> (Width, Height)
|
||||||
|
pos m oldcs | oob newcs = oldcs
|
||||||
|
| otherwise = newcs
|
||||||
|
where
|
||||||
|
newcs = new m oldcs
|
||||||
|
|
||||||
|
new Stop cs = cs
|
||||||
|
new N (r, c) = (r-1, c )
|
||||||
|
new S (r, c) = (r+1, c )
|
||||||
|
new E (r, c) = (r , c+1)
|
||||||
|
new W (r, c) = (r , c-1)
|
||||||
|
|
||||||
|
((lr, lc), (hr, hc)) = boundaries
|
||||||
|
oob (r, c) = r <= lr || c <= lc ||
|
||||||
|
r >= hr || c >= hc
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Draw
|
||||||
|
|
||||||
|
drawFun :: MyState -> Plane
|
||||||
|
drawFun (MyState (r, c) _ _) =
|
||||||
|
blankPlane mw mh &
|
||||||
|
(1, 1) % box mw mh '-' &
|
||||||
|
(2, 2) % box (mw-2) (mh-2) ' ' &
|
||||||
|
(15, 20) % textBox 10 4
|
||||||
|
"Tap WASD to move, tap again to stop." &
|
||||||
|
(20, 60) % textBox 8 10
|
||||||
|
"Press Q to quit." # color Blue Vivid &
|
||||||
|
(r, c) % cell '@' # invert
|
||||||
|
where
|
||||||
|
mh :: Height
|
||||||
|
mw :: Width
|
||||||
|
(mh, mw) = snd boundaries
|
||||||
189
vendored/ansi-terminal-game-1.8.0.0/example/Balls.hs
Normal file
189
vendored/ansi-terminal-game-1.8.0.0/example/Balls.hs
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
module Balls where
|
||||||
|
|
||||||
|
-- library module for `balls`
|
||||||
|
|
||||||
|
import Terminal.Game
|
||||||
|
|
||||||
|
import qualified Data.Bool as B
|
||||||
|
import qualified Data.Ix as I
|
||||||
|
import qualified Data.Maybe as M
|
||||||
|
import qualified Data.Tuple as T
|
||||||
|
|
||||||
|
{-
|
||||||
|
There are three things I will showcase in this example:
|
||||||
|
|
||||||
|
1. ** How you can display current FPS. **
|
||||||
|
This is done using `Game` to create your game rather than
|
||||||
|
`simpleGame`. `Game` is a bit more complex but you gain
|
||||||
|
additional infos to manipulate/blit, like FPS.
|
||||||
|
|
||||||
|
2. ** How your game can gracefully handle screen resize. **
|
||||||
|
Notice how if you resize the terminal, balls will still
|
||||||
|
fill the entire screen. This is again possible using `Game`
|
||||||
|
and the information passed via GameEnv (in this case, terminal
|
||||||
|
dimensions).
|
||||||
|
|
||||||
|
3. ** That — while FPS can change — game speed does not. **
|
||||||
|
Check the timer: even when screen is crowded and frames are
|
||||||
|
dropped, it is not slowed down.
|
||||||
|
|
||||||
|
|
||||||
|
This game runs at 60 FPS, you will almost surely never need such
|
||||||
|
a high TPS! 15–20 is more than enough in most cases.
|
||||||
|
-}
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Ball
|
||||||
|
|
||||||
|
data Ball = Ball { pChar :: Plane,
|
||||||
|
pSpeed :: Timed Bool,
|
||||||
|
pDir :: Coords,
|
||||||
|
pPos :: Coords }
|
||||||
|
|
||||||
|
-- change direction is necessary, then and move
|
||||||
|
modPar :: Dimensions -> Ball -> Maybe Ball
|
||||||
|
modPar ds b@(Ball _ _ d _) =
|
||||||
|
-- tick the ball and check it is time to move
|
||||||
|
let b' = tickBall b in
|
||||||
|
if not (fetchFrame . pSpeed $ b')
|
||||||
|
then Just b' -- no time to move for you
|
||||||
|
else
|
||||||
|
|
||||||
|
-- check all popssible directions
|
||||||
|
let pd = [d, togR d, togC d, togB d]
|
||||||
|
bs = map (\ld -> b' { pDir = ld }) pd
|
||||||
|
bs' = filter (isIn ds) $ map modPos bs in
|
||||||
|
|
||||||
|
-- returns a moved ball nor nothing to mark it “to eliminate”
|
||||||
|
case bs' of
|
||||||
|
[] -> Nothing
|
||||||
|
(cp:_) -> Just cp
|
||||||
|
where
|
||||||
|
togR (wr, wc) = (-wr, wc)
|
||||||
|
togC (wr, wc) = ( wr, -wc)
|
||||||
|
togB (wr, wc) = (-wr, -wc)
|
||||||
|
|
||||||
|
tickBall :: Ball -> Ball
|
||||||
|
tickBall b = b { pSpeed = tick (pSpeed b) }
|
||||||
|
|
||||||
|
modPos :: Ball -> Ball
|
||||||
|
modPos (Ball p t d@(dr, dc) (r, c)) = Ball p t d (r+dr, c+dc)
|
||||||
|
|
||||||
|
isIn :: Dimensions -> Ball -> Bool
|
||||||
|
isIn (w, h) (Ball p _ _ (pr, pc)) =
|
||||||
|
let (pw, ph) = planeSize p
|
||||||
|
in pr >= 1 &&
|
||||||
|
pr+ph-1 <= h &&
|
||||||
|
pc >= 1 &&
|
||||||
|
pc+pw-1 <= w
|
||||||
|
|
||||||
|
dpart :: Ball -> (Coords, Plane)
|
||||||
|
dpart (Ball p _ _ cs) = (cs, p)
|
||||||
|
|
||||||
|
genBall :: StdGen -> Dimensions -> (Ball, StdGen)
|
||||||
|
genBall g ds =
|
||||||
|
let (c, g1) = pickRandom [minBound..] g
|
||||||
|
(s, g2) = getRandom (1, 3) g1
|
||||||
|
(v, g3) = pickRandom dirs g2
|
||||||
|
(p, g4) = ranIx ((1,1), T.swap ds) g3
|
||||||
|
b = Ball (cell 'o' # color c Vivid)
|
||||||
|
(creaBoolTimerLoop s) v p
|
||||||
|
in (b, g4)
|
||||||
|
where
|
||||||
|
dirs = [(1, 1), (1, -1), (-1, 1), (-1, -1)]
|
||||||
|
|
||||||
|
-- tuples instances are yet to be added to `random`
|
||||||
|
-- as nov 21; this will do meanwhile.
|
||||||
|
ranIx :: I.Ix a => (a, a) -> StdGen -> (a, StdGen)
|
||||||
|
ranIx r wg = pickRandom (I.range r) wg
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Timer
|
||||||
|
|
||||||
|
type Timer = (Timed Bool, Integer)
|
||||||
|
|
||||||
|
ctimer :: TPS -> Timer
|
||||||
|
ctimer tps = (creaBoolTimerLoop tps, 0)
|
||||||
|
|
||||||
|
ltimer :: Timer -> Timer
|
||||||
|
ltimer (t, i) = let t' = tick t
|
||||||
|
k = B.bool 0 1 (fetchFrame t')
|
||||||
|
in (t', i+k)
|
||||||
|
|
||||||
|
dtimer :: Timer -> Plane
|
||||||
|
dtimer (_, i) = word . show $ i
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Game
|
||||||
|
|
||||||
|
data GState = GState { gen :: StdGen,
|
||||||
|
quit :: Bool,
|
||||||
|
timer :: Timer,
|
||||||
|
balls :: [Ball],
|
||||||
|
bslow :: Bool }
|
||||||
|
-- pSlow is not used in game, it is there just
|
||||||
|
-- for the test suite
|
||||||
|
|
||||||
|
fireworks :: StdGen -> Game GState
|
||||||
|
fireworks g = Game tps istate lfun dfun qfun
|
||||||
|
where
|
||||||
|
tps = 60
|
||||||
|
|
||||||
|
istate :: GState
|
||||||
|
istate = GState g False (ctimer tps) [] False
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Logic
|
||||||
|
|
||||||
|
lfun :: GEnv -> GState -> Event -> GState
|
||||||
|
lfun e s (KeyPress 's') =
|
||||||
|
let g = gen s
|
||||||
|
ds = eTermDims e
|
||||||
|
(b, g1) = genBall g ds
|
||||||
|
in s { gen = g1,
|
||||||
|
balls = b : balls s }
|
||||||
|
lfun _ s (KeyPress 'q') = s { quit = True }
|
||||||
|
lfun _ s (KeyPress _) = s
|
||||||
|
lfun r s Tick =
|
||||||
|
let ds = eTermDims r
|
||||||
|
|
||||||
|
ps = balls s
|
||||||
|
ps' = M.mapMaybe (modPar ds) ps
|
||||||
|
|
||||||
|
bs = eFPS r < 30
|
||||||
|
in s { timer = ltimer (timer s),
|
||||||
|
balls = filter (isIn ds) ps',
|
||||||
|
bslow = bs }
|
||||||
|
|
||||||
|
qfun :: GState -> Bool
|
||||||
|
qfun s = quit s
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Draw
|
||||||
|
|
||||||
|
dfun :: GEnv -> GState -> Plane
|
||||||
|
dfun r s = mergePlanes
|
||||||
|
(uncurry blankPlane ds)
|
||||||
|
(map dpart $ balls s) &
|
||||||
|
(1, 2) %^> tui # trans &
|
||||||
|
(1, 2) %.< inst # trans # bold
|
||||||
|
where
|
||||||
|
ds = eTermDims r
|
||||||
|
tm = timer s
|
||||||
|
|
||||||
|
tui :: Plane
|
||||||
|
tui = let fps = eFPS r
|
||||||
|
np = length $ balls s
|
||||||
|
|
||||||
|
l1 = word "FPS: " ||| word (show fps)
|
||||||
|
l2 = word "Timer: " ||| dtimer tm
|
||||||
|
l3 = word ("Balls: " ++ show np)
|
||||||
|
l4 = word ("Term. dims.: " ++ show ds)
|
||||||
|
in vcat [l1, l2, l3, l4]
|
||||||
|
|
||||||
|
inst :: Plane
|
||||||
|
inst = word "Press (s) to spawn" ===
|
||||||
|
word "Press (q) to quit"
|
||||||
|
|
||||||
|
trans :: Draw
|
||||||
|
trans = makeTransparent ' '
|
||||||
12
vendored/ansi-terminal-game-1.8.0.0/example/MainAlone.hs
Normal file
12
vendored/ansi-terminal-game-1.8.0.0/example/MainAlone.hs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
|
||||||
|
import Alone ( aloneInARoom, sizeCheck )
|
||||||
|
|
||||||
|
import Terminal.Game
|
||||||
|
|
||||||
|
-- run with: cabal new-run -f examples alone
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do sizeCheck
|
||||||
|
errorPress $ playGame aloneInARoom
|
||||||
12
vendored/ansi-terminal-game-1.8.0.0/example/MainBalls.hs
Normal file
12
vendored/ansi-terminal-game-1.8.0.0/example/MainBalls.hs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
import Balls
|
||||||
|
|
||||||
|
import Terminal.Game
|
||||||
|
|
||||||
|
-- Balls Main module. The meat of the game is in `examples/Balls.hs`
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = getStdGen >>= \g ->
|
||||||
|
playGame (fireworks g)
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user