Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
b78aab884e
|
|||
|
36e192ec32
|
|||
|
651722b935
|
|||
|
7a0d5a95c1
|
|||
|
2c583bcae9
|
|||
|
ab36d4418e
|
|||
|
f146c77797
|
|||
|
d863ac570b
|
|||
|
d05fad49a1
|
|||
|
fbbc4497ca
|
|||
|
4223586e62
|
|||
|
c859b3ee2b
|
|||
|
8a16b0de7c
|
|||
|
9faf17634b
|
|||
|
66a62c170c
|
|||
|
5186d959bc
|
|||
|
09a8a0bda0
|
|||
|
191f49adfc
|
|||
|
|
26b79c5763 | ||
|
c72841ca58
|
|||
|
63350dab71
|
|||
|
d110d20879
|
|||
|
b4e58478c3
|
|||
|
12d2acd7fd
|
|||
|
6073ebe476
|
|||
|
5c026591cb
|
|||
|
907365ddff
|
|||
|
684953464b
|
|||
|
6b978b42bc
|
|||
|
6831337289
|
|||
|
e40777a5d3
|
|||
|
51690d1df3
|
|||
|
72a06e964c
|
|||
|
9ffd402481
|
|||
|
dee8d4bc09
|
|||
|
6c57661797
|
|||
|
b9ff7c5af4
|
|||
|
072161ada2
|
|||
|
a67b3e8a57
|
|||
|
c9216fb444
|
|||
|
2aac17ac5f
|
|||
|
17a403b8ce
|
|||
|
b245c11b1d
|
|||
|
2ed047515e
|
|||
|
b16e561384
|
|||
|
|
2ebff1e887 | ||
|
655ee432f8
|
|||
|
67b7b2f292
|
|||
|
66961101c6
|
|||
|
326af49a8f
|
|||
|
3a7ed5ee2d
|
|||
|
56fa798406
|
|||
|
|
3fd9fae66a | ||
|
|
5d43168370 | ||
|
|
f8548fefb3 | ||
|
|
3565c32d51 | ||
|
7fab328acc
|
|||
|
a043b82b27
|
|||
|
20652fed94
|
|||
|
6fc52a4ec7
|
|||
|
834bcfa02c
|
|||
|
c99ecc0a66
|
|||
|
061e5dd832
|
|||
|
c97ade81fa
|
|||
|
82a22fe993
|
|||
|
dbadcf1858
|
|||
|
ff8865c5c3
|
|||
|
9833dee925
|
|||
|
aac2874f8f
|
|||
|
17524b21b3
|
|||
|
3f0befe30d
|
|||
|
76c286f95e
|
|||
|
0c415314b6
|
|||
|
717f386077
|
|||
|
7a841a480b
|
|||
|
43ea85b495
|
|||
|
8a6badca1d
|
|||
|
4064803e23
|
|||
|
2e03b075f8
|
|||
|
fe9c125bd6
|
|||
|
503fd57d7c
|
|||
|
e74e746213
|
|||
|
065f9c4965
|
|||
|
32f3c36589
|
|||
|
c2a8d39fb4
|
|||
|
f08cbe70fb
|
|||
|
a9630d0802
|
|||
|
c5c6c431b5
|
|||
|
71d78d2d72
|
|||
|
ccecda2eff
|
|||
|
3a5f8d6139
|
|||
|
74e0f39bc2
|
|||
|
274978a8a7
|
|||
|
8eea9bd6a5
|
|||
|
626a2dd020
|
|||
|
6b6ce221e0
|
|||
|
d038c361c0
|
|||
|
c05876cc60
|
|||
|
b9c4c9a0b7
|
|||
|
6697e804ee
|
|||
|
2c57def8f1
|
|||
|
62b16e957b
|
|||
|
18d7bdd85c
|
|||
|
190b5dedba
|
|||
|
886e45f788
|
|||
|
360daf2a09
|
|||
|
7bb67dd4c6
|
@@ -15,6 +15,9 @@ variables:
|
|||||||
# Bump to invalidate GitLab CI cache.
|
# Bump to invalidate GitLab CI cache.
|
||||||
CACHE_REV: 0
|
CACHE_REV: 0
|
||||||
|
|
||||||
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# CI Step
|
# CI Step
|
||||||
############################################################
|
############################################################
|
||||||
@@ -115,7 +118,7 @@ variables:
|
|||||||
script:
|
script:
|
||||||
- bash ./.gitlab/script/ghcup_version.sh
|
- bash ./.gitlab/script/ghcup_version.sh
|
||||||
variables:
|
variables:
|
||||||
JSON_VERSION: "0.0.6"
|
JSON_VERSION: "0.0.7"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 2 week
|
expire_in: 2 week
|
||||||
paths:
|
paths:
|
||||||
@@ -186,8 +189,8 @@ variables:
|
|||||||
- export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
- export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
||||||
- mkdir -p $CI_PROJECT_DIR/.brew_logs
|
- mkdir -p $CI_PROJECT_DIR/.brew_logs
|
||||||
- export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
- export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
||||||
- mkdir -p $CI_PROJECT_DIR/.brew_tmp
|
- mkdir -p /private/tmp/.brew_tmp
|
||||||
- export HOMEBREW_TEMP=$CI_PROJECT_DIR/.brew_tmp
|
- export HOMEBREW_TEMP=/private/tmp/.brew_tmp
|
||||||
|
|
||||||
# update and install packages
|
# update and install packages
|
||||||
- brew update
|
- brew update
|
||||||
@@ -217,6 +220,9 @@ variables:
|
|||||||
- .freebsd13
|
- .freebsd13
|
||||||
- .root_cleanup
|
- .root_cleanup
|
||||||
before_script:
|
before_script:
|
||||||
|
- sudo pkg update
|
||||||
|
- sudo pkg install --yes compat12x-amd64
|
||||||
|
- sudo ln -s libncurses.so.6 /usr/local/lib/libncurses.so.6.2
|
||||||
- ./.gitlab/before_script/freebsd/install_deps.sh
|
- ./.gitlab/before_script/freebsd/install_deps.sh
|
||||||
|
|
||||||
.test_ghcup_version:windows:
|
.test_ghcup_version:windows:
|
||||||
@@ -245,7 +251,7 @@ variables:
|
|||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
variables:
|
variables:
|
||||||
JSON_VERSION: "0.0.6"
|
JSON_VERSION: "0.0.7"
|
||||||
|
|
||||||
######## stack test ########
|
######## stack test ########
|
||||||
|
|
||||||
@@ -545,8 +551,8 @@ release:darwin:aarch64:
|
|||||||
- export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
- export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
||||||
- mkdir -p $CI_PROJECT_DIR/.brew_logs
|
- mkdir -p $CI_PROJECT_DIR/.brew_logs
|
||||||
- export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
- export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
||||||
- mkdir -p $CI_PROJECT_DIR/.brew_tmp
|
- mkdir -p /private/tmp/.brew_tmp
|
||||||
- export HOMEBREW_TEMP=$CI_PROJECT_DIR/.brew_tmp
|
- export HOMEBREW_TEMP=/private/tmp/.brew_tmp
|
||||||
|
|
||||||
# update and install packages
|
# update and install packages
|
||||||
- brew update
|
- brew update
|
||||||
@@ -595,6 +601,9 @@ release:freebsd13:
|
|||||||
- .release_ghcup
|
- .release_ghcup
|
||||||
- .root_cleanup
|
- .root_cleanup
|
||||||
before_script:
|
before_script:
|
||||||
|
- sudo pkg update
|
||||||
|
- sudo pkg install --yes compat12x-amd64
|
||||||
|
- sudo ln -s libncurses.so.6 /usr/local/lib/libncurses.so.6.2
|
||||||
- ./.gitlab/before_script/freebsd/install_deps.sh
|
- ./.gitlab/before_script/freebsd/install_deps.sh
|
||||||
variables:
|
variables:
|
||||||
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
||||||
|
|||||||
@@ -12,4 +12,8 @@ if [ "${OS}" = "WINDOWS" ] ; then
|
|||||||
rm -Rf /c/ghcup
|
rm -Rf /c/ghcup
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
|
rm -Rf /private/tmp/.brew_tmp
|
||||||
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -8,7 +8,15 @@ set -eux
|
|||||||
|
|
||||||
mkdir -p "${TMPDIR}"
|
mkdir -p "${TMPDIR}"
|
||||||
|
|
||||||
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-portbld-freebsd-ghcup > ./ghcup-bin
|
if freebsd-version | grep -E '^12.*' ; then
|
||||||
|
freebsd_ver=12
|
||||||
|
elif freebsd-version | grep -E '^13.*' ; then
|
||||||
|
freebsd_ver=13
|
||||||
|
else
|
||||||
|
(>&2 echo "Unsupported FreeBSD version! Please report a bug at https://gitlab.haskell.org/haskell/ghcup-hs/-/issues")
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-freebsd${freebsd_ver}-ghcup > ./ghcup-bin
|
||||||
chmod +x ghcup-bin
|
chmod +x ghcup-bin
|
||||||
|
|
||||||
./ghcup-bin -v upgrade -i -f
|
./ghcup-bin -v upgrade -i -f
|
||||||
|
|||||||
37
.gitlab/ghcup-run.files
Normal file
37
.gitlab/ghcup-run.files
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.
|
||||||
|
./cabal
|
||||||
|
./ghc
|
||||||
|
./ghc-8.10.7
|
||||||
|
./ghc-pkg
|
||||||
|
./ghc-pkg-8.10.7
|
||||||
|
./ghci
|
||||||
|
./ghci-8.10.7
|
||||||
|
./haddock
|
||||||
|
./haddock-8.10.7
|
||||||
|
./haskell-language-server-8.10.6
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0
|
||||||
|
./haskell-language-server-8.10.7
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0
|
||||||
|
./haskell-language-server-8.6.5
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0
|
||||||
|
./haskell-language-server-8.8.4
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0
|
||||||
|
./haskell-language-server-9.0.1
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0
|
||||||
|
./haskell-language-server-9.0.2
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0
|
||||||
|
./haskell-language-server-9.2.1
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0
|
||||||
|
./haskell-language-server-wrapper
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0
|
||||||
|
./hp2ps
|
||||||
|
./hp2ps-8.10.7
|
||||||
|
./hpc
|
||||||
|
./hpc-8.10.7
|
||||||
|
./hsc2hs
|
||||||
|
./hsc2hs-8.10.7
|
||||||
|
./runghc
|
||||||
|
./runghc-8.10.7
|
||||||
|
./runhaskell
|
||||||
|
./runhaskell-8.10.7
|
||||||
|
./stack
|
||||||
81
.gitlab/ghcup-run.files.windows
Normal file
81
.gitlab/ghcup-run.files.windows
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
.
|
||||||
|
./cabal.exe
|
||||||
|
./cabal.shim
|
||||||
|
./ghc-8.10.7.exe
|
||||||
|
./ghc-8.10.7.shim
|
||||||
|
./ghc-pkg-8.10.7.exe
|
||||||
|
./ghc-pkg-8.10.7.shim
|
||||||
|
./ghc-pkg.exe
|
||||||
|
./ghc-pkg.shim
|
||||||
|
./ghc.exe
|
||||||
|
./ghc.shim
|
||||||
|
./ghci-8.10.7.exe
|
||||||
|
./ghci-8.10.7.shim
|
||||||
|
./ghci.exe
|
||||||
|
./ghci.shim
|
||||||
|
./ghcii-8.10.7.sh-8.10.7.exe
|
||||||
|
./ghcii-8.10.7.sh-8.10.7.shim
|
||||||
|
./ghcii-8.10.7.sh.exe
|
||||||
|
./ghcii-8.10.7.sh.shim
|
||||||
|
./ghcii.sh-8.10.7.exe
|
||||||
|
./ghcii.sh-8.10.7.shim
|
||||||
|
./ghcii.sh.exe
|
||||||
|
./ghcii.sh.shim
|
||||||
|
./haddock-8.10.7.exe
|
||||||
|
./haddock-8.10.7.shim
|
||||||
|
./haddock.exe
|
||||||
|
./haddock.shim
|
||||||
|
./haskell-language-server-8.10.6.exe
|
||||||
|
./haskell-language-server-8.10.6.shim
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.10.7.exe
|
||||||
|
./haskell-language-server-8.10.7.shim
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.6.5.exe
|
||||||
|
./haskell-language-server-8.6.5.shim
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.8.4.exe
|
||||||
|
./haskell-language-server-8.8.4.shim
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.0.1.exe
|
||||||
|
./haskell-language-server-9.0.1.shim
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.0.2.exe
|
||||||
|
./haskell-language-server-9.0.2.shim
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.2.1.exe
|
||||||
|
./haskell-language-server-9.2.1.shim
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0.shim
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0.exe
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0.shim
|
||||||
|
./haskell-language-server-wrapper.exe
|
||||||
|
./haskell-language-server-wrapper.shim
|
||||||
|
./hp2ps-8.10.7.exe
|
||||||
|
./hp2ps-8.10.7.shim
|
||||||
|
./hp2ps.exe
|
||||||
|
./hp2ps.shim
|
||||||
|
./hpc-8.10.7.exe
|
||||||
|
./hpc-8.10.7.shim
|
||||||
|
./hpc.exe
|
||||||
|
./hpc.shim
|
||||||
|
./hsc2hs-8.10.7.exe
|
||||||
|
./hsc2hs-8.10.7.shim
|
||||||
|
./hsc2hs.exe
|
||||||
|
./hsc2hs.shim
|
||||||
|
./runghc-8.10.7.exe
|
||||||
|
./runghc-8.10.7.shim
|
||||||
|
./runghc.exe
|
||||||
|
./runghc.shim
|
||||||
|
./runhaskell-8.10.7.exe
|
||||||
|
./runhaskell-8.10.7.shim
|
||||||
|
./runhaskell.exe
|
||||||
|
./runhaskell.shim
|
||||||
|
./stack.exe
|
||||||
|
./stack.shim
|
||||||
@@ -5,8 +5,6 @@ set -eux
|
|||||||
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
||||||
|
|
||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
mkdir -p data/
|
|
||||||
git clone https://github.com/haskell/ghcup-metadata.git data/metadata
|
|
||||||
|
|
||||||
CI_PROJECT_DIR=$(pwd)
|
CI_PROJECT_DIR=$(pwd)
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ set -eux
|
|||||||
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
||||||
|
|
||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
mkdir -p data/
|
|
||||||
git clone https://github.com/haskell/ghcup-metadata.git data/metadata
|
|
||||||
|
|
||||||
CI_PROJECT_DIR=$(pwd)
|
CI_PROJECT_DIR=$(pwd)
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ set -eux
|
|||||||
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
||||||
|
|
||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
mkdir -p data/
|
|
||||||
git clone https://github.com/haskell/ghcup-metadata.git data/metadata
|
|
||||||
|
|
||||||
CI_PROJECT_DIR=$(pwd)
|
CI_PROJECT_DIR=$(pwd)
|
||||||
|
|
||||||
@@ -43,7 +41,7 @@ cabal --version
|
|||||||
|
|
||||||
eghcup debug-info
|
eghcup debug-info
|
||||||
|
|
||||||
eghcup compile hls -j $(nproc) -v ${HLS_TARGET_VERSION} ${GHC_VERSION}
|
eghcup compile hls -j $(nproc) -v ${HLS_TARGET_VERSION} --ghc ${GHC_VERSION}
|
||||||
|
|
||||||
[ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version` = "${HLS_TARGET_VERSION}" ] || [ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version | sed 's/.0$//'` = "${HLS_TARGET_VERSION}" ]
|
[ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version` = "${HLS_TARGET_VERSION}" ] || [ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version | sed 's/.0$//'` = "${HLS_TARGET_VERSION}" ]
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ set -eux
|
|||||||
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
||||||
|
|
||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
mkdir -p data/
|
|
||||||
git clone https://github.com/haskell/ghcup-metadata.git data/metadata
|
|
||||||
|
|
||||||
CI_PROJECT_DIR=$(pwd)
|
CI_PROJECT_DIR=$(pwd)
|
||||||
|
|
||||||
@@ -97,6 +95,7 @@ eghcup --numeric-version
|
|||||||
|
|
||||||
eghcup install ghc ${GHC_VERSION}
|
eghcup install ghc ${GHC_VERSION}
|
||||||
[ `$(eghcup whereis ghc ${GHC_VERSION}) --numeric-version` = "${GHC_VERSION}" ]
|
[ `$(eghcup whereis ghc ${GHC_VERSION}) --numeric-version` = "${GHC_VERSION}" ]
|
||||||
|
[ `eghcup run --ghc ${GHC_VERSION} -- ghc --numeric-version` = "${GHC_VERSION}" ]
|
||||||
eghcup set ghc ${GHC_VERSION}
|
eghcup set ghc ${GHC_VERSION}
|
||||||
eghcup install cabal ${CABAL_VERSION}
|
eghcup install cabal ${CABAL_VERSION}
|
||||||
[ `$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version` = "${CABAL_VERSION}" ]
|
[ `$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version` = "${CABAL_VERSION}" ]
|
||||||
@@ -104,6 +103,22 @@ eghcup unset cabal
|
|||||||
"$GHCUP_BIN"/cabal --version && exit || echo yes
|
"$GHCUP_BIN"/cabal --version && exit || echo yes
|
||||||
eghcup set cabal ${CABAL_VERSION}
|
eghcup set cabal ${CABAL_VERSION}
|
||||||
[ `$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version` = "${CABAL_VERSION}" ]
|
[ `$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version` = "${CABAL_VERSION}" ]
|
||||||
|
[ `eghcup run --cabal ${CABAL_VERSION} -- cabal --numeric-version` = "${CABAL_VERSION}" ]
|
||||||
|
|
||||||
|
if [ "${OS}" != "FREEBSD" ] ; then
|
||||||
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
|
eghcup run --ghc 8.10.7 --cabal 3.4.1.0 --hls 1.6.1.0 --stack 2.7.3 --install --bindir "$(pwd)/.bin"
|
||||||
|
if [ "${OS}" == "WINDOWS" ] ; then
|
||||||
|
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup-run.files.windows" | sort)
|
||||||
|
else
|
||||||
|
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup-run.files" | sort)
|
||||||
|
fi
|
||||||
|
actual=$(cd ".bin" && find . | sort)
|
||||||
|
[ "${actual}" = "${expected}" ]
|
||||||
|
unset actual expected
|
||||||
|
rm -rf .bin
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
cabal --version
|
cabal --version
|
||||||
|
|
||||||
@@ -133,7 +148,7 @@ else
|
|||||||
eghcup --offline install ghc 8.10.3
|
eghcup --offline install ghc 8.10.3
|
||||||
if [ "${ARCH}" = "64" ] ; then
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-linux.files" | sort)
|
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-linux.files" | sort)
|
||||||
actual=$(cd "${GHCUP_DIR}/ghc/8.10.3/" && find | sort)
|
actual=$(cd "${GHCUP_DIR}/ghc/8.10.3/" && find . | sort)
|
||||||
[ "${actual}" = "${expected}" ]
|
[ "${actual}" = "${expected}" ]
|
||||||
unset actual expected
|
unset actual expected
|
||||||
fi
|
fi
|
||||||
@@ -141,7 +156,7 @@ else
|
|||||||
eghcup prefetch ghc 8.10.3
|
eghcup prefetch ghc 8.10.3
|
||||||
eghcup --offline install ghc 8.10.3
|
eghcup --offline install ghc 8.10.3
|
||||||
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-windows.files" | sort)
|
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-windows.files" | sort)
|
||||||
actual=$(cd "${GHCUP_DIR}/ghc/8.10.3/" && find | sort)
|
actual=$(cd "${GHCUP_DIR}/ghc/8.10.3/" && find . | sort)
|
||||||
[ "${actual}" = "${expected}" ]
|
[ "${actual}" = "${expected}" ]
|
||||||
unset actual expected
|
unset actual expected
|
||||||
else
|
else
|
||||||
@@ -182,6 +197,8 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# check that lazy loading works for 'whereis'
|
# check that lazy loading works for 'whereis'
|
||||||
cp "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml.bak"
|
cp "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml.bak"
|
||||||
echo '**' > "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml"
|
echo '**' > "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml"
|
||||||
|
|||||||
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[submodule "data/metadata"]
|
||||||
|
path = data/metadata
|
||||||
|
url = https://github.com/haskell/ghcup-metadata.git
|
||||||
|
branch = ghcup-0.1.17.5
|
||||||
22
CHANGELOG.md
22
CHANGELOG.md
@@ -1,5 +1,27 @@
|
|||||||
# Revision history for ghcup
|
# Revision history for ghcup
|
||||||
|
|
||||||
|
## 0.1.17.5 -- 2022-02-26
|
||||||
|
|
||||||
|
* Implement `ghcup run` subcommand wrt [#137](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/137)
|
||||||
|
* Support installation of dynamic HLS bindists wrt [HLS #2675](https://github.com/haskell/haskell-language-server/pull/2675) and [#237](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/237)
|
||||||
|
* Fix XDG support when `~/.local/bin` is a symlink wrt [#311](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/311)
|
||||||
|
* Add support for quilt-style patches wrt [#230](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/230), by James Hobson
|
||||||
|
* Fix redundant upgrade warnings in `ghcup upgrade`
|
||||||
|
* Fix `ghcup whereis ghc` for non-standard versions wrt [#289](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/289)
|
||||||
|
* Don't print logs to stdout, but stderr
|
||||||
|
* Allow unpacking legacy lzma archives wrt [#307](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/307)
|
||||||
|
* Allow to disable self-upgrade functionality wrt [#305](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/305)
|
||||||
|
* Fix `ghcup install ghc --set` when ghc is already installed wrt [#291](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/291)
|
||||||
|
|
||||||
|
## 0.1.17.4 -- 2021-11-13
|
||||||
|
|
||||||
|
* add `--metadata-caching` option, allowing to also disable yaml metadata caching wrt [#278](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/278)
|
||||||
|
* make upgrading ghcup in TUI more pleasant wrt [#276](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/276)
|
||||||
|
* fix parsing of atypical GHC versions (e.g. `8.10.5-patch1`)
|
||||||
|
* fix compiling HLS dynamically linked, also see [#245](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/245)
|
||||||
|
* redo (and break) some of the `ghcup compile <tool>` interface, improving patch options and setting custom cabal.project files
|
||||||
|
* avoid redundant update warnings wrt [#283](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/283)
|
||||||
|
|
||||||
## 0.1.17.3 -- 2021-10-27
|
## 0.1.17.3 -- 2021-10-27
|
||||||
|
|
||||||
* clean up during unpack failures as well
|
* clean up during unpack failures as well
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ module BrickMain where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
|
import GHCup.Types.Optics ( getDirs )
|
||||||
import GHCup.Types hiding ( LeanAppState(..) )
|
import GHCup.Types hiding ( LeanAppState(..) )
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
@@ -26,6 +27,9 @@ import Brick.Widgets.List ( listSelectedFocusedAttr
|
|||||||
)
|
)
|
||||||
import Codec.Archive
|
import Codec.Archive
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
|
import Control.Monad.Fail ( MonadFail )
|
||||||
|
#endif
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Trans.Except
|
import Control.Monad.Trans.Except
|
||||||
import Control.Monad.Trans.Resource
|
import Control.Monad.Trans.Resource
|
||||||
@@ -40,6 +44,8 @@ import Data.Vector ( Vector
|
|||||||
import Data.Versions hiding ( str )
|
import Data.Versions hiding ( str )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
|
import System.Directory ( canonicalizePath )
|
||||||
|
import System.FilePath
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import System.IO.Unsafe
|
import System.IO.Unsafe
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
@@ -48,6 +54,8 @@ import URI.ByteString
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Graphics.Vty as Vty
|
import qualified Graphics.Vty as Vty
|
||||||
import qualified Data.Vector as V
|
import qualified Data.Vector as V
|
||||||
|
import System.Environment (getExecutablePath)
|
||||||
|
import qualified System.Posix.Process as SPP
|
||||||
|
|
||||||
|
|
||||||
hiddenTools :: [Tool]
|
hiddenTools :: [Tool]
|
||||||
@@ -432,27 +440,42 @@ install' _ (_, ListResult {..}) = do
|
|||||||
]
|
]
|
||||||
|
|
||||||
run (do
|
run (do
|
||||||
|
ce <- liftIO $ fmap (either (const Nothing) Just) $
|
||||||
|
try @_ @SomeException $ getExecutablePath >>= canonicalizePath
|
||||||
|
dirs <- lift getDirs
|
||||||
case lTool of
|
case lTool of
|
||||||
GHC -> do
|
GHC -> do
|
||||||
let vi = getVersionInfo lVer GHC dls
|
let vi = getVersionInfo lVer GHC dls
|
||||||
liftE $ installGHCBin lVer Nothing False $> vi
|
liftE $ installGHCBin lVer Nothing False $> (vi, dirs, ce)
|
||||||
Cabal -> do
|
Cabal -> do
|
||||||
let vi = getVersionInfo lVer Cabal dls
|
let vi = getVersionInfo lVer Cabal dls
|
||||||
liftE $ installCabalBin lVer Nothing False $> vi
|
liftE $ installCabalBin lVer Nothing False $> (vi, dirs, ce)
|
||||||
GHCup -> do
|
GHCup -> do
|
||||||
let vi = snd <$> getLatest dls GHCup
|
let vi = snd <$> getLatest dls GHCup
|
||||||
liftE $ upgradeGHCup Nothing False $> vi
|
liftE $ upgradeGHCup Nothing False $> (vi, dirs, ce)
|
||||||
HLS -> do
|
HLS -> do
|
||||||
let vi = getVersionInfo lVer HLS dls
|
let vi = getVersionInfo lVer HLS dls
|
||||||
liftE $ installHLSBin lVer Nothing False $> vi
|
liftE $ installHLSBin lVer Nothing False $> (vi, dirs, ce)
|
||||||
Stack -> do
|
Stack -> do
|
||||||
let vi = getVersionInfo lVer Stack dls
|
let vi = getVersionInfo lVer Stack dls
|
||||||
liftE $ installStackBin lVer Nothing False $> vi
|
liftE $ installStackBin lVer Nothing False $> (vi, dirs, ce)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight (vi, Dirs{..}, Just ce) -> do
|
||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo 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
|
||||||
|
liftIO $ SPP.executeFile ce False ["tui"] 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 ()
|
pure $ Right ()
|
||||||
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
||||||
VLeft (V NoUpdate) -> pure $ Right ()
|
VLeft (V NoUpdate) -> pure $ Right ()
|
||||||
@@ -470,9 +493,9 @@ set' _ (_, ListResult {..}) = do
|
|||||||
|
|
||||||
run (do
|
run (do
|
||||||
case lTool of
|
case lTool of
|
||||||
GHC -> liftE $ setGHC (GHCTargetVersion lCross lVer) SetGHCOnly $> ()
|
GHC -> liftE $ setGHC (GHCTargetVersion lCross lVer) SetGHCOnly Nothing $> ()
|
||||||
Cabal -> liftE $ setCabal lVer $> ()
|
Cabal -> liftE $ setCabal lVer $> ()
|
||||||
HLS -> liftE $ setHLS lVer $> ()
|
HLS -> liftE $ setHLS lVer SetHLSOnly Nothing $> ()
|
||||||
Stack -> liftE $ setStack lVer $> ()
|
Stack -> liftE $ setStack lVer $> ()
|
||||||
GHCup -> pure ()
|
GHCup -> pure ()
|
||||||
)
|
)
|
||||||
@@ -536,17 +559,7 @@ settings' = unsafePerformIO $ do
|
|||||||
, fileOutter = \_ -> pure ()
|
, fileOutter = \_ -> pure ()
|
||||||
, fancyColors = True
|
, fancyColors = True
|
||||||
}
|
}
|
||||||
newIORef $ AppState (Settings { cache = True
|
newIORef $ AppState defaultSettings
|
||||||
, noVerify = False
|
|
||||||
, keepDirs = Never
|
|
||||||
, downloader = Curl
|
|
||||||
, verbose = False
|
|
||||||
, urlSource = GHCupURL
|
|
||||||
, noNetwork = False
|
|
||||||
, gpgSetting = GPGNone
|
|
||||||
, noColor = False
|
|
||||||
, ..
|
|
||||||
})
|
|
||||||
dirs
|
dirs
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
(GHCupInfo mempty mempty mempty)
|
(GHCupInfo mempty mempty mempty)
|
||||||
@@ -605,4 +618,3 @@ getAppData mgi = runExceptT $ do
|
|||||||
flip runReaderT settings $ do
|
flip runReaderT settings $ do
|
||||||
lV <- listVersions Nothing Nothing
|
lV <- listVersions Nothing Nothing
|
||||||
pure $ BrickData (reverse lV)
|
pure $ BrickData (reverse lV)
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,16 @@ module GHCup.OptParse (
|
|||||||
, module GHCup.OptParse.Config
|
, module GHCup.OptParse.Config
|
||||||
, module GHCup.OptParse.Whereis
|
, module GHCup.OptParse.Whereis
|
||||||
, module GHCup.OptParse.List
|
, module GHCup.OptParse.List
|
||||||
|
#ifndef DISABLE_UPGRADE
|
||||||
, module GHCup.OptParse.Upgrade
|
, module GHCup.OptParse.Upgrade
|
||||||
|
#endif
|
||||||
, module GHCup.OptParse.ChangeLog
|
, module GHCup.OptParse.ChangeLog
|
||||||
, module GHCup.OptParse.Prefetch
|
, module GHCup.OptParse.Prefetch
|
||||||
, module GHCup.OptParse.GC
|
, module GHCup.OptParse.GC
|
||||||
, module GHCup.OptParse.DInfo
|
, module GHCup.OptParse.DInfo
|
||||||
, module GHCup.OptParse.Nuke
|
, module GHCup.OptParse.Nuke
|
||||||
, module GHCup.OptParse.ToolRequirements
|
, module GHCup.OptParse.ToolRequirements
|
||||||
|
, module GHCup.OptParse.Run
|
||||||
, module GHCup.OptParse
|
, module GHCup.OptParse
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@@ -31,11 +34,14 @@ import GHCup.OptParse.Install
|
|||||||
import GHCup.OptParse.Set
|
import GHCup.OptParse.Set
|
||||||
import GHCup.OptParse.UnSet
|
import GHCup.OptParse.UnSet
|
||||||
import GHCup.OptParse.Rm
|
import GHCup.OptParse.Rm
|
||||||
|
import GHCup.OptParse.Run
|
||||||
import GHCup.OptParse.Compile
|
import GHCup.OptParse.Compile
|
||||||
import GHCup.OptParse.Config
|
import GHCup.OptParse.Config
|
||||||
import GHCup.OptParse.Whereis
|
import GHCup.OptParse.Whereis
|
||||||
import GHCup.OptParse.List
|
import GHCup.OptParse.List
|
||||||
|
#ifndef DISABLE_UPGRADE
|
||||||
import GHCup.OptParse.Upgrade
|
import GHCup.OptParse.Upgrade
|
||||||
|
#endif
|
||||||
import GHCup.OptParse.ChangeLog
|
import GHCup.OptParse.ChangeLog
|
||||||
import GHCup.OptParse.Prefetch
|
import GHCup.OptParse.Prefetch
|
||||||
import GHCup.OptParse.GC
|
import GHCup.OptParse.GC
|
||||||
@@ -67,6 +73,7 @@ data Options = Options
|
|||||||
-- global options
|
-- global options
|
||||||
optVerbose :: Maybe Bool
|
optVerbose :: Maybe Bool
|
||||||
, optCache :: Maybe Bool
|
, optCache :: Maybe Bool
|
||||||
|
, optMetaCache :: Maybe Integer
|
||||||
, optUrlSource :: Maybe URI
|
, optUrlSource :: Maybe URI
|
||||||
, optNoVerify :: Maybe Bool
|
, optNoVerify :: Maybe Bool
|
||||||
, optKeepDirs :: Maybe KeepDirs
|
, optKeepDirs :: Maybe KeepDirs
|
||||||
@@ -88,7 +95,9 @@ data Command
|
|||||||
| Compile CompileCommand
|
| Compile CompileCommand
|
||||||
| Config ConfigCommand
|
| Config ConfigCommand
|
||||||
| Whereis WhereisOptions WhereisCommand
|
| Whereis WhereisOptions WhereisCommand
|
||||||
|
#ifndef DISABLE_UPGRADE
|
||||||
| Upgrade UpgradeOpts Bool
|
| Upgrade UpgradeOpts Bool
|
||||||
|
#endif
|
||||||
| ToolRequirements
|
| ToolRequirements
|
||||||
| ChangeLog ChangeLogOptions
|
| ChangeLog ChangeLogOptions
|
||||||
| Nuke
|
| Nuke
|
||||||
@@ -97,6 +106,7 @@ data Command
|
|||||||
#endif
|
#endif
|
||||||
| Prefetch PrefetchCommand
|
| Prefetch PrefetchCommand
|
||||||
| GC GCOptions
|
| GC GCOptions
|
||||||
|
| Run RunOptions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -105,6 +115,7 @@ opts =
|
|||||||
Options
|
Options
|
||||||
<$> invertableSwitch "verbose" 'v' False (help "Enable verbosity (default: disabled)")
|
<$> invertableSwitch "verbose" 'v' False (help "Enable verbosity (default: disabled)")
|
||||||
<*> invertableSwitch "cache" 'c' False (help "Cache downloads in ~/.ghcup/cache (default: disabled)")
|
<*> invertableSwitch "cache" 'c' False (help "Cache downloads in ~/.ghcup/cache (default: disabled)")
|
||||||
|
<*> optional (option auto (long "metadata-caching" <> help "How long the yaml metadata caching interval is (in seconds), 0 to disable" <> internal))
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader parseUri)
|
(eitherReader parseUri)
|
||||||
@@ -206,6 +217,7 @@ com =
|
|||||||
(info (List <$> listOpts <**> helper)
|
(info (List <$> listOpts <**> helper)
|
||||||
(progDesc "Show available GHCs and other tools")
|
(progDesc "Show available GHCs and other tools")
|
||||||
)
|
)
|
||||||
|
#ifndef DISABLE_UPGRADE
|
||||||
<> command
|
<> command
|
||||||
"upgrade"
|
"upgrade"
|
||||||
(info
|
(info
|
||||||
@@ -216,6 +228,7 @@ com =
|
|||||||
)
|
)
|
||||||
(progDesc "Upgrade ghcup")
|
(progDesc "Upgrade ghcup")
|
||||||
)
|
)
|
||||||
|
#endif
|
||||||
<> command
|
<> command
|
||||||
"compile"
|
"compile"
|
||||||
( Compile
|
( Compile
|
||||||
@@ -253,6 +266,16 @@ com =
|
|||||||
(progDesc "Garbage collection"
|
(progDesc "Garbage collection"
|
||||||
<> footerDoc ( Just $ text gcFooter ))
|
<> footerDoc ( Just $ text gcFooter ))
|
||||||
)
|
)
|
||||||
|
<> command
|
||||||
|
"run"
|
||||||
|
(Run
|
||||||
|
<$>
|
||||||
|
info
|
||||||
|
(runOpts <**> helper)
|
||||||
|
(progDesc "Run a command with the given tool in PATH"
|
||||||
|
<> footerDoc ( Just $ text runFooter )
|
||||||
|
)
|
||||||
|
)
|
||||||
<> commandGroup "Main commands:"
|
<> commandGroup "Main commands:"
|
||||||
)
|
)
|
||||||
<|> subparser
|
<|> subparser
|
||||||
|
|||||||
@@ -196,8 +196,8 @@ platformParser s' = case MP.parse (platformP <* MP.eof) "" (T.pack s') of
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
bindistParser :: String -> Either String URI
|
uriParser :: String -> Either String URI
|
||||||
bindistParser = first show . parseURI strictURIParserOptions . UTF8.fromString
|
uriParser = first show . parseURI strictURIParserOptions . UTF8.fromString
|
||||||
|
|
||||||
|
|
||||||
absolutePathParser :: FilePath -> Either String FilePath
|
absolutePathParser :: FilePath -> Either String FilePath
|
||||||
@@ -246,18 +246,6 @@ criteriaParser s' | t == T.pack "installed" = Right ListInstalled
|
|||||||
where t = T.toLower (T.pack s')
|
where t = T.toLower (T.pack s')
|
||||||
|
|
||||||
|
|
||||||
toolVersionParser :: Parser ToolVersion
|
|
||||||
toolVersionParser = verP' <|> toolP
|
|
||||||
where
|
|
||||||
verP' = ToolVersion <$> versionParser
|
|
||||||
toolP =
|
|
||||||
ToolTag
|
|
||||||
<$> option
|
|
||||||
(eitherReader tagEither)
|
|
||||||
(short 't' <> long "tag" <> metavar "TAG" <> help "The target tag")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
keepOnParser :: String -> Either String KeepDirs
|
keepOnParser :: String -> Either String KeepDirs
|
||||||
keepOnParser s' | t == T.pack "always" = Right Always
|
keepOnParser s' | t == T.pack "always" = Right Always
|
||||||
@@ -299,7 +287,7 @@ tagCompleter tool add = listIOCompleter $ do
|
|||||||
, fancyColors = False
|
, fancyColors = False
|
||||||
}
|
}
|
||||||
let appState = LeanAppState
|
let appState = LeanAppState
|
||||||
(Settings True False Never Curl False GHCupURL True GPGNone False)
|
(defaultSettings { noNetwork = True })
|
||||||
dirs'
|
dirs'
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
loggerConfig
|
loggerConfig
|
||||||
@@ -322,7 +310,7 @@ versionCompleter criteria tool = listIOCompleter $ do
|
|||||||
, fileOutter = mempty
|
, fileOutter = mempty
|
||||||
, fancyColors = False
|
, fancyColors = False
|
||||||
}
|
}
|
||||||
let settings = Settings True False Never Curl False GHCupURL True GPGNone False
|
let settings = defaultSettings { noNetwork = True }
|
||||||
let leanAppState = LeanAppState
|
let leanAppState = LeanAppState
|
||||||
settings
|
settings
|
||||||
dirs'
|
dirs'
|
||||||
@@ -399,7 +387,7 @@ fromVersion' (SetToolVersion v) tool = do
|
|||||||
Right pvpIn ->
|
Right pvpIn ->
|
||||||
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
||||||
Just (pvp_, vi') -> 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 (_tvTarget v) v', Just vi')
|
pure (GHCTargetVersion (_tvTarget v) v', Just vi')
|
||||||
Nothing -> pure (v, vi)
|
Nothing -> pure (v, vi)
|
||||||
@@ -472,42 +460,22 @@ checkForUpdates :: ( MonadReader env m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> m ()
|
=> m [(Tool, Version)]
|
||||||
checkForUpdates = do
|
checkForUpdates = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
||||||
lInstalled <- listVersions Nothing (Just ListInstalled)
|
lInstalled <- listVersions Nothing (Just ListInstalled)
|
||||||
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
||||||
|
|
||||||
forM_ (getLatest dls GHCup) $ \(l, _) -> do
|
ghcup <- forMM (getLatest dls GHCup) $ \(l, _) -> do
|
||||||
(Right ghc_ver) <- pure $ version $ prettyPVP ghcUpVer
|
(Right ghcup_ver) <- pure $ version $ prettyPVP ghcUpVer
|
||||||
when (l > ghc_ver)
|
if (l > ghcup_ver) then pure $ Just (GHCup, l) else pure Nothing
|
||||||
$ logWarn $
|
|
||||||
"New GHCup version available: " <> prettyVer l <> ". To upgrade, run 'ghcup upgrade'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls GHC) $ \(l, _) -> do
|
otherTools <- forM [GHC, Cabal, HLS, Stack] $ \t ->
|
||||||
let mghc_ver = latestInstalled GHC
|
forMM (getLatest dls t) $ \(l, _) -> do
|
||||||
forM mghc_ver $ \ghc_ver ->
|
let mver = latestInstalled t
|
||||||
when (l > ghc_ver)
|
forMM mver $ \ver ->
|
||||||
$ logWarn $
|
if (l > ver) then pure $ Just (t, l) else pure Nothing
|
||||||
"New GHC version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install ghc " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls Cabal) $ \(l, _) -> do
|
pure $ catMaybes (ghcup:otherTools)
|
||||||
let mcabal_ver = latestInstalled Cabal
|
where
|
||||||
forM mcabal_ver $ \cabal_ver ->
|
forMM a f = fmap join $ forM a f
|
||||||
when (l > cabal_ver)
|
|
||||||
$ logWarn $
|
|
||||||
"New Cabal version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install cabal " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls HLS) $ \(l, _) -> do
|
|
||||||
let mhls_ver = latestInstalled HLS
|
|
||||||
forM mhls_ver $ \hls_ver ->
|
|
||||||
when (l > hls_ver)
|
|
||||||
$ logWarn $
|
|
||||||
"New HLS version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install hls " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls Stack) $ \(l, _) -> do
|
|
||||||
let mstack_ver = latestInstalled Stack
|
|
||||||
forM mstack_ver $ \stack_ver ->
|
|
||||||
when (l > stack_ver)
|
|
||||||
$ logWarn $
|
|
||||||
"New Stack version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install stack " <> prettyVer l <> "'"
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import Prelude hiding ( appendFile )
|
|||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
|
|
||||||
|
import URI.ByteString hiding ( uriParser )
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
import System.FilePath (isPathSeparator)
|
import System.FilePath (isPathSeparator)
|
||||||
@@ -68,7 +69,7 @@ data GHCCompileOptions = GHCCompileOptions
|
|||||||
, bootstrapGhc :: Either Version FilePath
|
, bootstrapGhc :: Either Version FilePath
|
||||||
, jobs :: Maybe Int
|
, jobs :: Maybe Int
|
||||||
, buildConfig :: Maybe FilePath
|
, buildConfig :: Maybe FilePath
|
||||||
, patchDir :: Maybe FilePath
|
, patches :: Maybe (Either FilePath [URI])
|
||||||
, crossTarget :: Maybe Text
|
, crossTarget :: Maybe Text
|
||||||
, addConfArgs :: [Text]
|
, addConfArgs :: [Text]
|
||||||
, setCompile :: Bool
|
, setCompile :: Bool
|
||||||
@@ -84,10 +85,11 @@ data HLSCompileOptions = HLSCompileOptions
|
|||||||
, setCompile :: Bool
|
, setCompile :: Bool
|
||||||
, ovewrwiteVer :: Maybe Version
|
, ovewrwiteVer :: Maybe Version
|
||||||
, isolateDir :: Maybe FilePath
|
, isolateDir :: Maybe FilePath
|
||||||
, cabalProject :: Maybe FilePath
|
, cabalProject :: Maybe (Either FilePath URI)
|
||||||
, cabalProjectLocal :: Maybe FilePath
|
, cabalProjectLocal :: Maybe URI
|
||||||
, patchDir :: Maybe FilePath
|
, patches :: Maybe (Either FilePath [URI])
|
||||||
, targetGHCs :: [ToolVersion]
|
, targetGHCs :: [ToolVersion]
|
||||||
|
, cabalArgs :: [Text]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -148,7 +150,10 @@ Examples:
|
|||||||
These need to be available in PATH prior to compilation.
|
These need to be available in PATH prior to compilation.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
ghcup compile hls -v 1.4.0 -j 12 8.10.5 8.10.7 9.0.1|]
|
# compile 1.4.0 for ghc 8.10.5 and 8.10.7
|
||||||
|
ghcup compile hls -v 1.4.0 -j 12 --ghc 8.10.5 --ghc 8.10.7
|
||||||
|
# compile from master for ghc 8.10.7, linking everything dynamically
|
||||||
|
ghcup compile hls -g master -j 12 --ghc 8.10.7 -- --ghc-options='-dynamic'|]
|
||||||
|
|
||||||
|
|
||||||
ghcCompileOpts :: Parser GHCCompileOptions
|
ghcCompileOpts :: Parser GHCCompileOptions
|
||||||
@@ -195,13 +200,23 @@ ghcCompileOpts =
|
|||||||
"Absolute path to build config file"
|
"Absolute path to build config file"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> (optional
|
||||||
(option
|
(
|
||||||
str
|
(fmap Right $ many $ option
|
||||||
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
(eitherReader uriParser)
|
||||||
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
(long "patch" <> metavar "PATCH_URI" <> help
|
||||||
|
"URI to a patch (https/http/file)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|>
|
||||||
|
(fmap Left $ option
|
||||||
|
str
|
||||||
|
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
||||||
|
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1. This order is determined by a quilt series file if it exists, or the patches are lexicographically ordered)"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
str
|
str
|
||||||
@@ -296,26 +311,42 @@ hlsCompileOpts =
|
|||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
str
|
((fmap Right $ eitherReader uriParser) <|> (fmap Left str))
|
||||||
(long "cabal-project" <> metavar "CABAL_PROJECT" <> help
|
(long "cabal-project" <> metavar "CABAL_PROJECT" <> help
|
||||||
"If relative, specifies the path to cabal.project inside the unpacked HLS tarball/checkout. If absolute, will copy the file over."
|
"If relative filepath, specifies the path to cabal.project inside the unpacked HLS tarball/checkout. Otherwise expects a full URI with https/http/file scheme."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader absolutePathParser)
|
(eitherReader uriParser)
|
||||||
(long "cabal-project-local" <> metavar "CABAL_PROJECT_LOCAL" <> help
|
(long "cabal-project-local" <> metavar "CABAL_PROJECT_LOCAL" <> help
|
||||||
"Absolute path to a cabal.project.local to be used for the build. Will be copied over."
|
"URI (https/http/file) to a cabal.project.local to be used for the build. Will be copied over."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> (optional
|
||||||
(option
|
(
|
||||||
(eitherReader absolutePathParser)
|
(fmap Right $ many $ option
|
||||||
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
(eitherReader uriParser)
|
||||||
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
(long "patch" <> metavar "PATCH_URI" <> help
|
||||||
|
"URI to a patch (https/http/file)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|>
|
||||||
|
(fmap Left $ option
|
||||||
|
str
|
||||||
|
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
||||||
|
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> some (toolVersionArgument Nothing (Just GHC))
|
)
|
||||||
|
<*> some (
|
||||||
|
option (eitherReader toolVersionEither)
|
||||||
|
( long "ghc" <> metavar "GHC_VERSION|TAG" <> help "For which GHC version to compile for (can be specified multiple times)"
|
||||||
|
<> completer (tagCompleter GHC [])
|
||||||
|
<> completer (versionCompleter Nothing GHC))
|
||||||
|
)
|
||||||
|
<*> many (argument str (metavar "CABAL_ARGS" <> help "Additional arguments to cabal install, prefix with '-- ' (longopts)"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -403,11 +434,11 @@ compile :: ( Monad m
|
|||||||
)
|
)
|
||||||
=> CompileCommand
|
=> CompileCommand
|
||||||
-> Settings
|
-> Settings
|
||||||
|
-> Dirs
|
||||||
-> (forall eff a . ReaderT AppState m (VEither eff a) -> m (VEither eff a))
|
-> (forall eff a . ReaderT AppState m (VEither eff a) -> m (VEither eff a))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
compile compileCommand settings runAppState runLogger = do
|
compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||||
VRight Dirs{ .. } <- runAppState (VRight <$> getDirs)
|
|
||||||
case compileCommand of
|
case compileCommand of
|
||||||
(CompileHLS HLSCompileOptions { .. }) -> do
|
(CompileHLS HLSCompileOptions { .. }) -> do
|
||||||
runCompileHLS runAppState (do
|
runCompileHLS runAppState (do
|
||||||
@@ -430,11 +461,12 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
isolateDir
|
isolateDir
|
||||||
cabalProject
|
cabalProject
|
||||||
cabalProjectLocal
|
cabalProjectLocal
|
||||||
patchDir
|
patches
|
||||||
|
cabalArgs
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo targetVer HLS dls
|
let vi = getVersionInfo targetVer HLS dls
|
||||||
when setCompile $ void $ liftE $
|
when setCompile $ void $ liftE $
|
||||||
setHLS targetVer
|
setHLS targetVer SetHLSOnly Nothing
|
||||||
pure (vi, targetVer)
|
pure (vi, targetVer)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -477,7 +509,7 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
bootstrapGhc
|
bootstrapGhc
|
||||||
jobs
|
jobs
|
||||||
buildConfig
|
buildConfig
|
||||||
patchDir
|
patches
|
||||||
addConfArgs
|
addConfArgs
|
||||||
buildFlavour
|
buildFlavour
|
||||||
hadrian
|
hadrian
|
||||||
@@ -485,7 +517,7 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo (_tvVersion targetVer) GHC dls
|
let vi = getVersionInfo (_tvVersion targetVer) GHC dls
|
||||||
when setCompile $ void $ liftE $
|
when setCompile $ void $ liftE $
|
||||||
setGHC targetVer SetGHCOnly
|
setGHC targetVer SetGHCOnly Nothing
|
||||||
pure (vi, targetVer)
|
pure (vi, targetVer)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ updateSettings config' settings = do
|
|||||||
mergeConf :: UserSettings -> Settings -> Settings
|
mergeConf :: UserSettings -> Settings -> Settings
|
||||||
mergeConf UserSettings{..} Settings{..} =
|
mergeConf UserSettings{..} Settings{..} =
|
||||||
let cache' = fromMaybe cache uCache
|
let cache' = fromMaybe cache uCache
|
||||||
|
metaCache' = fromMaybe metaCache uMetaCache
|
||||||
noVerify' = fromMaybe noVerify uNoVerify
|
noVerify' = fromMaybe noVerify uNoVerify
|
||||||
keepDirs' = fromMaybe keepDirs uKeepDirs
|
keepDirs' = fromMaybe keepDirs uKeepDirs
|
||||||
downloader' = fromMaybe downloader uDownloader
|
downloader' = fromMaybe downloader uDownloader
|
||||||
@@ -129,7 +130,7 @@ updateSettings config' settings = do
|
|||||||
urlSource' = fromMaybe urlSource uUrlSource
|
urlSource' = fromMaybe urlSource uUrlSource
|
||||||
noNetwork' = fromMaybe noNetwork uNoNetwork
|
noNetwork' = fromMaybe noNetwork uNoNetwork
|
||||||
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
||||||
in Settings cache' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor
|
in Settings cache' metaCache' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ describe_result = $( LitE . StringL <$>
|
|||||||
runIO (do
|
runIO (do
|
||||||
CapturedProcess{..} <- do
|
CapturedProcess{..} <- do
|
||||||
dirs <- liftIO getAllDirs
|
dirs <- liftIO getAllDirs
|
||||||
let settings = AppState (Settings True False Never Curl False GHCupURL False GPGNone False)
|
let settings = AppState (defaultSettings { noNetwork = True })
|
||||||
dirs
|
dirs
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
flip runReaderT settings $ executeOut "git" ["describe"] Nothing
|
flip runReaderT settings $ executeOut "git" ["describe"] Nothing
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ gc GCOptions{..} runAppState runLogger = runGC runAppState (do
|
|||||||
when gcOldGHC rmOldGHC
|
when gcOldGHC rmOldGHC
|
||||||
lift $ when gcProfilingLibs rmProfilingLibs
|
lift $ when gcProfilingLibs rmProfilingLibs
|
||||||
lift $ when gcShareDir rmShareDir
|
lift $ when gcShareDir rmShareDir
|
||||||
lift $ when gcHLSNoGHC rmHLSNoGHC
|
liftE $ when gcHLSNoGHC rmHLSNoGHC
|
||||||
lift $ when gcCache rmCache
|
lift $ when gcCache rmCache
|
||||||
lift $ when gcTmp rmTmp
|
lift $ when gcTmp rmTmp
|
||||||
) >>= \case
|
) >>= \case
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import GHCup.OptParse.Common
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.File
|
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Utils.String.QQ
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ import Options.Applicative.Help.Pretty ( text )
|
|||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
import URI.ByteString
|
import URI.ByteString hiding ( uriParser )
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
|
||||||
@@ -187,7 +186,7 @@ installOpts tool =
|
|||||||
<*> ( ( (,)
|
<*> ( ( (,)
|
||||||
<$> optional
|
<$> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader bindistParser)
|
(eitherReader uriParser)
|
||||||
(short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
|
(short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
|
||||||
"Install the specified version from this bindist"
|
"Install the specified version from this bindist"
|
||||||
)
|
)
|
||||||
@@ -268,6 +267,64 @@ runInstTool appstate' mInstPlatform =
|
|||||||
@InstallEffects
|
@InstallEffects
|
||||||
|
|
||||||
|
|
||||||
|
type InstallGHCEffects = '[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
, BuildFailed
|
||||||
|
, DirNotEmpty
|
||||||
|
, AlreadyInstalled
|
||||||
|
|
||||||
|
, (AlreadyInstalled, NotInstalled)
|
||||||
|
, (UnknownArchive, NotInstalled)
|
||||||
|
, (ArchiveResult, NotInstalled)
|
||||||
|
, (FileDoesNotExistError, NotInstalled)
|
||||||
|
, (CopyError, NotInstalled)
|
||||||
|
, (NotInstalled, NotInstalled)
|
||||||
|
, (DirNotEmpty, NotInstalled)
|
||||||
|
, (NoDownload, NotInstalled)
|
||||||
|
, (BuildFailed, NotInstalled)
|
||||||
|
, (TagNotFound, NotInstalled)
|
||||||
|
, (DigestError, NotInstalled)
|
||||||
|
, (GPGError, NotInstalled)
|
||||||
|
, (DownloadFailed, NotInstalled)
|
||||||
|
, (TarDirDoesNotExist, NotInstalled)
|
||||||
|
, (NextVerNotFound, NotInstalled)
|
||||||
|
, (NoToolVersionSet, NotInstalled)
|
||||||
|
, (FileAlreadyExistsError, NotInstalled)
|
||||||
|
, (ProcessError, NotInstalled)
|
||||||
|
|
||||||
|
, (AlreadyInstalled, ())
|
||||||
|
, (UnknownArchive, ())
|
||||||
|
, (ArchiveResult, ())
|
||||||
|
, (FileDoesNotExistError, ())
|
||||||
|
, (CopyError, ())
|
||||||
|
, (NotInstalled, ())
|
||||||
|
, (DirNotEmpty, ())
|
||||||
|
, (NoDownload, ())
|
||||||
|
, (BuildFailed, ())
|
||||||
|
, (TagNotFound, ())
|
||||||
|
, (DigestError, ())
|
||||||
|
, (GPGError, ())
|
||||||
|
, (DownloadFailed, ())
|
||||||
|
, (TarDirDoesNotExist, ())
|
||||||
|
, (NextVerNotFound, ())
|
||||||
|
, (NoToolVersionSet, ())
|
||||||
|
, (FileAlreadyExistsError, ())
|
||||||
|
, (ProcessError, ())
|
||||||
|
|
||||||
|
, ((), NotInstalled)
|
||||||
|
]
|
||||||
|
|
||||||
|
runInstGHC :: AppState
|
||||||
|
-> Maybe PlatformRequest
|
||||||
|
-> Excepts InstallGHCEffects (ResourceT (ReaderT AppState IO)) a
|
||||||
|
-> IO (VEither InstallGHCEffects a)
|
||||||
|
runInstGHC appstate' mInstPlatform =
|
||||||
|
flip runReaderT (maybe appstate' (\x -> appstate'{ pfreq = x } :: AppState) mInstPlatform)
|
||||||
|
. runResourceT
|
||||||
|
. runE
|
||||||
|
@InstallGHCEffects
|
||||||
|
|
||||||
|
|
||||||
-------------------
|
-------------------
|
||||||
--[ Entrypoints ]--
|
--[ Entrypoints ]--
|
||||||
@@ -288,23 +345,25 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
installGHC InstallOptions{..} = do
|
installGHC InstallOptions{..} = do
|
||||||
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
||||||
(case instBindist of
|
(case instBindist of
|
||||||
Nothing -> runInstTool s' instPlatform $ do
|
Nothing -> runInstGHC s' instPlatform $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||||
liftE $ installGHCBin
|
void $ liftE $ sequenceE (installGHCBin
|
||||||
(_tvVersion v)
|
|
||||||
isolateDir
|
|
||||||
forceInstall
|
|
||||||
when instSet $ void $ liftE $ setGHC v SetGHCOnly
|
|
||||||
pure vi
|
|
||||||
Just uri -> do
|
|
||||||
runInstTool s'{ settings = settings {noVerify = True}} instPlatform $ do
|
|
||||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
|
||||||
liftE $ installGHCBindist
|
|
||||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "")
|
|
||||||
(_tvVersion v)
|
(_tvVersion v)
|
||||||
isolateDir
|
isolateDir
|
||||||
forceInstall
|
forceInstall
|
||||||
when instSet $ void $ liftE $ setGHC v SetGHCOnly
|
)
|
||||||
|
$ when instSet $ void $ setGHC v SetGHCOnly Nothing
|
||||||
|
pure vi
|
||||||
|
Just uri -> do
|
||||||
|
runInstGHC s'{ settings = settings {noVerify = True}} instPlatform $ do
|
||||||
|
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||||
|
void $ liftE $ sequenceE (installGHCBindist
|
||||||
|
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "")
|
||||||
|
(_tvVersion v)
|
||||||
|
isolateDir
|
||||||
|
forceInstall
|
||||||
|
)
|
||||||
|
$ when instSet $ void $ setGHC v SetGHCOnly Nothing
|
||||||
pure vi
|
pure vi
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -313,14 +372,25 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg ->
|
||||||
runLogger $ logInfo msg
|
runLogger $ logInfo msg
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
|
VLeft (V (AlreadyInstalled _ v, ())) -> do
|
||||||
|
runLogger $ logWarn $
|
||||||
|
"GHC ver " <> prettyVer v <> " already installed; if you really want to reinstall it, you may want to run 'ghcup install ghc --force " <> prettyVer v <> "'"
|
||||||
|
pure ExitSuccess
|
||||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
VLeft (V (AlreadyInstalled _ v)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
"GHC ver " <> prettyVer v <> " already installed; if you really want to reinstall it, you may want to run 'ghcup install ghc --force " <> prettyVer v <> "'"
|
"GHC ver " <> prettyVer v <> " already installed; if you really want to reinstall it, you may want to run 'ghcup install ghc --force " <> prettyVer v <> "'"
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
VLeft (V (DirNotEmpty fp)) -> do
|
VLeft (V (DirNotEmpty fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
"Install directory " <> T.pack fp <> " is not empty. Use 'ghcup install ghc --isolate " <> T.pack fp <> " --force ..." <> "' to install regardless."
|
"Install directory " <> T.pack fp <> " is not empty. Use 'ghcup install ghc --isolate " <> T.pack fp <> " --force ..." <> "' to install regardless."
|
||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
|
VLeft (V (DirNotEmpty fp, ())) -> do
|
||||||
|
runLogger $ logWarn $
|
||||||
|
"Install directory " <> T.pack fp <> " is not empty. Use 'ghcup install ghc --isolate " <> T.pack fp <> " --force ..." <> "' to install regardless."
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
|
||||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||||
case keepDirs settings of
|
case keepDirs settings of
|
||||||
Never -> runLogger (logError $ T.pack $ prettyShow err)
|
Never -> runLogger (logError $ T.pack $ prettyShow err)
|
||||||
@@ -328,6 +398,14 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
"Check the logs at " <> T.pack logsDir <> " and the build directory " <> T.pack tmpdir <> " for more clues." <> "\n" <>
|
"Check the logs at " <> T.pack logsDir <> " and the build directory " <> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||||
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
|
VLeft err@(V (BuildFailed tmpdir _, ())) -> do
|
||||||
|
case keepDirs settings of
|
||||||
|
Never -> runLogger (logError $ T.pack $ prettyShow err)
|
||||||
|
_ -> runLogger (logError $ T.pack (prettyShow err) <> "\n" <>
|
||||||
|
"Check the logs at " <> T.pack logsDir <> " and the build directory " <> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||||
|
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ do
|
runLogger $ do
|
||||||
logError $ T.pack $ prettyShow e
|
logError $ T.pack $ prettyShow e
|
||||||
@@ -390,8 +468,9 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
Just uri -> do
|
Just uri -> do
|
||||||
runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do
|
runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer HLS
|
(v, vi) <- liftE $ fromVersion instVer HLS
|
||||||
|
-- TODO: support legacy
|
||||||
liftE $ installHLSBindist
|
liftE $ installHLSBindist
|
||||||
(DownloadInfo uri Nothing "")
|
(DownloadInfo uri (Just $ RegexDir "haskell-language-server-*") "")
|
||||||
(_tvVersion v)
|
(_tvVersion v)
|
||||||
isolateDir
|
isolateDir
|
||||||
forceInstall
|
forceInstall
|
||||||
|
|||||||
348
app/ghcup/GHCup/OptParse/Run.hs
Normal file
348
app/ghcup/GHCup/OptParse/Run.hs
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
|
module GHCup.OptParse.Run where
|
||||||
|
|
||||||
|
|
||||||
|
import GHCup
|
||||||
|
import GHCup.Utils
|
||||||
|
import GHCup.Utils.Prelude
|
||||||
|
import GHCup.Utils.File
|
||||||
|
import GHCup.OptParse.Common
|
||||||
|
import GHCup.Errors
|
||||||
|
import GHCup.Types
|
||||||
|
import GHCup.Types.Optics ( getDirs )
|
||||||
|
import GHCup.Utils.Logger
|
||||||
|
import GHCup.Utils.String.QQ
|
||||||
|
|
||||||
|
import Control.Exception.Safe ( MonadMask, MonadCatch )
|
||||||
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
|
import Control.Monad.Fail ( MonadFail )
|
||||||
|
#endif
|
||||||
|
import Codec.Archive
|
||||||
|
import Control.Monad.Reader
|
||||||
|
import Control.Monad.Trans.Resource
|
||||||
|
import Data.Functor
|
||||||
|
import Data.Maybe (isNothing)
|
||||||
|
import Data.List ( intercalate )
|
||||||
|
import Haskus.Utils.Variant.Excepts
|
||||||
|
import Options.Applicative hiding ( style )
|
||||||
|
import Prelude hiding ( appendFile )
|
||||||
|
import System.Directory
|
||||||
|
import System.FilePath
|
||||||
|
import System.Environment
|
||||||
|
import System.IO.Temp
|
||||||
|
import System.Exit
|
||||||
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
|
|
||||||
|
import qualified Data.Map.Strict as Map
|
||||||
|
import qualified Data.Text as T
|
||||||
|
#ifndef IS_WINDOWS
|
||||||
|
import qualified System.Posix.Process as SPP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Options ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
data RunOptions = RunOptions
|
||||||
|
{ runAppendPATH :: Bool
|
||||||
|
, runInstTool' :: Bool
|
||||||
|
, runGHCVer :: Maybe ToolVersion
|
||||||
|
, runCabalVer :: Maybe ToolVersion
|
||||||
|
, runHLSVer :: Maybe ToolVersion
|
||||||
|
, runStackVer :: Maybe ToolVersion
|
||||||
|
, runBinDir :: Maybe FilePath
|
||||||
|
, runCOMMAND :: [String]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Parsers ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
runOpts :: Parser RunOptions
|
||||||
|
runOpts =
|
||||||
|
RunOptions
|
||||||
|
<$> switch
|
||||||
|
(short 'a' <> long "append" <> help "Append bin/ dir to PATH instead of prepending (this means that e.g. a system installation may take precedence)")
|
||||||
|
<*> switch
|
||||||
|
(short 'i' <> long "install" <> help "Install the tool, if missing")
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader toolVersionEither)
|
||||||
|
(metavar "GHC_VERSION" <> long "ghc" <> help "The ghc version")
|
||||||
|
)
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader toolVersionEither)
|
||||||
|
(metavar "CABAL_VERSION" <> long "cabal" <> help "The cabal version")
|
||||||
|
)
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader toolVersionEither)
|
||||||
|
(metavar "HLS_VERSION" <> long "hls" <> help "The HLS version")
|
||||||
|
)
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader toolVersionEither)
|
||||||
|
(metavar "STACK_VERSION" <> long "stack" <> help "The stack version")
|
||||||
|
)
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader isolateParser)
|
||||||
|
( short 'b'
|
||||||
|
<> long "bindir"
|
||||||
|
<> metavar "DIR"
|
||||||
|
<> help "directory where to create the tool symlinks (default: newly created system temp dir)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<*> 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."))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------
|
||||||
|
--[ Footer ]--
|
||||||
|
--------------
|
||||||
|
|
||||||
|
|
||||||
|
runFooter :: String
|
||||||
|
runFooter = [s|Discussion:
|
||||||
|
Adds the given tools to a dedicated bin/ directory and adds them to PATH, exposing
|
||||||
|
the relevant binaries, then executes a command.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# run VSCode with all latest toolchain exposed, installing missing versions if necessary
|
||||||
|
ghcup run --ghc latest --cabal latest --hls latest --stack latest --install -- code Setup.hs
|
||||||
|
|
||||||
|
# create a custom toolchain bin/ dir with GHC and cabal that can be manually added to PATH
|
||||||
|
ghcup run --ghc 8.10.7 --cabal 3.2.0.0 --bindir $HOME/toolchain/bin
|
||||||
|
|
||||||
|
# run a specific ghc version
|
||||||
|
ghcup run --ghc 8.10.7 -- ghc --version|]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
--[ Effect interpreters ]--
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
type RunEffects = '[ AlreadyInstalled
|
||||||
|
, UnknownArchive
|
||||||
|
, ArchiveResult
|
||||||
|
, FileDoesNotExistError
|
||||||
|
, CopyError
|
||||||
|
, NotInstalled
|
||||||
|
, DirNotEmpty
|
||||||
|
, NoDownload
|
||||||
|
, NotInstalled
|
||||||
|
, BuildFailed
|
||||||
|
, TagNotFound
|
||||||
|
, DigestError
|
||||||
|
, GPGError
|
||||||
|
, DownloadFailed
|
||||||
|
, TarDirDoesNotExist
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
, FileAlreadyExistsError
|
||||||
|
, ProcessError
|
||||||
|
]
|
||||||
|
|
||||||
|
runLeanRUN :: (MonadUnliftIO m, MonadIO m)
|
||||||
|
=> LeanAppState
|
||||||
|
-> Excepts RunEffects (ReaderT LeanAppState m) a
|
||||||
|
-> m (VEither RunEffects a)
|
||||||
|
runLeanRUN leanAppstate =
|
||||||
|
-- Don't use runLeanAppState here, which is disabled on windows.
|
||||||
|
-- This is the only command on all platforms that doesn't need full appstate.
|
||||||
|
flip runReaderT leanAppstate
|
||||||
|
. runE
|
||||||
|
@RunEffects
|
||||||
|
|
||||||
|
runRUN :: MonadUnliftIO m
|
||||||
|
=> (ReaderT AppState m (VEither RunEffects a) -> m (VEither RunEffects a))
|
||||||
|
-> Excepts RunEffects (ResourceT (ReaderT AppState m)) a
|
||||||
|
-> m (VEither RunEffects a)
|
||||||
|
runRUN runAppState =
|
||||||
|
runAppState
|
||||||
|
. runResourceT
|
||||||
|
. runE
|
||||||
|
@RunEffects
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------
|
||||||
|
--[ Entrypoint ]--
|
||||||
|
------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
run :: forall m.
|
||||||
|
( MonadFail m
|
||||||
|
, MonadMask m
|
||||||
|
, MonadCatch m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadUnliftIO m
|
||||||
|
)
|
||||||
|
=> RunOptions
|
||||||
|
-> (forall a. ReaderT AppState m (VEither RunEffects a) -> m (VEither RunEffects a))
|
||||||
|
-> LeanAppState
|
||||||
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
|
-> m ExitCode
|
||||||
|
run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||||
|
tmp <- case runBinDir of
|
||||||
|
Just bdir -> do
|
||||||
|
liftIO $ createDirRecursive' bdir
|
||||||
|
liftIO $ canonicalizePath bdir
|
||||||
|
Nothing -> liftIO (getTemporaryDirectory >>= \tmp -> createTempDirectory tmp "ghcup")
|
||||||
|
r <- do
|
||||||
|
addToolsToDir tmp
|
||||||
|
case r of
|
||||||
|
VRight _ -> do
|
||||||
|
case runCOMMAND of
|
||||||
|
[] -> do
|
||||||
|
liftIO $ putStr tmp
|
||||||
|
pure ExitSuccess
|
||||||
|
(cmd:args) -> do
|
||||||
|
newEnv <- liftIO $ addToPath tmp
|
||||||
|
#ifndef IS_WINDOWS
|
||||||
|
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
||||||
|
pure ExitSuccess
|
||||||
|
#else
|
||||||
|
r' <- runLeanRUN leanAppstate $ liftE $ lEM @_ @'[ProcessError] $ exec cmd args Nothing (Just newEnv)
|
||||||
|
case r' of
|
||||||
|
VRight _ -> pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ logError $ T.pack $ prettyShow e
|
||||||
|
pure $ ExitFailure 28
|
||||||
|
#endif
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ logError $ T.pack $ prettyShow e
|
||||||
|
pure $ ExitFailure 27
|
||||||
|
where
|
||||||
|
isToolTag :: ToolVersion -> Bool
|
||||||
|
isToolTag (ToolTag _) = True
|
||||||
|
isToolTag _ = False
|
||||||
|
|
||||||
|
-- TODO: doesn't work for cross
|
||||||
|
addToolsToDir tmp
|
||||||
|
| or (fmap (maybe False isToolTag) [runGHCVer, runCabalVer, runHLSVer, runStackVer]) || runInstTool' = runRUN runAppState $ do
|
||||||
|
forM_ runGHCVer $ \ver -> do
|
||||||
|
(v, _) <- liftE $ fromVersion (Just ver) GHC
|
||||||
|
installTool GHC v
|
||||||
|
setTool GHC v tmp
|
||||||
|
forM_ runCabalVer $ \ver -> do
|
||||||
|
(v, _) <- liftE $ fromVersion (Just ver) Cabal
|
||||||
|
installTool Cabal v
|
||||||
|
setTool Cabal v tmp
|
||||||
|
forM_ runHLSVer $ \ver -> do
|
||||||
|
(v, _) <- liftE $ fromVersion (Just ver) HLS
|
||||||
|
installTool HLS v
|
||||||
|
setTool HLS v tmp
|
||||||
|
forM_ runStackVer $ \ver -> do
|
||||||
|
(v, _) <- liftE $ fromVersion (Just ver) Stack
|
||||||
|
installTool Stack v
|
||||||
|
setTool Stack v tmp
|
||||||
|
| otherwise = runLeanRUN leanAppstate $ do
|
||||||
|
case runGHCVer of
|
||||||
|
Just (ToolVersion v) ->
|
||||||
|
setTool GHC v tmp
|
||||||
|
Nothing -> pure ()
|
||||||
|
_ -> fail "Internal error"
|
||||||
|
case runCabalVer of
|
||||||
|
Just (ToolVersion v) ->
|
||||||
|
setTool Cabal v tmp
|
||||||
|
Nothing -> pure ()
|
||||||
|
_ -> fail "Internal error"
|
||||||
|
case runHLSVer of
|
||||||
|
Just (ToolVersion v) ->
|
||||||
|
setTool HLS v tmp
|
||||||
|
Nothing -> pure ()
|
||||||
|
_ -> fail "Internal error"
|
||||||
|
case runStackVer of
|
||||||
|
Just (ToolVersion v) ->
|
||||||
|
setTool Stack v tmp
|
||||||
|
Nothing -> pure ()
|
||||||
|
_ -> fail "Internal error"
|
||||||
|
|
||||||
|
installTool tool v = do
|
||||||
|
isInstalled <- checkIfToolInstalled' tool v
|
||||||
|
case tool of
|
||||||
|
GHC -> do
|
||||||
|
unless isInstalled $ when (runInstTool' && isNothing (_tvTarget v)) $ void $ liftE $ installGHCBin
|
||||||
|
(_tvVersion v)
|
||||||
|
Nothing
|
||||||
|
False
|
||||||
|
Cabal -> do
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installCabalBin
|
||||||
|
(_tvVersion v)
|
||||||
|
Nothing
|
||||||
|
False
|
||||||
|
Stack -> do
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installStackBin
|
||||||
|
(_tvVersion v)
|
||||||
|
Nothing
|
||||||
|
False
|
||||||
|
HLS -> do
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installHLSBin
|
||||||
|
(_tvVersion v)
|
||||||
|
Nothing
|
||||||
|
False
|
||||||
|
GHCup -> pure ()
|
||||||
|
|
||||||
|
setTool tool v tmp =
|
||||||
|
case tool of
|
||||||
|
GHC -> do
|
||||||
|
void $ liftE $ setGHC v SetGHC_XYZ (Just tmp)
|
||||||
|
void $ liftE $ setGHC v SetGHCOnly (Just tmp)
|
||||||
|
Cabal -> do
|
||||||
|
bin <- liftE $ whereIsTool Cabal v
|
||||||
|
cbin <- liftIO $ canonicalizePath bin
|
||||||
|
lift $ createLink (relativeSymlink tmp cbin) (tmp </> ("cabal" <.> exeExt))
|
||||||
|
Stack -> do
|
||||||
|
bin <- liftE $ whereIsTool Stack v
|
||||||
|
cbin <- liftIO $ canonicalizePath bin
|
||||||
|
lift $ createLink (relativeSymlink tmp cbin) (tmp </> ("stack" <.> exeExt))
|
||||||
|
HLS -> do
|
||||||
|
Dirs {..} <- getDirs
|
||||||
|
let v' = _tvVersion v
|
||||||
|
legacy <- isLegacyHLS v'
|
||||||
|
if legacy
|
||||||
|
then do
|
||||||
|
-- TODO: factor this out
|
||||||
|
(Just hlsWrapper) <- hlsWrapperBinary v'
|
||||||
|
cw <- liftIO $ canonicalizePath (binDir </> hlsWrapper)
|
||||||
|
lift $ createLink (relativeSymlink tmp cw) (tmp </> takeFileName cw)
|
||||||
|
hlsBins <- hlsServerBinaries v' Nothing >>= liftIO . traverse (canonicalizePath . (binDir </>))
|
||||||
|
forM_ hlsBins $ \bin ->
|
||||||
|
lift $ createLink (relativeSymlink tmp bin) (tmp </> takeFileName bin)
|
||||||
|
liftE $ setHLS (_tvVersion v) SetHLSOnly (Just tmp)
|
||||||
|
else do
|
||||||
|
liftE $ setHLS (_tvVersion v) SetHLS_XYZ (Just tmp)
|
||||||
|
liftE $ setHLS (_tvVersion v) SetHLSOnly (Just tmp)
|
||||||
|
GHCup -> pure ()
|
||||||
|
|
||||||
|
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
|
||||||
@@ -271,10 +271,10 @@ set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
|||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setGHC' SetOptions{ sToolVer } =
|
setGHC' SetOptions{ sToolVer } =
|
||||||
case sToolVer of
|
case sToolVer of
|
||||||
(SetToolVersion v) -> runSetGHC runLeanAppState (liftE $ setGHC v SetGHCOnly >> pure v)
|
(SetToolVersion v) -> runSetGHC runLeanAppState (liftE $ setGHC v SetGHCOnly Nothing >> pure v)
|
||||||
_ -> runSetGHC runAppState (do
|
_ -> runSetGHC runAppState (do
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer GHC
|
v <- liftE $ fst <$> fromVersion' sToolVer GHC
|
||||||
liftE $ setGHC v SetGHCOnly
|
liftE $ setGHC v SetGHCOnly Nothing
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight GHCTargetVersion{..} -> do
|
VRight GHCTargetVersion{..} -> do
|
||||||
@@ -311,10 +311,10 @@ set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
|||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setHLS' SetOptions{ sToolVer } =
|
setHLS' SetOptions{ sToolVer } =
|
||||||
case sToolVer of
|
case sToolVer of
|
||||||
(SetToolVersion v) -> runSetHLS runLeanAppState (liftE $ setHLS (_tvVersion v) >> pure v)
|
(SetToolVersion v) -> runSetHLS runLeanAppState (liftE $ setHLS (_tvVersion v) SetHLSOnly Nothing >> pure v)
|
||||||
_ -> runSetHLS runAppState (do
|
_ -> runSetHLS runAppState (do
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer HLS
|
v <- liftE $ fst <$> fromVersion' sToolVer HLS
|
||||||
liftE $ setHLS (_tvVersion v)
|
liftE $ setHLS (_tvVersion v) SetHLSOnly Nothing
|
||||||
pure v
|
pure v
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
|
|||||||
@@ -113,17 +113,17 @@ runUpgrade runAppState =
|
|||||||
|
|
||||||
|
|
||||||
upgrade :: ( Monad m
|
upgrade :: ( Monad m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> UpgradeOpts
|
=> UpgradeOpts
|
||||||
-> Bool
|
-> Bool
|
||||||
|
-> Dirs
|
||||||
-> (forall a. ReaderT AppState m (VEither UpgradeEffects a) -> m (VEither UpgradeEffects a))
|
-> (forall a. ReaderT AppState m (VEither UpgradeEffects a) -> m (VEither UpgradeEffects a))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
upgrade uOpts force' runAppState runLogger = do
|
upgrade uOpts force' Dirs{..} runAppState runLogger = do
|
||||||
VRight Dirs{ .. } <- runAppState (VRight <$> getDirs)
|
|
||||||
target <- case uOpts of
|
target <- case uOpts of
|
||||||
UpgradeInplace -> Just <$> liftIO getExecutablePath
|
UpgradeInplace -> Just <$> liftIO getExecutablePath
|
||||||
(UpgradeAt p) -> pure $ Just p
|
(UpgradeAt p) -> pure $ Just p
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import GHCup.Download
|
|||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Platform
|
import GHCup.Platform
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
|
import GHCup.Types.Optics hiding ( toolRequirements )
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Utils.Prelude
|
||||||
@@ -39,6 +40,7 @@ import Data.Aeson.Encode.Pretty ( encodePretty )
|
|||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
import Data.Versions
|
||||||
import GHC.IO.Encoding
|
import GHC.IO.Encoding
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
@@ -55,6 +57,7 @@ import qualified Data.ByteString as B
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.IO as T
|
import qualified Data.Text.IO as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
|
import qualified GHCup.Types as Types
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -72,15 +75,16 @@ toSettings options = do
|
|||||||
where
|
where
|
||||||
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
||||||
mergeConf Options{..} UserSettings{..} noColor =
|
mergeConf Options{..} UserSettings{..} noColor =
|
||||||
let cache = fromMaybe (fromMaybe False uCache) optCache
|
let cache = fromMaybe (fromMaybe (Types.cache defaultSettings) uCache) optCache
|
||||||
noVerify = fromMaybe (fromMaybe False uNoVerify) optNoVerify
|
metaCache = fromMaybe (fromMaybe (Types.metaCache defaultSettings) uMetaCache) optMetaCache
|
||||||
verbose = fromMaybe (fromMaybe False uVerbose) optVerbose
|
noVerify = fromMaybe (fromMaybe (Types.noVerify defaultSettings) uNoVerify) optNoVerify
|
||||||
keepDirs = fromMaybe (fromMaybe Errors uKeepDirs) optKeepDirs
|
verbose = fromMaybe (fromMaybe (Types.verbose defaultSettings) uVerbose) optVerbose
|
||||||
|
keepDirs = fromMaybe (fromMaybe (Types.keepDirs defaultSettings) uKeepDirs) optKeepDirs
|
||||||
downloader = fromMaybe (fromMaybe defaultDownloader uDownloader) optsDownloader
|
downloader = fromMaybe (fromMaybe defaultDownloader uDownloader) optsDownloader
|
||||||
keyBindings = maybe defaultKeyBindings mergeKeys uKeyBindings
|
keyBindings = maybe defaultKeyBindings mergeKeys uKeyBindings
|
||||||
urlSource = maybe (fromMaybe GHCupURL uUrlSource) OwnSource optUrlSource
|
urlSource = maybe (fromMaybe (Types.urlSource defaultSettings) uUrlSource) OwnSource optUrlSource
|
||||||
noNetwork = fromMaybe (fromMaybe False uNoNetwork) optNoNetwork
|
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
|
||||||
gpgSetting = fromMaybe (fromMaybe GPGNone uGPGSetting) optGpg
|
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
|
||||||
in (Settings {..}, keyBindings)
|
in (Settings {..}, keyBindings)
|
||||||
#if defined(INTERNAL_DOWNLOADER)
|
#if defined(INTERNAL_DOWNLOADER)
|
||||||
defaultDownloader = Internal
|
defaultDownloader = Internal
|
||||||
@@ -136,7 +140,12 @@ main = do
|
|||||||
<> hidden
|
<> hidden
|
||||||
)
|
)
|
||||||
let listCommands = infoOption
|
let listCommands = infoOption
|
||||||
"install set rm install-cabal list upgrade compile debug-info tool-requirements changelog"
|
("install set rm install-cabal list"
|
||||||
|
#ifndef DISABLE_UPGRADE
|
||||||
|
<> " upgrade"
|
||||||
|
#endif
|
||||||
|
<> " compile debug-info tool-requirements changelog"
|
||||||
|
)
|
||||||
( long "list-commands"
|
( long "list-commands"
|
||||||
<> help "List available commands for shell completion"
|
<> help "List available commands for shell completion"
|
||||||
<> internal
|
<> internal
|
||||||
@@ -189,7 +198,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
||||||
appState = do
|
let appState = do
|
||||||
pfreq <- (
|
pfreq <- (
|
||||||
runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest
|
runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest
|
||||||
) >>= \case
|
) >>= \case
|
||||||
@@ -225,8 +234,32 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
Interactive -> pure ()
|
Interactive -> pure ()
|
||||||
#endif
|
#endif
|
||||||
|
-- check for new tools
|
||||||
_ -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
_ -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
||||||
Nothing -> runReaderT checkForUpdates s'
|
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
||||||
|
newTools <- lift checkForUpdates
|
||||||
|
forM_ newTools $ \newTool@(t, l) -> do
|
||||||
|
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/283
|
||||||
|
alreadyInstalling' <- alreadyInstalling optCommand newTool
|
||||||
|
when (not alreadyInstalling') $
|
||||||
|
case t of
|
||||||
|
#ifdef DISABLE_UPGRADE
|
||||||
|
GHCup -> pure ()
|
||||||
|
#else
|
||||||
|
GHCup -> runLogger $
|
||||||
|
logWarn ("New GHCup version available: "
|
||||||
|
<> prettyVer l
|
||||||
|
<> ". To upgrade, run 'ghcup upgrade'")
|
||||||
|
#endif
|
||||||
|
_ -> runLogger $
|
||||||
|
logWarn ("New "
|
||||||
|
<> T.pack (prettyShow t)
|
||||||
|
<> " version available. "
|
||||||
|
<> "To upgrade, run 'ghcup install "
|
||||||
|
<> T.pack (prettyShow t)
|
||||||
|
<> " "
|
||||||
|
<> prettyVer l
|
||||||
|
<> "'")
|
||||||
Just _ -> pure ()
|
Just _ -> pure ()
|
||||||
|
|
||||||
-- TODO: always run for windows
|
-- TODO: always run for windows
|
||||||
@@ -268,16 +301,19 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
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 runAppState runLogger
|
Compile compileCommand -> compile compileCommand settings dirs runAppState runLogger
|
||||||
Config configCommand -> config configCommand settings 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' -> upgrade uOpts force' runAppState runLogger
|
#ifndef DISABLE_UPGRADE
|
||||||
|
Upgrade uOpts force' -> upgrade uOpts force' dirs runAppState runLogger
|
||||||
|
#endif
|
||||||
ToolRequirements -> toolRequirements runAppState runLogger
|
ToolRequirements -> toolRequirements runAppState runLogger
|
||||||
ChangeLog changelogOpts -> changelog changelogOpts runAppState runLogger
|
ChangeLog changelogOpts -> changelog changelogOpts runAppState runLogger
|
||||||
Nuke -> nuke appState runLogger
|
Nuke -> nuke appState runLogger
|
||||||
Prefetch pfCom -> prefetch pfCom runAppState runLogger
|
Prefetch pfCom -> prefetch pfCom runAppState runLogger
|
||||||
GC gcOpts -> gc gcOpts runAppState runLogger
|
GC gcOpts -> gc gcOpts runAppState runLogger
|
||||||
|
Run runCommand -> run runCommand runAppState leanAppstate runLogger
|
||||||
|
|
||||||
case res of
|
case res of
|
||||||
ExitSuccess -> pure ()
|
ExitSuccess -> pure ()
|
||||||
@@ -285,4 +321,58 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
|
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
|
where
|
||||||
|
alreadyInstalling :: ( HasLog env
|
||||||
|
, MonadFail m
|
||||||
|
, MonadReader env m
|
||||||
|
, HasGHCupInfo env
|
||||||
|
, HasDirs env
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Command
|
||||||
|
-> (Tool, Version)
|
||||||
|
-> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
] m Bool
|
||||||
|
alreadyInstalling (Install (Right InstallOptions{..})) (GHC, ver) = cmp' GHC instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallGHC InstallOptions{..}))) (GHC, ver) = cmp' GHC instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallCabal InstallOptions{..}))) (Cabal, ver) = cmp' Cabal instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallHLS InstallOptions{..}))) (HLS, ver) = cmp' HLS instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallStack InstallOptions{..}))) (Stack, ver) = cmp' Stack instVer ver
|
||||||
|
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ ovewrwiteVer = Just over }))
|
||||||
|
(GHC, ver) = cmp' GHC (Just $ ToolVersion (mkTVer over)) ver
|
||||||
|
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ targetGhc = Left tver }))
|
||||||
|
(GHC, ver) = cmp' GHC (Just $ ToolVersion (mkTVer tver)) ver
|
||||||
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ ovewrwiteVer = Just over }))
|
||||||
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer over)) ver
|
||||||
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ targetHLS = Left tver }))
|
||||||
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer tver)) ver
|
||||||
|
#ifndef DISABLE_UPGRADE
|
||||||
|
alreadyInstalling (Upgrade _ _) (GHCup, _) = pure True
|
||||||
|
#endif
|
||||||
|
alreadyInstalling _ _ = pure False
|
||||||
|
|
||||||
|
cmp' :: ( HasLog env
|
||||||
|
, MonadFail m
|
||||||
|
, MonadReader env m
|
||||||
|
, HasGHCupInfo env
|
||||||
|
, HasDirs env
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Tool
|
||||||
|
-> Maybe ToolVersion
|
||||||
|
-> Version
|
||||||
|
-> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
] m Bool
|
||||||
|
cmp' tool instVer ver = do
|
||||||
|
(v, _) <- liftE $ fromVersion instVer tool
|
||||||
|
pure (v == mkTVer ver)
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ package ghcup
|
|||||||
tests: True
|
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.Cabal ==3.6.2.0,
|
any.Cabal ==3.6.2.0,
|
||||||
any.aeson >= 2.0.1.0
|
any.aeson >= 2.0.1.0
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.HUnit ==1.6.2.0,
|
any.HUnit ==1.6.2.0,
|
||||||
any.HsOpenSSL ==0.11.7.2,
|
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.QuickCheck ==2.14.2,
|
any.QuickCheck ==2.14.2,
|
||||||
QuickCheck -old-random +templatehaskell,
|
QuickCheck -old-random +templatehaskell,
|
||||||
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.0.1.0,
|
any.aeson ==2.0.2.0,
|
||||||
aeson -bytestring-builder -cffi +ordered-keymap,
|
aeson -bytestring-builder -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.6,
|
any.alex ==3.2.7.1,
|
||||||
alex +small_base,
|
any.ansi-terminal ==0.11.1,
|
||||||
any.ansi-terminal ==0.11,
|
|
||||||
ansi-terminal -example,
|
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,
|
||||||
@@ -28,10 +28,10 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.attoparsec ==0.13.2.5,
|
any.attoparsec ==0.13.2.5,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.base ==4.14.3.0,
|
any.base ==4.14.3.0,
|
||||||
any.base-compat ==0.12.0,
|
any.base-compat ==0.12.1,
|
||||||
any.base-compat-batteries ==0.12.0,
|
any.base-compat-batteries ==0.12.1,
|
||||||
any.base-orphans ==0.8.5,
|
any.base-orphans ==0.8.6,
|
||||||
any.base16-bytestring ==1.0.1.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base64-bytestring ==1.1.0.0,
|
any.base64-bytestring ==1.1.0.0,
|
||||||
any.bifunctors ==5.5.11,
|
any.bifunctors ==5.5.11,
|
||||||
bifunctors +semigroups +tagged,
|
bifunctors +semigroups +tagged,
|
||||||
@@ -52,7 +52,7 @@ constraints: any.Cabal ==3.6.2.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.2,
|
any.clock ==0.8.3,
|
||||||
clock -llvm,
|
clock -llvm,
|
||||||
any.colour ==2.3.6,
|
any.colour ==2.3.6,
|
||||||
any.comonad ==5.0.8,
|
any.comonad ==5.0.8,
|
||||||
@@ -66,7 +66,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
contravariant +semigroups +statevar +tagged,
|
contravariant +semigroups +statevar +tagged,
|
||||||
any.cpphs ==1.20.9.1,
|
any.cpphs ==1.20.9.1,
|
||||||
cpphs -old-locale,
|
cpphs -old-locale,
|
||||||
any.cryptohash-sha1 ==0.11.100.1,
|
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-clist ==0.1.2.3,
|
any.data-clist ==0.1.2.3,
|
||||||
@@ -87,13 +87,13 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.ghc-byteorder ==4.11.0.0.10,
|
any.ghc-byteorder ==4.11.0.0.10,
|
||||||
any.ghc-prim ==0.6.1,
|
any.ghc-prim ==0.6.1,
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.3.4.1,
|
any.hashable ==1.4.0.2,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable +containers +integer-gmp -random-initial-seed,
|
||||||
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.1,
|
any.haskus-utils-variant ==3.2.1,
|
||||||
any.heaps ==0.4,
|
any.heaps ==0.4,
|
||||||
any.hsc2hs ==0.68.7,
|
any.hsc2hs ==0.68.8,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.7.10,
|
any.hspec ==2.7.10,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.7.10,
|
||||||
@@ -103,8 +103,8 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.http-io-streams ==0.1.6.0,
|
any.http-io-streams ==0.1.6.0,
|
||||||
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.1,
|
any.indexed-traversable ==0.1.2,
|
||||||
any.indexed-traversable-instances ==0.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,
|
||||||
@@ -112,9 +112,9 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
io-streams +network -nointeractivetests +zlib,
|
io-streams +network -nointeractivetests +zlib,
|
||||||
any.language-c ==0.9.0.1,
|
any.language-c ==0.9.0.1,
|
||||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||||
any.libarchive ==3.0.3.1,
|
any.libarchive ==3.0.3.2,
|
||||||
libarchive -cross -low-memory -system-libarchive,
|
libarchive -cross -low-memory +no-exe -system-libarchive,
|
||||||
any.libyaml-streamly ==0.2.0,
|
any.libyaml-streamly ==0.2.1,
|
||||||
libyaml-streamly -no-unicode -system-libyaml,
|
libyaml-streamly -no-unicode -system-libyaml,
|
||||||
any.lockfree-queue ==0.2.3.1,
|
any.lockfree-queue ==0.2.3.1,
|
||||||
any.lzma-static ==5.2.5.4,
|
any.lzma-static ==5.2.5.4,
|
||||||
@@ -125,7 +125,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.microlens-th ==0.4.3.10,
|
any.microlens-th ==0.4.3.10,
|
||||||
any.monad-control ==1.0.3.1,
|
any.monad-control ==1.0.3.1,
|
||||||
any.mtl ==2.2.2,
|
any.mtl ==2.2.2,
|
||||||
any.network ==3.1.2.5,
|
any.network ==3.1.2.7,
|
||||||
network -devel,
|
network -devel,
|
||||||
any.network-uri ==2.6.4.1,
|
any.network-uri ==2.6.4.1,
|
||||||
any.openssl-streams ==1.2.3.0,
|
any.openssl-streams ==1.2.3.0,
|
||||||
@@ -145,15 +145,15 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.polyparse ==1.13,
|
any.polyparse ==1.13,
|
||||||
any.pretty ==1.1.3.6,
|
any.pretty ==1.1.3.6,
|
||||||
any.pretty-terminal ==0.1.0.0,
|
any.pretty-terminal ==0.1.0.0,
|
||||||
any.primitive ==0.7.2.0,
|
any.primitive ==0.7.3.0,
|
||||||
any.process ==1.6.13.2,
|
any.process ==1.6.13.2,
|
||||||
any.profunctors ==5.6.2,
|
any.profunctors ==5.6.2,
|
||||||
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,
|
any.random ==1.2.1,
|
||||||
any.recursion-schemes ==5.2.2.1,
|
any.recursion-schemes ==5.2.2.2,
|
||||||
recursion-schemes +template-haskell,
|
recursion-schemes +template-haskell,
|
||||||
any.regex-base ==0.94.0.1,
|
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.4.3,
|
any.resourcet ==1.2.4.3,
|
||||||
@@ -164,17 +164,17 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.safe-exceptions ==0.1.7.2,
|
any.safe-exceptions ==0.1.7.2,
|
||||||
any.scientific ==0.3.7.0,
|
any.scientific ==0.3.7.0,
|
||||||
scientific -bytestring-builder -integer-simple,
|
scientific -bytestring-builder -integer-simple,
|
||||||
any.semialign ==1.2,
|
any.semialign ==1.2.0.1,
|
||||||
semialign +semigroupoids,
|
semialign +semigroupoids,
|
||||||
any.semigroupoids ==5.3.6,
|
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.4,
|
any.split ==0.2.3.4,
|
||||||
any.splitmix ==0.1.0.3,
|
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.0,
|
any.streamly ==0.8.1.1,
|
||||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -no-fusion +opt -streamk -use-c-malloc,
|
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -use-c-malloc,
|
||||||
any.strict ==0.4.0.1,
|
any.strict ==0.4.0.1,
|
||||||
strict +assoc,
|
strict +assoc,
|
||||||
any.strict-base ==0.4.0.0,
|
any.strict-base ==0.4.0.0,
|
||||||
@@ -186,12 +186,14 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.terminal-size ==0.3.2.1,
|
any.terminal-size ==0.3.2.1,
|
||||||
any.terminfo ==0.4.1.4,
|
any.terminfo ==0.4.1.4,
|
||||||
any.text ==1.2.4.1,
|
any.text ==1.2.4.1,
|
||||||
|
any.text-short ==0.1.5,
|
||||||
|
text-short -asserts,
|
||||||
any.text-zipper ==0.11,
|
any.text-zipper ==0.11,
|
||||||
any.tf-random ==0.5,
|
any.tf-random ==0.5,
|
||||||
any.th-abstraction ==0.4.3.0,
|
any.th-abstraction ==0.4.3.0,
|
||||||
any.th-compat ==0.1.3,
|
any.th-compat ==0.1.3,
|
||||||
any.th-lift ==0.8.2,
|
any.th-lift ==0.8.2,
|
||||||
any.th-lift-instances ==0.1.18,
|
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,
|
||||||
@@ -200,14 +202,16 @@ constraints: any.Cabal ==3.6.2.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,
|
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.0,
|
||||||
|
unicode-data -ucd2haskell,
|
||||||
any.unix ==2.7.2.2,
|
any.unix ==2.7.2.2,
|
||||||
any.unix-bytestring ==0.3.7.5,
|
any.unix-bytestring ==0.3.7.6,
|
||||||
any.unix-compat ==0.5.3,
|
any.unix-compat ==0.5.4,
|
||||||
unix-compat -old-time,
|
unix-compat -old-time,
|
||||||
any.unliftio-core ==0.2.0.1,
|
any.unliftio-core ==0.2.0.1,
|
||||||
any.unordered-containers ==0.2.14.0,
|
any.unordered-containers ==0.2.16.0,
|
||||||
unordered-containers -debug,
|
unordered-containers -debug,
|
||||||
any.uri-bytestring ==0.3.3.1,
|
any.uri-bytestring ==0.3.3.1,
|
||||||
uri-bytestring -lib-werror,
|
uri-bytestring -lib-werror,
|
||||||
@@ -215,15 +219,15 @@ constraints: any.Cabal ==3.6.2.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.versions ==5.0.0,
|
any.versions ==5.0.2,
|
||||||
any.vty ==5.33,
|
any.vty ==5.33,
|
||||||
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,
|
||||||
any.xor ==0.0.1.0,
|
any.xor ==0.0.1.0,
|
||||||
any.yaml-streamly ==0.12.0,
|
any.yaml-streamly ==0.12.1,
|
||||||
yaml-streamly +no-examples +no-exe,
|
yaml-streamly +no-examples +no-exe,
|
||||||
any.zlib ==0.6.2.3,
|
any.zlib ==0.6.2.3,
|
||||||
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 2021-10-24T10:21:56Z
|
index-state: hackage.haskell.org 2022-02-15T12:16:42Z
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ package ghcup
|
|||||||
tests: True
|
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.Cabal ==3.6.2.0,
|
any.Cabal ==3.6.2.0,
|
||||||
any.aeson >= 2.0.1.0
|
any.aeson >= 2.0.1.0
|
||||||
@@ -26,4 +31,4 @@ package aeson
|
|||||||
|
|
||||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||||
|
|
||||||
with-compiler: ghc-9.0.1
|
with-compiler: ghc-9.0.2
|
||||||
@@ -4,18 +4,18 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.HUnit ==1.6.2.0,
|
any.HUnit ==1.6.2.0,
|
||||||
any.HsOpenSSL ==0.11.7.2,
|
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.QuickCheck ==2.14.2,
|
any.QuickCheck ==2.14.2,
|
||||||
QuickCheck -old-random +templatehaskell,
|
QuickCheck -old-random +templatehaskell,
|
||||||
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.0.1.0,
|
any.aeson ==2.0.2.0,
|
||||||
aeson -bytestring-builder -cffi +ordered-keymap,
|
aeson -bytestring-builder -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.6,
|
any.alex ==3.2.7.1,
|
||||||
alex +small_base,
|
any.ansi-terminal ==0.11.1,
|
||||||
any.ansi-terminal ==0.11,
|
|
||||||
ansi-terminal -example,
|
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,
|
||||||
@@ -27,11 +27,11 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
atomic-primops -debug,
|
atomic-primops -debug,
|
||||||
any.attoparsec ==0.13.2.5,
|
any.attoparsec ==0.13.2.5,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.base ==4.15.0.0,
|
any.base ==4.15.1.0,
|
||||||
any.base-compat ==0.12.0,
|
any.base-compat ==0.12.1,
|
||||||
any.base-compat-batteries ==0.12.0,
|
any.base-compat-batteries ==0.12.1,
|
||||||
any.base-orphans ==0.8.5,
|
any.base-orphans ==0.8.6,
|
||||||
any.base16-bytestring ==1.0.1.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base64-bytestring ==1.1.0.0,
|
any.base64-bytestring ==1.1.0.0,
|
||||||
any.bifunctors ==5.5.11,
|
any.bifunctors ==5.5.11,
|
||||||
bifunctors +semigroups +tagged,
|
bifunctors +semigroups +tagged,
|
||||||
@@ -52,7 +52,7 @@ constraints: any.Cabal ==3.6.2.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.2,
|
any.clock ==0.8.3,
|
||||||
clock -llvm,
|
clock -llvm,
|
||||||
any.colour ==2.3.6,
|
any.colour ==2.3.6,
|
||||||
any.comonad ==5.0.8,
|
any.comonad ==5.0.8,
|
||||||
@@ -66,13 +66,13 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
contravariant +semigroups +statevar +tagged,
|
contravariant +semigroups +statevar +tagged,
|
||||||
any.cpphs ==1.20.9.1,
|
any.cpphs ==1.20.9.1,
|
||||||
cpphs -old-locale,
|
cpphs -old-locale,
|
||||||
any.cryptohash-sha1 ==0.11.100.1,
|
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-clist ==0.1.2.3,
|
any.data-clist ==0.1.2.3,
|
||||||
any.data-fix ==0.3.2,
|
any.data-fix ==0.3.2,
|
||||||
any.deepseq ==1.4.5.0,
|
any.deepseq ==1.4.5.0,
|
||||||
any.directory ==1.3.6.1,
|
any.directory ==1.3.6.2,
|
||||||
any.disk-free-space ==0.1.0.1,
|
any.disk-free-space ==0.1.0.1,
|
||||||
any.distributive ==0.6.2.1,
|
any.distributive ==0.6.2.1,
|
||||||
distributive +semigroups +tagged,
|
distributive +semigroups +tagged,
|
||||||
@@ -83,18 +83,18 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.free ==5.1.7,
|
any.free ==5.1.7,
|
||||||
any.fusion-plugin-types ==0.1.0,
|
any.fusion-plugin-types ==0.1.0,
|
||||||
any.generic-arbitrary ==0.1.0,
|
any.generic-arbitrary ==0.1.0,
|
||||||
any.ghc-bignum ==1.0,
|
any.ghc-bignum ==1.1,
|
||||||
any.ghc-boot-th ==9.0.1,
|
any.ghc-boot-th ==9.0.2,
|
||||||
any.ghc-byteorder ==4.11.0.0.10,
|
any.ghc-byteorder ==4.11.0.0.10,
|
||||||
any.ghc-prim ==0.7.0,
|
any.ghc-prim ==0.7.0,
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.3.4.1,
|
any.hashable ==1.4.0.2,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable +containers +integer-gmp -random-initial-seed,
|
||||||
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.1,
|
any.haskus-utils-variant ==3.2.1,
|
||||||
any.heaps ==0.4,
|
any.heaps ==0.4,
|
||||||
any.hsc2hs ==0.68.7,
|
any.hsc2hs ==0.68.8,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.7.10,
|
any.hspec ==2.7.10,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.7.10,
|
||||||
@@ -104,17 +104,17 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.http-io-streams ==0.1.6.0,
|
any.http-io-streams ==0.1.6.0,
|
||||||
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.1,
|
any.indexed-traversable ==0.1.2,
|
||||||
any.indexed-traversable-instances ==0.1,
|
any.indexed-traversable-instances ==0.1.1,
|
||||||
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.1,
|
any.io-streams ==1.5.2.1,
|
||||||
io-streams +network -nointeractivetests +zlib,
|
io-streams +network -nointeractivetests +zlib,
|
||||||
any.language-c ==0.9.0.1,
|
any.language-c ==0.9.0.1,
|
||||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||||
any.libarchive ==3.0.3.1,
|
any.libarchive ==3.0.3.2,
|
||||||
libarchive -cross -low-memory -system-libarchive,
|
libarchive -cross -low-memory +no-exe -system-libarchive,
|
||||||
any.libyaml-streamly ==0.2.0,
|
any.libyaml-streamly ==0.2.1,
|
||||||
libyaml-streamly -no-unicode -system-libyaml,
|
libyaml-streamly -no-unicode -system-libyaml,
|
||||||
any.lockfree-queue ==0.2.3.1,
|
any.lockfree-queue ==0.2.3.1,
|
||||||
any.lzma-static ==5.2.5.4,
|
any.lzma-static ==5.2.5.4,
|
||||||
@@ -125,7 +125,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.microlens-th ==0.4.3.10,
|
any.microlens-th ==0.4.3.10,
|
||||||
any.monad-control ==1.0.3.1,
|
any.monad-control ==1.0.3.1,
|
||||||
any.mtl ==2.2.2,
|
any.mtl ==2.2.2,
|
||||||
any.network ==3.1.2.5,
|
any.network ==3.1.2.7,
|
||||||
network -devel,
|
network -devel,
|
||||||
any.network-uri ==2.6.4.1,
|
any.network-uri ==2.6.4.1,
|
||||||
any.openssl-streams ==1.2.3.0,
|
any.openssl-streams ==1.2.3.0,
|
||||||
@@ -145,36 +145,36 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.polyparse ==1.13,
|
any.polyparse ==1.13,
|
||||||
any.pretty ==1.1.3.6,
|
any.pretty ==1.1.3.6,
|
||||||
any.pretty-terminal ==0.1.0.0,
|
any.pretty-terminal ==0.1.0.0,
|
||||||
any.primitive ==0.7.2.0,
|
any.primitive ==0.7.3.0,
|
||||||
any.process ==1.6.11.0,
|
any.process ==1.6.13.2,
|
||||||
any.profunctors ==5.6.2,
|
any.profunctors ==5.6.2,
|
||||||
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,
|
any.random ==1.2.1,
|
||||||
any.recursion-schemes ==5.2.2.1,
|
any.recursion-schemes ==5.2.2.2,
|
||||||
recursion-schemes +template-haskell,
|
recursion-schemes +template-haskell,
|
||||||
any.regex-base ==0.94.0.1,
|
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.4.3,
|
any.resourcet ==1.2.4.3,
|
||||||
any.retry ==0.8.1.2,
|
any.retry ==0.8.1.2,
|
||||||
retry -lib-werror,
|
retry -lib-werror,
|
||||||
any.rts ==1.0,
|
any.rts ==1.0.2,
|
||||||
any.safe ==0.3.19,
|
any.safe ==0.3.19,
|
||||||
any.safe-exceptions ==0.1.7.2,
|
any.safe-exceptions ==0.1.7.2,
|
||||||
any.scientific ==0.3.7.0,
|
any.scientific ==0.3.7.0,
|
||||||
scientific -bytestring-builder -integer-simple,
|
scientific -bytestring-builder -integer-simple,
|
||||||
any.semialign ==1.2,
|
any.semialign ==1.2.0.1,
|
||||||
semialign +semigroupoids,
|
semialign +semigroupoids,
|
||||||
any.semigroupoids ==5.3.6,
|
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.4,
|
any.split ==0.2.3.4,
|
||||||
any.splitmix ==0.1.0.3,
|
any.splitmix ==0.1.0.4,
|
||||||
splitmix -optimised-mixer,
|
splitmix -optimised-mixer,
|
||||||
any.stm ==2.5.0.0,
|
any.stm ==2.5.0.0,
|
||||||
any.streamly ==0.8.0,
|
any.streamly ==0.8.1.1,
|
||||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -no-fusion +opt -streamk -use-c-malloc,
|
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -use-c-malloc,
|
||||||
any.strict ==0.4.0.1,
|
any.strict ==0.4.0.1,
|
||||||
strict +assoc,
|
strict +assoc,
|
||||||
any.strict-base ==0.4.0.0,
|
any.strict-base ==0.4.0.0,
|
||||||
@@ -184,14 +184,16 @@ constraints: any.Cabal ==3.6.2.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.2.1,
|
any.terminal-size ==0.3.2.1,
|
||||||
any.terminfo ==0.4.1.4,
|
any.terminfo ==0.4.1.5,
|
||||||
any.text ==1.2.4.1,
|
any.text ==1.2.5.0,
|
||||||
|
any.text-short ==0.1.5,
|
||||||
|
text-short -asserts,
|
||||||
any.text-zipper ==0.11,
|
any.text-zipper ==0.11,
|
||||||
any.tf-random ==0.5,
|
any.tf-random ==0.5,
|
||||||
any.th-abstraction ==0.4.3.0,
|
any.th-abstraction ==0.4.3.0,
|
||||||
any.th-compat ==0.1.3,
|
any.th-compat ==0.1.3,
|
||||||
any.th-lift ==0.8.2,
|
any.th-lift ==0.8.2,
|
||||||
any.th-lift-instances ==0.1.18,
|
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,
|
||||||
@@ -200,14 +202,16 @@ constraints: any.Cabal ==3.6.2.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,
|
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.0,
|
||||||
|
unicode-data -ucd2haskell,
|
||||||
any.unix ==2.7.2.2,
|
any.unix ==2.7.2.2,
|
||||||
any.unix-bytestring ==0.3.7.5,
|
any.unix-bytestring ==0.3.7.6,
|
||||||
any.unix-compat ==0.5.3,
|
any.unix-compat ==0.5.4,
|
||||||
unix-compat -old-time,
|
unix-compat -old-time,
|
||||||
any.unliftio-core ==0.2.0.1,
|
any.unliftio-core ==0.2.0.1,
|
||||||
any.unordered-containers ==0.2.14.0,
|
any.unordered-containers ==0.2.16.0,
|
||||||
unordered-containers -debug,
|
unordered-containers -debug,
|
||||||
any.uri-bytestring ==0.3.3.1,
|
any.uri-bytestring ==0.3.3.1,
|
||||||
uri-bytestring -lib-werror,
|
uri-bytestring -lib-werror,
|
||||||
@@ -215,15 +219,15 @@ constraints: any.Cabal ==3.6.2.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.versions ==5.0.0,
|
any.versions ==5.0.2,
|
||||||
any.vty ==5.33,
|
any.vty ==5.33,
|
||||||
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,
|
||||||
any.xor ==0.0.1.0,
|
any.xor ==0.0.1.0,
|
||||||
any.yaml-streamly ==0.12.0,
|
any.yaml-streamly ==0.12.1,
|
||||||
yaml-streamly +no-examples +no-exe,
|
yaml-streamly +no-examples +no-exe,
|
||||||
any.zlib ==0.6.2.3,
|
any.zlib ==0.6.2.3,
|
||||||
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 2021-10-24T10:21:56Z
|
index-state: hackage.haskell.org 2022-02-15T12:16:42Z
|
||||||
@@ -8,6 +8,11 @@ package ghcup
|
|||||||
tests: True
|
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.Cabal ==3.6.2.0,
|
any.Cabal ==3.6.2.0,
|
||||||
any.aeson >= 2.0.1.0
|
any.aeson >= 2.0.1.0
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ key-bindings:
|
|||||||
show-all-tools:
|
show-all-tools:
|
||||||
KChar: 't'
|
KChar: 't'
|
||||||
|
|
||||||
|
# The caching for the metadata files containing download info, depending on last access time
|
||||||
|
# of the file. These usually are in '~/.ghcup/cache/ghcup-<ver>.yaml'.
|
||||||
|
meta-cache: 300 # in seconds
|
||||||
|
|
||||||
# Where to get GHC/cabal/hls download info/versions from. For more detailed explanation
|
# Where to get GHC/cabal/hls download info/versions from. For more detailed explanation
|
||||||
# check the 'URLSource' type in the code.
|
# check the 'URLSource' type in the code.
|
||||||
url-source:
|
url-source:
|
||||||
|
|||||||
1
data/metadata
Submodule
1
data/metadata
Submodule
Submodule data/metadata added at 80b61ee4b7
13
docs/dev.md
13
docs/dev.md
@@ -12,8 +12,7 @@ organised tree-ish in `GHCup.Utils` and `GHCup.Utils.*`.
|
|||||||
Anything dealing with ghcup specific directories is in
|
Anything dealing with ghcup specific directories is in
|
||||||
`GHCup.Utils.Dirs`.
|
`GHCup.Utils.Dirs`.
|
||||||
|
|
||||||
Download information on where to fetch bindists from is in the appropriate
|
Download information on where to fetch bindists from is in the [ghcup-metadata](https://github.com/haskell/ghcup-metadata) repository.
|
||||||
yaml files: `data/metadata/ghcup-<yaml-ver>.yaml`.
|
|
||||||
|
|
||||||
## Design decisions
|
## Design decisions
|
||||||
|
|
||||||
@@ -89,7 +88,7 @@ Every subcommand now lives in its own module under [GHCup.OptParse.MyCommand](ht
|
|||||||
|
|
||||||
# Releasing
|
# Releasing
|
||||||
|
|
||||||
1. Update version in `ghcup.cabal` and `boostrap-haskell` (`ghver` variable at the top of the script)
|
1. Update version in `ghcup.cabal`
|
||||||
|
|
||||||
2. Update `GHCup.Version` module. `ghcupURL` must only be updated if we change the `GHCupInfo` type or the YAML representation of it. The version of the YAML represents the change increments. `ghcUpVer` is the current application version, read from `ghcup.cabal`.
|
2. Update `GHCup.Version` module. `ghcupURL` must only be updated if we change the `GHCupInfo` type or the YAML representation of it. The version of the YAML represents the change increments. `ghcUpVer` is the current application version, read from `ghcup.cabal`.
|
||||||
|
|
||||||
@@ -103,11 +102,13 @@ Every subcommand now lives in its own module under [GHCup.OptParse.MyCommand](ht
|
|||||||
|
|
||||||
7. Upload the final `ghcup-<ver>.yaml` (and a detached GPG sig of it) to `webhost.haskell.org/ghcup/data/` (for yaml versions <= 0.0.6) as well as [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata) (for all versions).
|
7. Upload the final `ghcup-<ver>.yaml` (and a detached GPG sig of it) to `webhost.haskell.org/ghcup/data/` (for yaml versions <= 0.0.6) as well as [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata) (for all versions).
|
||||||
|
|
||||||
8. Upload `bootstrap-haskell` and `bootstrap-haskell.ps1` to `webhost.haskell.org/ghcup/sh/`
|
8. Update version in `scripts/bootstrap/bootstrap-haskell` (`ghver` variable at the top of the script)
|
||||||
|
|
||||||
9. Update the top-level ghcup symlinks at `downloads.haskell.org/~ghcup`
|
9. Upload `scripts/bootstrap/bootstrap-haskell` and `scripts/bootstrap/bootstrap-haskell.ps1` to `webhost.haskell.org/ghcup/sh/`
|
||||||
|
|
||||||
10. Post on reddit/discourse/etc. and collect rewards
|
10. Update the top-level ghcup symlinks at `downloads.haskell.org/~ghcup` (see `scripts/update-sftp.sh`)
|
||||||
|
|
||||||
|
11. Post on reddit/discourse/etc. and collect rewards
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
|
|||||||
117
docs/guide.md
117
docs/guide.md
@@ -32,6 +32,17 @@ ghcup install cabal
|
|||||||
ghcup upgrade
|
ghcup upgrade
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Tags and shortcuts
|
||||||
|
|
||||||
|
GHCup has a number of tags and version shortcuts, that can be used as arguments to **install**/**set** etc.
|
||||||
|
All of the following are valid arguments to `ghcup install ghc`:
|
||||||
|
|
||||||
|
* `latest`, `recommended`
|
||||||
|
* `base-4.15.1.0`
|
||||||
|
* `9.0.2`, `9.0`, `9`
|
||||||
|
|
||||||
|
If the argument is omitted, the default is `recommended`.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
A configuration file can be put in `~/.ghcup/config.yaml`. The default config file
|
A configuration file can be put in `~/.ghcup/config.yaml`. The default config file
|
||||||
@@ -53,6 +64,25 @@ as e.g. `/etc/bash_completion.d/ghcup` (depending on distro)
|
|||||||
and make sure your bashrc sources the startup script
|
and make sure your bashrc sources the startup script
|
||||||
(`/usr/share/bash-completion/bash_completion` on some distros).
|
(`/usr/share/bash-completion/bash_completion` on some distros).
|
||||||
|
|
||||||
|
## Caching
|
||||||
|
|
||||||
|
GHCup has a few caching mechanisms to avoid redownloads. All cached files end up in `~/.ghcup/cache` by default.
|
||||||
|
|
||||||
|
### Downloads cache
|
||||||
|
|
||||||
|
Downloaded tarballs (such as GHC, cabal, etc.) are not cached by default unless you pass `ghcup --cache` or set caching
|
||||||
|
in your [config](#configuration) via `ghcup config set cache true`.
|
||||||
|
|
||||||
|
### Metadata cache
|
||||||
|
|
||||||
|
The metadata files (also see [github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata))
|
||||||
|
have a 5 minutes cache per default depending on the last access time of the file. That means if you run
|
||||||
|
`ghcup list` 10 times in a row, only the first time will trigger a download attempt.
|
||||||
|
|
||||||
|
### Clearing the cache
|
||||||
|
|
||||||
|
If you experience problems, consider clearing the cache via `ghcup gc --cache`.
|
||||||
|
|
||||||
## Compiling GHC from source
|
## Compiling GHC from source
|
||||||
|
|
||||||
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
|
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
|
||||||
@@ -119,6 +149,31 @@ and produce the binaries `ghc-8.10.2-eff` and `ghc-head` respectively.
|
|||||||
GHCup always needs to know which version the bindist corresponds to (this is not automatically
|
GHCup always needs to know which version the bindist corresponds to (this is not automatically
|
||||||
detected).
|
detected).
|
||||||
|
|
||||||
|
## Mirrors
|
||||||
|
|
||||||
|
GHCup allows to use custom mirrors/download-info hosted by yourself or 3rd parties.
|
||||||
|
|
||||||
|
To use a mirror, set the following option in `~/.ghcup/config.yaml`:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
url-source:
|
||||||
|
# Accepts file/http/https scheme
|
||||||
|
OwnSource: "https://some-url/ghcup-0.0.6.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
See [config.yaml](https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/data/config.yaml)
|
||||||
|
for more options.
|
||||||
|
|
||||||
|
Alternatively you can do it via a cli switch:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup --url-source=https://some-url/ghcup-0.0.6.yaml list
|
||||||
|
```
|
||||||
|
|
||||||
|
### Known mirrors
|
||||||
|
|
||||||
|
1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||||
|
|
||||||
## Isolated installs
|
## Isolated installs
|
||||||
|
|
||||||
Ghcup also enables you to install a tool (GHC, Cabal, HLS, Stack) at an isolated location of your choosing.
|
Ghcup also enables you to install a tool (GHC, Cabal, HLS, Stack) at an isolated location of your choosing.
|
||||||
@@ -169,66 +224,10 @@ For the full list of env variables and parameters to tweak the script behavior,
|
|||||||
* [bootstrap-haskell for linux/darwin/freebsd](https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell#L7)
|
* [bootstrap-haskell for linux/darwin/freebsd](https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell#L7)
|
||||||
* [bootstrap-haskell.ps1 for windows](https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell.ps1#L17)
|
* [bootstrap-haskell.ps1 for windows](https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell.ps1#L17)
|
||||||
|
|
||||||
### Example github workflow
|
### github workflows
|
||||||
|
|
||||||
On github workflows you can use [https://github.com/haskell/actions/](https://github.com/haskell/actions/)
|
On github workflows you can use [https://github.com/haskell/actions/](https://github.com/haskell/actions/).
|
||||||
|
GHCup itself is also pre-installed on all platforms, but may use non-standard install locations.
|
||||||
If you want to install ghcup manually though, here's an example config:
|
|
||||||
|
|
||||||
```yml
|
|
||||||
name: Haskell CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-cabal:
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
|
||||||
ghc: ['8.10.7', '9.0.1']
|
|
||||||
cabal: ['3.4.0.0']
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- if: matrix.os == 'windows-latest'
|
|
||||||
name: Install ghcup on windows
|
|
||||||
run: Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $false,$true,$true,$false,$false,$false,$false,"C:\"
|
|
||||||
|
|
||||||
- if: matrix.os == 'windows-latest'
|
|
||||||
name: Add ghcup to PATH
|
|
||||||
run: echo "/c/ghcup/bin" >> $GITHUB_PATH
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- if: matrix.os != 'windows-latest'
|
|
||||||
name: Install ghcup on non-windows
|
|
||||||
run: curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
|
|
||||||
|
|
||||||
- name: Install ghc/cabal
|
|
||||||
run: |
|
|
||||||
ghcup install ghc ${{ matrix.ghc }}
|
|
||||||
ghcup install cabal ${{ matrix.cabal }}
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Update cabal index
|
|
||||||
run: cabal update
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cabal build --enable-tests --enable-benchmarks
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: cabal test
|
|
||||||
shell: bash
|
|
||||||
```
|
|
||||||
|
|
||||||
## GPG verification
|
## GPG verification
|
||||||
|
|
||||||
|
|||||||
@@ -24,10 +24,20 @@ Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager
|
|||||||
|
|
||||||
If you want to know what these scripts do, check out the [source code at the repository](https://gitlab.haskell.org/haskell/ghcup-hs/-/tree/master/scripts/bootstrap). Advanced users may want to perform a [manual installation](#manual-install) and GPG verify the binaries.
|
If you want to know what these scripts do, check out the [source code at the repository](https://gitlab.haskell.org/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?
|
||||||
|
|
||||||
|
GHCup has two main channels for every tool: **recommended** and **latest**. By default, it installs *recommended*.
|
||||||
|
|
||||||
|
*latest* follows the latest release of every tool, while *recommended* is at the discretion of the GHCup maintainers and based on community adoption (hackage libraries, tools like HLS, stackage support, etc.) and known bugs.
|
||||||
|
|
||||||
|
Also see [tags and shortcuts](../guide/#tags-and-shortcuts) for more information.
|
||||||
|
|
||||||
## First steps
|
## First steps
|
||||||
|
|
||||||
1. To get started with creating a Haskell project, follow the [Getting Started with Haskell and Cabal](https://cabal.readthedocs.io/en/latest/getting-started.html) guide
|
1. To get started with creating a Haskell project, follow the [Getting Started with Haskell and Cabal](https://cabal.readthedocs.io/en/stable/getting-started.html) guide
|
||||||
2. To properly learn Haskell, run through the [CIS 194 Haskell course](https://www.cis.upenn.edu/~cis194/spring13/) including exercises
|
2. To learn Haskell, try any of those:
|
||||||
|
- A beginner friendly [4-lectures course](https://github.com/haskell-beginners-2022/course-plan) with exercises (by [Kowainik](https://kowainik.github.io/))
|
||||||
|
- An in-depth university [CIS 194 Haskell course](https://www.cis.upenn.edu/~cis194/spring13/) including exercises (by [Brent Yorgey](https://byorgey.wordpress.com/))
|
||||||
3. To learn more about Haskell Toolchain management, check out the [ghcup user guide](./guide.md)
|
3. To learn more about Haskell Toolchain management, check out the [ghcup user guide](./guide.md)
|
||||||
|
|
||||||
## Uninstallation
|
## Uninstallation
|
||||||
@@ -41,9 +51,9 @@ On windows, double-click on the `Uninstall Haskell.ps1` PowerShell script on you
|
|||||||
GHCup supports the following tools, which are also known as the **Haskell Toolchain**:
|
GHCup supports the following tools, which are also known as the **Haskell Toolchain**:
|
||||||
|
|
||||||
1. [GHC](https://www.haskell.org/ghc/)
|
1. [GHC](https://www.haskell.org/ghc/)
|
||||||
2. [cabal-install](https://cabal.readthedocs.io/en/latest/)
|
2. [cabal-install](https://cabal.readthedocs.io/en/stable/)
|
||||||
3. [haskell-language-server](https://haskell-language-server.readthedocs.io/en/latest/)
|
3. [haskell-language-server](https://haskell-language-server.readthedocs.io/en/stable/)
|
||||||
4. [stack](https://docs.haskellstack.org/en/latest/README/)
|
4. [stack](https://docs.haskellstack.org/en/stable/README/)
|
||||||
|
|
||||||
## Supported platforms
|
## Supported platforms
|
||||||
|
|
||||||
@@ -78,14 +88,15 @@ May or may not work, several issues:
|
|||||||
|
|
||||||
Unsupported. GHC may or may not work. Upgrade to WSL2.
|
Unsupported. GHC may or may not work. Upgrade to WSL2.
|
||||||
|
|
||||||
### MacOS <13
|
### MacOS <10.13
|
||||||
|
|
||||||
Not supported. Would require separate binaries, since >=13 binaries are incompatible.
|
Not supported. Would require separate binaries, since >=10.13 binaries are incompatible.
|
||||||
Please upgrade.
|
Please upgrade.
|
||||||
|
|
||||||
### MacOS aarch64
|
### MacOS aarch64
|
||||||
|
|
||||||
HLS bindists are still experimental. Stack is theoretically supported, but has no binaries yet.
|
HLS bindists are still experimental. Stack has only unofficial binaries for this platform.
|
||||||
|
There are various issues with GHC itself.
|
||||||
|
|
||||||
### FreeBSD
|
### FreeBSD
|
||||||
|
|
||||||
@@ -94,7 +105,7 @@ HLS bindists are experimental.
|
|||||||
|
|
||||||
### Linux ARMv7/AARCH64
|
### Linux ARMv7/AARCH64
|
||||||
|
|
||||||
Lower availability of bindists. HLS only has experimental ones. Stack not supported currently.
|
Lower availability of bindists. Stack and HLS binaries are experimental.
|
||||||
|
|
||||||
## Manual install
|
## Manual install
|
||||||
|
|
||||||
|
|||||||
38
ghcup.cabal
38
ghcup.cabal
@@ -1,6 +1,6 @@
|
|||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: ghcup
|
name: ghcup
|
||||||
version: 0.1.17.3
|
version: 0.1.17.5
|
||||||
license: LGPL-3.0-only
|
license: LGPL-3.0-only
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
copyright: Julian Ospald 2020
|
copyright: Julian Ospald 2020
|
||||||
@@ -48,6 +48,13 @@ flag no-exe
|
|||||||
default: False
|
default: False
|
||||||
manual: True
|
manual: True
|
||||||
|
|
||||||
|
flag disable-upgrade
|
||||||
|
description:
|
||||||
|
Build the brick powered tui (ghcup tui). This is disabled on windows.
|
||||||
|
|
||||||
|
default: False
|
||||||
|
manual: True
|
||||||
|
|
||||||
library
|
library
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
GHCup
|
GHCup
|
||||||
@@ -58,6 +65,7 @@ library
|
|||||||
GHCup.Requirements
|
GHCup.Requirements
|
||||||
GHCup.Types
|
GHCup.Types
|
||||||
GHCup.Types.JSON
|
GHCup.Types.JSON
|
||||||
|
GHCup.Types.JSON.Utils
|
||||||
GHCup.Types.Optics
|
GHCup.Types.Optics
|
||||||
GHCup.Utils
|
GHCup.Utils
|
||||||
GHCup.Utils.Dirs
|
GHCup.Utils.Dirs
|
||||||
@@ -96,7 +104,7 @@ library
|
|||||||
build-depends:
|
build-depends:
|
||||||
, aeson >=1.4
|
, aeson >=1.4
|
||||||
, async >=0.8 && <2.3
|
, async >=0.8 && <2.3
|
||||||
, base >=4.13 && <5
|
, base >=4.12 && <5
|
||||||
, base16-bytestring >=0.1.1.6 && <1.1
|
, base16-bytestring >=0.1.1.6 && <1.1
|
||||||
, binary ^>=0.8.6.0
|
, binary ^>=0.8.6.0
|
||||||
, bytestring ^>=0.10
|
, bytestring ^>=0.10
|
||||||
@@ -110,7 +118,7 @@ library
|
|||||||
, disk-free-space ^>=0.1.0.1
|
, disk-free-space ^>=0.1.0.1
|
||||||
, filepath ^>=1.4.2.1
|
, filepath ^>=1.4.2.1
|
||||||
, haskus-utils-types ^>=1.5
|
, haskus-utils-types ^>=1.5
|
||||||
, haskus-utils-variant >=3.0 && <3.2
|
, haskus-utils-variant ^>=3.2.1
|
||||||
, libarchive ^>=3.0.3.0
|
, libarchive ^>=3.0.3.0
|
||||||
, lzma-static ^>=5.2.5.3
|
, lzma-static ^>=5.2.5.3
|
||||||
, megaparsec >=8.0.0 && <9.1
|
, megaparsec >=8.0.0 && <9.1
|
||||||
@@ -166,11 +174,10 @@ library
|
|||||||
GHCup.Utils.File.Posix
|
GHCup.Utils.File.Posix
|
||||||
GHCup.Utils.Posix
|
GHCup.Utils.Posix
|
||||||
GHCup.Utils.Prelude.Posix
|
GHCup.Utils.Prelude.Posix
|
||||||
System.Console.Terminal.Common
|
|
||||||
System.Console.Terminal.Posix
|
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
, bz2 >=0.5.0.5 && <1.1
|
, bz2 >=0.5.0.5 && <1.1
|
||||||
|
, terminal-size ^>=0.3.2.1
|
||||||
, unix ^>=2.7
|
, unix ^>=2.7
|
||||||
, unix-bytestring ^>=0.3.7.3
|
, unix-bytestring ^>=0.3.7.3
|
||||||
|
|
||||||
@@ -193,10 +200,10 @@ executable ghcup
|
|||||||
GHCup.OptParse.Nuke
|
GHCup.OptParse.Nuke
|
||||||
GHCup.OptParse.Prefetch
|
GHCup.OptParse.Prefetch
|
||||||
GHCup.OptParse.Rm
|
GHCup.OptParse.Rm
|
||||||
|
GHCup.OptParse.Run
|
||||||
GHCup.OptParse.Set
|
GHCup.OptParse.Set
|
||||||
GHCup.OptParse.ToolRequirements
|
GHCup.OptParse.ToolRequirements
|
||||||
GHCup.OptParse.UnSet
|
GHCup.OptParse.UnSet
|
||||||
GHCup.OptParse.Upgrade
|
|
||||||
GHCup.OptParse.Whereis
|
GHCup.OptParse.Whereis
|
||||||
|
|
||||||
hs-source-dirs: app/ghcup
|
hs-source-dirs: app/ghcup
|
||||||
@@ -219,14 +226,15 @@ executable ghcup
|
|||||||
, 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.13 && <5
|
, base >=4.12 && <5
|
||||||
, bytestring ^>=0.10
|
, bytestring ^>=0.10
|
||||||
, cabal-plan ^>=0.7.2
|
, cabal-plan ^>=0.7.2
|
||||||
, containers ^>=0.6
|
, containers ^>=0.6
|
||||||
, deepseq ^>=1.4
|
, deepseq ^>=1.4
|
||||||
|
, directory ^>=1.3.6.0
|
||||||
, filepath ^>=1.4.2.1
|
, filepath ^>=1.4.2.1
|
||||||
, ghcup
|
, ghcup
|
||||||
, haskus-utils-variant >=3.0 && <3.2
|
, haskus-utils-variant ^>=3.2.1
|
||||||
, libarchive ^>=3.0.3.0
|
, libarchive ^>=3.0.3.0
|
||||||
, megaparsec >=8.0.0 && <9.1
|
, megaparsec >=8.0.0 && <9.1
|
||||||
, mtl ^>=2.2
|
, mtl ^>=2.2
|
||||||
@@ -236,6 +244,7 @@ executable ghcup
|
|||||||
, resourcet ^>=1.2.2
|
, resourcet ^>=1.2.2
|
||||||
, safe ^>=0.3.18
|
, safe ^>=0.3.18
|
||||||
, safe-exceptions ^>=0.1
|
, safe-exceptions ^>=0.1
|
||||||
|
, temporary ^>=1.3
|
||||||
, template-haskell >=2.7 && <2.18
|
, template-haskell >=2.7 && <2.18
|
||||||
, text ^>=1.2.4.0
|
, text ^>=1.2.4.0
|
||||||
, uri-bytestring ^>=0.3.2.2
|
, uri-bytestring ^>=0.3.2.2
|
||||||
@@ -252,14 +261,25 @@ executable ghcup
|
|||||||
build-depends:
|
build-depends:
|
||||||
, brick ^>=0.64
|
, brick ^>=0.64
|
||||||
, transformers ^>=0.5
|
, transformers ^>=0.5
|
||||||
|
, unix ^>=2.7
|
||||||
, vector ^>=0.12
|
, vector ^>=0.12
|
||||||
, vty >=5.28.2 && <5.34
|
, vty >=5.28.2 && <5.34
|
||||||
|
|
||||||
if os(windows)
|
if os(windows)
|
||||||
cpp-options: -DIS_WINDOWS
|
cpp-options: -DIS_WINDOWS
|
||||||
|
else
|
||||||
|
build-depends:
|
||||||
|
, unix ^>=2.7
|
||||||
|
|
||||||
if flag(no-exe)
|
if flag(no-exe)
|
||||||
buildable: False
|
buildable: False
|
||||||
|
|
||||||
|
if (flag(disable-upgrade))
|
||||||
|
cpp-options: -DDISABLE_UPGRADE
|
||||||
|
else
|
||||||
|
other-modules:
|
||||||
|
GHCup.OptParse.Upgrade
|
||||||
|
|
||||||
test-suite ghcup-test
|
test-suite ghcup-test
|
||||||
type: exitcode-stdio-1.0
|
type: exitcode-stdio-1.0
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
@@ -284,7 +304,7 @@ test-suite ghcup-test
|
|||||||
-fwarn-incomplete-record-updates
|
-fwarn-incomplete-record-updates
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
, base >=4.13 && <5
|
, base >=4.12 && <5
|
||||||
, bytestring ^>=0.10
|
, bytestring ^>=0.10
|
||||||
, containers ^>=0.6
|
, containers ^>=0.6
|
||||||
, generic-arbitrary ^>=0.1.0
|
, generic-arbitrary ^>=0.1.0
|
||||||
|
|||||||
2
hie.yaml
2
hie.yaml
@@ -4,7 +4,5 @@ cradle:
|
|||||||
path: ./lib
|
path: ./lib
|
||||||
- component: "ghcup:exe:ghcup"
|
- component: "ghcup:exe:ghcup"
|
||||||
path: ./app/ghcup
|
path: ./app/ghcup
|
||||||
- component: "ghcup:exe:ghcup-gen"
|
|
||||||
path: "./app/ghcup-gen"
|
|
||||||
- component: "ghcup:test:ghcup-test"
|
- component: "ghcup:test:ghcup-test"
|
||||||
path: ./test
|
path: ./test
|
||||||
|
|||||||
347
lib/GHCup.hs
347
lib/GHCup.hs
@@ -5,8 +5,8 @@
|
|||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
Module : GHCup
|
Module : GHCup
|
||||||
@@ -62,7 +62,7 @@ import Data.String ( fromString )
|
|||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Time.Clock
|
import Data.Time.Clock
|
||||||
import Data.Time.Format.ISO8601
|
import Data.Time.Format.ISO8601
|
||||||
import Data.Versions
|
import Data.Versions hiding ( patch )
|
||||||
import Distribution.Types.Version hiding ( Version )
|
import Distribution.Types.Version hiding ( Version )
|
||||||
import Distribution.Types.PackageId
|
import Distribution.Types.PackageId
|
||||||
import Distribution.Types.PackageDescription
|
import Distribution.Types.PackageDescription
|
||||||
@@ -84,6 +84,7 @@ import System.IO.Error
|
|||||||
import System.IO.Temp
|
import System.IO.Temp
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
import Text.Regex.Posix
|
import Text.Regex.Posix
|
||||||
|
import URI.ByteString
|
||||||
|
|
||||||
import qualified Crypto.Hash.SHA256 as SHA256
|
import qualified Crypto.Hash.SHA256 as SHA256
|
||||||
import qualified Data.List.NonEmpty as NE
|
import qualified Data.List.NonEmpty as NE
|
||||||
@@ -300,22 +301,6 @@ installPackedGHC dl msubdir inst ver forceInstall = do
|
|||||||
liftE $ runBuildAction tmpUnpack
|
liftE $ runBuildAction tmpUnpack
|
||||||
(Just inst)
|
(Just inst)
|
||||||
(installUnpackedGHC workdir inst ver)
|
(installUnpackedGHC workdir inst ver)
|
||||||
where
|
|
||||||
-- | Does basic checks for isolated installs
|
|
||||||
-- Isolated Directory:
|
|
||||||
-- 1. if it doesn't exist -> proceed
|
|
||||||
-- 2. if it exists and is empty -> proceed
|
|
||||||
-- 3. if it exists and is non-empty -> panic and leave the house
|
|
||||||
installDestSanityCheck :: ( MonadIO m
|
|
||||||
, MonadCatch m
|
|
||||||
) =>
|
|
||||||
FilePath ->
|
|
||||||
Excepts '[DirNotEmpty] m ()
|
|
||||||
installDestSanityCheck isoDir = do
|
|
||||||
hideErrorDef [doesNotExistErrorType] () $ do
|
|
||||||
contents <- liftIO $ getDirectoryContentsRecursive isoDir
|
|
||||||
unless (null contents) (throwE $ DirNotEmpty isoDir)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- | Install an unpacked GHC distribution. This only deals with the GHC
|
-- | Install an unpacked GHC distribution. This only deals with the GHC
|
||||||
@@ -581,6 +566,8 @@ installHLSBindist :: ( MonadMask m
|
|||||||
, TarDirDoesNotExist
|
, TarDirDoesNotExist
|
||||||
, ArchiveResult
|
, ArchiveResult
|
||||||
, FileAlreadyExistsError
|
, FileAlreadyExistsError
|
||||||
|
, ProcessError
|
||||||
|
, DirNotEmpty
|
||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
@@ -616,26 +603,55 @@ installHLSBindist dlinfo ver isoFilepath forceInstall = do
|
|||||||
|
|
||||||
-- the subdir of the archive where we do the work
|
-- the subdir of the archive where we do the work
|
||||||
workdir <- maybe (pure tmpUnpack) (liftE . intoSubdir tmpUnpack) (view dlSubdir dlinfo)
|
workdir <- maybe (pure tmpUnpack) (liftE . intoSubdir tmpUnpack) (view dlSubdir dlinfo)
|
||||||
|
legacy <- liftIO $ isLegacyHLSBindist workdir
|
||||||
|
|
||||||
|
if
|
||||||
|
| not forceInstall
|
||||||
|
, not legacy
|
||||||
|
, (Just fp) <- isoFilepath -> liftE $ installDestSanityCheck fp
|
||||||
|
| otherwise -> pure ()
|
||||||
|
|
||||||
case isoFilepath of
|
case isoFilepath of
|
||||||
Just isoDir -> do
|
Just isoDir -> do
|
||||||
lift $ logInfo $ "isolated installing HLS to " <> T.pack isoDir
|
lift $ logInfo $ "isolated installing HLS to " <> T.pack isoDir
|
||||||
liftE $ installHLSUnpacked workdir isoDir Nothing forceInstall
|
if legacy
|
||||||
|
then liftE $ installHLSUnpackedLegacy workdir isoDir Nothing forceInstall
|
||||||
|
else liftE $ runBuildAction tmpUnpack Nothing $ installHLSUnpacked workdir isoDir ver
|
||||||
|
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
liftE $ installHLSUnpacked workdir binDir (Just ver) forceInstall
|
if legacy
|
||||||
|
then liftE $ installHLSUnpackedLegacy workdir binDir (Just ver) forceInstall
|
||||||
|
else do
|
||||||
|
inst <- ghcupHLSDir ver
|
||||||
|
liftE $ runBuildAction tmpUnpack Nothing $ installHLSUnpacked workdir inst ver
|
||||||
|
liftE $ setHLS ver SetHLS_XYZ Nothing
|
||||||
|
|
||||||
liftE $ installHLSPostInst isoFilepath ver
|
liftE $ installHLSPostInst isoFilepath ver
|
||||||
|
|
||||||
|
isLegacyHLSBindist :: FilePath -- ^ Path to the unpacked hls bindist
|
||||||
|
-> IO Bool
|
||||||
|
isLegacyHLSBindist path = do
|
||||||
|
not <$> doesFileExist (path </> "GNUmakefile")
|
||||||
|
|
||||||
-- | Install an unpacked hls distribution.
|
-- | Install an unpacked hls distribution.
|
||||||
installHLSUnpacked :: (MonadReader env m, MonadFail m, HasLog env, MonadCatch m, MonadIO m)
|
installHLSUnpacked :: (MonadMask m, MonadUnliftIO m, MonadReader env m, MonadFail m, HasLog env, HasDirs env, HasSettings env, MonadCatch m, MonadIO m)
|
||||||
=> FilePath -- ^ Path to the unpacked hls bindist (where the executable resides)
|
=> FilePath -- ^ Path to the unpacked hls bindist (where the executable resides)
|
||||||
-> FilePath -- ^ Path to install to
|
-> FilePath -- ^ Path to install to
|
||||||
-> Maybe Version -- ^ Nothing for isolated install
|
-> Version
|
||||||
-> Bool -- ^ is it a force install
|
-> Excepts '[ProcessError, CopyError, FileAlreadyExistsError, NotInstalled] m ()
|
||||||
-> Excepts '[CopyError, FileAlreadyExistsError] m ()
|
installHLSUnpacked path inst _ = do
|
||||||
installHLSUnpacked path inst mver' forceInstall = do
|
lift $ logInfo "Installing HLS"
|
||||||
|
liftIO $ createDirRecursive' inst
|
||||||
|
lEM $ make ["PREFIX=" <> inst, "install"] (Just path)
|
||||||
|
|
||||||
|
-- | Install an unpacked hls distribution (legacy).
|
||||||
|
installHLSUnpackedLegacy :: (MonadReader env m, MonadFail m, HasLog env, MonadCatch m, MonadIO m)
|
||||||
|
=> FilePath -- ^ Path to the unpacked hls bindist (where the executable resides)
|
||||||
|
-> FilePath -- ^ Path to install to
|
||||||
|
-> Maybe Version -- ^ Nothing for isolated install
|
||||||
|
-> Bool -- ^ is it a force install
|
||||||
|
-> Excepts '[CopyError, FileAlreadyExistsError] m ()
|
||||||
|
installHLSUnpackedLegacy path inst mver' forceInstall = do
|
||||||
lift $ logInfo "Installing HLS"
|
lift $ logInfo "Installing HLS"
|
||||||
liftIO $ createDirRecursive' inst
|
liftIO $ createDirRecursive' inst
|
||||||
|
|
||||||
@@ -691,7 +707,7 @@ installHLSPostInst isoFilepath ver =
|
|||||||
-- create symlink if this is the latest version in a regular install
|
-- create symlink if this is the latest version in a regular install
|
||||||
hlsVers <- lift $ fmap rights getInstalledHLSs
|
hlsVers <- lift $ fmap rights getInstalledHLSs
|
||||||
let lInstHLS = headMay . reverse . sort $ hlsVers
|
let lInstHLS = headMay . reverse . sort $ hlsVers
|
||||||
when (maybe True (ver >=) lInstHLS) $ liftE $ setHLS ver
|
when (maybe True (ver >=) lInstHLS) $ liftE $ setHLS ver SetHLSOnly Nothing
|
||||||
|
|
||||||
|
|
||||||
-- | Installs hls binaries @haskell-language-server-\<ghcver\>@
|
-- | Installs hls binaries @haskell-language-server-\<ghcver\>@
|
||||||
@@ -724,6 +740,8 @@ installHLSBin :: ( MonadMask m
|
|||||||
, TarDirDoesNotExist
|
, TarDirDoesNotExist
|
||||||
, ArchiveResult
|
, ArchiveResult
|
||||||
, FileAlreadyExistsError
|
, FileAlreadyExistsError
|
||||||
|
, ProcessError
|
||||||
|
, DirNotEmpty
|
||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
@@ -750,9 +768,10 @@ compileHLS :: ( MonadMask m
|
|||||||
-> Maybe Int
|
-> Maybe Int
|
||||||
-> Maybe Version
|
-> Maybe Version
|
||||||
-> Maybe FilePath
|
-> Maybe FilePath
|
||||||
-> Maybe FilePath
|
-> Maybe (Either FilePath URI)
|
||||||
-> Maybe FilePath
|
-> Maybe URI
|
||||||
-> Maybe FilePath
|
-> Maybe (Either FilePath [URI]) -- ^ patches
|
||||||
|
-> [Text] -- ^ additional args to cabal install
|
||||||
-> Excepts '[ NoDownload
|
-> Excepts '[ NoDownload
|
||||||
, GPGError
|
, GPGError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
@@ -763,11 +782,12 @@ compileHLS :: ( MonadMask m
|
|||||||
, BuildFailed
|
, BuildFailed
|
||||||
, NotInstalled
|
, NotInstalled
|
||||||
] m Version
|
] m Version
|
||||||
compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patchdir = do
|
compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patches cabalArgs = do
|
||||||
PlatformRequest { .. } <- lift getPlatformReq
|
PlatformRequest { .. } <- lift getPlatformReq
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
Dirs { .. } <- lift getDirs
|
Dirs { .. } <- lift getDirs
|
||||||
|
|
||||||
|
|
||||||
(workdir, tver) <- case targetHLS of
|
(workdir, tver) <- case targetHLS of
|
||||||
-- unpack from version tarball
|
-- unpack from version tarball
|
||||||
Left tver -> do
|
Left tver -> do
|
||||||
@@ -834,48 +854,51 @@ compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patc
|
|||||||
liftE $ runBuildAction
|
liftE $ runBuildAction
|
||||||
workdir
|
workdir
|
||||||
Nothing
|
Nothing
|
||||||
(reThrowAll @_ @'[PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed workdir) $ do
|
(reThrowAll @_ @'[GPGError, DownloadFailed, DigestError, PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed workdir) $ do
|
||||||
let installDir = workdir </> "out"
|
let installDir = workdir </> "out"
|
||||||
liftIO $ createDirRecursive' installDir
|
liftIO $ createDirRecursive' installDir
|
||||||
|
|
||||||
-- apply patches
|
-- apply patches
|
||||||
forM_ patchdir (\dir -> liftE $ applyPatches dir workdir)
|
liftE $ applyAnyPatch patches workdir
|
||||||
|
|
||||||
-- set up project files
|
-- set up project files
|
||||||
cp <- case cabalProject of
|
cp <- case cabalProject of
|
||||||
Just cp
|
Just (Left cp)
|
||||||
| isAbsolute cp -> do
|
| isAbsolute cp -> do
|
||||||
copyFileE cp (workdir </> "cabal.project")
|
copyFileE cp (workdir </> "cabal.project")
|
||||||
pure "cabal.project"
|
pure "cabal.project"
|
||||||
| otherwise -> pure (takeFileName cp)
|
| otherwise -> pure (takeFileName cp)
|
||||||
|
Just (Right uri) -> do
|
||||||
|
tmpUnpack <- lift withGHCupTmpDir
|
||||||
|
cp <- liftE $ download uri Nothing Nothing tmpUnpack (Just "cabal.project") False
|
||||||
|
copyFileE cp (workdir </> "cabal.project")
|
||||||
|
pure "cabal.project"
|
||||||
Nothing -> pure "cabal.project"
|
Nothing -> pure "cabal.project"
|
||||||
forM_ cabalProjectLocal $ \cpl -> copyFileE cpl (workdir </> cp <.> "local")
|
forM_ cabalProjectLocal $ \uri -> do
|
||||||
|
tmpUnpack <- lift withGHCupTmpDir
|
||||||
let targets = ["exe:haskell-language-server", "exe:haskell-language-server-wrapper"]
|
cpl <- liftE $ download uri Nothing Nothing tmpUnpack (Just (cp <.> "local")) False
|
||||||
|
copyFileE cpl (workdir </> cp <.> "local")
|
||||||
artifacts <- forM (sort ghcs) $ \ghc -> do
|
artifacts <- forM (sort ghcs) $ \ghc -> do
|
||||||
let ghcInstallDir = installDir </> T.unpack (prettyVer ghc)
|
let ghcInstallDir = installDir </> T.unpack (prettyVer ghc)
|
||||||
liftIO $ createDirRecursive' ghcInstallDir
|
liftIO $ createDirRecursive' installDir
|
||||||
lift $ logInfo $ "Building HLS " <> prettyVer installVer <> " for GHC version " <> prettyVer ghc
|
lift $ logInfo $ "Building HLS " <> prettyVer installVer <> " for GHC version " <> prettyVer ghc
|
||||||
liftE $ lEM @_ @'[ProcessError] $
|
liftE $ lEM @_ @'[ProcessError] $
|
||||||
execLogged "cabal" ( [ "v2-build"
|
execLogged "cabal" ( [ "v2-install"
|
||||||
, "-w"
|
, "-w"
|
||||||
, "ghc-" <> T.unpack (prettyVer ghc)
|
, "ghc-" <> T.unpack (prettyVer ghc)
|
||||||
|
, "--install-method=copy"
|
||||||
] ++
|
] ++
|
||||||
maybe [] (\j -> ["--jobs=" <> show j]) jobs ++
|
maybe [] (\j -> ["--jobs=" <> show j]) jobs ++
|
||||||
[ "--project-file=" <> cp
|
[ "--overwrite-policy=always"
|
||||||
] ++ targets
|
, "--disable-profiling"
|
||||||
|
, "--disable-tests"
|
||||||
|
, "--installdir=" <> ghcInstallDir
|
||||||
|
, "--project-file=" <> cp
|
||||||
|
] ++ fmap T.unpack cabalArgs ++ [
|
||||||
|
"exe:haskell-language-server"
|
||||||
|
, "exe:haskell-language-server-wrapper"]
|
||||||
)
|
)
|
||||||
(Just workdir) "cabal" Nothing
|
(Just workdir) "cabal" Nothing
|
||||||
forM_ targets $ \target -> do
|
|
||||||
let cabal = "cabal"
|
|
||||||
args = ["list-bin", target]
|
|
||||||
CapturedProcess{..} <- lift $ executeOut cabal args (Just workdir)
|
|
||||||
case _exitCode of
|
|
||||||
ExitFailure i -> throwE (NonZeroExit i cabal args)
|
|
||||||
_ -> pure ()
|
|
||||||
let cbin = stripNewlineEnd . T.unpack . decUTF8Safe' $ _stdOut
|
|
||||||
copyFileE cbin (ghcInstallDir </> takeFileName cbin)
|
|
||||||
pure ghcInstallDir
|
pure ghcInstallDir
|
||||||
|
|
||||||
forM_ artifacts $ \artifact -> do
|
forM_ artifacts $ \artifact -> do
|
||||||
@@ -888,9 +911,9 @@ compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patc
|
|||||||
case isolateDir of
|
case isolateDir of
|
||||||
Just isoDir -> do
|
Just isoDir -> do
|
||||||
lift $ logInfo $ "isolated installing HLS to " <> T.pack isoDir
|
lift $ logInfo $ "isolated installing HLS to " <> T.pack isoDir
|
||||||
liftE $ installHLSUnpacked installDir isoDir Nothing True
|
liftE $ installHLSUnpackedLegacy installDir isoDir Nothing True
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
liftE $ installHLSUnpacked installDir binDir (Just installVer) True
|
liftE $ installHLSUnpackedLegacy installDir binDir (Just installVer) True
|
||||||
)
|
)
|
||||||
|
|
||||||
liftE $ installHLSPostInst isolateDir installVer
|
liftE $ installHLSPostInst isolateDir installVer
|
||||||
@@ -1069,22 +1092,29 @@ setGHC :: ( MonadReader env m
|
|||||||
)
|
)
|
||||||
=> GHCTargetVersion
|
=> GHCTargetVersion
|
||||||
-> SetGHC
|
-> SetGHC
|
||||||
|
-> Maybe FilePath -- if set, signals that we're not operating in ~/.ghcup/bin
|
||||||
|
-- and don't want mess with other versions
|
||||||
-> Excepts '[NotInstalled] m GHCTargetVersion
|
-> Excepts '[NotInstalled] m GHCTargetVersion
|
||||||
setGHC ver sghc = do
|
setGHC ver sghc mBinDir = do
|
||||||
let verS = T.unpack $ prettyVer (_tvVersion ver)
|
let verS = T.unpack $ prettyVer (_tvVersion ver)
|
||||||
ghcdir <- lift $ ghcupGHCDir ver
|
ghcdir <- lift $ ghcupGHCDir ver
|
||||||
|
|
||||||
whenM (lift $ not <$> ghcInstalled ver) (throwE (NotInstalled GHC ver))
|
whenM (lift $ not <$> ghcInstalled ver) (throwE (NotInstalled GHC ver))
|
||||||
|
|
||||||
-- symlink destination
|
-- symlink destination
|
||||||
Dirs {..} <- lift getDirs
|
binDir <- case mBinDir of
|
||||||
|
Just x -> pure x
|
||||||
|
Nothing -> do
|
||||||
|
Dirs {binDir = f} <- lift getDirs
|
||||||
|
pure f
|
||||||
|
|
||||||
-- first delete the old symlinks (this fixes compatibility issues
|
-- first delete the old symlinks (this fixes compatibility issues
|
||||||
-- with old ghcup)
|
-- with old ghcup)
|
||||||
case sghc of
|
when (isNothing mBinDir) $
|
||||||
SetGHCOnly -> liftE $ rmPlain (_tvTarget ver)
|
case sghc of
|
||||||
SetGHC_XY -> liftE $ rmMajorSymlinks ver
|
SetGHCOnly -> liftE $ rmPlainGHC (_tvTarget ver)
|
||||||
SetGHC_XYZ -> liftE $ rmMinorSymlinks ver
|
SetGHC_XY -> liftE $ rmMajorGHCSymlinks ver
|
||||||
|
SetGHC_XYZ -> liftE $ rmMinorGHCSymlinks ver
|
||||||
|
|
||||||
-- for ghc tools (ghc, ghci, haddock, ...)
|
-- for ghc tools (ghc, ghci, haddock, ...)
|
||||||
verfiles <- ghcToolFiles ver
|
verfiles <- ghcToolFiles ver
|
||||||
@@ -1102,16 +1132,18 @@ setGHC ver sghc = do
|
|||||||
pure $ Just (file <> "-" <> verS)
|
pure $ Just (file <> "-" <> verS)
|
||||||
|
|
||||||
-- create symlink
|
-- create symlink
|
||||||
forM mTargetFile $ \targetFile -> do
|
forM_ mTargetFile $ \targetFile -> do
|
||||||
|
bindir <- ghcInternalBinDir ver
|
||||||
let fullF = binDir </> targetFile <> exeExt
|
let fullF = binDir </> targetFile <> exeExt
|
||||||
fileWithExt = file <> exeExt
|
fileWithExt = bindir </> file <> exeExt
|
||||||
destL <- lift $ ghcLinkDestination fileWithExt ver
|
destL <- binarySymLinkDestination binDir fileWithExt
|
||||||
lift $ createLink destL fullF
|
lift $ createLink destL fullF
|
||||||
|
|
||||||
-- create symlink for share dir
|
when (isNothing mBinDir) $ do
|
||||||
when (isNothing . _tvTarget $ ver) $ lift $ symlinkShareDir ghcdir verS
|
-- create symlink for share dir
|
||||||
|
when (isNothing . _tvTarget $ ver) $ lift $ symlinkShareDir ghcdir verS
|
||||||
|
|
||||||
when (sghc == SetGHCOnly) $ lift warnAboutHlsCompatibility
|
when (sghc == SetGHCOnly) $ lift warnAboutHlsCompatibility
|
||||||
|
|
||||||
pure ver
|
pure ver
|
||||||
|
|
||||||
@@ -1164,7 +1196,7 @@ unsetGHC :: ( MonadReader env m
|
|||||||
)
|
)
|
||||||
=> Maybe Text
|
=> Maybe Text
|
||||||
-> Excepts '[NotInstalled] m ()
|
-> Excepts '[NotInstalled] m ()
|
||||||
unsetGHC = rmPlain
|
unsetGHC = rmPlainGHC
|
||||||
|
|
||||||
|
|
||||||
-- | Set the @~\/.ghcup\/bin\/cabal@ symlink.
|
-- | Set the @~\/.ghcup\/bin\/cabal@ symlink.
|
||||||
@@ -1216,35 +1248,60 @@ setHLS :: ( MonadReader env m
|
|||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
)
|
)
|
||||||
=> Version
|
=> Version
|
||||||
|
-> SetHLS -- Nothing for legacy
|
||||||
|
-> Maybe FilePath -- if set, signals that we're not operating in ~/.ghcup/bin
|
||||||
|
-- and don't want mess with other versions
|
||||||
-> Excepts '[NotInstalled] m ()
|
-> Excepts '[NotInstalled] m ()
|
||||||
setHLS ver = do
|
setHLS ver shls mBinDir = do
|
||||||
Dirs {..} <- lift getDirs
|
whenM (lift $ not <$> hlsInstalled ver) (throwE (NotInstalled HLS (GHCTargetVersion Nothing ver)))
|
||||||
|
|
||||||
-- Delete old symlinks, since these might have different ghc versions than the
|
-- symlink destination
|
||||||
-- selected version, so we could end up with stray or incorrect symlinks.
|
binDir <- case mBinDir of
|
||||||
oldSyms <- lift hlsSymlinks
|
Just x -> pure x
|
||||||
forM_ oldSyms $ \f -> do
|
Nothing -> do
|
||||||
lift $ logDebug $ "rm " <> T.pack (binDir </> f)
|
Dirs {binDir = f} <- lift getDirs
|
||||||
lift $ rmLink (binDir </> f)
|
pure f
|
||||||
|
|
||||||
-- set haskell-language-server-<ghcver> symlinks
|
-- first delete the old symlinks
|
||||||
bins <- lift $ hlsServerBinaries ver Nothing
|
when (isNothing mBinDir) $
|
||||||
when (null bins) $ throwE $ NotInstalled HLS (GHCTargetVersion Nothing ver)
|
case shls of
|
||||||
|
-- not for legacy
|
||||||
|
SetHLS_XYZ -> liftE $ rmMinorHLSSymlinks ver
|
||||||
|
-- legacy and new
|
||||||
|
SetHLSOnly -> liftE rmPlainHLS
|
||||||
|
|
||||||
forM_ bins $ \f -> do
|
case shls of
|
||||||
let destL = f
|
-- not for legacy
|
||||||
let target = (<> exeExt) . head . splitOn "~" $ f
|
SetHLS_XYZ -> do
|
||||||
lift $ createLink destL (binDir </> target)
|
bins <- lift $ hlsInternalServerScripts ver Nothing
|
||||||
|
|
||||||
-- set haskell-language-server-wrapper symlink
|
forM_ bins $ \f -> do
|
||||||
let destL = "haskell-language-server-wrapper-" <> T.unpack (prettyVer ver) <> exeExt
|
let fname = takeFileName f
|
||||||
let wrapper = binDir </> "haskell-language-server-wrapper" <> exeExt
|
destL <- binarySymLinkDestination binDir f
|
||||||
|
let target = if "haskell-language-server-wrapper" `isPrefixOf` fname
|
||||||
|
then fname <> "-" <> T.unpack (prettyVer ver) <> exeExt
|
||||||
|
else fname <> "~" <> T.unpack (prettyVer ver) <> exeExt
|
||||||
|
lift $ createLink destL (binDir </> target)
|
||||||
|
|
||||||
lift $ createLink destL wrapper
|
-- legacy and new
|
||||||
|
SetHLSOnly -> do
|
||||||
|
-- set haskell-language-server-<ghcver> symlinks
|
||||||
|
bins <- lift $ hlsServerBinaries ver Nothing
|
||||||
|
when (null bins) $ throwE $ NotInstalled HLS (GHCTargetVersion Nothing ver)
|
||||||
|
|
||||||
lift warnAboutHlsCompatibility
|
forM_ bins $ \f -> do
|
||||||
|
let destL = f
|
||||||
|
let target = (<> exeExt) . head . splitOn "~" $ f
|
||||||
|
lift $ createLink destL (binDir </> target)
|
||||||
|
|
||||||
pure ()
|
-- set haskell-language-server-wrapper symlink
|
||||||
|
let destL = "haskell-language-server-wrapper-" <> T.unpack (prettyVer ver) <> exeExt
|
||||||
|
let wrapper = binDir </> "haskell-language-server-wrapper" <> exeExt
|
||||||
|
|
||||||
|
lift $ createLink destL wrapper
|
||||||
|
|
||||||
|
when (isNothing mBinDir) $
|
||||||
|
lift warnAboutHlsCompatibility
|
||||||
|
|
||||||
|
|
||||||
unsetHLS :: ( MonadMask m
|
unsetHLS :: ( MonadMask m
|
||||||
@@ -1574,7 +1631,7 @@ listVersions lt' criteria = do
|
|||||||
|
|
||||||
currentGHCup :: Map.Map Version VersionInfo -> Maybe ListResult
|
currentGHCup :: Map.Map Version VersionInfo -> Maybe ListResult
|
||||||
currentGHCup av =
|
currentGHCup av =
|
||||||
let currentVer = 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
|
||||||
@@ -1714,14 +1771,14 @@ rmGHCVer ver = do
|
|||||||
-- this isn't atomic, order matters
|
-- this isn't atomic, order matters
|
||||||
when isSetGHC $ do
|
when isSetGHC $ do
|
||||||
lift $ logInfo "Removing ghc symlinks"
|
lift $ logInfo "Removing ghc symlinks"
|
||||||
liftE $ rmPlain (_tvTarget ver)
|
liftE $ rmPlainGHC (_tvTarget ver)
|
||||||
|
|
||||||
lift $ logInfo "Removing ghc-x.y.z symlinks"
|
lift $ logInfo "Removing ghc-x.y.z symlinks"
|
||||||
liftE $ rmMinorSymlinks ver
|
liftE $ rmMinorGHCSymlinks ver
|
||||||
|
|
||||||
lift $ logInfo "Removing/rewiring ghc-x.y symlinks"
|
lift $ logInfo "Removing/rewiring ghc-x.y symlinks"
|
||||||
-- first remove
|
-- first remove
|
||||||
handle (\(_ :: ParseError) -> pure ()) $ liftE $ rmMajorSymlinks ver
|
handle (\(_ :: ParseError) -> pure ()) $ liftE $ rmMajorGHCSymlinks ver
|
||||||
-- then fix them (e.g. with an earlier version)
|
-- then fix them (e.g. with an earlier version)
|
||||||
|
|
||||||
lift $ logInfo $ "Removing directory recursively: " <> T.pack dir
|
lift $ logInfo $ "Removing directory recursively: " <> T.pack dir
|
||||||
@@ -1733,7 +1790,7 @@ rmGHCVer ver = do
|
|||||||
$ fmap Just
|
$ fmap Just
|
||||||
$ getMajorMinorV (_tvVersion ver)
|
$ getMajorMinorV (_tvVersion ver)
|
||||||
forM_ v' $ \(mj, mi) -> lift (getGHCForPVP (PVP (fromIntegral mj :| [fromIntegral mi])) (_tvTarget ver))
|
forM_ v' $ \(mj, mi) -> lift (getGHCForPVP (PVP (fromIntegral mj :| [fromIntegral mi])) (_tvTarget ver))
|
||||||
>>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY)
|
>>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY Nothing)
|
||||||
|
|
||||||
Dirs {..} <- lift getDirs
|
Dirs {..} <- lift getDirs
|
||||||
|
|
||||||
@@ -1788,24 +1845,19 @@ rmHLSVer :: ( MonadMask m
|
|||||||
rmHLSVer ver = do
|
rmHLSVer ver = do
|
||||||
whenM (lift $ fmap not $ hlsInstalled ver) $ throwE (NotInstalled HLS (GHCTargetVersion Nothing ver))
|
whenM (lift $ fmap not $ hlsInstalled ver) $ throwE (NotInstalled HLS (GHCTargetVersion Nothing ver))
|
||||||
|
|
||||||
isHlsSet <- lift hlsSet
|
isHlsSet <- lift hlsSet
|
||||||
|
|
||||||
Dirs {..} <- lift getDirs
|
liftE $ rmMinorHLSSymlinks ver
|
||||||
|
hlsDir <- ghcupHLSDir ver
|
||||||
bins <- lift $ hlsAllBinaries ver
|
recyclePathForcibly hlsDir
|
||||||
forM_ bins $ \f -> lift $ recycleFile (binDir </> f)
|
|
||||||
|
|
||||||
when (Just ver == isHlsSet) $ do
|
when (Just ver == isHlsSet) $ do
|
||||||
-- delete all set symlinks
|
-- delete all set symlinks
|
||||||
oldSyms <- lift hlsSymlinks
|
rmPlainHLS
|
||||||
forM_ oldSyms $ \f -> do
|
|
||||||
let fullF = binDir </> f
|
|
||||||
lift $ logDebug $ "rm " <> T.pack fullF
|
|
||||||
lift $ rmLink fullF
|
|
||||||
-- set latest hls
|
-- set latest hls
|
||||||
hlsVers <- lift $ fmap rights getInstalledHLSs
|
hlsVers <- lift $ fmap rights getInstalledHLSs
|
||||||
case headMay . reverse . sort $ hlsVers of
|
case headMay . reverse . sort $ hlsVers of
|
||||||
Just latestver -> setHLS latestver
|
Just latestver -> setHLS latestver SetHLSOnly Nothing
|
||||||
Nothing -> pure ()
|
Nothing -> pure ()
|
||||||
|
|
||||||
|
|
||||||
@@ -2090,7 +2142,7 @@ compileGHC :: ( MonadMask m
|
|||||||
-> Either Version FilePath -- ^ version to bootstrap with
|
-> Either Version FilePath -- ^ version to bootstrap with
|
||||||
-> Maybe Int -- ^ jobs
|
-> Maybe Int -- ^ jobs
|
||||||
-> Maybe FilePath -- ^ build config
|
-> Maybe FilePath -- ^ build config
|
||||||
-> Maybe FilePath -- ^ patch directory
|
-> Maybe (Either FilePath [URI]) -- ^ patches
|
||||||
-> [Text] -- ^ additional args to ./configure
|
-> [Text] -- ^ additional args to ./configure
|
||||||
-> Maybe String -- ^ build flavour
|
-> Maybe String -- ^ build flavour
|
||||||
-> Bool
|
-> Bool
|
||||||
@@ -2119,7 +2171,7 @@ compileGHC :: ( MonadMask m
|
|||||||
]
|
]
|
||||||
m
|
m
|
||||||
GHCTargetVersion
|
GHCTargetVersion
|
||||||
compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour hadrian isolateDir
|
compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadrian isolateDir
|
||||||
= do
|
= do
|
||||||
PlatformRequest { .. } <- lift getPlatformReq
|
PlatformRequest { .. } <- lift getPlatformReq
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
@@ -2143,7 +2195,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
workdir <- maybe (pure tmpUnpack)
|
workdir <- maybe (pure tmpUnpack)
|
||||||
(liftE . intoSubdir tmpUnpack)
|
(liftE . intoSubdir tmpUnpack)
|
||||||
(view dlSubdir dlInfo)
|
(view dlSubdir dlInfo)
|
||||||
forM_ patchdir (\dir -> liftE $ applyPatches dir workdir)
|
liftE $ applyAnyPatch patches workdir
|
||||||
|
|
||||||
pure (workdir, tmpUnpack, tver)
|
pure (workdir, tmpUnpack, tver)
|
||||||
|
|
||||||
@@ -2151,7 +2203,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
Right GitBranch{..} -> do
|
Right GitBranch{..} -> do
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
let git args = execLogged "git" ("--no-pager":args) (Just tmpUnpack) "git" Nothing
|
let git args = execLogged "git" ("--no-pager":args) (Just tmpUnpack) "git" Nothing
|
||||||
tver <- reThrowAll @_ @'[PatchFailed, ProcessError, NotFoundInPATH] DownloadFailed $ do
|
tver <- reThrowAll @_ @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, DownloadFailed, GPGError] DownloadFailed $ do
|
||||||
let rep = fromMaybe "https://gitlab.haskell.org/ghc/ghc.git" repo
|
let rep = fromMaybe "https://gitlab.haskell.org/ghc/ghc.git" repo
|
||||||
lift $ logInfo $ "Fetching git repo " <> T.pack rep <> " at ref " <> T.pack ref <> " (this may take a while)"
|
lift $ logInfo $ "Fetching git repo " <> T.pack rep <> " at ref " <> T.pack ref <> " (this may take a while)"
|
||||||
lEM $ git [ "init" ]
|
lEM $ git [ "init" ]
|
||||||
@@ -2171,7 +2223,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
|
|
||||||
lEM $ git [ "checkout", "FETCH_HEAD" ]
|
lEM $ git [ "checkout", "FETCH_HEAD" ]
|
||||||
lEM $ git [ "submodule", "update", "--init", "--depth", "1" ]
|
lEM $ git [ "submodule", "update", "--init", "--depth", "1" ]
|
||||||
forM_ patchdir (\dir -> liftE $ applyPatches dir tmpUnpack)
|
liftE $ applyAnyPatch patches tmpUnpack
|
||||||
lEM $ execWithGhcEnv "python3" ["./boot"] (Just tmpUnpack) "ghc-bootstrap"
|
lEM $ execWithGhcEnv "python3" ["./boot"] (Just tmpUnpack) "ghc-bootstrap"
|
||||||
lEM $ execWithGhcEnv "sh" ["./configure"] (Just tmpUnpack) "ghc-bootstrap"
|
lEM $ execWithGhcEnv "sh" ["./configure"] (Just tmpUnpack) "ghc-bootstrap"
|
||||||
CapturedProcess {..} <- lift $ makeOut
|
CapturedProcess {..} <- lift $ makeOut
|
||||||
@@ -2239,7 +2291,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
Nothing -> do
|
Nothing -> do
|
||||||
reThrowAll GHCupSetError $ postGHCInstall installVer
|
reThrowAll GHCupSetError $ postGHCInstall installVer
|
||||||
-- restore
|
-- restore
|
||||||
when alreadySet $ liftE $ void $ setGHC installVer SetGHCOnly
|
when alreadySet $ liftE $ void $ setGHC installVer SetGHCOnly Nothing
|
||||||
|
|
||||||
_ -> pure ()
|
_ -> pure ()
|
||||||
|
|
||||||
@@ -2505,6 +2557,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
execWithGhcEnv :: ( MonadReader env m
|
execWithGhcEnv :: ( MonadReader env m
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadThrow m)
|
, MonadThrow m)
|
||||||
=> FilePath -- ^ thing to execute
|
=> FilePath -- ^ thing to execute
|
||||||
@@ -2576,7 +2629,7 @@ upgradeGHCup mtarget force' = do
|
|||||||
|
|
||||||
lift $ logInfo "Upgrading GHCup..."
|
lift $ logInfo "Upgrading GHCup..."
|
||||||
let latestVer = fromJust $ fst <$> getLatest dls GHCup
|
let latestVer = fromJust $ fst <$> 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
|
||||||
tmp <- lift withGHCupTmpDir
|
tmp <- lift withGHCupTmpDir
|
||||||
@@ -2632,7 +2685,7 @@ postGHCInstall :: ( MonadReader env m
|
|||||||
=> GHCTargetVersion
|
=> GHCTargetVersion
|
||||||
-> Excepts '[NotInstalled] m ()
|
-> Excepts '[NotInstalled] m ()
|
||||||
postGHCInstall ver@GHCTargetVersion {..} = do
|
postGHCInstall ver@GHCTargetVersion {..} = do
|
||||||
void $ liftE $ setGHC ver SetGHC_XYZ
|
void $ liftE $ setGHC ver SetGHC_XYZ Nothing
|
||||||
|
|
||||||
-- Create ghc-x.y symlinks. This may not be the current
|
-- Create ghc-x.y symlinks. This may not be the current
|
||||||
-- version, create it regardless.
|
-- version, create it regardless.
|
||||||
@@ -2641,7 +2694,7 @@ postGHCInstall ver@GHCTargetVersion {..} = do
|
|||||||
$ fmap Just
|
$ fmap Just
|
||||||
$ getMajorMinorV _tvVersion
|
$ getMajorMinorV _tvVersion
|
||||||
forM_ v' $ \(mj, mi) -> lift (getGHCForPVP (PVP (fromIntegral mj :| [fromIntegral mi])) _tvTarget)
|
forM_ v' $ \(mj, mi) -> lift (getGHCForPVP (PVP (fromIntegral mj :| [fromIntegral mi])) _tvTarget)
|
||||||
>>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY)
|
>>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY Nothing)
|
||||||
|
|
||||||
|
|
||||||
-- | Reports the binary location of a given tool:
|
-- | Reports the binary location of a given tool:
|
||||||
@@ -2680,7 +2733,11 @@ whereIsTool tool ver@GHCTargetVersion {..} = do
|
|||||||
HLS -> do
|
HLS -> do
|
||||||
whenM (lift $ fmap not $ hlsInstalled _tvVersion)
|
whenM (lift $ fmap not $ hlsInstalled _tvVersion)
|
||||||
$ throwE (NotInstalled HLS (GHCTargetVersion Nothing _tvVersion))
|
$ throwE (NotInstalled HLS (GHCTargetVersion Nothing _tvVersion))
|
||||||
pure (binDir dirs </> "haskell-language-server-wrapper-" <> T.unpack (prettyVer _tvVersion) <> exeExt)
|
ifM (lift $ isLegacyHLS _tvVersion)
|
||||||
|
(pure (binDir dirs </> "haskell-language-server-wrapper-" <> T.unpack (prettyVer _tvVersion) <> exeExt))
|
||||||
|
$ do
|
||||||
|
bdir <- lift $ ghcupHLSDir _tvVersion
|
||||||
|
pure (bdir </> "bin" </> "haskell-language-server-wrapper" <> exeExt)
|
||||||
|
|
||||||
Stack -> do
|
Stack -> do
|
||||||
whenM (lift $ fmap not $ stackInstalled _tvVersion)
|
whenM (lift $ fmap not $ stackInstalled _tvVersion)
|
||||||
@@ -2698,13 +2755,21 @@ checkIfToolInstalled :: ( MonadIO m
|
|||||||
Tool ->
|
Tool ->
|
||||||
Version ->
|
Version ->
|
||||||
m Bool
|
m Bool
|
||||||
|
checkIfToolInstalled tool ver = checkIfToolInstalled' tool (mkTVer ver)
|
||||||
|
|
||||||
checkIfToolInstalled tool ver =
|
checkIfToolInstalled' :: ( MonadIO m
|
||||||
|
, MonadReader env m
|
||||||
|
, HasDirs env
|
||||||
|
, MonadCatch m) =>
|
||||||
|
Tool ->
|
||||||
|
GHCTargetVersion ->
|
||||||
|
m Bool
|
||||||
|
checkIfToolInstalled' tool ver =
|
||||||
case tool of
|
case tool of
|
||||||
Cabal -> cabalInstalled ver
|
Cabal -> cabalInstalled (_tvVersion ver)
|
||||||
HLS -> hlsInstalled ver
|
HLS -> hlsInstalled (_tvVersion ver)
|
||||||
Stack -> stackInstalled ver
|
Stack -> stackInstalled (_tvVersion ver)
|
||||||
GHC -> ghcInstalled $ mkTVer ver
|
GHC -> ghcInstalled ver
|
||||||
_ -> pure False
|
_ -> pure False
|
||||||
|
|
||||||
throwIfFileAlreadyExists :: ( MonadIO m ) =>
|
throwIfFileAlreadyExists :: ( MonadIO m ) =>
|
||||||
@@ -2793,21 +2858,31 @@ rmHLSNoGHC :: ( MonadReader env m
|
|||||||
, HasLog env
|
, HasLog env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
|
, MonadFail m
|
||||||
|
, MonadUnliftIO m
|
||||||
)
|
)
|
||||||
=> m ()
|
=> Excepts '[NotInstalled] m ()
|
||||||
rmHLSNoGHC = do
|
rmHLSNoGHC = do
|
||||||
Dirs {..} <- getDirs
|
Dirs {..} <- getDirs
|
||||||
ghcs <- fmap rights getInstalledGHCs
|
ghcs <- fmap rights getInstalledGHCs
|
||||||
hlses <- fmap rights getInstalledHLSs
|
hlses <- fmap rights getInstalledHLSs
|
||||||
forM_ hlses $ \hls -> do
|
forM_ hlses $ \hls -> do
|
||||||
hlsGHCs <- fmap mkTVer <$> hlsGHCVersions' hls
|
hlsGHCs <- fmap mkTVer <$> hlsGHCVersions' hls
|
||||||
forM_ hlsGHCs $ \ghc -> do
|
let candidates = filter (`notElem` ghcs) hlsGHCs
|
||||||
when (ghc `notElem` ghcs) $ do
|
if (length hlsGHCs - length candidates) <= 0
|
||||||
bins <- hlsServerBinaries hls (Just $ _tvVersion ghc)
|
then rmHLSVer hls
|
||||||
forM_ bins $ \bin -> do
|
else
|
||||||
let f = binDir </> bin
|
forM_ candidates $ \ghc -> do
|
||||||
|
bins1 <- fmap (binDir </>) <$> hlsServerBinaries hls (Just $ _tvVersion ghc)
|
||||||
|
bins2 <- ifM (isLegacyHLS hls) (pure []) $ do
|
||||||
|
shs <- hlsInternalServerScripts hls (Just $ _tvVersion ghc)
|
||||||
|
bins <- hlsInternalServerBinaries hls (Just $ _tvVersion ghc)
|
||||||
|
libs <- hlsInternalServerLibs hls (_tvVersion ghc)
|
||||||
|
pure (shs ++ bins ++ libs)
|
||||||
|
forM_ (bins1 ++ bins2) $ \f -> do
|
||||||
logDebug $ "rm " <> T.pack f
|
logDebug $ "rm " <> T.pack f
|
||||||
rmFile f
|
rmFile f
|
||||||
|
pure ()
|
||||||
|
|
||||||
|
|
||||||
rmCache :: ( MonadReader env m
|
rmCache :: ( MonadReader env m
|
||||||
@@ -2845,3 +2920,25 @@ rmTmp = do
|
|||||||
let p = tmpdir </> f
|
let p = tmpdir </> f
|
||||||
logDebug $ "rm -rf " <> T.pack p
|
logDebug $ "rm -rf " <> T.pack p
|
||||||
rmPathForcibly p
|
rmPathForcibly p
|
||||||
|
|
||||||
|
|
||||||
|
applyAnyPatch :: ( MonadReader env m
|
||||||
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
|
, HasSettings env
|
||||||
|
, MonadUnliftIO m
|
||||||
|
, MonadCatch m
|
||||||
|
, MonadResource m
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadMask m
|
||||||
|
, MonadIO m)
|
||||||
|
=> Maybe (Either FilePath [URI])
|
||||||
|
-> FilePath
|
||||||
|
-> Excepts '[PatchFailed, DownloadFailed, DigestError, GPGError] m ()
|
||||||
|
applyAnyPatch Nothing _ = pure ()
|
||||||
|
applyAnyPatch (Just (Left pdir)) workdir = liftE $ applyPatches pdir workdir
|
||||||
|
applyAnyPatch (Just (Right uris)) workdir = do
|
||||||
|
tmpUnpack <- lift withGHCupTmpDir
|
||||||
|
forM_ uris $ \uri -> do
|
||||||
|
patch <- liftE $ download uri Nothing Nothing tmpUnpack Nothing False
|
||||||
|
liftE $ applyPatch patch workdir
|
||||||
|
|||||||
@@ -242,14 +242,18 @@ getBase uri = do
|
|||||||
e <- liftIO $ doesFileExist json_file
|
e <- liftIO $ doesFileExist json_file
|
||||||
currentTime <- liftIO getCurrentTime
|
currentTime <- liftIO getCurrentTime
|
||||||
Dirs { cacheDir } <- lift getDirs
|
Dirs { cacheDir } <- lift getDirs
|
||||||
|
Settings { metaCache } <- lift getSettings
|
||||||
|
|
||||||
-- for local files, let's short-circuit and ignore access time
|
-- for local files, let's short-circuit and ignore access time
|
||||||
if | scheme == "file" -> liftE $ download uri' Nothing Nothing cacheDir Nothing True
|
if | scheme == "file" -> liftE $ download uri' Nothing Nothing cacheDir Nothing True
|
||||||
| e -> do
|
| e -> do
|
||||||
accessTime <- liftIO $ getAccessTime json_file
|
accessTime <- fmap utcTimeToPOSIXSeconds $ liftIO $ getAccessTime json_file
|
||||||
|
let sinceLastAccess = utcTimeToPOSIXSeconds currentTime - accessTime
|
||||||
|
let cacheInterval = fromInteger metaCache
|
||||||
|
lift $ logDebug $ "last access was " <> T.pack (show sinceLastAccess) <> " ago, cache interval is " <> T.pack (show cacheInterval)
|
||||||
-- access time won't work on most linuxes, but we can try regardless
|
-- access time won't work on most linuxes, but we can try regardless
|
||||||
if | ((utcTimeToPOSIXSeconds currentTime - utcTimeToPOSIXSeconds accessTime) > 300) ->
|
if | metaCache <= 0 -> dlWithMod currentTime json_file
|
||||||
|
| (sinceLastAccess > cacheInterval) ->
|
||||||
-- no access in last 5 minutes, re-check upstream mod time
|
-- no access in last 5 minutes, re-check upstream mod time
|
||||||
dlWithMod currentTime json_file
|
dlWithMod currentTime json_file
|
||||||
| otherwise -> pure json_file
|
| otherwise -> pure json_file
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskellQuotes #-}
|
||||||
|
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
@@ -27,6 +28,9 @@ import GHCup.Utils.Logger
|
|||||||
import GHCup.Utils.Prelude
|
import GHCup.Utils.Prelude
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Utils.String.QQ
|
||||||
|
|
||||||
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
|
import Control.Monad.Fail ( MonadFail )
|
||||||
|
#endif
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
@@ -30,12 +31,15 @@ import Data.Map.Strict ( Map )
|
|||||||
import Data.List.NonEmpty ( NonEmpty (..) )
|
import Data.List.NonEmpty ( NonEmpty (..) )
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
import Text.PrettyPrint.HughesPJClass (Pretty, pPrint, text)
|
import GHC.IO.Exception ( ExitCode )
|
||||||
|
import Optics ( makeLenses )
|
||||||
|
import Text.PrettyPrint.HughesPJClass (Pretty, pPrint, text, (<+>))
|
||||||
import URI.ByteString
|
import URI.ByteString
|
||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
import Graphics.Vty ( Key(..) )
|
import Graphics.Vty ( Key(..) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified GHC.Generics as GHC
|
import qualified GHC.Generics as GHC
|
||||||
|
|
||||||
@@ -294,6 +298,7 @@ instance NFData (URIRef Absolute) where
|
|||||||
|
|
||||||
data UserSettings = UserSettings
|
data UserSettings = UserSettings
|
||||||
{ uCache :: Maybe Bool
|
{ uCache :: Maybe Bool
|
||||||
|
, uMetaCache :: Maybe Integer
|
||||||
, uNoVerify :: Maybe Bool
|
, uNoVerify :: Maybe Bool
|
||||||
, uVerbose :: Maybe Bool
|
, uVerbose :: Maybe Bool
|
||||||
, uKeepDirs :: Maybe KeepDirs
|
, uKeepDirs :: Maybe KeepDirs
|
||||||
@@ -306,12 +311,13 @@ data UserSettings = UserSettings
|
|||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
defaultUserSettings :: UserSettings
|
defaultUserSettings :: UserSettings
|
||||||
defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
defaultUserSettings = UserSettings 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 =
|
||||||
UserSettings {
|
UserSettings {
|
||||||
uCache = Just cache
|
uCache = Just cache
|
||||||
|
, uMetaCache = Just metaCache
|
||||||
, uNoVerify = Just noVerify
|
, uNoVerify = Just noVerify
|
||||||
, uVerbose = Just verbose
|
, uVerbose = Just verbose
|
||||||
, uKeepDirs = Just keepDirs
|
, uKeepDirs = Just keepDirs
|
||||||
@@ -335,6 +341,7 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
|
|||||||
}
|
}
|
||||||
in UserSettings {
|
in UserSettings {
|
||||||
uCache = Just cache
|
uCache = Just cache
|
||||||
|
, uMetaCache = Just metaCache
|
||||||
, uNoVerify = Just noVerify
|
, uNoVerify = Just noVerify
|
||||||
, uVerbose = Just verbose
|
, uVerbose = Just verbose
|
||||||
, uKeepDirs = Just keepDirs
|
, uKeepDirs = Just keepDirs
|
||||||
@@ -410,6 +417,7 @@ instance NFData LeanAppState
|
|||||||
|
|
||||||
data Settings = Settings
|
data Settings = Settings
|
||||||
{ cache :: Bool
|
{ cache :: Bool
|
||||||
|
, metaCache :: Integer
|
||||||
, noVerify :: Bool
|
, noVerify :: Bool
|
||||||
, keepDirs :: KeepDirs
|
, keepDirs :: KeepDirs
|
||||||
, downloader :: Downloader
|
, downloader :: Downloader
|
||||||
@@ -421,6 +429,12 @@ data Settings = Settings
|
|||||||
}
|
}
|
||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
|
defaultMetaCache :: Integer
|
||||||
|
defaultMetaCache = 300 -- 5 minutes
|
||||||
|
|
||||||
|
defaultSettings :: Settings
|
||||||
|
defaultSettings = Settings False defaultMetaCache False Never Curl False GHCupURL False GPGNone False
|
||||||
|
|
||||||
instance NFData Settings
|
instance NFData Settings
|
||||||
|
|
||||||
data Dirs = Dirs
|
data Dirs = Dirs
|
||||||
@@ -474,6 +488,10 @@ data SetGHC = SetGHCOnly -- ^ unversioned 'ghc'
|
|||||||
| SetGHC_XYZ -- ^ ghc-x.y.z
|
| SetGHC_XYZ -- ^ ghc-x.y.z
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
data SetHLS = SetHLSOnly -- ^ unversioned 'hls'
|
||||||
|
| SetHLS_XYZ -- ^ haskell-language-server-a.b.c~x.y.z, where a.b.c is GHC version and x.y.z is HLS version
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
|
||||||
data PlatformResult = PlatformResult
|
data PlatformResult = PlatformResult
|
||||||
{ _platform :: Platform
|
{ _platform :: Platform
|
||||||
@@ -586,3 +604,27 @@ data LoggerConfig = LoggerConfig
|
|||||||
|
|
||||||
instance NFData LoggerConfig where
|
instance NFData LoggerConfig where
|
||||||
rnf (LoggerConfig !lcPrintDebug !_ !_ !fancyColors) = rnf (lcPrintDebug, fancyColors)
|
rnf (LoggerConfig !lcPrintDebug !_ !_ !fancyColors) = rnf (lcPrintDebug, fancyColors)
|
||||||
|
|
||||||
|
data ProcessError = NonZeroExit Int FilePath [String]
|
||||||
|
| PTerminated FilePath [String]
|
||||||
|
| PStopped FilePath [String]
|
||||||
|
| NoSuchPid FilePath [String]
|
||||||
|
deriving Show
|
||||||
|
|
||||||
|
instance Pretty ProcessError where
|
||||||
|
pPrint (NonZeroExit e exe args) =
|
||||||
|
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "failed with exit code" <+> text (show e <> ".")
|
||||||
|
pPrint (PTerminated exe args) =
|
||||||
|
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "terminated."
|
||||||
|
pPrint (PStopped exe args) =
|
||||||
|
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "stopped."
|
||||||
|
pPrint (NoSuchPid exe args) =
|
||||||
|
text "Could not find PID for process running " <+> pPrint exe <+> text " with arguments " <+> text (show args) <+> text "."
|
||||||
|
data CapturedProcess = CapturedProcess
|
||||||
|
{ _exitCode :: ExitCode
|
||||||
|
, _stdOut :: BL.ByteString
|
||||||
|
, _stdErr :: BL.ByteString
|
||||||
|
}
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
makeLenses ''CapturedProcess
|
||||||
|
|||||||
@@ -22,10 +22,8 @@ Portability : portable
|
|||||||
module GHCup.Types.JSON where
|
module GHCup.Types.JSON where
|
||||||
|
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
|
import GHCup.Types.JSON.Utils
|
||||||
import GHCup.Utils.MegaParsec
|
import GHCup.Utils.MegaParsec
|
||||||
import GHCup.Utils.Prelude
|
|
||||||
import GHCup.Utils.Logger () -- TH is broken shite and needs GHCup.Utils.Logger for linking, although we don't depend on the file.
|
|
||||||
-- This is due to the boot file.
|
|
||||||
|
|
||||||
import Control.Applicative ( (<|>) )
|
import Control.Applicative ( (<|>) )
|
||||||
import Data.Aeson hiding (Key)
|
import Data.Aeson hiding (Key)
|
||||||
@@ -40,6 +38,7 @@ import Text.Casing
|
|||||||
|
|
||||||
import qualified Data.List.NonEmpty as NE
|
import qualified Data.List.NonEmpty as NE
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.Encoding.Error as E
|
||||||
import qualified Text.Megaparsec as MP
|
import qualified Text.Megaparsec as MP
|
||||||
import qualified Text.Megaparsec.Char as MPC
|
import qualified Text.Megaparsec.Char as MPC
|
||||||
|
|
||||||
@@ -78,7 +77,7 @@ instance FromJSON Tag where
|
|||||||
x -> pure (UnknownTag x)
|
x -> pure (UnknownTag x)
|
||||||
|
|
||||||
instance ToJSON URI where
|
instance ToJSON URI where
|
||||||
toJSON = toJSON . decUTF8Safe . serializeURIRef'
|
toJSON = toJSON . E.decodeUtf8With E.lenientDecode . serializeURIRef'
|
||||||
|
|
||||||
instance FromJSON URI where
|
instance FromJSON URI where
|
||||||
parseJSON = withText "URL" $ \t ->
|
parseJSON = withText "URL" $ \t ->
|
||||||
|
|||||||
17
lib/GHCup/Types/JSON/Utils.hs
Normal file
17
lib/GHCup/Types/JSON/Utils.hs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{-|
|
||||||
|
Module : GHCup.Types.JSON.Utils
|
||||||
|
Description : Utils for TH splices
|
||||||
|
Copyright : (c) Julian Ospald, 2020
|
||||||
|
License : LGPL-3.0
|
||||||
|
Maintainer : hasufell@hasufell.de
|
||||||
|
Stability : experimental
|
||||||
|
Portability : portable
|
||||||
|
-}
|
||||||
|
|
||||||
|
module GHCup.Types.JSON.Utils where
|
||||||
|
|
||||||
|
import qualified Data.Text as T
|
||||||
|
|
||||||
|
removeLensFieldLabel :: String -> String
|
||||||
|
removeLensFieldLabel str' =
|
||||||
|
maybe str' T.unpack . T.stripPrefix (T.pack "_") . T.pack $ str'
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
|
||||||
{-# LANGUAGE TypeApplications #-}
|
{-# LANGUAGE TypeApplications #-}
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
|
|
||||||
@@ -59,6 +58,7 @@ import Control.Monad.Reader
|
|||||||
import Control.Monad.Trans.Resource
|
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.Bifunctor ( first )
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Foldable
|
import Data.Foldable
|
||||||
@@ -66,7 +66,7 @@ import Data.List
|
|||||||
import Data.List.NonEmpty ( NonEmpty( (:|) ))
|
import Data.List.NonEmpty ( NonEmpty( (:|) ))
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Versions
|
import Data.Versions hiding ( patch )
|
||||||
import GHC.IO.Exception
|
import GHC.IO.Exception
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Optics
|
import Optics
|
||||||
@@ -110,8 +110,8 @@ import qualified Data.List.NonEmpty as NE
|
|||||||
-- >>> import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
-- >>> import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
-- >>> let lc = LoggerConfig { lcPrintDebug = False, consoleOutter = mempty, fileOutter = mempty, fancyColors = False }
|
-- >>> let lc = LoggerConfig { lcPrintDebug = False, consoleOutter = mempty, fileOutter = mempty, fancyColors = False }
|
||||||
-- >>> dirs' <- getAllDirs
|
-- >>> dirs' <- getAllDirs
|
||||||
-- >>> let installedVersions = [ ([pver|8.10.7|], Nothing), ([pver|8.10.4|], Nothing), ([pver|8.8.4|], Nothing), ([pver|8.8.3|], Nothing) ]
|
-- >>> let installedVersions = [ ([pver|8.10.7|], "-debug+lol", Nothing), ([pver|8.10.4|], "", Nothing), ([pver|8.8.4|], "", Nothing), ([pver|8.8.3|], "", Nothing) ]
|
||||||
-- >>> let settings = Settings True False Never Curl False GHCupURL True GPGNone False
|
-- >>> let settings = Settings True 0 False Never Curl False GHCupURL True GPGNone False
|
||||||
-- >>> let leanAppState = LeanAppState settings dirs' defaultKeyBindings lc
|
-- >>> let leanAppState = LeanAppState settings dirs' defaultKeyBindings lc
|
||||||
-- >>> cwd <- getCurrentDirectory
|
-- >>> cwd <- getCurrentDirectory
|
||||||
-- >>> (Right ref) <- pure $ parseURI strictURIParserOptions $ "file://" <> E.encodeUtf8 (T.pack cwd) <> "/data/metadata/" <> (urlBaseName . view pathL' $ ghcupURL)
|
-- >>> (Right ref) <- pure $ parseURI strictURIParserOptions $ "file://" <> E.encodeUtf8 (T.pack cwd) <> "/data/metadata/" <> (urlBaseName . view pathL' $ ghcupURL)
|
||||||
@@ -124,31 +124,32 @@ import qualified Data.List.NonEmpty as NE
|
|||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
|
||||||
-- | The symlink destination of a ghc tool.
|
-- | Create a relative symlink destination for the binary directory,
|
||||||
ghcLinkDestination :: ( MonadReader env m
|
-- given a target toolpath.
|
||||||
, HasDirs env
|
binarySymLinkDestination :: ( MonadThrow m
|
||||||
, MonadThrow m, MonadIO m)
|
, MonadIO m
|
||||||
=> FilePath -- ^ the tool, such as 'ghc', 'haddock' etc.
|
)
|
||||||
-> GHCTargetVersion
|
=> FilePath -- ^ binary dir
|
||||||
-> m FilePath
|
-> FilePath -- ^ the full toolpath
|
||||||
ghcLinkDestination tool ver = do
|
-> m FilePath
|
||||||
Dirs {..} <- getDirs
|
binarySymLinkDestination binDir toolPath = do
|
||||||
ghcd <- ghcupGHCDir ver
|
toolPath' <- liftIO $ canonicalizePath toolPath
|
||||||
pure (relativeSymlink binDir (ghcd </> "bin" </> tool))
|
binDir' <- liftIO $ canonicalizePath binDir
|
||||||
|
pure (relativeSymlink binDir' toolPath')
|
||||||
|
|
||||||
|
|
||||||
-- | Removes the minor GHC symlinks, e.g. ghc-8.6.5.
|
-- | Removes the minor GHC symlinks, e.g. ghc-8.6.5.
|
||||||
rmMinorSymlinks :: ( MonadReader env m
|
rmMinorGHCSymlinks :: ( MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, HasLog env
|
, HasLog env
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
)
|
)
|
||||||
=> GHCTargetVersion
|
=> GHCTargetVersion
|
||||||
-> Excepts '[NotInstalled] m ()
|
-> Excepts '[NotInstalled] m ()
|
||||||
rmMinorSymlinks tv@GHCTargetVersion{..} = do
|
rmMinorGHCSymlinks tv@GHCTargetVersion{..} = do
|
||||||
Dirs {..} <- lift getDirs
|
Dirs {..} <- lift getDirs
|
||||||
|
|
||||||
files <- liftE $ ghcToolFiles tv
|
files <- liftE $ ghcToolFiles tv
|
||||||
@@ -160,17 +161,17 @@ rmMinorSymlinks tv@GHCTargetVersion{..} = do
|
|||||||
|
|
||||||
|
|
||||||
-- | Removes the set ghc version for the given target, if any.
|
-- | Removes the set ghc version for the given target, if any.
|
||||||
rmPlain :: ( MonadReader env m
|
rmPlainGHC :: ( MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
, HasLog env
|
, HasLog env
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
)
|
)
|
||||||
=> Maybe Text -- ^ target
|
=> Maybe Text -- ^ target
|
||||||
-> Excepts '[NotInstalled] m ()
|
-> Excepts '[NotInstalled] m ()
|
||||||
rmPlain target = do
|
rmPlainGHC target = do
|
||||||
Dirs {..} <- lift getDirs
|
Dirs {..} <- lift getDirs
|
||||||
mtv <- lift $ ghcSet target
|
mtv <- lift $ ghcSet target
|
||||||
forM_ mtv $ \tv -> do
|
forM_ mtv $ \tv -> do
|
||||||
@@ -186,17 +187,17 @@ rmPlain target = do
|
|||||||
|
|
||||||
|
|
||||||
-- | Remove the major GHC symlink, e.g. ghc-8.6.
|
-- | Remove the major GHC symlink, e.g. ghc-8.6.
|
||||||
rmMajorSymlinks :: ( MonadReader env m
|
rmMajorGHCSymlinks :: ( MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, HasLog env
|
, HasLog env
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
)
|
)
|
||||||
=> GHCTargetVersion
|
=> GHCTargetVersion
|
||||||
-> Excepts '[NotInstalled] m ()
|
-> Excepts '[NotInstalled] m ()
|
||||||
rmMajorSymlinks tv@GHCTargetVersion{..} = do
|
rmMajorGHCSymlinks tv@GHCTargetVersion{..} = do
|
||||||
Dirs {..} <- lift getDirs
|
Dirs {..} <- lift getDirs
|
||||||
(mj, mi) <- getMajorMinorV _tvVersion
|
(mj, mi) <- getMajorMinorV _tvVersion
|
||||||
let v' = intToText mj <> "." <> intToText mi
|
let v' = intToText mj <> "." <> intToText mi
|
||||||
@@ -209,6 +210,62 @@ rmMajorSymlinks tv@GHCTargetVersion{..} = do
|
|||||||
lift $ hideError doesNotExistErrorType $ rmLink fullF
|
lift $ hideError doesNotExistErrorType $ rmLink fullF
|
||||||
|
|
||||||
|
|
||||||
|
-- | Removes the minor HLS files, e.g. 'haskell-language-server-8.10.7~1.6.1.0'
|
||||||
|
-- and 'haskell-language-server-wrapper-1.6.1.0'.
|
||||||
|
rmMinorHLSSymlinks :: ( MonadReader env m
|
||||||
|
, HasDirs env
|
||||||
|
, MonadIO m
|
||||||
|
, HasLog env
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadFail m
|
||||||
|
, MonadMask m
|
||||||
|
)
|
||||||
|
=> Version
|
||||||
|
-> Excepts '[NotInstalled] m ()
|
||||||
|
rmMinorHLSSymlinks ver = do
|
||||||
|
Dirs {..} <- lift getDirs
|
||||||
|
|
||||||
|
hlsBins <- hlsAllBinaries ver
|
||||||
|
forM_ hlsBins $ \f -> do
|
||||||
|
let fullF = binDir </> f
|
||||||
|
lift $ logDebug ("rm -f " <> T.pack fullF)
|
||||||
|
-- on unix, this may be either a file (legacy) or a symlink
|
||||||
|
-- on windows, this is always a file... hence 'rmFile'
|
||||||
|
-- works consistently across platforms
|
||||||
|
lift $ rmFile fullF
|
||||||
|
|
||||||
|
-- | Removes the set HLS version, if any.
|
||||||
|
rmPlainHLS :: ( MonadReader env m
|
||||||
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadFail m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadMask m
|
||||||
|
)
|
||||||
|
=> Excepts '[NotInstalled] m ()
|
||||||
|
rmPlainHLS = do
|
||||||
|
Dirs {..} <- lift getDirs
|
||||||
|
|
||||||
|
-- delete 'haskell-language-server-8.10.7'
|
||||||
|
hlsBins <- fmap (filter (\f -> not ("haskell-language-server-wrapper" `isPrefixOf` f) && ('~' `notElem` f)))
|
||||||
|
$ liftIO $ handleIO (\_ -> pure []) $ findFiles
|
||||||
|
binDir
|
||||||
|
(makeRegexOpts compExtended execBlank ([s|^haskell-language-server-.*$|] :: ByteString))
|
||||||
|
forM_ hlsBins $ \f -> do
|
||||||
|
let fullF = binDir </> f
|
||||||
|
lift $ logDebug ("rm -f " <> T.pack fullF)
|
||||||
|
if isWindows
|
||||||
|
then lift $ rmLink fullF
|
||||||
|
else lift $ rmFile fullF
|
||||||
|
|
||||||
|
-- 'haskell-language-server-wrapper'
|
||||||
|
let hlswrapper = binDir </> "haskell-language-server-wrapper" <> exeExt
|
||||||
|
lift $ logDebug ("rm -f " <> T.pack hlswrapper)
|
||||||
|
if isWindows
|
||||||
|
then lift $ hideError doesNotExistErrorType $ rmLink hlswrapper
|
||||||
|
else lift $ hideError doesNotExistErrorType $ rmFile hlswrapper
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
@@ -352,7 +409,8 @@ cabalSet = do
|
|||||||
|
|
||||||
|
|
||||||
-- | Get all installed hls, by matching on
|
-- | Get all installed hls, by matching on
|
||||||
-- @~\/.ghcup\/bin/haskell-language-server-wrapper-<\hlsver\>@.
|
-- @~\/.ghcup\/bin/haskell-language-server-wrapper-<\hlsver\>@,
|
||||||
|
-- as well as @~\/.ghcup\/hls\/<\hlsver\>@
|
||||||
getInstalledHLSs :: (MonadReader env m, HasDirs env, MonadIO m, MonadCatch m)
|
getInstalledHLSs :: (MonadReader env m, HasDirs env, MonadIO m, MonadCatch m)
|
||||||
=> m [Either FilePath Version]
|
=> m [Either FilePath Version]
|
||||||
getInstalledHLSs = do
|
getInstalledHLSs = do
|
||||||
@@ -363,7 +421,7 @@ getInstalledHLSs = do
|
|||||||
execBlank
|
execBlank
|
||||||
([s|^haskell-language-server-wrapper-.*$|] :: ByteString)
|
([s|^haskell-language-server-wrapper-.*$|] :: ByteString)
|
||||||
)
|
)
|
||||||
forM bins $ \f ->
|
legacy <- forM bins $ \f ->
|
||||||
case
|
case
|
||||||
version . T.pack <$> (stripSuffix exeExt =<< stripPrefix "haskell-language-server-wrapper-" f)
|
version . T.pack <$> (stripSuffix exeExt =<< stripPrefix "haskell-language-server-wrapper-" f)
|
||||||
of
|
of
|
||||||
@@ -371,6 +429,14 @@ getInstalledHLSs = do
|
|||||||
Just (Left _) -> pure $ Left f
|
Just (Left _) -> pure $ Left f
|
||||||
Nothing -> pure $ Left f
|
Nothing -> pure $ Left f
|
||||||
|
|
||||||
|
hlsdir <- ghcupHLSBaseDir
|
||||||
|
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectory hlsdir
|
||||||
|
new <- forM fs $ \f -> case parseGHCupHLSDir f of
|
||||||
|
Right r -> pure $ Right r
|
||||||
|
Left _ -> pure $ Left f
|
||||||
|
pure (nub (new <> legacy))
|
||||||
|
|
||||||
|
|
||||||
-- | Get all installed stacks, by matching on
|
-- | Get all installed stacks, by matching on
|
||||||
-- @~\/.ghcup\/bin/stack-<\stackver\>@.
|
-- @~\/.ghcup\/bin/stack-<\stackver\>@.
|
||||||
getInstalledStacks :: (MonadReader env m, HasDirs env, MonadIO m, MonadCatch m)
|
getInstalledStacks :: (MonadReader env m, HasDirs env, MonadIO m, MonadCatch m)
|
||||||
@@ -446,6 +512,10 @@ hlsInstalled ver = do
|
|||||||
vers <- fmap rights getInstalledHLSs
|
vers <- fmap rights getInstalledHLSs
|
||||||
pure $ elem ver vers
|
pure $ elem ver vers
|
||||||
|
|
||||||
|
isLegacyHLS :: (MonadIO m, MonadReader env m, HasDirs env, MonadCatch m) => Version -> m Bool
|
||||||
|
isLegacyHLS ver = do
|
||||||
|
bdir <- ghcupHLSDir ver
|
||||||
|
not <$> liftIO (doesDirectoryExist bdir)
|
||||||
|
|
||||||
|
|
||||||
-- Return the currently set hls version, if any.
|
-- Return the currently set hls version, if any.
|
||||||
@@ -517,7 +587,7 @@ hlsGHCVersions' v' = do
|
|||||||
pure . sortBy (flip compare) . rights $ vers
|
pure . sortBy (flip compare) . rights $ vers
|
||||||
|
|
||||||
|
|
||||||
-- | Get all server binaries for an hls version, if any.
|
-- | Get all server binaries for an hls version from the ~/.ghcup/bin directory, if any.
|
||||||
hlsServerBinaries :: (MonadReader env m, HasDirs env, MonadIO m)
|
hlsServerBinaries :: (MonadReader env m, HasDirs env, MonadIO m)
|
||||||
=> Version
|
=> Version
|
||||||
-> Maybe Version -- ^ optional GHC version
|
-> Maybe Version -- ^ optional GHC version
|
||||||
@@ -538,6 +608,44 @@ hlsServerBinaries ver mghcVer = do
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- | Get all scripts for a hls version from the ~/.ghcup/hls/<ver>/bin directory, if any.
|
||||||
|
-- Returns the full path.
|
||||||
|
hlsInternalServerScripts :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m)
|
||||||
|
=> Version
|
||||||
|
-> Maybe Version -- ^ optional GHC version
|
||||||
|
-> m [FilePath]
|
||||||
|
hlsInternalServerScripts ver mghcVer = do
|
||||||
|
dir <- ghcupHLSDir ver
|
||||||
|
let bdir = dir </> "bin"
|
||||||
|
fmap (bdir </>) . filter (\f -> maybe True (\gv -> ("-" <> T.unpack (prettyVer gv)) `isSuffixOf` f) mghcVer)
|
||||||
|
<$> liftIO (listDirectory bdir)
|
||||||
|
|
||||||
|
-- | Get all binaries for a hls version from the ~/.ghcup/hls/<ver>/lib/haskell-language-server-<ver>/bin directory, if any.
|
||||||
|
-- Returns the full path.
|
||||||
|
hlsInternalServerBinaries :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m, MonadFail m)
|
||||||
|
=> Version
|
||||||
|
-> Maybe Version -- ^ optional GHC version
|
||||||
|
-> m [FilePath]
|
||||||
|
hlsInternalServerBinaries ver mghcVer = do
|
||||||
|
dir <- ghcupHLSDir ver
|
||||||
|
let regex = makeRegexOpts compExtended execBlank ([s|^haskell-language-server-.*$|] :: ByteString)
|
||||||
|
(Just bdir) <- fmap headMay $ liftIO $ expandFilePath [Left (dir </> "lib"), Right regex, Left "bin"]
|
||||||
|
fmap (bdir </>) . filter (\f -> maybe True (\gv -> ("-" <> T.unpack (prettyVer gv)) `isSuffixOf` f) mghcVer)
|
||||||
|
<$> liftIO (listDirectory bdir)
|
||||||
|
|
||||||
|
-- | Get all libraries for a hls version from the ~/.ghcup/hls/<ver>/lib/haskell-language-server-<ver>/lib/<ghc-ver>/
|
||||||
|
-- directory, if any.
|
||||||
|
-- Returns the full path.
|
||||||
|
hlsInternalServerLibs :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m, MonadFail m)
|
||||||
|
=> Version
|
||||||
|
-> Version -- ^ GHC version
|
||||||
|
-> m [FilePath]
|
||||||
|
hlsInternalServerLibs ver ghcVer = do
|
||||||
|
dir <- ghcupHLSDir ver
|
||||||
|
let regex = makeRegexOpts compExtended execBlank ([s|^haskell-language-server-.*$|] :: ByteString)
|
||||||
|
(Just bdir) <- fmap headMay $ liftIO $ expandFilePath [Left (dir </> "lib"), Right regex, Left ("lib" </> T.unpack (prettyVer ghcVer))]
|
||||||
|
fmap (bdir </>) <$> liftIO (listDirectory bdir)
|
||||||
|
|
||||||
|
|
||||||
-- | Get the wrapper binary for an hls version, if any.
|
-- | Get the wrapper binary for an hls version, if any.
|
||||||
hlsWrapperBinary :: (MonadReader env m, HasDirs env, MonadThrow m, MonadIO m)
|
hlsWrapperBinary :: (MonadReader env m, HasDirs env, MonadThrow m, MonadIO m)
|
||||||
@@ -568,22 +676,6 @@ hlsAllBinaries ver = do
|
|||||||
pure (maybeToList wrapper ++ hls)
|
pure (maybeToList wrapper ++ hls)
|
||||||
|
|
||||||
|
|
||||||
-- | Get the active symlinks for hls.
|
|
||||||
hlsSymlinks :: (MonadReader env m, HasDirs env, MonadIO m, MonadCatch m) => m [FilePath]
|
|
||||||
hlsSymlinks = do
|
|
||||||
Dirs {..} <- getDirs
|
|
||||||
oldSyms <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
|
||||||
binDir
|
|
||||||
(makeRegexOpts compExtended
|
|
||||||
execBlank
|
|
||||||
([s|^haskell-language-server-.*$|] :: ByteString)
|
|
||||||
)
|
|
||||||
filterM
|
|
||||||
( liftIO
|
|
||||||
. pathIsLink
|
|
||||||
. (binDir </>)
|
|
||||||
)
|
|
||||||
oldSyms
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -631,34 +723,34 @@ getGHCForPVP pvpIn mt = do
|
|||||||
ghcs <- rights <$> getInstalledGHCs
|
ghcs <- rights <$> getInstalledGHCs
|
||||||
-- we're permissive here... failed parse just means we have no match anyway
|
-- we're permissive here... failed parse just means we have no match anyway
|
||||||
let ghcs' = catMaybes $ flip fmap ghcs $ \GHCTargetVersion{..} -> do
|
let ghcs' = catMaybes $ flip fmap ghcs $ \GHCTargetVersion{..} -> do
|
||||||
pvp_ <- versionToPVP _tvVersion
|
(pvp_, rest) <- versionToPVP _tvVersion
|
||||||
pure (pvp_, _tvTarget)
|
pure (pvp_, rest, _tvTarget)
|
||||||
|
|
||||||
getGHCForPVP' pvpIn ghcs' mt
|
getGHCForPVP' pvpIn ghcs' mt
|
||||||
|
|
||||||
-- | Like 'getGHCForPVP', except with explicit input parameter.
|
-- | Like 'getGHCForPVP', except with explicit input parameter.
|
||||||
--
|
--
|
||||||
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8|] installedVersions Nothing
|
-- >>> getGHCForPVP' [pver|8|] installedVersions Nothing
|
||||||
-- "Just 8.10.7"
|
-- Just (GHCTargetVersion {_tvTarget = Nothing, _tvVersion = Version {_vEpoch = Nothing, _vChunks = (Digits 8 :| []) :| [Digits 10 :| [],Digits 7 :| []], _vRel = [Str "debug" :| []], _vMeta = Just "lol"}})
|
||||||
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8.8|] installedVersions Nothing
|
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8.8|] installedVersions Nothing
|
||||||
-- "Just 8.8.4"
|
-- "Just 8.8.4"
|
||||||
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8.10.4|] installedVersions Nothing
|
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8.10.4|] installedVersions Nothing
|
||||||
-- "Just 8.10.4"
|
-- "Just 8.10.4"
|
||||||
getGHCForPVP' :: MonadThrow m
|
getGHCForPVP' :: MonadThrow m
|
||||||
=> PVP
|
=> PVP
|
||||||
-> [(PVP, Maybe Text)] -- ^ installed GHCs
|
-> [(PVP, Text, Maybe Text)] -- ^ installed GHCs
|
||||||
-> Maybe Text -- ^ the target triple
|
-> Maybe Text -- ^ the target triple
|
||||||
-> m (Maybe GHCTargetVersion)
|
-> m (Maybe GHCTargetVersion)
|
||||||
getGHCForPVP' pvpIn ghcs' mt = do
|
getGHCForPVP' pvpIn ghcs' mt = do
|
||||||
let mResult = lastMay
|
let mResult = lastMay
|
||||||
. sortBy (\(x, _) (y, _) -> compare x y)
|
. sortBy (\(x, _, _) (y, _, _) -> compare x y)
|
||||||
. filter
|
. filter
|
||||||
(\(pvp_, target) ->
|
(\(pvp_, _, target) ->
|
||||||
target == mt && matchPVPrefix pvp_ pvpIn
|
target == mt && matchPVPrefix pvp_ pvpIn
|
||||||
)
|
)
|
||||||
$ ghcs'
|
$ ghcs'
|
||||||
forM mResult $ \(pvp_, target) -> do
|
forM mResult $ \(pvp_, rest, target) -> do
|
||||||
ver' <- pvpToVersion pvp_
|
ver' <- pvpToVersion pvp_ rest
|
||||||
pure (GHCTargetVersion target ver')
|
pure (GHCTargetVersion target ver')
|
||||||
|
|
||||||
|
|
||||||
@@ -679,7 +771,7 @@ getLatestToolFor :: MonadThrow m
|
|||||||
getLatestToolFor tool pvpIn dls = do
|
getLatestToolFor tool pvpIn dls = do
|
||||||
let ls = fromMaybe [] $ preview (ix tool % to Map.toDescList) dls
|
let ls = fromMaybe [] $ preview (ix tool % to Map.toDescList) dls
|
||||||
let ps = catMaybes $ fmap (\(v, vi) -> (,vi) <$> versionToPVP v) ls
|
let ps = catMaybes $ fmap (\(v, vi) -> (,vi) <$> versionToPVP v) ls
|
||||||
pure . headMay . filter (\(v, _) -> matchPVPrefix pvpIn v) $ ps
|
pure . fmap (first fst) . headMay . filter (\((v, _), _) -> matchPVPrefix pvpIn v) $ ps
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -714,7 +806,7 @@ unpackToDir dfp av = do
|
|||||||
(untar . GZip.decompress =<< rf av)
|
(untar . GZip.decompress =<< rf av)
|
||||||
| ".tar.xz" `isSuffixOf` fn -> do
|
| ".tar.xz" `isSuffixOf` fn -> do
|
||||||
filecontents <- liftE $ rf av
|
filecontents <- liftE $ rf av
|
||||||
let decompressed = Lzma.decompress filecontents
|
let decompressed = Lzma.decompressWith (Lzma.defaultDecompressParams { Lzma.decompressAutoDecoder= True }) filecontents
|
||||||
liftE $ untar decompressed
|
liftE $ untar decompressed
|
||||||
| ".tar.bz2" `isSuffixOf` fn ->
|
| ".tar.bz2" `isSuffixOf` fn ->
|
||||||
liftE (untar . BZip.decompress =<< rf av)
|
liftE (untar . BZip.decompress =<< rf av)
|
||||||
@@ -743,7 +835,7 @@ getArchiveFiles av = do
|
|||||||
(entries . GZip.decompress =<< rf av)
|
(entries . GZip.decompress =<< rf av)
|
||||||
| ".tar.xz" `isSuffixOf` fn -> do
|
| ".tar.xz" `isSuffixOf` fn -> do
|
||||||
filecontents <- liftE $ rf av
|
filecontents <- liftE $ rf av
|
||||||
let decompressed = Lzma.decompress filecontents
|
let decompressed = Lzma.decompressWith (Lzma.defaultDecompressParams { Lzma.decompressAutoDecoder= True }) filecontents
|
||||||
liftE $ entries decompressed
|
liftE $ entries decompressed
|
||||||
| ".tar.bz2" `isSuffixOf` fn ->
|
| ".tar.bz2" `isSuffixOf` fn ->
|
||||||
liftE (entries . BZip.decompress =<< rf av)
|
liftE (entries . BZip.decompress =<< rf av)
|
||||||
@@ -808,8 +900,16 @@ getLatestBaseVersion av pvpVer =
|
|||||||
--[ Other ]--
|
--[ Other ]--
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
-- | Usually @~\/.ghcup\/ghc\/\<ver\>\/bin\/@
|
||||||
|
ghcInternalBinDir :: (MonadReader env m, HasDirs env, MonadThrow m, MonadFail m, MonadIO m)
|
||||||
|
=> GHCTargetVersion
|
||||||
|
-> m FilePath
|
||||||
|
ghcInternalBinDir ver = do
|
||||||
|
ghcdir <- ghcupGHCDir ver
|
||||||
|
pure (ghcdir </> "bin")
|
||||||
|
|
||||||
-- | Get tool files from @~\/.ghcup\/bin\/ghc\/\<ver\>\/bin\/\*@
|
|
||||||
|
-- | Get tool files from @~\/.ghcup\/ghc\/\<ver\>\/bin\/\*@
|
||||||
-- while ignoring @*-\<ver\>@ symlinks and accounting for cross triple prefix.
|
-- while ignoring @*-\<ver\>@ symlinks and accounting for cross triple prefix.
|
||||||
--
|
--
|
||||||
-- Returns unversioned relative files without extension, e.g.:
|
-- Returns unversioned relative files without extension, e.g.:
|
||||||
@@ -819,11 +919,10 @@ ghcToolFiles :: (MonadReader env m, HasDirs env, MonadThrow m, MonadFail m, Mona
|
|||||||
=> GHCTargetVersion
|
=> GHCTargetVersion
|
||||||
-> Excepts '[NotInstalled] m [FilePath]
|
-> Excepts '[NotInstalled] m [FilePath]
|
||||||
ghcToolFiles ver = do
|
ghcToolFiles ver = do
|
||||||
ghcdir <- lift $ ghcupGHCDir ver
|
bindir <- ghcInternalBinDir ver
|
||||||
let bindir = ghcdir </> "bin"
|
|
||||||
|
|
||||||
-- fail if ghc is not installed
|
-- fail if ghc is not installed
|
||||||
whenM (fmap not $ liftIO $ doesDirectoryExist ghcdir)
|
whenM (fmap not $ ghcInstalled ver)
|
||||||
(throwE (NotInstalled GHC ver))
|
(throwE (NotInstalled GHC ver))
|
||||||
|
|
||||||
files <- liftIO (listDirectory bindir >>= filterM (doesFileExist . (bindir </>)))
|
files <- liftIO (listDirectory bindir >>= filterM (doesFileExist . (bindir </>)))
|
||||||
@@ -855,6 +954,7 @@ make :: ( MonadThrow m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadReader env m
|
, MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
)
|
)
|
||||||
=> [String]
|
=> [String]
|
||||||
@@ -877,28 +977,43 @@ makeOut args workdir = do
|
|||||||
executeOut mymake args workdir
|
executeOut mymake args workdir
|
||||||
|
|
||||||
|
|
||||||
-- | Try to apply patches in order. Fails with 'PatchFailed'
|
-- | Try to apply patches in order. The order is determined by
|
||||||
-- on first failure.
|
-- a quilt series file (in the patch directory) if one exists,
|
||||||
|
-- else the patches are applied in lexicographical order.
|
||||||
|
-- Fails with 'PatchFailed' on first failure.
|
||||||
applyPatches :: (MonadReader env m, HasDirs env, HasLog env, MonadIO m)
|
applyPatches :: (MonadReader env m, HasDirs env, HasLog env, MonadIO m)
|
||||||
=> FilePath -- ^ dir containing patches
|
=> FilePath -- ^ dir containing patches
|
||||||
-> FilePath -- ^ dir to apply patches in
|
-> FilePath -- ^ dir to apply patches in
|
||||||
-> Excepts '[PatchFailed] m ()
|
-> Excepts '[PatchFailed] m ()
|
||||||
applyPatches pdir ddir = do
|
applyPatches pdir ddir = do
|
||||||
patches <- (fmap . fmap) (pdir </>) $ liftIO $ findFiles
|
let lexicographical = (fmap . fmap) (pdir </>) $ sort <$> findFiles
|
||||||
pdir
|
pdir
|
||||||
(makeRegexOpts compExtended
|
(makeRegexOpts compExtended
|
||||||
execBlank
|
execBlank
|
||||||
([s|.+\.(patch|diff)$|] :: ByteString)
|
([s|.+\.(patch|diff)$|] :: ByteString)
|
||||||
)
|
)
|
||||||
forM_ (sort patches) $ \patch' -> do
|
let quilt = map (pdir </>) . lines <$> readFile (pdir </> "series")
|
||||||
lift $ logInfo $ "Applying patch " <> T.pack patch'
|
|
||||||
fmap (either (const Nothing) Just)
|
patches <- liftIO $ quilt `catchIO` (\e ->
|
||||||
(exec
|
if isDoesNotExistError e || isPermissionError e then
|
||||||
"patch"
|
lexicographical
|
||||||
["-p1", "-i", patch']
|
else throwIO e)
|
||||||
(Just ddir)
|
forM_ patches $ \patch' -> applyPatch patch' ddir
|
||||||
Nothing)
|
|
||||||
!? PatchFailed
|
|
||||||
|
applyPatch :: (MonadReader env m, HasDirs env, HasLog env, MonadIO m)
|
||||||
|
=> FilePath -- ^ Patch
|
||||||
|
-> FilePath -- ^ dir to apply patches in
|
||||||
|
-> Excepts '[PatchFailed] m ()
|
||||||
|
applyPatch patch ddir = do
|
||||||
|
lift $ logInfo $ "Applying patch " <> T.pack patch
|
||||||
|
fmap (either (const Nothing) Just)
|
||||||
|
(exec
|
||||||
|
"patch"
|
||||||
|
["-p1", "-s", "-f", "-i", patch]
|
||||||
|
(Just ddir)
|
||||||
|
Nothing)
|
||||||
|
!? PatchFailed
|
||||||
|
|
||||||
|
|
||||||
-- | https://gitlab.haskell.org/ghc/ghc/-/issues/17353
|
-- | https://gitlab.haskell.org/ghc/ghc/-/issues/17353
|
||||||
@@ -1132,11 +1247,27 @@ ensureDirectories (Dirs baseDir binDir cacheDir logsDir confDir trashDir) = do
|
|||||||
|
|
||||||
-- | For ghc without arch triple, this is:
|
-- | For ghc without arch triple, this is:
|
||||||
--
|
--
|
||||||
-- - ghc-<ver> (e.g. ghc-8.10.4)
|
-- - ghc
|
||||||
--
|
--
|
||||||
-- For ghc with arch triple:
|
-- For ghc with arch triple:
|
||||||
--
|
--
|
||||||
-- - <triple>-ghc-<ver> (e.g. arm-linux-gnueabihf-ghc-8.10.4)
|
-- - <triple>-ghc (e.g. arm-linux-gnueabihf-ghc)
|
||||||
ghcBinaryName :: GHCTargetVersion -> String
|
ghcBinaryName :: GHCTargetVersion -> String
|
||||||
ghcBinaryName (GHCTargetVersion (Just t) v') = T.unpack (t <> "-ghc-" <> prettyVer v' <> T.pack exeExt)
|
ghcBinaryName (GHCTargetVersion (Just t) _) = T.unpack (t <> "-ghc" <> T.pack exeExt)
|
||||||
ghcBinaryName (GHCTargetVersion Nothing v') = T.unpack ("ghc-" <> prettyVer v' <> T.pack exeExt)
|
ghcBinaryName (GHCTargetVersion Nothing _) = T.unpack ("ghc" <> T.pack exeExt)
|
||||||
|
|
||||||
|
|
||||||
|
-- | Does basic checks for isolated installs
|
||||||
|
-- Isolated Directory:
|
||||||
|
-- 1. if it doesn't exist -> proceed
|
||||||
|
-- 2. if it exists and is empty -> proceed
|
||||||
|
-- 3. if it exists and is non-empty -> panic and leave the house
|
||||||
|
installDestSanityCheck :: ( MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
) =>
|
||||||
|
FilePath ->
|
||||||
|
Excepts '[DirNotEmpty] m ()
|
||||||
|
installDestSanityCheck isoDir = do
|
||||||
|
hideErrorDef [doesNotExistErrorType] () $ do
|
||||||
|
contents <- liftIO $ getDirectoryContentsRecursive isoDir
|
||||||
|
unless (null contents) (throwE $ DirNotEmpty isoDir)
|
||||||
|
|||||||
@@ -20,8 +20,11 @@ module GHCup.Utils.Dirs
|
|||||||
, ghcupCacheDir
|
, ghcupCacheDir
|
||||||
, ghcupGHCBaseDir
|
, ghcupGHCBaseDir
|
||||||
, ghcupGHCDir
|
, ghcupGHCDir
|
||||||
|
, ghcupHLSBaseDir
|
||||||
|
, ghcupHLSDir
|
||||||
, mkGhcupTmpDir
|
, mkGhcupTmpDir
|
||||||
, parseGHCupGHCDir
|
, parseGHCupGHCDir
|
||||||
|
, parseGHCupHLSDir
|
||||||
, relativeSymlink
|
, relativeSymlink
|
||||||
, withGHCupTmpDir
|
, withGHCupTmpDir
|
||||||
, getConfigFilePath
|
, getConfigFilePath
|
||||||
@@ -46,6 +49,7 @@ import Control.Monad.Reader
|
|||||||
import Control.Monad.Trans.Resource hiding (throwM)
|
import Control.Monad.Trans.Resource hiding (throwM)
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
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
|
import Optics
|
||||||
@@ -244,6 +248,24 @@ parseGHCupGHCDir :: MonadThrow m => FilePath -> m GHCTargetVersion
|
|||||||
parseGHCupGHCDir (T.pack -> fp) =
|
parseGHCupGHCDir (T.pack -> fp) =
|
||||||
throwEither $ MP.parse ghcTargetVerP "" fp
|
throwEither $ MP.parse ghcTargetVerP "" fp
|
||||||
|
|
||||||
|
parseGHCupHLSDir :: MonadThrow m => FilePath -> m Version
|
||||||
|
parseGHCupHLSDir (T.pack -> fp) =
|
||||||
|
throwEither $ MP.parse version' "" fp
|
||||||
|
|
||||||
|
-- | ~/.ghcup/hls by default, for new-style installs.
|
||||||
|
ghcupHLSBaseDir :: (MonadReader env m, HasDirs env) => m FilePath
|
||||||
|
ghcupHLSBaseDir = do
|
||||||
|
Dirs {..} <- getDirs
|
||||||
|
pure (baseDir </> "hls")
|
||||||
|
|
||||||
|
-- | Gets '~/.ghcup/hls/<hls-ver>' for new-style installs.
|
||||||
|
ghcupHLSDir :: (MonadReader env m, HasDirs env, MonadThrow m)
|
||||||
|
=> Version
|
||||||
|
-> m FilePath
|
||||||
|
ghcupHLSDir ver = do
|
||||||
|
basedir <- ghcupHLSBaseDir
|
||||||
|
let verdir = T.unpack $ prettyVer ver
|
||||||
|
pure (basedir </> verdir)
|
||||||
|
|
||||||
mkGhcupTmpDir :: ( MonadReader env m
|
mkGhcupTmpDir :: ( MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
@@ -313,6 +335,7 @@ useXDG :: IO Bool
|
|||||||
useXDG = isJust <$> lookupEnv "GHCUP_USE_XDG_DIRS"
|
useXDG = isJust <$> lookupEnv "GHCUP_USE_XDG_DIRS"
|
||||||
|
|
||||||
|
|
||||||
|
-- | Like 'relpath'. Assumes the inputs are resolved in case of symlinks.
|
||||||
relativeSymlink :: FilePath -- ^ the path in which to create the symlink
|
relativeSymlink :: FilePath -- ^ the path in which to create the symlink
|
||||||
-> FilePath -- ^ the symlink destination
|
-> FilePath -- ^ the symlink destination
|
||||||
-> FilePath
|
-> FilePath
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
|
||||||
|
|
||||||
module GHCup.Utils.File.Common where
|
module GHCup.Utils.File.Common (
|
||||||
|
module GHCup.Utils.File.Common
|
||||||
|
, ProcessError(..)
|
||||||
|
, CapturedProcess(..)
|
||||||
|
) where
|
||||||
|
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Utils.Prelude
|
||||||
|
import GHCup.Types(ProcessError(..), CapturedProcess(..))
|
||||||
|
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
@@ -13,7 +16,7 @@ import Data.Text ( Text )
|
|||||||
import Data.Void
|
import Data.Void
|
||||||
import GHC.IO.Exception
|
import GHC.IO.Exception
|
||||||
import Optics hiding ((<|), (|>))
|
import Optics hiding ((<|), (|>))
|
||||||
import System.Directory
|
import System.Directory hiding (findFiles)
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import Text.PrettyPrint.HughesPJClass hiding ( (<>) )
|
import Text.PrettyPrint.HughesPJClass hiding ( (<>) )
|
||||||
import Text.Regex.Posix
|
import Text.Regex.Posix
|
||||||
@@ -24,33 +27,6 @@ import qualified Text.Megaparsec as MP
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
data ProcessError = NonZeroExit Int FilePath [String]
|
|
||||||
| PTerminated FilePath [String]
|
|
||||||
| PStopped FilePath [String]
|
|
||||||
| NoSuchPid FilePath [String]
|
|
||||||
deriving Show
|
|
||||||
|
|
||||||
instance Pretty ProcessError where
|
|
||||||
pPrint (NonZeroExit e exe args) =
|
|
||||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "failed with exit code" <+> text (show e <> ".")
|
|
||||||
pPrint (PTerminated exe args) =
|
|
||||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "terminated."
|
|
||||||
pPrint (PStopped exe args) =
|
|
||||||
text "Process" <+> pPrint exe <+> text "with arguments" <+> pPrint args <+> text "stopped."
|
|
||||||
pPrint (NoSuchPid exe args) =
|
|
||||||
text "Could not find PID for process running " <+> pPrint exe <+> text " with arguments " <+> text (show args) <+> text "."
|
|
||||||
|
|
||||||
data CapturedProcess = CapturedProcess
|
|
||||||
{ _exitCode :: ExitCode
|
|
||||||
, _stdOut :: BL.ByteString
|
|
||||||
, _stdErr :: BL.ByteString
|
|
||||||
}
|
|
||||||
deriving (Eq, Show)
|
|
||||||
|
|
||||||
makeLenses ''CapturedProcess
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- | Search for a file in the search paths.
|
-- | Search for a file in the search paths.
|
||||||
--
|
--
|
||||||
-- Catches `PermissionDenied` and `NoSuchThing` and returns `Nothing`.
|
-- Catches `PermissionDenied` and `NoSuchThing` and returns `Nothing`.
|
||||||
@@ -100,6 +76,21 @@ isInPath p = do
|
|||||||
else pure False
|
else pure False
|
||||||
|
|
||||||
|
|
||||||
|
-- | Follows the first match in case of Regex.
|
||||||
|
expandFilePath :: [Either FilePath Regex] -> IO [FilePath]
|
||||||
|
expandFilePath = go ""
|
||||||
|
where
|
||||||
|
go :: FilePath -> [Either FilePath Regex] -> IO [FilePath]
|
||||||
|
go p [] = pure [p]
|
||||||
|
go p (x:xs) = do
|
||||||
|
case x of
|
||||||
|
Left s -> go (p </> s) xs
|
||||||
|
Right regex -> do
|
||||||
|
fps <- findFiles p regex
|
||||||
|
res <- forM fps $ \fp -> go (p </> fp) xs
|
||||||
|
pure $ mconcat res
|
||||||
|
|
||||||
|
|
||||||
findFiles :: FilePath -> Regex -> IO [FilePath]
|
findFiles :: FilePath -> Regex -> IO [FilePath]
|
||||||
findFiles path regex = do
|
findFiles path regex = do
|
||||||
contents <- listDirectory path
|
contents <- listDirectory path
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import Data.Sequence ( Seq, (|>) )
|
|||||||
import Data.List
|
import Data.List
|
||||||
import Data.Word8
|
import Data.Word8
|
||||||
import GHC.IO.Exception
|
import GHC.IO.Exception
|
||||||
import System.Console.Terminal.Common
|
import System.IO ( stderr )
|
||||||
import System.IO.Error
|
import System.IO.Error
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.Directory
|
import System.Directory
|
||||||
@@ -51,7 +51,7 @@ import qualified Data.Sequence as Sq
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
import qualified System.Posix.Process as SPP
|
import qualified System.Posix.Process as SPP
|
||||||
import qualified System.Console.Terminal.Posix as TP
|
import qualified System.Console.Terminal.Size as TP
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified "unix-bytestring" System.Posix.IO.ByteString
|
import qualified "unix-bytestring" System.Posix.IO.ByteString
|
||||||
@@ -73,6 +73,7 @@ executeOut path args chdir = liftIO $ captureOutStreams $ do
|
|||||||
|
|
||||||
execLogged :: ( MonadReader env m
|
execLogged :: ( MonadReader env m
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
|
, HasLog env
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadThrow m)
|
, MonadThrow m)
|
||||||
@@ -85,6 +86,7 @@ execLogged :: ( MonadReader env m
|
|||||||
execLogged exe args chdir lfile env = do
|
execLogged exe args chdir lfile env = do
|
||||||
Settings {..} <- getSettings
|
Settings {..} <- getSettings
|
||||||
Dirs {..} <- getDirs
|
Dirs {..} <- getDirs
|
||||||
|
logDebug $ T.pack $ "Running " <> exe <> " with arguments " <> show args
|
||||||
let logfile = logsDir </> lfile <> ".log"
|
let logfile = logsDir </> lfile <> ".log"
|
||||||
liftIO $ bracket (openFd logfile WriteOnly (Just newFilePerms) defaultFileFlags{ append = True })
|
liftIO $ bracket (openFd logfile WriteOnly (Just newFilePerms) defaultFileFlags{ append = True })
|
||||||
closeFd
|
closeFd
|
||||||
@@ -141,14 +143,14 @@ execLogged exe args chdir lfile env = do
|
|||||||
printToRegion :: Fd -> Fd -> Int -> MVar Bool -> Bool -> IO ()
|
printToRegion :: Fd -> Fd -> Int -> MVar Bool -> Bool -> IO ()
|
||||||
printToRegion fileFd fdIn size pState no_color = do
|
printToRegion fileFd fdIn size pState no_color = do
|
||||||
-- init region
|
-- init region
|
||||||
forM_ [1..size] $ \_ -> BS.putStr "\n"
|
forM_ [1..size] $ \_ -> BS.hPut stderr "\n"
|
||||||
|
|
||||||
void $ flip runStateT mempty
|
void $ flip runStateT mempty
|
||||||
$ do
|
$ do
|
||||||
handle
|
handle
|
||||||
(\(ex :: SomeException) -> do
|
(\(ex :: SomeException) -> do
|
||||||
ps <- liftIO $ takeMVar pState
|
ps <- liftIO $ takeMVar pState
|
||||||
when ps (liftIO $ BS.putStr (pos1 <> moveLineUp size <> clearScreen))
|
when ps (liftIO $ BS.hPut stderr (pos1 <> moveLineUp size <> clearScreen))
|
||||||
throw ex
|
throw ex
|
||||||
) $ readTilEOF lineAction fdIn
|
) $ readTilEOF lineAction fdIn
|
||||||
|
|
||||||
@@ -180,10 +182,10 @@ execLogged exe args chdir lfile env = do
|
|||||||
modify (swapRegs bs')
|
modify (swapRegs bs')
|
||||||
liftIO TP.size >>= \case
|
liftIO TP.size >>= \case
|
||||||
Nothing -> pure ()
|
Nothing -> pure ()
|
||||||
Just (Window _ w) -> do
|
Just (TP.Window _ w) -> do
|
||||||
regs <- get
|
regs <- get
|
||||||
liftIO $ forM_ (Sq.zip regs (Sq.fromList [0..(Sq.length regs - 1)])) $ \(bs, i) -> do
|
liftIO $ forM_ (Sq.zip regs (Sq.fromList [0..(Sq.length regs - 1)])) $ \(bs, i) -> do
|
||||||
BS.putStr
|
BS.hPut stderr
|
||||||
. overwriteNthLine (size - i)
|
. overwriteNthLine (size - i)
|
||||||
. trim w
|
. trim w
|
||||||
. blue
|
. blue
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ module GHCup.Utils.File.Windows where
|
|||||||
import {-# SOURCE #-} GHCup.Utils ( getLinkTarget, pathIsLink )
|
import {-# SOURCE #-} GHCup.Utils ( getLinkTarget, pathIsLink )
|
||||||
import GHCup.Utils.Dirs
|
import GHCup.Utils.Dirs
|
||||||
import GHCup.Utils.File.Common
|
import GHCup.Utils.File.Common
|
||||||
|
import GHCup.Utils.Logger
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ import qualified Control.Exception as EX
|
|||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
|
import qualified Data.Text as T
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -149,6 +151,7 @@ executeOut path args chdir = do
|
|||||||
|
|
||||||
execLogged :: ( MonadReader env m
|
execLogged :: ( MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadThrow m)
|
, MonadThrow m)
|
||||||
@@ -160,6 +163,7 @@ execLogged :: ( MonadReader env m
|
|||||||
-> m (Either ProcessError ())
|
-> m (Either ProcessError ())
|
||||||
execLogged exe args chdir lfile env = do
|
execLogged exe args chdir lfile env = do
|
||||||
Dirs {..} <- getDirs
|
Dirs {..} <- getDirs
|
||||||
|
logDebug $ T.pack $ "Running " <> exe <> " with arguments " <> show args
|
||||||
let stdoutLogfile = logsDir </> lfile <> ".stdout.log"
|
let stdoutLogfile = logsDir </> lfile <> ".stdout.log"
|
||||||
stderrLogfile = logsDir </> lfile <> ".stderr.log"
|
stderrLogfile = logsDir </> lfile <> ".stderr.log"
|
||||||
cp <- createProcessWithMingwPath ((proc exe args)
|
cp <- createProcessWithMingwPath ((proc exe args)
|
||||||
@@ -192,7 +196,8 @@ execLogged exe args chdir lfile env = do
|
|||||||
then pure ()
|
then pure ()
|
||||||
else do
|
else do
|
||||||
void $ BS.appendFile logFile some
|
void $ BS.appendFile logFile some
|
||||||
void $ BS.hPut stdout some
|
-- subprocess stdout also goes to stderr for logging
|
||||||
|
void $ BS.hPut stderr some
|
||||||
go
|
go
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
|
||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ module GHCup.Utils.Logger where
|
|||||||
|
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
import {-# SOURCE #-} GHCup.Utils.File.Common
|
import {-# SOURCE #-} GHCup.Utils.File.Common (findFiles)
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Utils.String.QQ
|
||||||
|
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
|
||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
|
|
||||||
module GHCup.Utils.Logger where
|
module GHCup.Utils.Logger where
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ where
|
|||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
import {-# SOURCE #-} GHCup.Utils.Logger
|
import {-# SOURCE #-} GHCup.Utils.Logger (logWarn)
|
||||||
#if defined(IS_WINDOWS)
|
#if defined(IS_WINDOWS)
|
||||||
import GHCup.Utils.Prelude.Windows
|
import GHCup.Utils.Prelude.Windows
|
||||||
#else
|
#else
|
||||||
@@ -44,7 +44,7 @@ import Control.Monad.IO.Class
|
|||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.List ( nub, intercalate, stripPrefix, isPrefixOf, dropWhileEnd )
|
import Data.List ( nub, intercalate, stripPrefix, isPrefixOf, dropWhileEnd, intersperse )
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Foldable
|
import Data.Foldable
|
||||||
import Data.List.NonEmpty ( NonEmpty( (:|) ))
|
import Data.List.NonEmpty ( NonEmpty( (:|) ))
|
||||||
@@ -308,23 +308,46 @@ intToText :: Integral a => a -> T.Text
|
|||||||
intToText = TL.toStrict . B.toLazyText . B.decimal
|
intToText = TL.toStrict . B.toLazyText . B.decimal
|
||||||
|
|
||||||
|
|
||||||
removeLensFieldLabel :: String -> String
|
pvpToVersion :: MonadThrow m => PVP -> Text -> m Version
|
||||||
removeLensFieldLabel str' =
|
pvpToVersion pvp_ rest =
|
||||||
maybe str' T.unpack . T.stripPrefix (T.pack "_") . T.pack $ str'
|
either (\_ -> throwM $ ParseError "Couldn't convert PVP to Version") pure . version . (<> rest) . prettyPVP $ pvp_
|
||||||
|
|
||||||
|
-- | Convert a version to a PVP and unparsable rest.
|
||||||
pvpToVersion :: MonadThrow m => PVP -> m Version
|
--
|
||||||
pvpToVersion =
|
-- -- prop> \v -> let (Just (pvp', r)) = versionToPVP v in pvpToVersion pvp' r === Just v
|
||||||
either (\_ -> throwM $ ParseError "Couldn't convert PVP to Version") pure . version . prettyPVP
|
versionToPVP :: MonadThrow m => Version -> m (PVP, Text)
|
||||||
|
versionToPVP (Version (Just _) _ _ _) = throwM $ ParseError "Unexpected epoch"
|
||||||
versionToPVP :: MonadThrow m => Version -> m PVP
|
versionToPVP v = either (\_ -> (, rest v) <$> alternative v) (pure . (, mempty)) . pvp . prettyVer $ v
|
||||||
versionToPVP v = either (\_ -> alternative v) pure . pvp . prettyVer $ v
|
|
||||||
where
|
where
|
||||||
alternative :: MonadThrow m => Version -> m PVP
|
alternative :: MonadThrow m => Version -> m PVP
|
||||||
alternative v' = case NE.takeWhile isDigit (_vChunks v') of
|
alternative v' = case NE.takeWhile isDigit (_vChunks v') of
|
||||||
[] -> throwM $ ParseError "Couldn't convert Version to PVP"
|
[] -> throwM $ ParseError "Couldn't convert Version to PVP"
|
||||||
xs -> pure $ pvpFromList (unsafeDigit <$> xs)
|
xs -> pure $ pvpFromList (unsafeDigit <$> xs)
|
||||||
|
|
||||||
|
rest :: Version -> Text
|
||||||
|
rest (Version _ cs pr me) =
|
||||||
|
let chunks = NE.dropWhile isDigit cs
|
||||||
|
ver = intersperse (T.pack ".") . chunksAsT $ chunks
|
||||||
|
me' = maybe [] (\m -> [T.pack "+",m]) me
|
||||||
|
pr' = foldable [] (T.pack "-" :) $ intersperse (T.pack ".") (chunksAsT pr)
|
||||||
|
prefix = case (ver, pr', me') of
|
||||||
|
(_:_, _, _) -> T.pack "."
|
||||||
|
_ -> T.pack ""
|
||||||
|
in prefix <> mconcat (ver <> pr' <> me')
|
||||||
|
where
|
||||||
|
chunksAsT :: Functor t => t VChunk -> t Text
|
||||||
|
chunksAsT = fmap (foldMap f)
|
||||||
|
where
|
||||||
|
f :: VUnit -> Text
|
||||||
|
f (Digits i) = T.pack $ show i
|
||||||
|
f (Str s) = s
|
||||||
|
|
||||||
|
foldable :: Foldable f => f b -> (f a -> f b) -> f a -> f b
|
||||||
|
foldable d g f | null f = d
|
||||||
|
| otherwise = g f
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
isDigit :: VChunk -> Bool
|
isDigit :: VChunk -> Bool
|
||||||
isDigit (Digits _ :| []) = True
|
isDigit (Digits _ :| []) = True
|
||||||
isDigit _ = False
|
isDigit _ = False
|
||||||
@@ -449,7 +472,9 @@ recyclePathForcibly fp
|
|||||||
let dest = tmp </> takeFileName fp
|
let dest = tmp </> takeFileName fp
|
||||||
liftIO (moveFile fp dest)
|
liftIO (moveFile fp dest)
|
||||||
`catch`
|
`catch`
|
||||||
(\e -> if isPermissionError e {- EXDEV on windows -} then recover (liftIO $ removePathForcibly fp) else throwIO e)
|
(\e -> if | isDoesNotExistError e -> pure ()
|
||||||
|
| isPermissionError e {- EXDEV on windows -} -> recover (liftIO $ removePathForcibly fp)
|
||||||
|
| otherwise -> throwIO e)
|
||||||
`finally`
|
`finally`
|
||||||
liftIO (handleIO (\_ -> pure ()) $ removePathForcibly tmp)
|
liftIO (handleIO (\_ -> pure ()) $ removePathForcibly tmp)
|
||||||
| otherwise = liftIO $ removePathForcibly fp
|
| otherwise = liftIO $ removePathForcibly fp
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskellQuotes #-}
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
Module : GHCup.Utils.String.QQ
|
Module : GHCup.Utils.String.QQ
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
{-# LANGUAGE DeriveLift #-}
|
{-# LANGUAGE DeriveLift #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
{-# LANGUAGE StandaloneDeriving #-}
|
{-# LANGUAGE StandaloneDeriving #-}
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskellQuotes #-}
|
||||||
|
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
@@ -53,6 +53,9 @@ deriving instance Data VUnit
|
|||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
deriving instance Lift (NonEmpty Word)
|
deriving instance Lift (NonEmpty Word)
|
||||||
|
deriving instance Lift (NonEmpty VChunk)
|
||||||
|
deriving instance Lift (NonEmpty MChunk)
|
||||||
|
deriving instance Lift (NonEmpty VUnit)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qq :: (Text -> Q Exp) -> QuasiQuoter
|
qq :: (Text -> Q Exp) -> QuasiQuoter
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import qualified Data.Text as T
|
|||||||
-- Note that when updating this, CI requires that the file exsists AND the same file exists at
|
-- Note that when updating this, CI requires that the file exsists AND the same file exists at
|
||||||
-- 'https://www.haskell.org/ghcup/exp/ghcup-<ver>.yaml' with some newlines added.
|
-- 'https://www.haskell.org/ghcup/exp/ghcup-<ver>.yaml' with some newlines added.
|
||||||
ghcupURL :: URI
|
ghcupURL :: URI
|
||||||
ghcupURL = [uri|https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.6.yaml|]
|
ghcupURL = [uri|https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml|]
|
||||||
|
|
||||||
-- | The current ghcup version.
|
-- | The current ghcup version.
|
||||||
ghcUpVer :: PVP
|
ghcUpVer :: PVP
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
|
||||||
{-# LANGUAGE DeriveTraversable #-}
|
|
||||||
|
|
||||||
#if __GLASGOW_HASKELL__ >= 702
|
|
||||||
#define LANGUAGE_DeriveGeneric
|
|
||||||
{-# LANGUAGE DeriveGeneric #-}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
module System.Console.Terminal.Common
|
|
||||||
( Window(..)
|
|
||||||
) where
|
|
||||||
|
|
||||||
import Data.Data (Typeable, Data)
|
|
||||||
|
|
||||||
#if __GLASGOW_HASKELL__ < 710
|
|
||||||
import Data.Foldable (Foldable)
|
|
||||||
import Data.Traversable (Traversable)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LANGUAGE_DeriveGeneric
|
|
||||||
import GHC.Generics
|
|
||||||
( Generic
|
|
||||||
#if __GLASGOW_HASKELL__ >= 706
|
|
||||||
, Generic1
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-- | Terminal window width and height
|
|
||||||
data Window a = Window
|
|
||||||
{ height :: !a
|
|
||||||
, width :: !a
|
|
||||||
} deriving
|
|
||||||
( Show, Eq, Read, Data, Typeable
|
|
||||||
, Foldable, Functor, Traversable
|
|
||||||
#ifdef LANGUAGE_DeriveGeneric
|
|
||||||
, Generic
|
|
||||||
#if __GLASGOW_HASKELL__ >= 706
|
|
||||||
, Generic1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
{-# LANGUAGE CApiFFI #-}
|
|
||||||
|
|
||||||
module System.Console.Terminal.Posix
|
|
||||||
( size, fdSize, hSize
|
|
||||||
) where
|
|
||||||
|
|
||||||
import System.Console.Terminal.Common
|
|
||||||
import Control.Exception (catch)
|
|
||||||
import Data.Typeable (cast)
|
|
||||||
import Foreign
|
|
||||||
import Foreign.C.Error
|
|
||||||
import Foreign.C.Types
|
|
||||||
import GHC.IO.FD (FD(FD, fdFD))
|
|
||||||
import GHC.IO.Handle.Internals (withHandle_)
|
|
||||||
import GHC.IO.Handle.Types (Handle, Handle__(Handle__, haDevice))
|
|
||||||
#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ < 706)
|
|
||||||
import Prelude hiding (catch)
|
|
||||||
#endif
|
|
||||||
import System.Posix.Types (Fd(Fd))
|
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
|
|
||||||
#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
|
|
||||||
|
|
||||||
|
|
||||||
-- Interesting part of @struct winsize@
|
|
||||||
data CWin = CWin CUShort CUShort
|
|
||||||
|
|
||||||
instance Storable CWin where
|
|
||||||
sizeOf _ = (#size struct winsize)
|
|
||||||
alignment _ = (#alignment struct winsize)
|
|
||||||
peek ptr = do
|
|
||||||
row <- (#peek struct winsize, ws_row) ptr
|
|
||||||
col <- (#peek struct winsize, ws_col) ptr
|
|
||||||
return $ CWin row col
|
|
||||||
poke ptr (CWin row col) = do
|
|
||||||
(#poke struct winsize, ws_row) ptr row
|
|
||||||
(#poke struct winsize, ws_col) ptr col
|
|
||||||
|
|
||||||
|
|
||||||
fdSize :: Integral n => Fd -> IO (Maybe (Window n))
|
|
||||||
fdSize (Fd fd) = with (CWin 0 0) $ \ws -> do
|
|
||||||
_ <- throwErrnoIfMinus1 "ioctl" $
|
|
||||||
ioctl fd (#const TIOCGWINSZ) ws
|
|
||||||
CWin row col <- peek ws
|
|
||||||
return . Just $ Window (fromIntegral row) (fromIntegral col)
|
|
||||||
`catch`
|
|
||||||
handler
|
|
||||||
where
|
|
||||||
handler :: IOError -> IO (Maybe (Window h))
|
|
||||||
handler _ = return Nothing
|
|
||||||
|
|
||||||
foreign import capi "sys/ioctl.h ioctl"
|
|
||||||
ioctl :: CInt -> CULong -> Ptr CWin -> IO CInt
|
|
||||||
|
|
||||||
size :: Integral n => IO (Maybe (Window n))
|
|
||||||
size = fdSize (Fd (#const STDOUT_FILENO))
|
|
||||||
|
|
||||||
hSize :: Integral n => Handle -> IO (Maybe (Window n))
|
|
||||||
hSize h = withHandle_ "hSize" h $ \Handle__ { haDevice = dev } ->
|
|
||||||
case cast dev of
|
|
||||||
Nothing -> return Nothing
|
|
||||||
Just FD { fdFD = fd } -> fdSize (Fd fd)
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
site_name: GHCup
|
site_name: GHCup
|
||||||
site_url: https://www.haskell.org/ghcup
|
site_url: https://www.haskell.org/ghcup
|
||||||
site_description: GHCup documentation
|
site_description: GHCup is an installer for the general purpose language Haskell.
|
||||||
site_author: GHCup Team
|
site_author: GHCup Team
|
||||||
site_favicon: haskell_logo.png
|
site_favicon: haskell_logo.png
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
plat="$(uname -s)"
|
plat="$(uname -s)"
|
||||||
arch=$(uname -m)
|
arch=$(uname -m)
|
||||||
ghver="0.1.17.3"
|
ghver="0.1.17.4"
|
||||||
base_url="https://downloads.haskell.org/~ghcup"
|
base_url="https://downloads.haskell.org/~ghcup"
|
||||||
|
|
||||||
export GHCUP_SKIP_UPDATE_CHECK=yes
|
export GHCUP_SKIP_UPDATE_CHECK=yes
|
||||||
@@ -39,7 +39,6 @@ case "${plat}" in
|
|||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
: "${GHCUP_INSTALL_BASE_PREFIX:=$HOME}"
|
: "${GHCUP_INSTALL_BASE_PREFIX:=$HOME}"
|
||||||
export GHCUP_USE_XDG_DIRS
|
|
||||||
|
|
||||||
if [ -n "${GHCUP_USE_XDG_DIRS}" ] ; then
|
if [ -n "${GHCUP_USE_XDG_DIRS}" ] ; then
|
||||||
GHCUP_DIR=${XDG_DATA_HOME:=$HOME/.local/share}/ghcup
|
GHCUP_DIR=${XDG_DATA_HOME:=$HOME/.local/share}/ghcup
|
||||||
@@ -237,7 +236,7 @@ download_ghcup() {
|
|||||||
*) die "Unknown architecture: ${arch}"
|
*) die "Unknown architecture: ${arch}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
_url=${base_url}/${ghver}/x86_64-portbld-freebsd${freebsd_ver}-ghcup-${ghver}
|
_url=${base_url}/${ghver}/x86_64-freebsd${freebsd_ver}-ghcup-${ghver}
|
||||||
;;
|
;;
|
||||||
"Darwin"|"darwin")
|
"Darwin"|"darwin")
|
||||||
case "${arch}" in
|
case "${arch}" in
|
||||||
@@ -281,7 +280,20 @@ download_ghcup() {
|
|||||||
|
|
||||||
# we may overwrite this in adjust_bashrc
|
# we may overwrite this in adjust_bashrc
|
||||||
cat <<-EOF > "${GHCUP_DIR}"/env || die "Failed to create env file"
|
cat <<-EOF > "${GHCUP_DIR}"/env || die "Failed to create env file"
|
||||||
export PATH="\$HOME/.cabal/bin:${GHCUP_BIN}:\$PATH"
|
case ":\$PATH:" in
|
||||||
|
*:"${GHCUP_BIN}":*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
export PATH="${GHCUP_BIN}:\$PATH"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case ":\$PATH:" in
|
||||||
|
*:"\$HOME/.cabal/bin":*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
export PATH="\$HOME/.cabal/bin:\$PATH"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
@@ -369,12 +381,38 @@ adjust_bashrc() {
|
|||||||
case $1 in
|
case $1 in
|
||||||
1)
|
1)
|
||||||
cat <<-EOF > "${GHCUP_DIR}"/env || die "Failed to create env file"
|
cat <<-EOF > "${GHCUP_DIR}"/env || die "Failed to create env file"
|
||||||
export PATH="\$HOME/.cabal/bin:${GHCUP_BIN}:\$PATH"
|
case ":\$PATH:" in
|
||||||
|
*:"${GHCUP_BIN}":*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
export PATH="${GHCUP_BIN}:\$PATH"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case ":\$PATH:" in
|
||||||
|
*:"\$HOME/.cabal/bin":*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
export PATH="\$HOME/.cabal/bin:\$PATH"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
EOF
|
EOF
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
cat <<-EOF > "${GHCUP_DIR}"/env || die "Failed to create env file"
|
cat <<-EOF > "${GHCUP_DIR}"/env || die "Failed to create env file"
|
||||||
export PATH="\$PATH:\$HOME/.cabal/bin:${GHCUP_BIN}"
|
case ":\$PATH:" in
|
||||||
|
*:"\$HOME/.cabal/bin":*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
export PATH="\$PATH:\$HOME/.cabal/bin"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case ":\$PATH:" in
|
||||||
|
*:"${GHCUP_BIN}":*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
export PATH="\$PATH:${GHCUP_BIN}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
EOF
|
EOF
|
||||||
;;
|
;;
|
||||||
*) ;;
|
*) ;;
|
||||||
@@ -487,7 +525,7 @@ ask_cabal_config_init() {
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
return 1
|
return 0
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -505,8 +543,8 @@ do_cabal_config_init() {
|
|||||||
adjust_cabal_config
|
adjust_cabal_config
|
||||||
;;
|
;;
|
||||||
0)
|
0)
|
||||||
echo "Make sure that your global cabal.config references the correct mingw64 paths (extra-prog-path, extra-include-dirs and extra-lib-dirs)."
|
warn "Make sure that your global cabal.config references the correct mingw64 paths (extra-prog-path, extra-include-dirs and extra-lib-dirs)."
|
||||||
echo "And set the environment variable GHCUP_MSYS2 to the root path of your msys2 installation."
|
warn "And set the environment variable GHCUP_MSYS2 to the root path of your msys2 installation."
|
||||||
sleep 5
|
sleep 5
|
||||||
return ;;
|
return ;;
|
||||||
*) ;;
|
*) ;;
|
||||||
@@ -679,7 +717,7 @@ if [ -z "${BOOTSTRAP_HASKELL_MINIMAL}" ] ; then
|
|||||||
|
|
||||||
do_cabal_config_init $ask_cabal_config_init_answer
|
do_cabal_config_init $ask_cabal_config_init_answer
|
||||||
|
|
||||||
edo cabal new-update
|
edo cabal new-update --ignore-project
|
||||||
else # don't install ghc and cabal
|
else # don't install ghc and cabal
|
||||||
case "${plat}" in
|
case "${plat}" in
|
||||||
MSYS*|MINGW*)
|
MSYS*|MINGW*)
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ param (
|
|||||||
[switch]$InstallStack,
|
[switch]$InstallStack,
|
||||||
# Whether to install hls as well
|
# Whether to install hls as well
|
||||||
[switch]$InstallHLS,
|
[switch]$InstallHLS,
|
||||||
# Specify the bootstrap url (default: 'https://www.haskell.org/ghcup/sh/bootstrap-haskell')
|
|
||||||
[string]$InstallDir,
|
|
||||||
# Instead of installing a new MSys2, use an existing installation
|
|
||||||
[string]$BootstrapUrl,
|
|
||||||
# Specify the install root (default: 'C:\')
|
# Specify the install root (default: 'C:\')
|
||||||
|
[string]$InstallDir,
|
||||||
|
# Specify the bootstrap url (default: 'https://www.haskell.org/ghcup/sh/bootstrap-haskell')
|
||||||
|
[string]$BootstrapUrl,
|
||||||
|
# Instead of installing a new MSys2, use an existing installation
|
||||||
[string]$ExistingMsys2Dir,
|
[string]$ExistingMsys2Dir,
|
||||||
# Specify the cabal root directory (default: '$InstallDir\cabal')
|
# Specify the cabal root directory (default: '$InstallDir\cabal')
|
||||||
[string]$CabalDir
|
[string]$CabalDir
|
||||||
@@ -246,6 +246,7 @@ if ($Silent -and !($InstallDir)) {
|
|||||||
$GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix)
|
$GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$GhcupBasePrefix = $GhcupBasePrefix.TrimEnd().TrimStart()
|
||||||
if (!($GhcupBasePrefix)) {
|
if (!($GhcupBasePrefix)) {
|
||||||
Print-Msg -color Red -msg "No directory specified!"
|
Print-Msg -color Red -msg "No directory specified!"
|
||||||
} elseif (!(Test-Path -LiteralPath ('{0}' -f $GhcupBasePrefix))) {
|
} elseif (!(Test-Path -LiteralPath ('{0}' -f $GhcupBasePrefix))) {
|
||||||
@@ -333,6 +334,7 @@ if ($CabalDir) {
|
|||||||
$CabalDirPrompt = Read-Host
|
$CabalDirPrompt = Read-Host
|
||||||
$CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt]
|
$CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt]
|
||||||
|
|
||||||
|
$CabDirEnv = $CabDirEnv.TrimEnd().TrimStart()
|
||||||
if (!($CabDirEnv)) {
|
if (!($CabDirEnv)) {
|
||||||
Print-Msg -color Red -msg "No directory specified!"
|
Print-Msg -color Red -msg "No directory specified!"
|
||||||
} elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
|
} elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
|
||||||
@@ -401,16 +403,17 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
|
|||||||
# Download the archive
|
# Download the archive
|
||||||
Print-Msg -msg 'Downloading Msys2 archive...'
|
Print-Msg -msg 'Downloading Msys2 archive...'
|
||||||
$archive = 'msys2-x86_64-latest.sfx.exe'
|
$archive = 'msys2-x86_64-latest.sfx.exe'
|
||||||
|
$archivePath = ('{0}\{1}' -f ([IO.Path]::GetTempPath()), "$archive")
|
||||||
|
|
||||||
if (Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) {
|
if (Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) {
|
||||||
Exec "curl.exe" '-o' ('{0}\{1}' -f $env:TEMP, $archive) ('https://repo.msys2.org/distrib/{0}' -f $archive)
|
Exec "curl.exe" '-o' "$archivePath" ('https://repo.msys2.org/distrib/{0}' -f "$archive")
|
||||||
} else {
|
} else {
|
||||||
Get-FileWCSynchronous -url ('https://repo.msys2.org/distrib/{0}' -f $archive) -destinationFolder "$env:TEMP" -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...'
|
||||||
$null = & "$env:TEMP\$archive" '-y' ('-o{0}' -f $GhcupDir) # Extract
|
$null = & "$archivePath" '-y' ('-o{0}' -f $GhcupDir) # Extract
|
||||||
Remove-Item -Path ('{0}/{1}' -f $env:TEMP, $archive)
|
Remove-Item -Path "$archivePath"
|
||||||
|
|
||||||
Print-Msg -msg 'Processing MSYS2 bash for first time use...'
|
Print-Msg -msg 'Processing MSYS2 bash for first time use...'
|
||||||
Exec "$Bash" '-lc' 'exit'
|
Exec "$Bash" '-lc' 'exit'
|
||||||
@@ -444,6 +447,7 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
|
|||||||
Print-Msg -color Magenta -msg 'Input existing MSys2 toolchain directory:'
|
Print-Msg -color Magenta -msg 'Input existing MSys2 toolchain directory:'
|
||||||
$MsysDir = Read-Host
|
$MsysDir = Read-Host
|
||||||
}
|
}
|
||||||
|
$MsysDir = $MsysDir.TrimEnd().TrimStart()
|
||||||
if (!($MsysDir)) {
|
if (!($MsysDir)) {
|
||||||
Print-Msg -color Red -msg "No directory specified!"
|
Print-Msg -color Red -msg "No directory specified!"
|
||||||
} elseif (!(Test-Path -LiteralPath ('{0}' -f $MsysDir))) {
|
} elseif (!(Test-Path -LiteralPath ('{0}' -f $MsysDir))) {
|
||||||
|
|||||||
38
scripts/update-sftp.sh
Executable file
38
scripts/update-sftp.sh
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
url=$1
|
||||||
|
ver=$2
|
||||||
|
|
||||||
|
die() {
|
||||||
|
(>&2 printf "%s\\n" "$1")
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -z $url ] && die "no url set"
|
||||||
|
[ -z $ver ] && die "no version set"
|
||||||
|
|
||||||
|
sftp $url <<EOF
|
||||||
|
cd ghcup
|
||||||
|
|
||||||
|
rm aarch64-apple-darwin-ghcup
|
||||||
|
rm aarch64-linux-ghcup
|
||||||
|
rm armv7-linux-ghcup
|
||||||
|
rm i386-linux-ghcup
|
||||||
|
rm x86_64-apple-darwin-ghcup
|
||||||
|
rm x86_64-linux-ghcup
|
||||||
|
rm x86_64-mingw64-ghcup.exe
|
||||||
|
rm x86_64-freebsd12-ghcup
|
||||||
|
rm x86_64-freebsd13-ghcup
|
||||||
|
|
||||||
|
symlink ${ver}/aarch64-apple-darwin-ghcup-${ver} aarch64-apple-darwin-ghcup
|
||||||
|
symlink ${ver}/aarch64-linux-ghcup-${ver} aarch64-linux-ghcup
|
||||||
|
symlink ${ver}/armv7-linux-ghcup-${ver} armv7-linux-ghcup
|
||||||
|
symlink ${ver}/i386-linux-ghcup-${ver} i386-linux-ghcup
|
||||||
|
symlink ${ver}/x86_64-apple-darwin-ghcup-${ver} x86_64-apple-darwin-ghcup
|
||||||
|
symlink ${ver}/x86_64-freebsd12-ghcup-${ver} x86_64-freebsd12-ghcup
|
||||||
|
symlink ${ver}/x86_64-freebsd13-ghcup-${ver} x86_64-freebsd13-ghcup
|
||||||
|
symlink ${ver}/x86_64-linux-ghcup-${ver} x86_64-linux-ghcup
|
||||||
|
symlink ${ver}/x86_64-mingw64-ghcup-${ver}.exe x86_64-mingw64-ghcup.exe
|
||||||
|
EOF
|
||||||
|
|
||||||
|
curl -X PURGE https://downloads.haskell.org/~ghcup/
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
resolver: lts-18.12
|
resolver: lts-18.25
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- .
|
- .
|
||||||
@@ -16,7 +16,6 @@ extra-deps:
|
|||||||
- composition-prelude-3.0.0.2@sha256:1ffed216bd28d810fce0b5be83a661e2a892696d73b3f8de5c0f5edb9b5f0090,1216
|
- composition-prelude-3.0.0.2@sha256:1ffed216bd28d810fce0b5be83a661e2a892696d73b3f8de5c0f5edb9b5f0090,1216
|
||||||
- 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.1@sha256:e602dd23e068c98d03c1027af20503addef8df6368577622453f44ccabea2a5b,2159
|
|
||||||
- heaps-0.3.6.1@sha256:7928b759ca5180d35722c45948c0bde264229f3c99c1888188a3d9285f13d3d2,1340
|
- heaps-0.3.6.1@sha256:7928b759ca5180d35722c45948c0bde264229f3c99c1888188a3d9285f13d3d2,1340
|
||||||
- hpath-filepath-0.10.4@sha256:e9e44fb5fdbade7f30b5b5451257dbee15b6ef1aae4060034d73008bb3b5d878,1269
|
- hpath-filepath-0.10.4@sha256:e9e44fb5fdbade7f30b5b5451257dbee15b6ef1aae4060034d73008bb3b5d878,1269
|
||||||
- hpath-posix-0.13.3@sha256:abe472cf16bccd3a8b8814865ed3551a728fde0f3a2baea2acc03023bec6c565,1615
|
- hpath-posix-0.13.3@sha256:abe472cf16bccd3a8b8814865ed3551a728fde0f3a2baea2acc03023bec6c565,1615
|
||||||
@@ -40,6 +39,11 @@ extra-deps:
|
|||||||
- xor-0.0.1.0@sha256:f8362b4a68562b9afbcd727ff64c1a303970df3a032e0033d2f4c094c3501df3,2243
|
- xor-0.0.1.0@sha256:f8362b4a68562b9afbcd727ff64c1a303970df3a032e0033d2f4c094c3501df3,2243
|
||||||
- yaml-streamly-0.12.0
|
- yaml-streamly-0.12.0
|
||||||
|
|
||||||
|
- git: https://github.com/hasufell/packages.git
|
||||||
|
commit: cc0b4688f8bb374fa92f17c856949de795b56291
|
||||||
|
subdirs:
|
||||||
|
- haskus-utils-variant
|
||||||
|
|
||||||
flags:
|
flags:
|
||||||
http-io-streams:
|
http-io-streams:
|
||||||
brotli: false
|
brotli: false
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
module GHCup.Types.JSONSpec where
|
module GHCup.Types.JSONSpec where
|
||||||
|
|
||||||
import GHCup.ArbitraryTypes ()
|
import GHCup.ArbitraryTypes ()
|
||||||
import GHCup.Types
|
import GHCup.Types hiding ( defaultSettings )
|
||||||
import GHCup.Types.JSON ()
|
import GHCup.Types.JSON ()
|
||||||
|
|
||||||
import Test.Aeson.GenericSpecs
|
import Test.Aeson.GenericSpecs
|
||||||
|
|||||||
Reference in New Issue
Block a user