Compare commits

...

48 Commits

Author SHA1 Message Date
bbbe52f453 Bump stack to 2.7.3 2021-07-20 22:30:50 +02:00
7a2570019a Return the version during 'ghcup compile ghc -g <commit>'
Fixes #181
2021-07-20 11:42:36 +02:00
c5b4e82b48 Merge branch 'issue-187' 2021-07-20 00:57:08 +02:00
4ed72fb517 Preserve mtimes on unpacked GHC tarballs on windows wrt #187 2021-07-19 23:33:01 +02:00
5217aa0a1d Merge branch 'issue-180' 2021-07-19 20:55:17 +02:00
3caf91c640 Fix ensureGlobalTools 2021-07-19 19:08:43 +02:00
eb26a5133f Merge branch 'www-fix-true' 2021-07-19 17:01:03 +02:00
9e9402a3a2 Fix www 2021-07-19 16:58:42 +02:00
bc13a4555d Fix runLeanWhereIs on windows 2021-07-19 16:56:28 +02:00
eaad2caf25 Add prefetch command 2021-07-19 16:51:40 +02:00
6143cdf2e0 Add --offline switch wrt #186 2021-07-19 13:49:24 +02:00
2c7176d998 Use LabelOptic and add LeanAppState
Wrt #186
2021-07-18 14:39:49 +02:00
327b80cf56 Add cross compilation to CI test 2021-07-15 23:26:48 +02:00
005c9fbb83 Modernize CI scripts 2021-07-15 22:44:54 +02:00
42134fd2a5 Fix whereIsTool for cross 2021-07-15 22:38:42 +02:00
bc85a7d9c3 Fix cross installation
See https://gitlab.haskell.org/ghc/ghc/-/issues/14297
2021-07-15 20:32:09 +02:00
7e14fd4a08 Only run unsafeInterleaveIO when necessary 2021-07-15 20:30:14 +02:00
bf74d1e828 Merge branch 'issue-179' 2021-07-15 20:01:25 +02:00
f04708e8ae Speed up 'whereis' subcommand wrt #179 2021-07-15 20:01:00 +02:00
80e1924e5f Merge branch 'scoop' 2021-07-13 20:27:15 +02:00
c7393bd7c5 Fork shimgen into main repo, fixes #161 2021-07-13 20:25:29 +02:00
664713bb13 Fix darwin:aarch64 release 2021-07-13 19:41:12 +02:00
01715fdefc Merge branch 'github-actions' 2021-07-13 17:26:03 +02:00
ab9b24e109 Switch to github actions wrt #178 and #159 2021-07-13 17:25:42 +02:00
34ecb1a56e Add build-tool-depends: hspec-discover:hspec-discover 2021-07-13 17:25:13 +02:00
e3aef38f75 Merge branch 'update-stack-yaml' 2021-07-13 15:51:54 +02:00
ead2b76050 Switch to github actions wrt #178 and #159 2021-07-13 15:42:20 +02:00
2f35513f6e Update stack.yaml 2021-07-13 15:26:43 +02:00
8573c99088 Update freeze stuff 2021-07-13 15:18:34 +02:00
dfe63332b2 Improve messages in bootstrap-haskell.ps1 2021-07-13 14:50:22 +02:00
767ae48c7b Merge branch 'fix-install-stack' 2021-07-12 23:17:32 +02:00
f4160464c0 Merge branch 'www-update-win' 2021-07-12 23:15:46 +02:00
a572b1d5f0 Merge branch 'issue-177' 2021-07-12 23:15:06 +02:00
82587d26b5 Interactive should be the default! 2021-07-12 22:21:55 +02:00
ec98826e6d Fix installStackBindist 2021-07-12 22:15:45 +02:00
b4fcd05e8f Ask all questions at the beginning wrt #177 2021-07-12 22:14:56 +02:00
1345ec938b Merge branch 'issue-173' 2021-07-12 17:09:46 +02:00
227f3acaa5 Implement 'whereis' subcommand, fixes #173 2021-07-12 17:09:18 +02:00
c20636f597 Fix adjust_bashrc on windows 2021-07-11 23:29:03 +02:00
c2d437150a Merge branch 'issue-118' 2021-07-11 22:22:03 +02:00
9ff1467612 Add user choice for prepend/append of PATH
Fixes #118
2021-07-11 22:08:19 +02:00
9218efd71a Update linux aarch64 and armv7 ghcup binaries, fixing #160 2021-07-11 19:35:46 +02:00
bcd244a92a Merge branch 'improve-logging' 2021-07-11 17:41:32 +02:00
7de552ed82 Merge branch 'issue-160-CI' 2021-07-11 16:12:01 +02:00
5cf297a4d2 Clarify stack postinstall message wrt #153 2021-07-11 15:09:16 +02:00
d86f84eef4 Improve logging with newlines 2021-07-11 14:34:05 +02:00
83458c6c1e Merge branch 'issue-163' 2021-07-11 13:51:27 +02:00
b862ca52a9 Update arm/aarch CI 2021-07-11 13:43:53 +02:00
43 changed files with 2976 additions and 1127 deletions

109
.github/release.yaml vendored Normal file
View File

@@ -0,0 +1,109 @@
name: Create Release
on:
push:
tags:
- 'v*'
jobs:
draft_release:
name: Create Release
runs-on: ubuntu-latest
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: |
Changes in this Release
- First Change
- Second Change
draft: true
prerelease: false
release-mac:
name: Create Release for macOS
needs: draft_release
runs-on: ${{ matrix.os }}
env:
MACOSX_DEPLOYMENT_TARGET: 10.13
strategy:
matrix:
os:
- macOS-10.15
steps:
- name: Checkout code
uses: actions/checkout@v2
- uses: haskell/actions/setup@v1.2
with:
ghc-version: 8.10.4
cabal-version: 3.4.0.0
- name: create ~/.local/bin
run: mkdir -p "$HOME/.local/bin"
shell: bash
- name: Add ~/.local/bin to PATH
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
shell: bash
- name: Update cabal cache
run: cabal update
shell: bash
- name: Install cabal dependencies
run: cabal build --only-dependencies
shell: bash
- name: Build
run: cabal build -w ghc-${GHC_VERSION} --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" -ftui
shell: bash
- name: Install
run: cp "$(cabal list-bin exe:ghcup)" ~/.local/bin/ghcup
shell: bash
- name: Strip
run: strip ~/.local/bin/ghcup
shell: bash
- name: Run tests
run: cabal test --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" all
shell: bash
- name: Install git
run: brew install git
- name: set HOME
run: echo "HOME=$HOME" >> $GITHUB_ENV
shell: bash
- name: Set ASSET_PATH
run: echo "ASSET_PATH=$HOME/.local/bin/ghcup" >> $GITHUB_ENV
shell: bash
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.draft_release.outputs.upload_url }}
asset_path: ${{ env.ASSET_PATH }}
asset_name: ghcup-${{ matrix.os }}
asset_content_type: application/octet-stream
- if: always()
uses: actions/upload-artifact@v2
with:
name: plan.json
path: ./dist-newstyle/cache/plan.json

109
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,109 @@
name: Create Release
on:
push:
tags:
- 'v*'
jobs:
draft_release:
name: Draft Release
runs-on: ubuntu-latest
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: |
Changes in this Release
- First Change
- Second Change
draft: true
prerelease: false
release-mac:
name: Create Release
needs: draft_release
runs-on: ${{ matrix.os }}
env:
MACOSX_DEPLOYMENT_TARGET: 10.13
strategy:
matrix:
os:
- macOS-10.15
steps:
- name: Checkout code
uses: actions/checkout@v2
- uses: haskell/actions/setup@v1.2
with:
ghc-version: 8.10.4
cabal-version: 3.4.0.0
- name: create ~/.local/bin
run: mkdir -p "$HOME/.local/bin"
shell: bash
- name: Add ~/.local/bin to PATH
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
shell: bash
- name: Update cabal cache
run: cabal update
shell: bash
- name: Install cabal dependencies
run: cabal build --only-dependencies --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" -ftui
shell: bash
- name: Build
run: cabal build --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" -ftui
shell: bash
- name: Install
run: cp "$(cabal list-bin exe:ghcup)" ~/.local/bin/ghcup
shell: bash
- name: Strip
run: strip ~/.local/bin/ghcup
shell: bash
- name: Run tests
run: cabal test --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" all
shell: bash
- name: Install git
run: brew install git
- name: set HOME
run: echo "HOME=$HOME" >> $GITHUB_ENV
shell: bash
- name: Set ASSET_PATH
run: echo "ASSET_PATH=$HOME/.local/bin/ghcup" >> $GITHUB_ENV
shell: bash
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.draft_release.outputs.upload_url }}
asset_path: ${{ env.ASSET_PATH }}
asset_name: ghcup-${{ matrix.os }}
asset_content_type: application/octet-stream
- if: always()
uses: actions/upload-artifact@v2
with:
name: plan.json
path: ./dist-newstyle/cache/plan.json

29
.github/workflows/shimgen.yaml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Shimgen CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build-shimgen:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest]
steps:
- uses: actions/checkout@v2
- uses: ilammy/msvc-dev-cmd@v1
- name: compile
run: cl /O1 scoop-better-shimexe/shim.c
- uses: actions/upload-artifact@v2
with:
name: shim.exe
path: shim.exe

View File

@@ -21,6 +21,7 @@ variables:
OS: "LINUX" OS: "LINUX"
ARCH: "64" ARCH: "64"
CABAL_DIR: "$CI_PROJECT_DIR/cabal" CABAL_DIR: "$CI_PROJECT_DIR/cabal"
CROSS: ""
.alpine:64bit: .alpine:64bit:
image: "alpine:3.12" image: "alpine:3.12"
@@ -41,7 +42,7 @@ variables:
CABAL_DIR: "$CI_PROJECT_DIR/cabal" CABAL_DIR: "$CI_PROJECT_DIR/cabal"
.linux:armv7: .linux:armv7:
image: "arm32v7/fedora" image: "registry.gitlab.haskell.org/ghc/ci-images/armv7-linux-deb10:$DOCKER_REV"
tags: tags:
- armv7-linux - armv7-linux
variables: variables:
@@ -50,7 +51,7 @@ variables:
CABAL_DIR: "$CI_PROJECT_DIR/cabal" CABAL_DIR: "$CI_PROJECT_DIR/cabal"
.linux:aarch64: .linux:aarch64:
image: "arm64v8/fedora" image: "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb10:$DOCKER_REV"
tags: tags:
- aarch64-linux - aarch64-linux
variables: variables:
@@ -105,6 +106,10 @@ variables:
- golden - golden
when: on_failure when: on_failure
# .test_ghcup_scoop:
# script:
# - cl /O1 scoop-better-shimexe/shim.c
.test_ghcup_version:linux: .test_ghcup_version:linux:
extends: extends:
- .test_ghcup_version - .test_ghcup_version
@@ -124,14 +129,14 @@ variables:
- .test_ghcup_version - .test_ghcup_version
- .linux:armv7 - .linux:armv7
before_script: before_script:
- ./.gitlab/before_script/linux/install_deps_manual.sh - ./.gitlab/before_script/linux/install_deps.sh
.test_ghcup_version:aarch64: .test_ghcup_version:aarch64:
extends: extends:
- .test_ghcup_version - .test_ghcup_version
- .linux:aarch64 - .linux:aarch64
before_script: before_script:
- ./.gitlab/before_script/linux/install_deps_manual.sh - ./.gitlab/before_script/linux/install_deps.sh
.test_ghcup_version:darwin: .test_ghcup_version:darwin:
extends: extends:
@@ -184,6 +189,12 @@ variables:
- set CABAL_DIR="$CI_PROJECT_DIR/cabal" - set CABAL_DIR="$CI_PROJECT_DIR/cabal"
- bash ./.gitlab/before_script/windows/install_deps.sh - bash ./.gitlab/before_script/windows/install_deps.sh
# .test_ghcup_scoop:windows:
# extends:
# - .windows
# - .test_ghcup_scoop
# - .root_cleanup
.release_ghcup: .release_ghcup:
script: script:
- bash ./.gitlab/script/ghcup_release.sh - bash ./.gitlab/script/ghcup_release.sh
@@ -258,6 +269,24 @@ test:linux:latest:
CABAL_VERSION: "3.4.0.0" CABAL_VERSION: "3.4.0.0"
needs: [] needs: []
test:linux:cross-armv7:
stage: test
extends:
- .test_ghcup_version
- .debian
variables:
GHC_VERSION: "8.10.4"
GHC_TARGET_VERSION: "8.10.5"
CABAL_VERSION: "3.4.0.0"
CROSS: "arm-linux-gnueabihf"
needs: []
when: manual
before_script:
- ./.gitlab/before_script/linux/install_deps.sh
script:
- ./.gitlab/script/ghcup_cross.sh
######## linux 32bit test ######## ######## linux 32bit test ########
test:linux:recommended:32bit: test:linux:recommended:32bit:
@@ -276,6 +305,7 @@ test:linux:recommended:armv7:
variables: variables:
GHC_VERSION: "8.10.4" GHC_VERSION: "8.10.4"
CABAL_VERSION: "3.4.0.0" CABAL_VERSION: "3.4.0.0"
CROSS: ""
when: manual when: manual
needs: [] needs: []
@@ -285,6 +315,7 @@ test:linux:recommended:aarch64:
variables: variables:
GHC_VERSION: "8.10.4" GHC_VERSION: "8.10.4"
CABAL_VERSION: "3.4.0.0" CABAL_VERSION: "3.4.0.0"
CROSS: ""
when: manual when: manual
needs: [] needs: []
@@ -338,6 +369,11 @@ test:windows:recommended:
CABAL_VERSION: "3.4.0.0" CABAL_VERSION: "3.4.0.0"
needs: [] needs: []
# test:windows:scoop:
# stage: test
# extends: .test_ghcup_scoop:windows
# needs: []
######## linux release ######## ######## linux release ########
release:linux:64bit: release:linux:64bit:
@@ -374,11 +410,12 @@ release:linux:armv7:
- .linux:armv7 - .linux:armv7
- .release_ghcup - .release_ghcup
before_script: before_script:
- ./.gitlab/before_script/linux/install_deps_manual.sh - ./.gitlab/before_script/linux/install_deps.sh
variables: variables:
ARTIFACT: "armv7-linux-ghcup" ARTIFACT: "armv7-linux-ghcup"
GHC_VERSION: "8.10.4" GHC_VERSION: "8.10.4"
CABAL_VERSION: "3.4.0.0" CABAL_VERSION: "3.4.0.0"
CROSS: ""
release:linux:aarch64: release:linux:aarch64:
stage: release stage: release
@@ -387,11 +424,12 @@ release:linux:aarch64:
- .linux:aarch64 - .linux:aarch64
- .release_ghcup - .release_ghcup
before_script: before_script:
- ./.gitlab/before_script/linux/install_deps_manual.sh - ./.gitlab/before_script/linux/install_deps.sh
variables: variables:
ARTIFACT: "aarch64-linux-ghcup" ARTIFACT: "aarch64-linux-ghcup"
GHC_VERSION: "8.10.4" GHC_VERSION: "8.10.4"
CABAL_VERSION: "3.4.0.0" CABAL_VERSION: "3.4.0.0"
CROSS: ""
######## darwin release ######## ######## darwin release ########
@@ -420,13 +458,19 @@ release:darwin:aarch64:
script: | script: |
set -Eeuo pipefail set -Eeuo pipefail
function runInNixShell() { function runInNixShell() {
time nix-shell .gitlab/shell.nix \ time nix-shell $CI_PROJECT_DIR/.gitlab/shell.nix \
-I nixpkgs=https://github.com/angerman/nixpkgs/archive/75f7281738b.tar.gz \ -I nixpkgs=https://github.com/angerman/nixpkgs/archive/75f7281738b.tar.gz \
--argstr system "aarch64-darwin" \ --argstr system "aarch64-darwin" \
--pure \ --pure \
--keep CI_PROJECT_DIR --keep MAKE_ARGS --keep HADRIAN_ARGS --keep CABAL_CACHE \ --keep CI_PROJECT_DIR \
--keep MACOSX_DEPLOYMENT_TARGET \ --keep MACOSX_DEPLOYMENT_TARGET \
--keep JSON_VERSION --keep ARTIFACT \ --keep JSON_VERSION \
--keep ARTIFACT \
--keep OS \
--keep ARCH \
--keep CABAL_DIR \
--keep GHC_VERSION \
--keep CABAL_VERSION \
--run "$1" 2>&1 --run "$1" 2>&1
} }
runInNixShell ./.gitlab/before_script/darwin/install_deps.sh 2>&1 runInNixShell ./.gitlab/before_script/darwin/install_deps.sh 2>&1

View File

@@ -7,13 +7,67 @@ set -eux
mkdir -p "${TMPDIR}" mkdir -p "${TMPDIR}"
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-linux-ghcup > ./ghcup-bin if [ "${CROSS}" = "arm-linux-gnueabihf" ] ; then
chmod +x ghcup-bin sudo apt-get install -y autoconf build-essential gcc-arm-linux-gnueabihf
sudo dpkg --add-architecture armhf
sudo apt-get update -y
sudo apt-get install -y libncurses-dev:armhf
fi
./ghcup-bin upgrade -i -f case "${ARCH}" in
./ghcup-bin install ${GHC_VERSION} ARM*)
./ghcup-bin set ${GHC_VERSION} case "${ARCH}" in
./ghcup-bin install-cabal ${CABAL_VERSION} "ARM")
ghc_url=https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-armv7-deb10-linux.tar.xz
cabal_url=home.smart-cactus.org/~ben/cabal-install-${CABAL_VERSION}-armv7-linux-bootstrapped.tar.xz
;;
"ARM64")
ghc_url=https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-aarch64-deb10-linux.tar.xz
cabal_url=https://downloads.haskell.org/~cabal/cabal-install-${CABAL_VERSION}/cabal-install-${CABAL_VERSION}-aarch64-ubuntu-18.04.tar.xz
;;
*)
exit 1 ;;
esac
mkdir -p "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin
curl -O "${ghc_url}"
tar -xf ghc-*.tar.*
cd ghc-${GHC_VERSION}
./configure --prefix="${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/ghc/${GHC_VERSION}
make install
for i in "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/ghc/${GHC_VERSION}/bin/*-${GHC_VERSION} ; do
ln -s "${i}" "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/${i##*/}
done
for x in "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/*-${GHC_VERSION} ; do
ln -s ${x##*/} ${x%-${GHC_VERSION}}
done
cd ..
rm -rf ghc-${GHC_VERSION} ghc-*.tar.*
unset x i
mkdir cabal-install
cd cabal-install
curl -O "${cabal_url}"
tar -xf cabal-install-*
mv cabal "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/cabal
cd ..
rm -rf cabal-install
;;
*)
url=https://downloads.haskell.org/~ghcup/x86_64-linux-ghcup
curl -sSfL "${url}" > ./ghcup-bin
chmod +x ghcup-bin
./ghcup-bin upgrade -i -f
./ghcup-bin install ghc ${GHC_VERSION}
./ghcup-bin set ghc ${GHC_VERSION}
./ghcup-bin install cabal ${CABAL_VERSION}
;;
esac

View File

@@ -1,64 +0,0 @@
#!/bin/sh
set -eux
. "$( cd "$(dirname "$0")" ; pwd -P )/../../ghcup_env"
mkdir -p "${TMPDIR}"
ednf() {
case "${ARCH}" in
"ARM")
sudo dnf -y --forcearch armv7hl "$@"
;;
"ARM64")
sudo dnf -y --forcearch aarch64 "$@"
;;
*) exit 1 ;;
esac
}
ednf update
ednf install gcc gcc-c++ gmp gmp-devel make ncurses ncurses-devel xz xz-devel perl zlib zlib-devel openssl-devel openssl-libs openssl libffi libffi-devel lbzip2 lbzip2-utils bzip2-devel
if [ "${ARCH}" = "ARM64" ] ; then
ednf install numactl numactl-libs numactl-devel
fi
ednf install bash wget curl git tar
ednf install llvm9.0 llvm9.0-devel llvm9.0-libs llvm9.0-static
case "${ARCH}" in
"ARM")
ghc_url=https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-armv7-deb10-linux.tar.xz
cabal_url=home.smart-cactus.org/~ben/cabal-install-${CABAL_VERSION}-armv7-linux-bootstrapped.tar.xz
;;
"ARM64")
ghc_url=https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-aarch64-deb10-linux.tar.xz
cabal_url=https://downloads.haskell.org/~cabal/cabal-install-${CABAL_VERSION}/cabal-install-${CABAL_VERSION}-aarch64-ubuntu-18.04.tar.xz
;;
*) exit 1 ;;
esac
mkdir -p "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin
curl -O "${ghc_url}"
tar -xf ghc-*.tar.*
cd ghc-${GHC_VERSION}
./configure --prefix="${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/ghc/${GHC_VERSION}
make install
for i in "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/ghc/${GHC_VERSION}/bin/*-${GHC_VERSION} ; do
ln -s "${i}" "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/${i##*/}
done
for x in "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/*-${GHC_VERSION} ; do
ln -s ${x##*/} ${x%-${GHC_VERSION}}
done
cd ..
rm -rf ghc-${GHC_VERSION} ghc-*.tar.*
unset x i
mkdir cabal-install
cd cabal-install
curl -O "${cabal_url}"
tar -xf cabal-install-*
mv cabal "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/cabal
cd ..
rm -rf cabal-install

View File

@@ -4,6 +4,6 @@ if [ "${OS}" = "WINDOWS" ] ; then
export TMPDIR="$CI_PROJECT_DIR/tmp" export TMPDIR="$CI_PROJECT_DIR/tmp"
else else
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR" export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
export PATH="$CI_PROJECT_DIR/.ghcup/bin:$CI_PROJECT_DIR/.local/bin:$PATH" export PATH="$CI_PROJECT_DIR/.ghcup/bin:$CI_PROJECT_DIR/.local/bin:/opt/llvm/bin:$PATH"
export TMPDIR="$CI_PROJECT_DIR/tmp" export TMPDIR="$CI_PROJECT_DIR/tmp"
fi fi

52
.gitlab/script/ghcup_cross.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/sh
set -eux
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
mkdir -p "$CI_PROJECT_DIR"/.local/bin
CI_PROJECT_DIR=$(pwd)
ecabal() {
cabal "$@"
}
eghcup() {
ghcup -v -c -s file://$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml "$@"
}
git describe --always
### build
ecabal update
ecabal build -w ghc-${GHC_VERSION}
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" "$CI_PROJECT_DIR"/.local/bin/ghcup
### cleanup
rm -rf "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup
### manual cli based testing
eghcup --numeric-version
eghcup install ghc ${GHC_VERSION}
eghcup set ghc ${GHC_VERSION}
eghcup install cabal ${CABAL_VERSION}
cabal --version
eghcup debug-info
eghcup compile ghc -j $(nproc) -v ${GHC_TARGET_VERSION} -b ${GHC_VERSION} -x ${CROSS} -- --enable-unregisterised
eghcup set ghc ${CROSS}-${GHC_TARGET_VERSION}
[ `$(eghcup whereis ghc ${CROSS}-${GHC_TARGET_VERSION}) --numeric-version` = "${GHC_TARGET_VERSION}" ]
# nuke
eghcup nuke
[ ! -e "${GHCUP_INSTALL_BASE_PREFIX}/.ghcup" ]

View File

@@ -15,10 +15,6 @@ git describe
# build # build
ecabal update ecabal update
(
cd /tmp
ecabal install -w ghc-${GHC_VERSION} --installdir="$CI_PROJECT_DIR"/.local/bin hspec-discover
)
if [ "${OS}" = "LINUX" ] ; then if [ "${OS}" = "LINUX" ] ; then
if [ "${ARCH}" = "32" ] ; then if [ "${ARCH}" = "32" ] ; then

View File

@@ -26,11 +26,6 @@ git describe --always
ecabal update ecabal update
(
cd /tmp
ecabal install -w ghc-${GHC_VERSION} --installdir="$CI_PROJECT_DIR"/.local/bin hspec-discover
)
if [ "${OS}" = "DARWIN" ] ; then if [ "${OS}" = "DARWIN" ] ; then
ecabal build -w ghc-${GHC_VERSION} -ftui ecabal build -w ghc-${GHC_VERSION} -ftui
ecabal test -w ghc-${GHC_VERSION} -ftui ghcup-test ecabal test -w ghc-${GHC_VERSION} -ftui ghcup-test
@@ -83,9 +78,11 @@ ghcup-gen check -f ghcup-${JSON_VERSION}.yaml
eghcup --numeric-version eghcup --numeric-version
eghcup install ${GHC_VERSION} eghcup install ghc ${GHC_VERSION}
eghcup set ${GHC_VERSION} [ `$(eghcup whereis ghc ${GHC_VERSION}) --numeric-version` = "${GHC_VERSION}" ]
eghcup install-cabal ${CABAL_VERSION} eghcup set ghc ${GHC_VERSION}
eghcup install cabal ${CABAL_VERSION}
[ `$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version` = "${CABAL_VERSION}" ]
cabal --version cabal --version
@@ -110,25 +107,27 @@ else
# test installing new ghc doesn't mess with currently set GHC # test installing new ghc doesn't mess with currently set GHC
# https://gitlab.haskell.org/haskell/ghcup-hs/issues/7 # https://gitlab.haskell.org/haskell/ghcup-hs/issues/7
if [ "${OS}" = "LINUX" ] ; then if [ "${OS}" = "LINUX" ] ; then
eghcup --downloader=wget install 8.10.3 eghcup --downloader=wget prefetch ghc 8.10.3
eghcup --offline install ghc 8.10.3
else # test wget a bit else # test wget a bit
eghcup install 8.10.3 eghcup prefetch ghc 8.10.3
eghcup --offline install ghc 8.10.3
fi fi
[ "$(ghc --numeric-version)" = "${ghc_ver}" ] [ "$(ghc --numeric-version)" = "${ghc_ver}" ]
eghcup set 8.10.3 eghcup --offline set 8.10.3
eghcup set 8.10.3 eghcup set 8.10.3
[ "$(ghc --numeric-version)" = "8.10.3" ] [ "$(ghc --numeric-version)" = "8.10.3" ]
eghcup set ${GHC_VERSION} eghcup set ${GHC_VERSION}
[ "$(ghc --numeric-version)" = "${ghc_ver}" ] [ "$(ghc --numeric-version)" = "${ghc_ver}" ]
eghcup rm 8.10.3 eghcup --offline rm 8.10.3
[ "$(ghc --numeric-version)" = "${ghc_ver}" ] [ "$(ghc --numeric-version)" = "${ghc_ver}" ]
if [ "${OS}" = "DARWIN" ] ; then if [ "${OS}" = "DARWIN" ] ; then
eghcup install hls eghcup install hls
haskell-language-server-wrapper --version $(eghcup whereis hls) --version
eghcup install stack eghcup install stack
stack --version $(eghcup whereis stack) --version
elif [ "${OS}" = "LINUX" ] ; then elif [ "${OS}" = "LINUX" ] ; then
if [ "${ARCH}" = "64" ] ; then if [ "${ARCH}" = "64" ] ; then
eghcup install hls eghcup install hls
@@ -140,6 +139,11 @@ else
fi fi
fi fi
# check that lazy loading works for 'whereis'
cp "$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml" "$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml.bak"
echo '**' > "$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml"
eghcup whereis ghc $(ghc --numeric-version)
mv -f "$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml.bak" "$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml"
eghcup rm $(ghc --numeric-version) eghcup rm $(ghc --numeric-version)
@@ -151,6 +155,7 @@ if [ "${OS}" = "LINUX" ] ; then
fi fi
fi fi
eghcup upgrade eghcup upgrade
eghcup upgrade -f eghcup upgrade -f

View File

@@ -1,37 +0,0 @@
jobs:
include:
- os: osx
osx_image: xcode8
language: generic
env: ARTIFACT=x86_64-apple-darwin-10.11-ghcup
- os: osx
osx_image: xcode10.1
language: generic
env: ARTIFACT=x86_64-apple-darwin-10.13-ghcup
- os: osx
osx_image: xcode11.3
language: generic
env: ARTIFACT=x86_64-apple-darwin-10.14-ghcup
allow_failures:
- os: osx
osx_image: xcode8
language: generic
env: ARTIFACT=x86_64-apple-darwin-10.11-ghcup
script: ".travis/build.sh"
deploy:
provider: releases
api_key:
secure: GQESg4TcYf3PQJRRaZV/kWS0hsF+OFnH2+EcwpgnIcfx4+aogMyprdh745KtBXe1FlFN1luKHksFjqceqhcg/xcNyeCJiSnLWMn4D/i4WUperEHseRBi5yZZCB1AvOjIlHrE4DS3a8pyEm1GV3G7CKY5Fu8jBjof2SnyENfd7fofhjtNHWmeFS+jBn8HRDf1YaSRYxzTw6uHLrPLsybfgQZVl7babMu/38Ghin0f5pz5OlNokzDxaubIYQHOZ7st7YndHJtBWWql/KualBWbMILy88dUVQBnbqQLP2P8d1ME8ILUjJVqz33HiRU0JzlEJyWfbvEjcJ6iD8M6n4nXTaxfu3i2UhhGsQ6SSBNKssMP4tji8nkNpMqG59wLQ/zhcetEm71fKkgJNrIMNllkqlWSo5K74IqqP9kiLg/qm8ipOJjui0gPk8tZXKcV+ztX1d1OVCapoLfiDM5l/0LLQXaTOXOV1x3e5LLQ/w2doNiH3eh5CV4II9dRu7owpaiiMBHMssmT0pH99jEeF6giHLKtt3y7l2GWoRLPdhsZZ54gxsaBxZt9GuypmkbNcr97CEnAVaWij5v0CF3w4rAWqy/tAxQpIDJOIOQBgmwG5WrBAKyKrFvEpBL5a8BPcRWJDvqKC83QeWpvPrEVdgJevC6ZN1MKzrb2SiPOwC2Kerc=
file: $ARTIFACT
on:
repo: haskell/ghcup-hs
tags: true
skip_cleanup: true
draft: true

View File

@@ -1,28 +0,0 @@
#!/bin/sh
set -ex
mkdir -p ~/.ghcup/bin
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-apple-darwin-ghcup > ~/.ghcup/bin/ghcup
chmod +x ~/.ghcup/bin/ghcup
export PATH="$HOME/.ghcup/bin:$PATH"
ghcup install 8.10.4
ghcup install-cabal 3.4.0.0
ghcup set 8.10.4
## install ghcup
cabal update
(
cd /tmp
cabal install --installdir="$HOME"/.ghcup/bin hspec-discover
)
cabal build --constraint="zlib +static" --constraint="lzma +static" -ftui
cp "$(cabal new-exec --verbose=0 --offline sh -- -c 'command -v ghcup')" .
strip ./ghcup
cp ghcup "./${ARTIFACT}"

View File

@@ -12,7 +12,7 @@ import GHCup
import GHCup.Download import GHCup.Download
import GHCup.Errors import GHCup.Errors
import GHCup.Platform import GHCup.Platform
import GHCup.Types import GHCup.Types hiding ( LeanAppState (..) )
import GHCup.Types.Optics import GHCup.Types.Optics
import GHCup.Utils import GHCup.Utils
import GHCup.Utils.Logger import GHCup.Utils.Logger
@@ -226,7 +226,7 @@ validateTarballs (TarballFilter etool versionRegex) dls gt = do
, rawOutter = \_ -> pure () , rawOutter = \_ -> pure ()
} }
downloadAll dli = do downloadAll dli = do
dirs <- liftIO getDirs dirs <- liftIO getAllDirs
pfreq <- ( pfreq <- (
runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest
@@ -237,7 +237,7 @@ validateTarballs (TarballFilter etool versionRegex) dls gt = do
($(logError) $ T.pack $ prettyShow e) ($(logError) $ T.pack $ prettyShow e)
liftIO $ exitWith (ExitFailure 2) liftIO $ exitWith (ExitFailure 2)
let appstate = AppState (Settings True False Never Curl False GHCupURL) dirs defaultKeyBindings (GHCupInfo mempty mempty mempty) pfreq let appstate = AppState (Settings True False Never Curl False GHCupURL False) dirs defaultKeyBindings (GHCupInfo mempty mempty mempty) pfreq
r <- r <-
runLogger runLogger
@@ -256,17 +256,17 @@ validateTarballs (TarballFilter etool versionRegex) dls gt = do
case etool of case etool of
Right (Just GHCup) -> do Right (Just GHCup) -> do
tmpUnpack <- lift mkGhcupTmpDir tmpUnpack <- lift mkGhcupTmpDir
_ <- liftE $ download (settings appstate) dli tmpUnpack Nothing _ <- liftE $ download dli tmpUnpack Nothing
pure Nothing pure Nothing
Right _ -> do Right _ -> do
p <- liftE $ downloadCached (settings appstate) dirs dli Nothing p <- liftE $ downloadCached dli Nothing
fmap (Just . head . splitDirectories . head) fmap (Just . head . splitDirectories . head)
. liftE . liftE
. getArchiveFiles . getArchiveFiles
$ p $ p
Left ShimGen -> do Left ShimGen -> do
tmpUnpack <- lift mkGhcupTmpDir tmpUnpack <- lift mkGhcupTmpDir
_ <- liftE $ download (settings appstate) dli tmpUnpack Nothing _ <- liftE $ download dli tmpUnpack Nothing
pure Nothing pure Nothing
case r of case r of
VRight (Just basePath) -> do VRight (Just basePath) -> do

View File

@@ -13,7 +13,7 @@ module BrickMain where
import GHCup import GHCup
import GHCup.Download import GHCup.Download
import GHCup.Errors import GHCup.Errors
import GHCup.Types import GHCup.Types hiding ( LeanAppState(..) )
import GHCup.Utils import GHCup.Utils
import GHCup.Utils.Prelude ( decUTF8Safe ) import GHCup.Utils.Prelude ( decUTF8Safe )
import GHCup.Utils.File import GHCup.Utils.File
@@ -53,8 +53,6 @@ import System.IO.Unsafe
import Text.PrettyPrint.HughesPJClass ( prettyShow ) import Text.PrettyPrint.HughesPJClass ( prettyShow )
import URI.ByteString import URI.ByteString
import qualified GHCup.Types as GT
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
@@ -550,13 +548,14 @@ changelog' _ (_, ListResult {..}) = do
settings' :: IORef AppState settings' :: IORef AppState
{-# NOINLINE settings' #-} {-# NOINLINE settings' #-}
settings' = unsafePerformIO $ do settings' = unsafePerformIO $ do
dirs <- getDirs dirs <- getAllDirs
newIORef $ AppState (Settings { cache = True newIORef $ AppState (Settings { cache = True
, noVerify = False , noVerify = False
, keepDirs = Never , keepDirs = Never
, downloader = Curl , downloader = Curl
, verbose = False , verbose = False
, urlSource = GHCupURL , urlSource = GHCupURL
, noNetwork = False
, .. , ..
}) })
dirs dirs
@@ -578,9 +577,8 @@ logger' = unsafePerformIO
brickMain :: AppState brickMain :: AppState
-> LoggerConfig -> LoggerConfig
-> GHCupInfo
-> IO () -> IO ()
brickMain s l gi = do brickMain s l = do
writeIORef settings' s writeIORef settings' s
-- logger interpreter -- logger interpreter
writeIORef logger' l writeIORef logger' l
@@ -588,7 +586,7 @@ brickMain s l gi = do
no_color <- isJust <$> lookupEnv "NO_COLOR" no_color <- isJust <$> lookupEnv "NO_COLOR"
eAppData <- getAppData (Just gi) eAppData <- getAppData (Just $ ghcupInfo s)
case eAppData of case eAppData of
Right ad -> Right ad ->
defaultMain defaultMain
@@ -596,7 +594,7 @@ brickMain s l gi = do
(BrickState ad (BrickState ad
defaultAppSettings defaultAppSettings
(constructList ad defaultAppSettings Nothing) (constructList ad defaultAppSettings Nothing)
(keyBindings s) (keyBindings (s :: AppState))
) )
$> () $> ()
@@ -620,7 +618,7 @@ getGHCupInfo = do
. flip runReaderT settings . flip runReaderT settings
. runE @'[JSONError , DownloadFailed , FileDoesNotExistError] . runE @'[JSONError , DownloadFailed , FileDoesNotExistError]
$ liftE $ liftE
$ getDownloadsF (GT.settings settings) (GT.dirs settings) $ getDownloadsF
case r of case r of
VRight a -> pure $ Right a VRight a -> pure $ Right a

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,12 @@
# * BOOTSTRAP_HASKELL_NO_UPGRADE - any nonzero value to not trigger the upgrade # * BOOTSTRAP_HASKELL_NO_UPGRADE - any nonzero value to not trigger the upgrade
# * GHCUP_USE_XDG_DIRS - any nonzero value to respect The XDG Base Directory Specification # * GHCUP_USE_XDG_DIRS - any nonzero value to respect The XDG Base Directory Specification
# * BOOTSTRAP_HASKELL_VERBOSE - any nonzero value for more verbose installation # * BOOTSTRAP_HASKELL_VERBOSE - any nonzero value for more verbose installation
# * BOOTSTRAP_HASKELL_GHC_VERSION # * BOOTSTRAP_HASKELL_GHC_VERSION - the ghc version to install
# * BOOTSTRAP_HASKELL_CABAL_VERSION # * BOOTSTRAP_HASKELL_CABAL_VERSION - the cabal version to install
# * BOOTSTRAP_HASKELL_INSTALL_STACK - whether to install latest stack
# * BOOTSTRAP_HASKELL_INSTALL_HLS - whether to install latest hls
# * BOOTSTRAP_HASKELL_ADJUST_BASHRC - whether to adjust PATH in bashrc (prepend)
# * BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG - whether to adjust mingw paths in cabal.config on windows
# License: LGPL-3.0 # License: LGPL-3.0
@@ -19,6 +23,8 @@ arch=$(uname -m)
ghver="0.1.15.2" ghver="0.1.15.2"
base_url="https://downloads.haskell.org/~ghcup" base_url="https://downloads.haskell.org/~ghcup"
export GHCUP_SKIP_UPDATE_CHECK=yes
case "${plat}" in case "${plat}" in
MSYS*|MINGW*) MSYS*|MINGW*)
: "${GHCUP_INSTALL_BASE_PREFIX:=/c}" : "${GHCUP_INSTALL_BASE_PREFIX:=/c}"
@@ -60,6 +66,28 @@ warn() {
esac esac
} }
yellow() {
case "${plat}" in
MSYS*|MINGW*)
echo -e "\\033[0;33m$1\\033[0m"
;;
*)
printf "\\033[0;33m%s\\033[0m\\n" "$1"
;;
esac
}
green() {
case "${plat}" in
MSYS*|MINGW*)
echo -e "\\033[0;32m$1\\033[0m"
;;
*)
printf "\\033[0;32m%s\\033[0m\\n" "$1"
;;
esac
}
edo() { edo() {
"$@" || die "\"$*\" failed!" "$@" || die "\"$*\" failed!"
} }
@@ -80,40 +108,42 @@ _eghcup() {
} }
_done() { _done() {
echo
echo "==============================================================================="
case "${plat}" in case "${plat}" in
MSYS*|MINGW*) MSYS*|MINGW*)
echo green
echo "All done!" green "All done!"
echo green
echo "In a new powershell or cmd.exe session, now you can..." green "In a new powershell or cmd.exe session, now you can..."
echo green
echo "Start a simple repl via:" green "Start a simple repl via:"
echo " ghci" green " ghci"
echo green
echo "Start a new haskell project in the current directory via:" green "Start a new haskell project in the current directory via:"
echo " cabal init --interactive" green " cabal init --interactive"
echo green
echo "Install other GHC versions and tools via:" green "Install other GHC versions and tools via:"
echo " ghcup list" green " ghcup list"
echo " ghcup install <tool> <version>" green " ghcup install <tool> <version>"
echo green
echo "To install system libraries and update msys2/mingw64," green "To install system libraries and update msys2/mingw64,"
echo "open the \"Mingw haskell shell\"" green "open the \"Mingw haskell shell\""
echo "and the \"Mingw package management docs\"" green "and the \"Mingw package management docs\""
echo "desktop shortcuts." green "desktop shortcuts."
;; ;;
*) *)
echo green
echo "All done!" green "All done!"
echo green
echo "To start a simple repl, run:" green "To start a simple repl, run:"
echo " ghci" green " ghci"
echo green
echo "To start a new haskell project in the current directory, run:" green "To start a new haskell project in the current directory, run:"
echo " cabal init --interactive" green " cabal init --interactive"
echo green
echo "To install other GHC versions and tools, run:" green "To install other GHC versions and tools, run:"
echo " ghcup tui" green " ghcup tui"
;; ;;
esac esac
@@ -201,16 +231,21 @@ download_ghcup() {
;; ;;
esac esac
edo mkdir -p "${GHCUP_DIR}" edo mkdir -p "${GHCUP_DIR}"
# 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" export PATH="\$HOME/.cabal/bin:${GHCUP_BIN}:\$PATH"
EOF EOF
# shellcheck disable=SC1090 # shellcheck disable=SC1090
edo . "${GHCUP_DIR}"/env edo . "${GHCUP_DIR}"/env
eghcup upgrade eghcup upgrade
} }
adjust_bashrc() { # Figures out the users login shell and sets
# GHCUP_PROFILE_FILE and MY_SHELL variables.
find_shell() {
case $SHELL in case $SHELL in
*/zsh) # login shell is zsh */zsh) # login shell is zsh
GHCUP_PROFILE_FILE="$HOME/.zshrc" GHCUP_PROFILE_FILE="$HOME/.zshrc"
@@ -234,66 +269,259 @@ adjust_bashrc() {
MY_SHELL="fish" ;; MY_SHELL="fish" ;;
*) return ;; *) return ;;
esac esac
}
# Ask user if they want to adjust the bashrc.
warn "" ask_bashrc() {
warn "Detected ${MY_SHELL} shell on your system..." if [ -n "${BOOTSTRAP_HASKELL_ADJUST_BASHRC}" ] ; then
warn "If you want ghcup to automatically add the required PATH variable to \"${GHCUP_PROFILE_FILE}\"" return 1
warn "" fi
warn "[Y] Yes [N] No [?] Help (default is \"Y\")."
warn ""
while true; do while true; do
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
read -r next_answer </dev/tty echo "-------------------------------------------------------------------------------"
warn ""
warn "Detected ${MY_SHELL} shell on your system..."
warn "Do you want ghcup to automatically add the required PATH variable to \"${GHCUP_PROFILE_FILE}\"?"
warn ""
warn "[P] Yes, prepend [A] Yes, append [N] No [?] Help (default is \"P\")."
warn ""
read -r bashrc_answer </dev/tty
else else
next_answer="yes" return 1
fi fi
case $bashrc_answer in
case $next_answer in [Pp]* | "")
[Nn]*) return 1
return ;;
[Yy]* | "")
case $MY_SHELL in
"") break ;;
fish)
mkdir -p "${GHCUP_PROFILE_FILE%/*}"
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
echo "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME ; test -f $GHCUP_DIR/env ; and set -gx PATH \$HOME/.cabal/bin $GHCUP_BIN \$PATH # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
break ;;
bash)
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
case "${plat}" in
"Darwin"|"darwin")
if ! grep -q "ghcup-env" "${HOME}/.bash_profile" ; then
echo "[[ -f ~/.bashrc ]] && source ~/.bashrc # ghcup-env" >> "${HOME}/.bash_profile"
fi
;;
esac
break ;;
zsh)
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
break ;;
esac
warn "OK! ${GHCUP_PROFILE_FILE} has been modified. Restart your terminal for the changes to take effect,"
warn "or type \"source ${GHCUP_DIR}/env\" to apply them in your current terminal session."
return
;; ;;
[Aa]*)
return 2
;;
[Nn]*)
return 0;;
*) *)
echo "Possible choices are:" echo "Possible choices are:"
echo echo
echo "Y - Yes, update my \"${GHCUP_PROFILE_FILE}\" (default)" echo "P - Yes, prepend to PATH, taking precedence (default)"
echo "A - Yes, append to PATH"
echo "N - No, don't mess with my configuration" echo "N - No, don't mess with my configuration"
echo echo
echo "Please make your choice and press ENTER." echo "Please make your choice and press ENTER."
;; ;;
esac esac
done done
unset bashrc_answer
} }
# Needs 'find_shell' to be called beforehand.
adjust_bashrc() {
case $1 in
1)
cat <<-EOF > "${GHCUP_DIR}"/env || die "Failed to create env file"
export PATH="\$HOME/.cabal/bin:${GHCUP_BIN}:\$PATH"
EOF
;;
2)
cat <<-EOF > "${GHCUP_DIR}"/env || die "Failed to create env file"
export PATH="\$HOME/.cabal/bin:\$PATH:${GHCUP_BIN}"
EOF
;;
*) ;;
esac
case $1 in
1 | 2)
case $MY_SHELL in
"") break ;;
fish)
mkdir -p "${GHCUP_PROFILE_FILE%/*}"
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
case $1 in
1)
echo "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME ; set -gx PATH \$HOME/.cabal/bin $GHCUP_BIN \$PATH # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
;;
2)
echo "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME ; set -gx PATH \$HOME/.cabal/bin \$PATH $GHCUP_BIN # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
;;
esac
break ;;
bash)
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
case "${plat}" in
"Darwin"|"darwin")
if ! grep -q "ghcup-env" "${HOME}/.bash_profile" ; then
echo "[[ -f ~/.bashrc ]] && source ~/.bashrc # ghcup-env" >> "${HOME}/.bash_profile"
fi
;;
esac
break ;;
zsh)
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
break ;;
esac
warn "OK! ${GHCUP_PROFILE_FILE} has been modified. Restart your terminal for the changes to take effect,"
warn "or type \"source ${GHCUP_DIR}/env\" to apply them in your current terminal session."
return
;;
*)
;;
esac
}
adjust_cabal_config() {
edo cabal user-config -a "extra-prog-path: $(cygpath -w "$GHCUP_BIN"), $(cygpath -w "$HOME"/AppData/Roaming/cabal/bin), $(cygpath -w "$GHCUP_MSYS2"/usr/bin), $(cygpath -w "$GHCUP_MSYS2"/mingw64/bin)" -a "extra-include-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/include)" -a "extra-lib-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/lib)" -f init
}
ask_cabal_config_init() {
case "${plat}" in
MSYS*|MINGW*)
if [ -n "${BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG}" ] ; then
return 1
fi
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
echo "-------------------------------------------------------------------------------"
warn "Create an initial cabal.config including relevant msys2 paths (recommended)?"
warn "[Y] Yes [N] No [?] Help (default is \"Y\")."
echo
while true; do
read -r mingw_answer </dev/tty
case $mingw_answer in
[Yy]* | "")
return 1 ;;
[Nn]*)
return 0 ;;
*)
echo "Possible choices are:"
echo
echo "Y - Yes, create a cabal.config with pre-set paths to msys2/mingw64 (default)"
echo "N - No, leave the current/default cabal config untouched"
echo
echo "Please make your choice and press ENTER."
;;
esac
done
else
return 1
fi
;;
esac
unset mingw_answer
return 0
}
do_cabal_config_init() {
case "${plat}" in
MSYS*|MINGW*)
case $1 in
1)
adjust_cabal_config
;;
0)
echo "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."
sleep 5
return ;;
*) ;;
esac
esac
}
ask_hls() {
if [ -n "${BOOTSTRAP_HASKELL_INSTALL_HLS}" ] ; then
return 1
fi
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
echo "-------------------------------------------------------------------------------"
warn "Do you want to install haskell-language-server (HLS)?"
warn "HLS is a language-server that provides IDE-like functionality"
warn "and can integrate with different editors, such as Vim, Emacs, VS Code, Atom, ..."
warn "Also see https://github.com/haskell/haskell-language-server/blob/master/README.md"
warn ""
warn "[Y] Yes [N] No [?] Help (default is \"N\")."
warn ""
while true; do
read -r hls_answer </dev/tty
case $hls_answer in
[Yy]*)
return 1
;;
[Nn]* | "")
return 0
;;
*)
echo "Possible choices are:"
echo
echo "Y - Yes, install the haskell-langauge-server"
echo "N - No, don't install anything more (default)"
echo
echo "Please make your choice and press ENTER."
;;
esac
done
else
return 0
fi
unset hls_answer
}
ask_stack() {
if [ -n "${BOOTSTRAP_HASKELL_INSTALL_STACK}" ] ; then
return 1
fi
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
echo "-------------------------------------------------------------------------------"
warn "Do you want to install stack?"
warn "Stack is a haskell build tool similar to cabal that is used by some projects."
warn "Also see https://docs.haskellstack.org/"
warn ""
warn "[Y] Yes [N] No [?] Help (default is \"N\")."
warn ""
while true; do
read -r stack_answer </dev/tty
case $stack_answer in
[Yy]*)
return 1 ;;
[Nn]* | "")
return 0 ;;
*)
echo "Possible choices are:"
echo
echo "Y - Yes, install stack"
echo "N - No, don't install anything more (default)"
echo
echo "Please make your choice and press ENTER."
;;
esac
done
else
return 0
fi
unset stack_answer
}
find_shell
echo echo
echo "Welcome to Haskell!" echo "Welcome to Haskell!"
@@ -325,12 +553,20 @@ echo
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
warn "Press ENTER to proceed or ctrl-c to abort." warn "Press ENTER to proceed or ctrl-c to abort."
warn "Note that this script can be re-run at any given time." warn "Note that this script can be re-run at any given time."
echo
# Wait for user input to continue. # Wait for user input to continue.
# shellcheck disable=SC2034 # shellcheck disable=SC2034
read -r answer </dev/tty read -r answer </dev/tty
fi fi
ask_bashrc
ask_bashrc_answer=$?
ask_cabal_config_init
ask_cabal_config_init_answer=$?
ask_hls
ask_hls_answer=$?
ask_stack
ask_stack_answer=$?
edo mkdir -p "${GHCUP_BIN}" edo mkdir -p "${GHCUP_BIN}"
if command -V "ghcup" >/dev/null 2>&1 ; then if command -V "ghcup" >/dev/null 2>&1 ; then
@@ -360,118 +596,52 @@ eghcup --cache install ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}"
eghcup set ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}" eghcup set ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}"
eghcup --cache install cabal "${BOOTSTRAP_HASKELL_CABAL_VERSION}" eghcup --cache install cabal "${BOOTSTRAP_HASKELL_CABAL_VERSION}"
adjust_cabal_config() { do_cabal_config_init $ask_cabal_config_init_answer
edo cabal user-config -a "extra-prog-path: $(cygpath -w "$GHCUP_BIN"), $(cygpath -w "$HOME"/AppData/Roaming/cabal/bin), $(cygpath -w "$GHCUP_MSYS2"/usr/bin), $(cygpath -w "$GHCUP_MSYS2"/mingw64/bin)" -a "extra-include-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/include)" -a "extra-lib-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/lib)" -f init
}
case "${plat}" in
MSYS*|MINGW*)
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
warn "Create an initial cabal.config including relevant msys2 paths (recommended)?"
warn "[Y] Yes [N] No [?] Help (default is \"Y\")."
echo
while true; do
read -r mingw_answer </dev/tty
case $mingw_answer in
[Yy]* | "")
adjust_cabal_config
break ;;
[Nn]*)
echo "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."
sleep 5
break ;;
*)
echo "Possible choices are:"
echo
echo "Y - Yes, create a cabal.config with pre-set paths to msys2/mingw64 (default)"
echo "N - No, leave the current/default cabal config untouched"
echo
echo "Please make your choice and press ENTER."
;;
esac
done
else
adjust_cabal_config
fi
;;
esac
edo cabal new-update edo cabal new-update
case $ask_hls_answer in
1)
_eghcup --cache install hls || warn "HLS installation failed, continuing anyway"
;;
*) ;;
esac
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then case $ask_stack_answer in
warn "Do you want to install haskell-language-server (HLS) now?" 1)
warn "HLS is a language-server that provides IDE-like functionality" _eghcup --cache install stack || warn "Stack installation failed, continuing anyway"
warn "and can integrate with different editors, such as Vim, Emacs, VS Code, Atom, ..." ;;
warn "Also see https://github.com/haskell/haskell-language-server/blob/master/README.md" *) ;;
warn "" esac
warn "[Y] Yes [N] No [?] Help (default is \"N\")."
warn ""
while true; do
read -r hls_answer </dev/tty
case $hls_answer in
[Yy]*)
_eghcup --cache install hls || warn "HLS installation failed, continuing anyway"
break ;;
[Nn]* | "")
break ;;
*)
echo "Possible choices are:"
echo
echo "Y - Yes, install the haskell-langauge-server"
echo "N - No, don't install anything more (default)"
echo
echo "Please make your choice and press ENTER."
;;
esac
done
warn "Do you want to install stack now?"
warn "Stack is a haskell build tool similar to cabal that is used by some projects."
warn "Also see https://docs.haskellstack.org/"
warn ""
warn "[Y] Yes [N] No [?] Help (default is \"N\")."
warn ""
while true; do
read -r stack_answer </dev/tty
case $stack_answer in
[Yy]*)
_eghcup --cache install stack || warn "Stack installation failed, continuing anyway"
break ;;
[Nn]* | "")
break ;;
*)
echo "Possible choices are:"
echo
echo "Y - Yes, install stack"
echo "N - No, don't install anything more (default)"
echo
echo "Please make your choice and press ENTER."
;;
esac
done
fi
# short-circuit script based on platform # short-circuit script based on platform
case "${plat}" in case "${plat}" in
MSYS*|MINGW*) MSYS*|MINGW*)
# For windows we always adjust bashrc, since it's inside msys2 # For windows we always adjust bashrc, since it's inside msys2
adjust_bashrc adjust_bashrc $adjust_bashrc_answer
;; ;;
*) *)
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
echo "In order to run ghc and cabal, you need to adjust your PATH variable." case $ask_bashrc_answer in
echo "You may want to source '$GHCUP_DIR/env' in your shell" 1 | 2)
echo "configuration to do so (e.g. ~/.bashrc)." echo
echo "==============================================================================="
adjust_bashrc echo
yellow "In order to run ghc and cabal, start a new shell or"
yellow "run 'source $GHCUP_DIR/env' in your current shell session."
adjust_bashrc $adjust_bashrc_answer
;;
*)
echo
echo "==============================================================================="
echo
yellow "In order to run ghc and cabal, you need to adjust your PATH variable."
yellow "You may want to source '$GHCUP_DIR/env' in your shell"
yellow "configuration to do so (e.g. ~/.bashrc)."
;;
esac
fi fi
;; ;;
esac esac

View File

@@ -26,7 +26,13 @@ param (
# Specify the bootstrap url (default: 'https://www.haskell.org/ghcup/sh/bootstrap-haskell') # Specify the bootstrap url (default: 'https://www.haskell.org/ghcup/sh/bootstrap-haskell')
[string]$BootstrapUrl, [string]$BootstrapUrl,
# Run the final bootstrap script via 'bash' instead of a full newly spawned msys2 shell # Run the final bootstrap script via 'bash' instead of a full newly spawned msys2 shell
[switch]$InBash [switch]$InBash,
# Whether to install stack as well
[switch]$InstallStack,
# Whether to install hls as well
[switch]$InstallHLS,
# Skip adjusting cabal.config with mingw paths
[switch]$NoAdjustCabalConfig
) )
$Silent = !$Interactive $Silent = !$Interactive
@@ -150,15 +156,6 @@ function Exec
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
$elevated = ([Security.Principal.WindowsPrincipal] `
[Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if ($elevated) {
Print-Msg -color Yellow -msg ('This script should not be run as administrator/elevated. Waiting 10s before continuing anyway...')
Start-Sleep -s 10
}
$GhcupBasePrefixEnv = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user') $GhcupBasePrefixEnv = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user')
if ($GhcupBasePrefixEnv) { if ($GhcupBasePrefixEnv) {
@@ -187,6 +184,7 @@ if ($GhcupBasePrefixEnv) {
} }
} }
# ask for base install prefix
if ($Silent -and !($InstallDir)) { if ($Silent -and !($InstallDir)) {
$GhcupBasePrefix = $defaultGhcupBasePrefix $GhcupBasePrefix = $defaultGhcupBasePrefix
} elseif ($InstallDir) { } elseif ($InstallDir) {
@@ -234,6 +232,7 @@ $GhcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user'
Print-Msg -msg 'Preparing for GHCup installation...' Print-Msg -msg 'Preparing for GHCup installation...'
# ask what to do in case ghcup is already installed
if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) { if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) {
Print-Msg -msg ('GHCup already installed at ''{0}''...' -f $GhcupDir) Print-Msg -msg ('GHCup already installed at ''{0}''...' -f $GhcupDir)
if ($Overwrite) { if ($Overwrite) {
@@ -263,8 +262,73 @@ if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) {
$null = New-Item -Path ('{0}' -f $GhcupDir) -ItemType 'directory' -ErrorAction SilentlyContinue $null = New-Item -Path ('{0}' -f $GhcupDir) -ItemType 'directory' -ErrorAction SilentlyContinue
$null = New-Item -Path ('{0}' -f $GhcupDir) -Name 'bin' -ItemType 'directory' -ErrorAction SilentlyContinue $null = New-Item -Path ('{0}' -f $GhcupDir) -Name 'bin' -ItemType 'directory' -ErrorAction SilentlyContinue
Print-Msg -msg 'First checking for Msys2...' # ask for cabal dir destination
if ($CabalDir) {
$CabDirEnv = $CabalDir
if (!($CabDirEnv)) {
Print-Msg -color Red -msg "No directory specified!"
Exit 1
} elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
Exit 1
}
} elseif (!($Silent)) {
while ($true) {
$defaultCabalDir = ('{0}\cabal' -f $GhcupBasePrefix)
Print-Msg -color Magenta -msg ('Specify Cabal directory (this is where haskell packages end up). Press enter to accept the default [{0}]:' -f $defaultCabalDir)
$CabalDirPrompt = Read-Host
$CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt]
if (!($CabDirEnv)) {
Print-Msg -color Red -msg "No directory specified!"
} elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
} else {
Break
}
}
} else {
$CabDirEnv = ('{0}\cabal' -f $GhcupBasePrefix)
}
# ask whether to install HLS
if (!($InstallHLS)) {
if (!($Silent)) {
$HLSdecision = $Host.UI.PromptForChoice('Install HLS'
, 'Do you want to install the haskell-language-server (HLS) for development purposes as well?'
, [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes'
'&No'
'&Abort'), 1)
if ($HLSdecision -eq 0) {
$InstallHLS = $true
} elseif ($HLSdecision -eq 2) {
Exit 0
}
}
}
# ask whether to install stack
if (!($InstallStack)) {
if (!($Silent)) {
$StackDecision = $Host.UI.PromptForChoice('Install stack'
, 'Do you want to install stack as well?'
, [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes'
'&No'
'&Abort'), 1)
if ($StackDecision -eq 0) {
$InstallStack = $true
} elseif ($StackDecision -eq 2) {
Exit 0
}
}
}
# mingw foo
Print-Msg -msg 'First checking for Msys2...'
if (!(Test-Path -Path ('{0}' -f $MsysDir))) { if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
if ($Silent) { if ($Silent) {
$msys2Decision = 0 $msys2Decision = 0
@@ -276,7 +340,10 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
} }
if ($msys2Decision -eq 0) { if ($msys2Decision -eq 0) {
Print-Msg -msg ('...Msys2 doesn''t exist, installing into {0} ...this may take a while' -f $MsysDir) Print-Msg -msg ('...Msys2 doesn''t exist, installing into {0}' -f $MsysDir)
Print-Msg -msg 'Starting installation in 5 seconds, this may take a while...'
Start-Sleep -s 5
# Download the archive # Download the archive
Print-Msg -msg 'Downloading Msys2 archive...' Print-Msg -msg 'Downloading Msys2 archive...'
@@ -339,6 +406,9 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
} }
} else { } else {
Print-Msg -msg ('...Msys2 found in {0} ...skipping Msys2 installation.' -f $MsysDir) Print-Msg -msg ('...Msys2 found in {0} ...skipping Msys2 installation.' -f $MsysDir)
Print-Msg -msg 'Starting installation in 5 seconds, this may take a while...'
Start-Sleep -s 5
} }
Print-Msg -msg 'Creating shortcuts...' Print-Msg -msg 'Creating shortcuts...'
@@ -351,34 +421,7 @@ Create-Shortcut -SourceExe 'https://www.msys2.org/docs/package-management' -Argu
Print-Msg -msg ('Adding {0}\bin to Users Path...' -f $GhcupDir) Print-Msg -msg ('Adding {0}\bin to Users Path...' -f $GhcupDir)
Add-EnvPath -Path ('{0}\bin' -f ([System.IO.Path]::GetFullPath("$GhcupDir"))) -Container 'User' Add-EnvPath -Path ('{0}\bin' -f ([System.IO.Path]::GetFullPath("$GhcupDir"))) -Container 'User'
if ($CabalDir) {
$CabDirEnv = $CabalDir
if (!($CabDirEnv)) {
Print-Msg -color Red -msg "No directory specified!"
Exit 1
} elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
Exit 1
}
} elseif (!($Silent)) {
while ($true) {
$defaultCabalDir = ('{0}\cabal' -f $GhcupBasePrefix)
Print-Msg -color Magenta -msg ('Specify Cabal directory (this is where haskell packages end up). Press enter to accept the default [{0}]:' -f $defaultCabalDir)
$CabalDirPrompt = Read-Host
$CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt]
if (!($CabDirEnv)) {
Print-Msg -color Red -msg "No directory specified!"
} elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
} else {
Break
}
}
} else {
$CabDirEnv = ('{0}\cabal' -f $GhcupBasePrefix)
}
$CabalDirFull = [System.IO.Path]::GetFullPath("$CabDirEnv") $CabalDirFull = [System.IO.Path]::GetFullPath("$CabDirEnv")
Print-Msg -msg ('Setting CABAL_DIR to ''{0}''' -f $CabalDirFull) Print-Msg -msg ('Setting CABAL_DIR to ''{0}''' -f $CabalDirFull)
@@ -388,16 +431,25 @@ Print-Msg -msg 'Starting GHCup installer...'
$Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir) $Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir)
if ($Silent) { # The bootstrap script is always silent, since we ask relevant questions here
$SilentExport = 'export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 ;' $SilentExport = 'export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 ;'
} else {
$SilentExport = '' if ($InstallStack) {
$StackInstallExport = 'export BOOTSTRAP_HASKELL_INSTALL_STACK=1 ;'
}
if ($InstallHLS) {
$HLSInstallExport = 'export BOOTSTRAP_HASKELL_INSTALL_HLS=1 ;'
}
if (!($NoAdjustCabalConfig)) {
$AdjustCabalConfigExport = 'export BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG=1 ;'
} }
if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell") -Or $InBash) { if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell") -Or $InBash) {
Exec "$Bash" '-lc' ('{4} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; [[ ''{0}'' = https* ]] && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull) Exec "$Bash" '-lc' ('{4} {6} {7} {8} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; [[ ''{0}'' = https* ]] && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport)
} else { } else {
Exec "$Msys2Shell" '-mingw64' '-mintty' '-c' ('{4} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; [[ ''{0}'' = https* ]] && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull) Exec "$Msys2Shell" '-mingw64' '-mintty' '-c' ('{4} {6} {7} {8} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; [[ ''{0}'' = https* ]] && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport)
} }
@@ -429,3 +481,5 @@ if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell") -Or $InBa

View File

@@ -1,20 +0,0 @@
packages: ./ghcup.cabal
with-compiler: ghc-8.10.4
optional-packages: ./3rdparty/*/*.cabal
optimization: 2
package streamly
ghc-options: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
package ghcup
ghc-options: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
constraints: http-io-streams -brotli
package libarchive
flags: -system-libarchive
allow-newer: base, ghc-prim, template-haskell

28
cabal.ghc8105.project Normal file
View File

@@ -0,0 +1,28 @@
packages: ./ghcup.cabal
optional-packages: ./vendored/*/*.cabal
optimization: 2
package ghcup
tests: True
flags: +tui
source-repository-package
type: git
location: https://github.com/Bodigrim/tar
tag: ac197ec7ea4838dc2b4e22b9b888b080cedf29cf
source-repository-package
type: git
location: https://github.com/bgamari/terminal-size
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
constraints: http-io-streams -brotli
package libarchive
flags: -system-libarchive
allow-newer: base, ghc-prim, template-haskell, language-c
with-compiler: ghc-8.10.5

View File

@@ -1,12 +1,11 @@
active-repositories: hackage.haskell.org:merge active-repositories: hackage.haskell.org:merge
constraints: any.Cabal ==3.2.1.0, constraints: any.Cabal ==3.2.1.0,
any.HUnit ==1.6.2.0, any.HUnit ==1.6.2.0,
any.IfElse ==0.85, any.HsOpenSSL ==0.11.7,
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
any.QuickCheck ==2.14.2, any.QuickCheck ==2.14.2,
QuickCheck -old-random +templatehaskell, QuickCheck -old-random +templatehaskell,
any.StateVar ==1.2.1, any.StateVar ==1.2.1,
any.abstract-deque ==0.3,
abstract-deque -usecas,
any.aeson ==1.5.6.0, any.aeson ==1.5.6.0,
aeson -bytestring-builder -cffi -developer -fast, aeson -bytestring-builder -cffi -developer -fast,
any.aeson-pretty ==0.8.8, any.aeson-pretty ==0.8.8,
@@ -18,31 +17,32 @@ constraints: any.Cabal ==3.2.1.0,
any.ansi-wl-pprint ==0.6.9, any.ansi-wl-pprint ==0.6.9,
ansi-wl-pprint -example, ansi-wl-pprint -example,
any.array ==0.5.4.0, any.array ==0.5.4.0,
any.ascii-string ==1.0.1.4,
any.assoc ==1.0.2, any.assoc ==1.0.2,
any.async ==2.2.3, any.async ==2.2.3,
async -bench, async -bench,
any.atomic-primops ==0.8.4,
atomic-primops -debug,
any.attoparsec ==0.13.2.5, any.attoparsec ==0.13.2.5,
attoparsec -developer, attoparsec -developer,
any.auto-update ==0.1.6, any.auto-update ==0.1.6,
any.base ==4.14.1.0, any.base ==4.14.2.0,
any.base-compat ==0.11.2, any.base-compat ==0.11.2,
any.base-compat-batteries ==0.11.2, any.base-compat-batteries ==0.11.2,
any.base-orphans ==0.8.4, any.base-orphans ==0.8.4,
any.base16-bytestring ==1.0.1.0, any.base16-bytestring ==1.0.1.0,
any.base64-bytestring ==1.2.0.1, any.base64-bytestring ==1.1.0.0,
any.bifunctors ==5.5.10, any.bifunctors ==5.5.11,
bifunctors +semigroups +tagged, bifunctors +semigroups +tagged,
any.binary ==0.8.8.0, any.binary ==0.8.8.0,
any.bindings-DSL ==1.0.25,
any.blaze-builder ==0.4.2.1, any.blaze-builder ==0.4.2.1,
any.brick ==0.61,
brick -demos,
any.bytestring ==0.10.12.0, any.bytestring ==0.10.12.0,
any.bz2 ==1.0.1.0, any.bz2 ==1.0.1.0,
bz2 -cross +with-bzlib, bz2 -cross +with-bzlib,
any.c2hs ==0.28.7, any.bzlib-conduit ==0.3.0.2,
any.c2hs ==0.28.8,
c2hs +base3 -regression, c2hs +base3 -regression,
any.call-stack ==0.3.0, any.call-stack ==0.4.0,
any.case-insensitive ==1.2.1.0, any.case-insensitive ==1.2.1.0,
any.casing ==0.1.4.1, any.casing ==0.1.4.1,
any.cereal ==0.5.8.1, any.cereal ==0.5.8.1,
@@ -54,7 +54,7 @@ constraints: any.Cabal ==3.2.1.0,
clock -llvm, clock -llvm,
any.cmdargs ==0.10.21, any.cmdargs ==0.10.21,
cmdargs +quotation -testprog, cmdargs +quotation -testprog,
any.colour ==2.3.5, any.colour ==2.3.6,
any.comonad ==5.0.8, any.comonad ==5.0.8,
comonad +containers +distributive +indexed-traversable, comonad +containers +distributive +indexed-traversable,
any.composition-prelude ==3.0.0.2, any.composition-prelude ==3.0.0.2,
@@ -62,16 +62,25 @@ constraints: any.Cabal ==3.2.1.0,
any.concurrent-output ==1.10.12, any.concurrent-output ==1.10.12,
any.conduit ==1.3.4.1, any.conduit ==1.3.4.1,
any.conduit-extra ==1.3.5, any.conduit-extra ==1.3.5,
any.containers ==0.6.2.1, any.conduit-zstd ==0.0.2.0,
any.config-ini ==0.2.4.0,
config-ini -enable-doctests,
any.containers ==0.6.4.1,
any.contravariant ==1.5.3, any.contravariant ==1.5.3,
contravariant +semigroups +statevar +tagged, contravariant +semigroups +statevar +tagged,
any.cpphs ==1.20.9.1,
cpphs -old-locale,
any.cryptohash-sha1 ==0.11.100.1,
any.cryptohash-sha256 ==0.11.102.0, any.cryptohash-sha256 ==0.11.102.0,
cryptohash-sha256 -exe +use-cbits, cryptohash-sha256 -exe +use-cbits,
any.data-clist ==0.1.2.3,
any.data-default-class ==0.1.2.0, any.data-default-class ==0.1.2.0,
any.data-fix ==0.3.1, any.data-fix ==0.3.1,
any.deepseq ==1.4.4.0, any.deepseq ==1.4.4.0,
any.deferred-folds ==0.9.17, any.digest ==0.0.1.3,
digest -bytestring-in-base,
any.directory ==1.3.6.0, any.directory ==1.3.6.0,
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,
any.dlist ==1.0, any.dlist ==1.0,
@@ -79,62 +88,55 @@ constraints: any.Cabal ==3.2.1.0,
any.easy-file ==0.2.2, any.easy-file ==0.2.2,
any.errors ==2.3.0, any.errors ==2.3.0,
any.exceptions ==0.10.4, any.exceptions ==0.10.4,
any.fast-logger ==3.0.3, any.extra ==1.7.9,
any.fast-logger ==3.0.5,
any.filepath ==1.4.2.1, any.filepath ==1.4.2.1,
any.focus ==1.0.2, any.free ==5.1.7,
any.foldl ==1.4.11,
any.free ==5.1.6,
any.fusion-plugin-types ==0.1.0,
any.generic-arbitrary ==0.1.0, any.generic-arbitrary ==0.1.0,
any.generics-sop ==0.5.1.1, any.generics-sop ==0.5.1.1,
any.ghc-boot-th ==8.10.4, any.ghc-boot-th ==8.10.5,
any.ghc-byteorder ==4.11.0.0.10,
any.ghc-prim ==0.6.1, any.ghc-prim ==0.6.1,
ghcup -internal-downloader -tar -tui,
any.happy ==1.20.0, any.happy ==1.20.0,
any.hashable ==1.3.1.0, any.hashable ==1.3.2.0,
hashable +integer-gmp, hashable +integer-gmp -random-initial-seed,
any.haskell-src-exts ==1.23.1, any.haskell-src-exts ==1.23.1,
any.haskell-src-meta ==0.8.7, any.haskell-src-meta ==0.8.7,
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.1,
any.heaps ==0.3.6.1,
any.hpath ==0.11.0,
any.hpath-directory ==0.14.1,
any.hpath-filepath ==0.10.4, any.hpath-filepath ==0.10.4,
any.hpath-io ==0.14.1, any.hpath-posix ==0.13.3,
any.hpath-posix ==0.13.2,
any.hsc2hs ==0.68.7, any.hsc2hs ==0.68.7,
hsc2hs -in-ghc-tree, hsc2hs -in-ghc-tree,
any.hspec ==2.7.8, any.hspec ==2.7.10,
any.hspec-core ==2.7.8, any.hspec-core ==2.7.10,
any.hspec-discover ==2.7.8, any.hspec-discover ==2.7.10,
any.hspec-expectations ==0.8.2, any.hspec-expectations ==0.8.2,
any.hspec-golden-aeson ==0.7.0.0, any.hspec-golden-aeson ==0.9.0.0,
any.indexed-profunctors ==0.1, any.http-io-streams ==0.1.6.0,
http-io-streams -brotli +fast-xor,
any.indexed-profunctors ==0.1.1,
any.indexed-traversable ==0.1.1, any.indexed-traversable ==0.1.1,
any.indexed-traversable-instances ==0.1, any.indexed-traversable-instances ==0.1,
any.integer-gmp ==1.0.3.0, any.integer-gmp ==1.0.3.0,
any.integer-logarithms ==1.0.3.1, any.integer-logarithms ==1.0.3.1,
integer-logarithms -check-bounds +integer-gmp, integer-logarithms -check-bounds +integer-gmp,
any.language-c ==0.8.3, any.io-streams ==1.5.2.1,
language-c -allwarnings +iecfpextension +separatesyb +usebytestrings, io-streams +network -nointeractivetests +zlib,
any.libarchive ==3.0.2.1, any.language-c ==0.9.0.1,
language-c -allwarnings +iecfpextension +usebytestrings,
any.libarchive ==3.0.2.2,
libarchive -cross -low-memory -system-libarchive, libarchive -cross -low-memory -system-libarchive,
any.libyaml ==0.1.2, any.libyaml ==0.1.2,
libyaml -no-unicode -system-libyaml, libyaml -no-unicode -system-libyaml,
any.lifted-base ==0.2.3.12, any.lifted-base ==0.2.3.12,
any.list-t ==1.0.4, any.lzma-static ==5.2.5.4,
any.lockfree-queue ==0.2.3.1,
lzma -static,
any.math-functions ==0.3.4.1,
math-functions +system-erf +system-expm1,
any.megaparsec ==9.0.1, any.megaparsec ==9.0.1,
megaparsec -dev, megaparsec -dev,
any.microlens ==0.4.12.0, any.microlens ==0.4.12.0,
any.microlens-mtl ==0.2.0.1, any.microlens-mtl ==0.2.0.1,
any.microlens-th ==0.4.3.9, any.microlens-th ==0.4.3.10,
any.mmorph ==1.1.5,
any.monad-control ==1.0.2.3, any.monad-control ==1.0.2.3,
any.monad-logger ==0.3.36, any.monad-logger ==0.3.36,
monad-logger +template_haskell, monad-logger +template_haskell,
@@ -142,11 +144,12 @@ constraints: any.Cabal ==3.2.1.0,
monad-loops +base4, monad-loops +base4,
any.mono-traversable ==1.0.15.1, any.mono-traversable ==1.0.15.1,
any.mtl ==2.2.2, any.mtl ==2.2.2,
any.mwc-random ==0.15.0.1, any.network ==3.1.2.2,
any.network ==3.1.2.1,
network -devel, network -devel,
any.network-uri ==2.6.4.1,
any.old-locale ==1.0.0.7, any.old-locale ==1.0.0.7,
any.old-time ==1.1.0.3, any.old-time ==1.1.0.3,
any.openssl-streams ==1.2.3.0,
any.optics ==0.4, any.optics ==0.4,
any.optics-core ==0.4, any.optics-core ==0.4,
optics-core -explicit-generic-labels, optics-core -explicit-generic-labels,
@@ -161,25 +164,25 @@ constraints: any.Cabal ==3.2.1.0,
any.parsec ==3.1.14.0, any.parsec ==3.1.14.0,
any.parser-combinators ==1.3.0, any.parser-combinators ==1.3.0,
parser-combinators -dev, parser-combinators -dev,
any.polyparse ==1.13,
any.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.1.0, any.primitive ==0.7.1.0,
any.primitive-extras ==0.8.2,
any.primitive-unlifted ==0.1.3.0,
any.process ==1.6.9.0, any.process ==1.6.9.0,
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.0, any.random ==1.2.0,
any.recursion-schemes ==5.2.2, any.recursion-schemes ==5.2.2.1,
recursion-schemes +template-haskell, recursion-schemes +template-haskell,
any.regex-base ==0.94.0.1,
any.regex-posix ==0.96.0.0, any.regex-posix ==0.96.0.0,
regex-posix -_regex-posix-clib, regex-posix -_regex-posix-clib,
any.resourcet ==1.2.4.2, any.resourcet ==1.2.4.2,
any.rts ==1.0, any.rts ==1.0.1,
any.safe ==0.3.19, any.safe ==0.3.19,
any.safe-exceptions ==0.1.7.1, any.safe-exceptions ==0.1.7.2,
any.scientific ==0.3.6.2, any.scientific ==0.3.7.0,
scientific -bytestring-builder -integer-simple, scientific -bytestring-builder -integer-simple,
any.semigroupoids ==5.3.5, any.semigroupoids ==5.3.5,
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers, semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
@@ -188,36 +191,31 @@ constraints: any.Cabal ==3.2.1.0,
any.split ==0.2.3.4, any.split ==0.2.3.4,
any.splitmix ==0.1.0.3, any.splitmix ==0.1.0.3,
splitmix -optimised-mixer, splitmix -optimised-mixer,
any.stm ==2.5.0.0, any.stm ==2.5.0.1,
any.stm-chans ==3.0.0.4, any.stm-chans ==3.0.0.4,
any.streaming-commons ==0.2.2.1, any.streaming-commons ==0.2.2.1,
streaming-commons -use-bytestring-builder, streaming-commons -use-bytestring-builder,
any.streamly ==0.7.3,
streamly -debug -dev -examples -examples-sdl -fusion-plugin -has-llvm -inspection -no-fusion -streamk,
any.streamly-bytestring ==0.1.2,
any.streamly-posix ==0.1.0.1,
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,
any.string-interpolate ==0.3.1.0, any.string-interpolate ==0.3.1.1,
string-interpolate -bytestring-builder -extended-benchmarks -text-builder, string-interpolate -bytestring-builder -extended-benchmarks -text-builder,
any.syb ==0.7.2.1, any.syb ==0.7.2.1,
any.tagged ==0.8.6.1, any.tagged ==0.8.6.1,
tagged +deepseq +transformers, tagged +deepseq +transformers,
any.tasty ==1.3.1, any.tar ==0.6.0.0,
tasty +clock,
any.tasty-hunit ==0.10.0.3,
any.tasty-quickcheck ==0.10.1.2,
any.template-haskell ==2.16.0.0, any.template-haskell ==2.16.0.0,
any.temporary ==1.3,
any.terminal-progress-bar ==0.4.1,
any.terminal-size ==0.3.2.1, any.terminal-size ==0.3.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-conversions ==0.3.1, any.text-conversions ==0.3.1,
any.text-short ==0.1.3, any.text-zipper ==0.11,
text-short -asserts,
any.tf-random ==0.5, any.tf-random ==0.5,
any.th-abstraction ==0.4.2.0, any.th-abstraction ==0.4.2.0,
any.th-compat ==0.1.1, any.th-compat ==0.1.2,
any.th-expand-syns ==0.4.8.0,
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.18,
any.th-orphans ==0.13.11, any.th-orphans ==0.13.11,
@@ -225,7 +223,7 @@ constraints: any.Cabal ==3.2.1.0,
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,
any.time-compat ==1.9.5, any.time-compat ==1.9.6,
time-compat -old-locale, time-compat -old-locale,
any.transformers ==0.5.6.2, any.transformers ==0.5.6.2,
any.transformers-base ==0.4.5.2, any.transformers-base ==0.4.5.2,
@@ -233,29 +231,34 @@ constraints: any.Cabal ==3.2.1.0,
any.transformers-compat ==0.6.6, any.transformers-compat ==0.6.6,
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two, transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
any.typed-process ==0.2.6.0, any.typed-process ==0.2.6.0,
any.unbounded-delays ==0.1.1.1,
any.unix ==2.7.2.2, any.unix ==2.7.2.2,
any.unix-bytestring ==0.3.7.3, any.unix-bytestring ==0.3.7.3,
any.unix-compat ==0.5.3, any.unix-compat ==0.5.3,
unix-compat -old-time, unix-compat -old-time,
any.unix-time ==0.4.7, any.unix-time ==0.4.7,
any.unliftio-core ==0.2.0.1, any.unliftio-core ==0.2.0.1,
any.unordered-containers ==0.2.13.0, any.unordered-containers ==0.2.14.0,
unordered-containers -debug, unordered-containers -debug,
any.uri-bytestring ==0.3.3.0, any.uri-bytestring ==0.3.3.1,
uri-bytestring -lib-werror, uri-bytestring -lib-werror,
any.utf8-string ==1.0.2, any.utf8-string ==1.0.2,
any.uuid-types ==1.0.4, any.uuid-types ==1.0.5,
any.vector ==0.12.2.0, any.vector ==0.12.3.0,
vector +boundschecks -internalchecks -unsafechecks -wall, vector +boundschecks -internalchecks -unsafechecks -wall,
any.vector-algorithms ==0.8.0.4, any.vector-algorithms ==0.8.0.4,
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks, vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
any.versions ==4.0.3, any.versions ==5.0.0,
any.vty ==5.33, any.vty ==5.33,
any.wcwidth ==0.0.2, any.word-wrap ==0.4.1,
wcwidth -cli +split-base,
any.word8 ==0.1.3, any.word8 ==0.1.3,
any.xor ==0.0.1.0,
any.yaml ==0.11.5.0, any.yaml ==0.11.5.0,
yaml +no-examples +no-exe, yaml +no-examples +no-exe,
zlib -non-blocking-ffi -pkg-config -static any.zip ==1.7.1,
index-state: hackage.haskell.org 2021-03-07T18:36:25Z zip -dev -disable-bzip2 -disable-zstd,
any.zlib ==0.6.2.3,
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
any.zlib-bindings ==0.1.1.5,
any.zstd ==0.1.2.0,
zstd +standalone
index-state: hackage.haskell.org 2021-07-12T18:00:24Z

View File

@@ -1,20 +0,0 @@
packages: ./ghcup.cabal
with-compiler: ghc-8.8.4
optional-packages: ./3rdparty/*/*.cabal
optimization: 2
package streamly
ghc-options: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
package ghcup
ghc-options: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
constraints: http-io-streams -brotli
package libarchive
flags: -system-libarchive
allow-newer: base, ghc-prim, template-haskell

28
cabal.ghc901.project Normal file
View File

@@ -0,0 +1,28 @@
packages: ./ghcup.cabal
optional-packages: ./vendored/*/*.cabal
optimization: 2
package ghcup
tests: True
flags: +tui
source-repository-package
type: git
location: https://github.com/Bodigrim/tar
tag: ac197ec7ea4838dc2b4e22b9b888b080cedf29cf
source-repository-package
type: git
location: https://github.com/bgamari/terminal-size
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
constraints: http-io-streams -brotli
package libarchive
flags: -system-libarchive
allow-newer: base, ghc-prim, template-haskell, language-c
with-compiler: ghc-9.0.1

View File

@@ -1,12 +1,11 @@
active-repositories: hackage.haskell.org:merge active-repositories: hackage.haskell.org:merge
constraints: any.Cabal ==3.0.1.0, constraints: any.Cabal ==3.4.0.0,
any.HUnit ==1.6.2.0, any.HUnit ==1.6.2.0,
any.IfElse ==0.85, any.HsOpenSSL ==0.11.7,
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
any.QuickCheck ==2.14.2, any.QuickCheck ==2.14.2,
QuickCheck -old-random +templatehaskell, QuickCheck -old-random +templatehaskell,
any.StateVar ==1.2.1, any.StateVar ==1.2.1,
any.abstract-deque ==0.3,
abstract-deque -usecas,
any.aeson ==1.5.6.0, any.aeson ==1.5.6.0,
aeson -bytestring-builder -cffi -developer -fast, aeson -bytestring-builder -cffi -developer -fast,
any.aeson-pretty ==0.8.8, any.aeson-pretty ==0.8.8,
@@ -18,31 +17,32 @@ constraints: any.Cabal ==3.0.1.0,
any.ansi-wl-pprint ==0.6.9, any.ansi-wl-pprint ==0.6.9,
ansi-wl-pprint -example, ansi-wl-pprint -example,
any.array ==0.5.4.0, any.array ==0.5.4.0,
any.ascii-string ==1.0.1.4,
any.assoc ==1.0.2, any.assoc ==1.0.2,
any.async ==2.2.3, any.async ==2.2.3,
async -bench, async -bench,
any.atomic-primops ==0.8.4,
atomic-primops -debug,
any.attoparsec ==0.13.2.5, any.attoparsec ==0.13.2.5,
attoparsec -developer, attoparsec -developer,
any.auto-update ==0.1.6, any.auto-update ==0.1.6,
any.base ==4.13.0.0, any.base ==4.15.0.0,
any.base-compat ==0.11.2, any.base-compat ==0.11.2,
any.base-compat-batteries ==0.11.2, any.base-compat-batteries ==0.11.2,
any.base-orphans ==0.8.4, any.base-orphans ==0.8.4,
any.base16-bytestring ==1.0.1.0, any.base16-bytestring ==1.0.1.0,
any.base64-bytestring ==1.2.0.1, any.base64-bytestring ==1.1.0.0,
any.bifunctors ==5.5.10, any.bifunctors ==5.5.11,
bifunctors +semigroups +tagged, bifunctors +semigroups +tagged,
any.binary ==0.8.7.0, any.binary ==0.8.8.0,
any.bindings-DSL ==1.0.25,
any.blaze-builder ==0.4.2.1, any.blaze-builder ==0.4.2.1,
any.bytestring ==0.10.10.1, any.brick ==0.61,
brick -demos,
any.bytestring ==0.10.12.1,
any.bz2 ==1.0.1.0, any.bz2 ==1.0.1.0,
bz2 -cross +with-bzlib, bz2 -cross +with-bzlib,
any.c2hs ==0.28.7, any.bzlib-conduit ==0.3.0.2,
any.c2hs ==0.28.8,
c2hs +base3 -regression, c2hs +base3 -regression,
any.call-stack ==0.3.0, any.call-stack ==0.4.0,
any.case-insensitive ==1.2.1.0, any.case-insensitive ==1.2.1.0,
any.casing ==0.1.4.1, any.casing ==0.1.4.1,
any.cereal ==0.5.8.1, any.cereal ==0.5.8.1,
@@ -54,7 +54,7 @@ constraints: any.Cabal ==3.0.1.0,
clock -llvm, clock -llvm,
any.cmdargs ==0.10.21, any.cmdargs ==0.10.21,
cmdargs +quotation -testprog, cmdargs +quotation -testprog,
any.colour ==2.3.5, any.colour ==2.3.6,
any.comonad ==5.0.8, any.comonad ==5.0.8,
comonad +containers +distributive +indexed-traversable, comonad +containers +distributive +indexed-traversable,
any.composition-prelude ==3.0.0.2, any.composition-prelude ==3.0.0.2,
@@ -62,16 +62,25 @@ constraints: any.Cabal ==3.0.1.0,
any.concurrent-output ==1.10.12, any.concurrent-output ==1.10.12,
any.conduit ==1.3.4.1, any.conduit ==1.3.4.1,
any.conduit-extra ==1.3.5, any.conduit-extra ==1.3.5,
any.containers ==0.6.2.1, any.conduit-zstd ==0.0.2.0,
any.config-ini ==0.2.4.0,
config-ini -enable-doctests,
any.containers ==0.6.4.1,
any.contravariant ==1.5.3, any.contravariant ==1.5.3,
contravariant +semigroups +statevar +tagged, contravariant +semigroups +statevar +tagged,
any.cpphs ==1.20.9.1,
cpphs -old-locale,
any.cryptohash-sha1 ==0.11.100.1,
any.cryptohash-sha256 ==0.11.102.0, any.cryptohash-sha256 ==0.11.102.0,
cryptohash-sha256 -exe +use-cbits, cryptohash-sha256 -exe +use-cbits,
any.data-clist ==0.1.2.3,
any.data-default-class ==0.1.2.0, any.data-default-class ==0.1.2.0,
any.data-fix ==0.3.1, any.data-fix ==0.3.1,
any.deepseq ==1.4.4.0, any.deepseq ==1.4.5.0,
any.deferred-folds ==0.9.17, any.digest ==0.0.1.3,
any.directory ==1.3.6.0, digest -bytestring-in-base,
any.directory ==1.3.6.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,
any.dlist ==1.0, any.dlist ==1.0,
@@ -79,63 +88,55 @@ constraints: any.Cabal ==3.0.1.0,
any.easy-file ==0.2.2, any.easy-file ==0.2.2,
any.errors ==2.3.0, any.errors ==2.3.0,
any.exceptions ==0.10.4, any.exceptions ==0.10.4,
exceptions +transformers-0-4, any.extra ==1.7.9,
any.fast-logger ==3.0.3, any.fast-logger ==3.0.5,
any.filepath ==1.4.2.1, any.filepath ==1.4.2.1,
any.focus ==1.0.2, any.free ==5.1.7,
any.foldl ==1.4.11,
any.free ==5.1.6,
any.fusion-plugin-types ==0.1.0,
any.generic-arbitrary ==0.1.0, any.generic-arbitrary ==0.1.0,
any.generics-sop ==0.5.1.1, any.generics-sop ==0.5.1.1,
any.ghc-boot-th ==8.8.4, any.ghc-bignum ==1.0,
any.ghc-prim ==0.5.3, any.ghc-boot-th ==9.0.1,
ghcup -internal-downloader -tar -tui, any.ghc-byteorder ==4.11.0.0.10,
any.ghc-prim ==0.7.0,
any.happy ==1.20.0, any.happy ==1.20.0,
any.hashable ==1.3.1.0, any.hashable ==1.3.2.0,
hashable +integer-gmp, hashable +integer-gmp -random-initial-seed,
any.haskell-src-exts ==1.23.1, any.haskell-src-exts ==1.23.1,
any.haskell-src-meta ==0.8.7, any.haskell-src-meta ==0.8.7,
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.1,
any.heaps ==0.3.6.1,
any.hpath ==0.11.0,
any.hpath-directory ==0.14.1,
any.hpath-filepath ==0.10.4, any.hpath-filepath ==0.10.4,
any.hpath-io ==0.14.1, any.hpath-posix ==0.13.3,
any.hpath-posix ==0.13.2,
any.hsc2hs ==0.68.7, any.hsc2hs ==0.68.7,
hsc2hs -in-ghc-tree, hsc2hs -in-ghc-tree,
any.hspec ==2.7.8, any.hspec ==2.7.10,
any.hspec-core ==2.7.8, any.hspec-core ==2.7.10,
any.hspec-discover ==2.7.8, any.hspec-discover ==2.7.10,
any.hspec-expectations ==0.8.2, any.hspec-expectations ==0.8.2,
any.hspec-golden-aeson ==0.7.0.0, any.hspec-golden-aeson ==0.9.0.0,
any.indexed-profunctors ==0.1, any.http-io-streams ==0.1.6.0,
http-io-streams -brotli +fast-xor,
any.indexed-profunctors ==0.1.1,
any.indexed-traversable ==0.1.1, any.indexed-traversable ==0.1.1,
any.indexed-traversable-instances ==0.1, any.indexed-traversable-instances ==0.1,
any.integer-gmp ==1.0.2.0,
any.integer-logarithms ==1.0.3.1, any.integer-logarithms ==1.0.3.1,
integer-logarithms -check-bounds +integer-gmp, integer-logarithms -check-bounds +integer-gmp,
any.language-c ==0.8.3, any.io-streams ==1.5.2.1,
language-c -allwarnings +iecfpextension +separatesyb +usebytestrings, io-streams +network -nointeractivetests +zlib,
any.libarchive ==3.0.2.1, any.language-c ==0.9.0.1,
language-c -allwarnings +iecfpextension +usebytestrings,
any.libarchive ==3.0.2.2,
libarchive -cross -low-memory -system-libarchive, libarchive -cross -low-memory -system-libarchive,
any.libyaml ==0.1.2, any.libyaml ==0.1.2,
libyaml -no-unicode -system-libyaml, libyaml -no-unicode -system-libyaml,
any.lifted-base ==0.2.3.12, any.lifted-base ==0.2.3.12,
any.list-t ==1.0.4, any.lzma-static ==5.2.5.4,
any.lockfree-queue ==0.2.3.1,
lzma -static,
any.math-functions ==0.3.4.1,
math-functions +system-erf +system-expm1,
any.megaparsec ==9.0.1, any.megaparsec ==9.0.1,
megaparsec -dev, megaparsec -dev,
any.microlens ==0.4.12.0, any.microlens ==0.4.12.0,
any.microlens-mtl ==0.2.0.1, any.microlens-mtl ==0.2.0.1,
any.microlens-th ==0.4.3.9, any.microlens-th ==0.4.3.10,
any.mmorph ==1.1.5,
any.monad-control ==1.0.2.3, any.monad-control ==1.0.2.3,
any.monad-logger ==0.3.36, any.monad-logger ==0.3.36,
monad-logger +template_haskell, monad-logger +template_haskell,
@@ -143,11 +144,12 @@ constraints: any.Cabal ==3.0.1.0,
monad-loops +base4, monad-loops +base4,
any.mono-traversable ==1.0.15.1, any.mono-traversable ==1.0.15.1,
any.mtl ==2.2.2, any.mtl ==2.2.2,
any.mwc-random ==0.15.0.1, any.network ==3.1.2.2,
any.network ==3.1.2.1,
network -devel, network -devel,
any.network-uri ==2.6.4.1,
any.old-locale ==1.0.0.7, any.old-locale ==1.0.0.7,
any.old-time ==1.1.0.3, any.old-time ==1.1.0.3,
any.openssl-streams ==1.2.3.0,
any.optics ==0.4, any.optics ==0.4,
any.optics-core ==0.4, any.optics-core ==0.4,
optics-core -explicit-generic-labels, optics-core -explicit-generic-labels,
@@ -162,25 +164,25 @@ constraints: any.Cabal ==3.0.1.0,
any.parsec ==3.1.14.0, any.parsec ==3.1.14.0,
any.parser-combinators ==1.3.0, any.parser-combinators ==1.3.0,
parser-combinators -dev, parser-combinators -dev,
any.polyparse ==1.13,
any.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.1.0, any.primitive ==0.7.1.0,
any.primitive-extras ==0.8.2, any.process ==1.6.11.0,
any.primitive-unlifted ==0.1.3.0,
any.process ==1.6.9.0,
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.0, any.random ==1.2.0,
any.recursion-schemes ==5.2.2, any.recursion-schemes ==5.2.2.1,
recursion-schemes +template-haskell, recursion-schemes +template-haskell,
any.regex-base ==0.94.0.1,
any.regex-posix ==0.96.0.0, any.regex-posix ==0.96.0.0,
regex-posix -_regex-posix-clib, regex-posix -_regex-posix-clib,
any.resourcet ==1.2.4.2, any.resourcet ==1.2.4.2,
any.rts ==1.0, any.rts ==1.0,
any.safe ==0.3.19, any.safe ==0.3.19,
any.safe-exceptions ==0.1.7.1, any.safe-exceptions ==0.1.7.2,
any.scientific ==0.3.6.2, any.scientific ==0.3.7.0,
scientific -bytestring-builder -integer-simple, scientific -bytestring-builder -integer-simple,
any.semigroupoids ==5.3.5, any.semigroupoids ==5.3.5,
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers, semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
@@ -193,32 +195,27 @@ constraints: any.Cabal ==3.0.1.0,
any.stm-chans ==3.0.0.4, any.stm-chans ==3.0.0.4,
any.streaming-commons ==0.2.2.1, any.streaming-commons ==0.2.2.1,
streaming-commons -use-bytestring-builder, streaming-commons -use-bytestring-builder,
any.streamly ==0.7.3,
streamly -debug -dev -examples -examples-sdl -fusion-plugin -has-llvm -inspection -no-fusion -streamk,
any.streamly-bytestring ==0.1.2,
any.streamly-posix ==0.1.0.1,
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,
any.string-interpolate ==0.3.1.0, any.string-interpolate ==0.3.1.1,
string-interpolate -bytestring-builder -extended-benchmarks -text-builder, string-interpolate -bytestring-builder -extended-benchmarks -text-builder,
any.syb ==0.7.2.1, any.syb ==0.7.2.1,
any.tagged ==0.8.6.1, any.tagged ==0.8.6.1,
tagged +deepseq +transformers, tagged +deepseq +transformers,
any.tasty ==1.3.1, any.tar ==0.6.0.0,
tasty +clock, any.template-haskell ==2.17.0.0,
any.tasty-hunit ==0.10.0.3, any.temporary ==1.3,
any.tasty-quickcheck ==0.10.1.2, any.terminal-progress-bar ==0.4.1,
any.template-haskell ==2.15.0.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.0, any.text ==1.2.4.1,
any.text-conversions ==0.3.1, any.text-conversions ==0.3.1,
any.text-short ==0.1.3, any.text-zipper ==0.11,
text-short -asserts,
any.tf-random ==0.5, any.tf-random ==0.5,
any.th-abstraction ==0.4.2.0, any.th-abstraction ==0.4.2.0,
any.th-compat ==0.1.1, any.th-compat ==0.1.2,
any.th-expand-syns ==0.4.8.0,
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.18,
any.th-orphans ==0.13.11, any.th-orphans ==0.13.11,
@@ -226,7 +223,7 @@ constraints: any.Cabal ==3.0.1.0,
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,
any.time-compat ==1.9.5, any.time-compat ==1.9.6,
time-compat -old-locale, time-compat -old-locale,
any.transformers ==0.5.6.2, any.transformers ==0.5.6.2,
any.transformers-base ==0.4.5.2, any.transformers-base ==0.4.5.2,
@@ -234,29 +231,34 @@ constraints: any.Cabal ==3.0.1.0,
any.transformers-compat ==0.6.6, any.transformers-compat ==0.6.6,
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two, transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
any.typed-process ==0.2.6.0, any.typed-process ==0.2.6.0,
any.unbounded-delays ==0.1.1.1,
any.unix ==2.7.2.2, any.unix ==2.7.2.2,
any.unix-bytestring ==0.3.7.3, any.unix-bytestring ==0.3.7.3,
any.unix-compat ==0.5.3, any.unix-compat ==0.5.3,
unix-compat -old-time, unix-compat -old-time,
any.unix-time ==0.4.7, any.unix-time ==0.4.7,
any.unliftio-core ==0.2.0.1, any.unliftio-core ==0.2.0.1,
any.unordered-containers ==0.2.13.0, any.unordered-containers ==0.2.14.0,
unordered-containers -debug, unordered-containers -debug,
any.uri-bytestring ==0.3.3.0, any.uri-bytestring ==0.3.3.1,
uri-bytestring -lib-werror, uri-bytestring -lib-werror,
any.utf8-string ==1.0.2, any.utf8-string ==1.0.2,
any.uuid-types ==1.0.4, any.uuid-types ==1.0.5,
any.vector ==0.12.2.0, any.vector ==0.12.3.0,
vector +boundschecks -internalchecks -unsafechecks -wall, vector +boundschecks -internalchecks -unsafechecks -wall,
any.vector-algorithms ==0.8.0.4, any.vector-algorithms ==0.8.0.4,
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks, vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
any.versions ==4.0.3, any.versions ==5.0.0,
any.vty ==5.33, any.vty ==5.33,
any.wcwidth ==0.0.2, any.word-wrap ==0.4.1,
wcwidth -cli +split-base,
any.word8 ==0.1.3, any.word8 ==0.1.3,
any.xor ==0.0.1.0,
any.yaml ==0.11.5.0, any.yaml ==0.11.5.0,
yaml +no-examples +no-exe, yaml +no-examples +no-exe,
zlib -non-blocking-ffi -pkg-config -static any.zip ==1.7.1,
index-state: hackage.haskell.org 2021-03-07T18:36:25Z zip -dev -disable-bzip2 -disable-zstd,
any.zlib ==0.6.2.3,
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
any.zlib-bindings ==0.1.1.5,
any.zstd ==0.1.2.0,
zstd +standalone
index-state: hackage.haskell.org 2021-07-12T18:00:24Z

View File

@@ -2060,8 +2060,8 @@ ghcupDownloads:
A_ARM64: A_ARM64:
Linux_UnknownLinux: Linux_UnknownLinux:
unknown_versioning: unknown_versioning:
dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/aarch64-linux-ghcup-0.1.15.2-r2 dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/aarch64-linux-ghcup-0.1.15.2-r1
dlHash: d67702f7c9e3586e85ed7c1bd09b7544da55bd1d3b4a961a07018348f78cf76b dlHash: d853372440f3d43babbb868fad399811241760f2233829c92403fcbea8c547ec
Darwin: Darwin:
unknown_versioning: unknown_versioning:
dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/aarch64-apple-darwin-ghcup-0.1.15.2 dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/aarch64-apple-darwin-ghcup-0.1.15.2
@@ -2069,8 +2069,8 @@ ghcupDownloads:
A_ARM: A_ARM:
Linux_UnknownLinux: Linux_UnknownLinux:
unknown_versioning: unknown_versioning:
dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/armv7-linux-ghcup-0.1.15.2 dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/armv7-linux-ghcup-0.1.15.2-r1
dlHash: 03a4af5ed895ada1dd21f4cc3f64dc9078a5bf4268313021d004c04bea7f9c2e dlHash: f8add9b39e1f7d0f03904dc69a8683259972a4472432c1ade27d918c39a4a874
HLS: HLS:
1.1.0: 1.1.0:
viTags: [] viTags: []
@@ -2120,8 +2120,17 @@ ghcupDownloads:
- old - old
viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v251 viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v251
viPostInstall: &stack-post | viPostInstall: &stack-post |
Stack manages GHC versions internally by default. In order to make it use ghcup installed GHC versions have a look at the options 'system-ghc', 'compiler-check' and 'compiler': https://docs.haskellstack.org/en/stable/yaml_configuration/#system-ghc Stack manages GHC versions internally by default. In order to make it use ghcup installed
Additionally, you should upgrade stack only through ghcup. GHC versions you can run the following commands:
stack config set install-ghc false --global
stack config set system-ghc true --global
On windows, you may find the following config options useful too:
skip-msys, extra-path, extra-include-dirs, extra-lib-dirs
Also check out: https://docs.haskellstack.org/en/stable/yaml_configuration
!!! Additionally, you should upgrade stack only through ghcup and not use 'stack upgrade' !!!
viArch: viArch:
A_64: A_64:
Linux_UnknownLinux: Linux_UnknownLinux:
@@ -2146,14 +2155,13 @@ ghcupDownloads:
unknown_versioning: *stack-251-64 unknown_versioning: *stack-251-64
2.7.1: 2.7.1:
viTags: viTags:
- Recommended - old
- Latest
viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v271 viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v271
viPostInstall: *stack-post viPostInstall: *stack-post
viArch: viArch:
A_64: A_64:
Linux_UnknownLinux: Linux_UnknownLinux:
unknown_versioning: &stack-64 unknown_versioning: &stack-271-64
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.7.1/stack-2.7.1-linux-x86_64.tar.gz dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.7.1/stack-2.7.1-linux-x86_64.tar.gz
dlHash: 2bc47749ee4be5eccb52a2d4a6a00b0f3b28b92517742b40c675836d7db2777d dlHash: 2bc47749ee4be5eccb52a2d4a6a00b0f3b28b92517742b40c675836d7db2777d
dlSubdir: dlSubdir:
@@ -2171,5 +2179,33 @@ ghcupDownloads:
dlSubdir: dlSubdir:
RegexDir: "stack-.*" RegexDir: "stack-.*"
Linux_Alpine: Linux_Alpine:
unknown_versioning: *stack-64 unknown_versioning: *stack-271-64
2.7.3:
viTags:
- Latest
- Recommended
viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v273
viPostInstall: *stack-post
viArch:
A_64:
Linux_UnknownLinux:
unknown_versioning: &stack-273-64
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.7.3/stack-2.7.3-linux-x86_64.tar.gz
dlHash: a6c090555fa1c64aa61c29aa4449765a51d79e870cf759cde192937cd614e72b
dlSubdir:
RegexDir: "stack-.*"
Darwin:
unknown_versioning:
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.7.3/stack-2.7.3-osx-x86_64.tar.gz
dlHash: 42e5000a00af44a7b26852421ac63ce75f510ad1a97742cb131107088ee9fe30
dlSubdir:
RegexDir: "stack-.*"
Windows:
unknown_versioning:
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.7.3/stack-2.7.3-windows-x86_64.tar.gz
dlHash: e6ba12e0ecabf0df2567d88a0d247da238bc114bcccfca4195f5e86472c9330c
dlSubdir:
RegexDir: "stack-.*"
Linux_Alpine:
unknown_versioning: *stack-273-64

View File

@@ -82,7 +82,6 @@ library
QuasiQuotes QuasiQuotes
RecordWildCards RecordWildCards
ScopedTypeVariables ScopedTypeVariables
Strict
StrictData StrictData
TupleSections TupleSections
TypeApplications TypeApplications
@@ -117,7 +116,7 @@ library
, megaparsec >=8.0.0 && <9.1 , megaparsec >=8.0.0 && <9.1
, monad-logger ^>=0.3.31 , monad-logger ^>=0.3.31
, mtl ^>=2.2 , mtl ^>=2.2
, optics >=0.2 && <0.5 , optics ^>=0.4
, optics-vl ^>=0.2 , optics-vl ^>=0.2
, os-release ^>=1.0.0 , os-release ^>=1.0.0
, parsec ^>=3.1 , parsec ^>=3.1
@@ -195,7 +194,6 @@ executable ghcup
PackageImports PackageImports
RecordWildCards RecordWildCards
ScopedTypeVariables ScopedTypeVariables
Strict
StrictData StrictData
TupleSections TupleSections
@@ -207,6 +205,7 @@ executable ghcup
, base >=4.13 && <5 , base >=4.13 && <5
, bytestring ^>=0.10 , bytestring ^>=0.10
, containers ^>=0.6 , containers ^>=0.6
, deepseq ^>=1.4
, filepath ^>=1.4.2.1 , filepath ^>=1.4.2.1
, ghcup , ghcup
, haskus-utils-variant >=3.0 && <3.2 , haskus-utils-variant >=3.0 && <3.2
@@ -261,7 +260,6 @@ executable ghcup-gen
QuasiQuotes QuasiQuotes
RecordWildCards RecordWildCards
ScopedTypeVariables ScopedTypeVariables
Strict
StrictData StrictData
TupleSections TupleSections
TypeApplications TypeApplications
@@ -281,7 +279,7 @@ executable ghcup-gen
, haskus-utils-variant >=3.0 && <3.2 , haskus-utils-variant >=3.0 && <3.2
, monad-logger ^>=0.3.31 , monad-logger ^>=0.3.31
, mtl ^>=2.2 , mtl ^>=2.2
, optics >=0.2 && <0.5 , optics ^>=0.4
, optparse-applicative >=0.15.1.0 && <0.17 , optparse-applicative >=0.15.1.0 && <0.17
, pretty ^>=1.1.3.1 , pretty ^>=1.1.3.1
, pretty-terminal ^>=0.1.0.0 , pretty-terminal ^>=0.1.0.0
@@ -305,6 +303,7 @@ executable ghcup-gen
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
build-tool-depends: hspec-discover:hspec-discover -any
hs-source-dirs: test hs-source-dirs: test
other-modules: other-modules:
GHCup.ArbitraryTypes GHCup.ArbitraryTypes

File diff suppressed because it is too large Load Diff

View File

@@ -107,32 +107,31 @@ import qualified Data.Yaml as Y
getDownloadsF :: ( FromJSONKey Tool getDownloadsF :: ( FromJSONKey Tool
, FromJSONKey Version , FromJSONKey Version
, FromJSON VersionInfo , FromJSON VersionInfo
, MonadReader env m
, HasSettings env
, HasDirs env
, MonadIO m , MonadIO m
, MonadCatch m , MonadCatch m
, MonadLogger m , MonadLogger m
, MonadThrow m , MonadThrow m
, MonadFail m , MonadFail m
) )
=> Settings => Excepts
-> Dirs
-> Excepts
'[JSONError , DownloadFailed , FileDoesNotExistError] '[JSONError , DownloadFailed , FileDoesNotExistError]
m m
GHCupInfo GHCupInfo
getDownloadsF settings@Settings{ urlSource } dirs = do getDownloadsF = do
Settings { urlSource } <- lift getSettings
case urlSource of case urlSource of
GHCupURL -> liftE $ getBase dirs settings GHCupURL -> liftE $ getBase ghcupURL
(OwnSource url) -> do (OwnSource url) -> liftE $ getBase url
bs <- reThrowAll DownloadFailed $ downloadBS (downloader settings) url
lE' JSONDecodeError $ first show $ Y.decodeEither' (L.toStrict bs)
(OwnSpec av) -> pure av (OwnSpec av) -> pure av
(AddSource (Left ext)) -> do (AddSource (Left ext)) -> do
base <- liftE $ getBase dirs settings base <- liftE $ getBase ghcupURL
pure (mergeGhcupInfo base ext) pure (mergeGhcupInfo base ext)
(AddSource (Right uri)) -> do (AddSource (Right uri)) -> do
base <- liftE $ getBase dirs settings base <- liftE $ getBase ghcupURL
bsExt <- reThrowAll DownloadFailed $ downloadBS (downloader settings) uri ext <- liftE $ getBase uri
ext <- lE' JSONDecodeError $ first show $ Y.decodeEither' (L.toStrict bsExt)
pure (mergeGhcupInfo base ext) pure (mergeGhcupInfo base ext)
where where
@@ -149,33 +148,49 @@ getDownloadsF settings@Settings{ urlSource } dirs = do
in GHCupInfo tr newDownloads newGlobalTools in GHCupInfo tr newDownloads newGlobalTools
readFromCache :: (MonadIO m, MonadCatch m, MonadLogger m) readFromCache :: ( MonadReader env m
=> Dirs , HasDirs env
-> Excepts '[JSONError, FileDoesNotExistError] m GHCupInfo , MonadIO m
readFromCache Dirs {..} = do , MonadCatch m)
lift $ $(logWarn) => URI
[i|Could not get download info, trying cached version (this may not be recent!)|] -> Excepts '[JSONError, FileDoesNotExistError] m L.ByteString
let path = view pathL' ghcupURL readFromCache uri = do
let yaml_file = cacheDir </> (T.unpack . decUTF8Safe . urlBaseName $ path) Dirs{..} <- lift getDirs
bs <- let yaml_file = cacheDir </> (T.unpack . decUTF8Safe . urlBaseName . view pathL' $ uri)
handleIO' NoSuchThing handleIO' NoSuchThing (\_ -> throwE $ FileDoesNotExistError yaml_file)
(\_ -> throwE $ FileDoesNotExistError yaml_file) . liftIO
$ liftIO . L.readFile
$ L.readFile yaml_file $ yaml_file
lE' JSONDecodeError $ first show $ Y.decodeEither' (L.toStrict bs)
getBase :: (MonadFail m, MonadIO m, MonadCatch m, MonadLogger m) getBase :: ( MonadReader env m
=> Dirs , HasDirs env
-> Settings , HasSettings env
, MonadFail m
, MonadIO m
, MonadCatch m
, MonadLogger m
)
=> URI
-> Excepts '[JSONError , FileDoesNotExistError] m GHCupInfo -> Excepts '[JSONError , FileDoesNotExistError] m GHCupInfo
getBase dirs@Dirs{..} Settings{ downloader } = getBase uri = do
handleIO (\_ -> readFromCache dirs) Settings { noNetwork } <- lift getSettings
$ catchE @_ @'[JSONError, FileDoesNotExistError] bs <- if noNetwork
(\(DownloadFailed _) -> readFromCache dirs) then readFromCache uri
(reThrowAll @_ @_ @'[JSONError, DownloadFailed] DownloadFailed (smartDl ghcupURL) else handleIO (\_ -> warnCache >> readFromCache uri)
>>= (liftE . lE' @_ @_ @'[JSONError] JSONDecodeError . first show . Y.decodeEither' . L.toStrict)) . catchE @_ @'[JSONError, FileDoesNotExistError] (\(DownloadFailed _) -> warnCache >> readFromCache uri)
where . reThrowAll @_ @_ @'[JSONError, DownloadFailed] DownloadFailed
$ smartDl uri
liftE
. lE' @_ @_ @'[JSONError] JSONDecodeError
. first show
. Y.decodeEither'
. L.toStrict
$ bs
where
warnCache = lift $ $(logWarn)
[i|Could not get download info, trying cached version (this may not be recent!)|]
-- First check if the json file is in the ~/.ghcup/cache dir -- First check if the json file is in the ~/.ghcup/cache dir
-- and check it's access time. If it has been accessed within the -- and check it's access time. If it has been accessed within the
-- last 5 minutes, just reuse it. -- last 5 minutes, just reuse it.
@@ -185,8 +200,11 @@ getBase dirs@Dirs{..} Settings{ downloader } =
-- than the local file. -- than the local file.
-- --
-- Always save the local file with the mod time of the remote file. -- Always save the local file with the mod time of the remote file.
smartDl :: forall m1 smartDl :: forall m1 env1
. ( MonadCatch m1 . ( MonadReader env1 m1
, HasDirs env1
, HasSettings env1
, MonadCatch m1
, MonadIO m1 , MonadIO m1
, MonadFail m1 , MonadFail m1
, MonadLogger m1 , MonadLogger m1
@@ -200,13 +218,15 @@ getBase dirs@Dirs{..} Settings{ downloader } =
, NoLocationHeader , NoLocationHeader
, TooManyRedirs , TooManyRedirs
, ProcessError , ProcessError
, NoNetwork
] ]
m1 m1
L.ByteString L.ByteString
smartDl uri' = do smartDl uri' = do
Dirs{..} <- lift getDirs
let path = view pathL' uri' let path = view pathL' uri'
let json_file = cacheDir </> (T.unpack . decUTF8Safe . urlBaseName $ path) let json_file = cacheDir </> (T.unpack . decUTF8Safe . urlBaseName $ path)
e <- liftIO $ doesFileExist json_file e <- liftIO $ doesFileExist json_file
if e if e
then do then do
accessTime <- liftIO $ getAccessTime json_file accessTime <- liftIO $ getAccessTime json_file
@@ -237,11 +257,11 @@ getBase dirs@Dirs{..} Settings{ downloader } =
where where
dlWithMod modTime json_file = do dlWithMod modTime json_file = do
bs <- liftE $ downloadBS downloader uri' bs <- liftE $ downloadBS uri'
liftIO $ writeFileWithModTime modTime json_file bs liftIO $ writeFileWithModTime modTime json_file bs
pure bs pure bs
dlWithoutMod json_file = do dlWithoutMod json_file = do
bs <- liftE $ downloadBS downloader uri' bs <- liftE $ downloadBS uri'
liftIO $ hideError doesNotExistErrorType $ rmFile json_file liftIO $ hideError doesNotExistErrorType $ rmFile json_file
liftIO $ L.writeFile json_file bs liftIO $ L.writeFile json_file bs
liftIO $ setModificationTime json_file (posixSecondsToUTCTime (fromIntegral @Int 0)) liftIO $ setModificationTime json_file (posixSecondsToUTCTime (fromIntegral @Int 0))
@@ -279,39 +299,46 @@ getBase dirs@Dirs{..} Settings{ downloader } =
setModificationTime path utctime setModificationTime path utctime
getDownloadInfo :: Tool getDownloadInfo :: ( MonadReader env m
, HasPlatformReq env
, HasGHCupInfo env
)
=> Tool
-> Version -> Version
-- ^ tool version -- ^ tool version
-> PlatformRequest -> Excepts
-> GHCupDownloads '[NoDownload]
-> Either NoDownload DownloadInfo m
getDownloadInfo t v (PlatformRequest a p mv) dls = maybe DownloadInfo
(Left NoDownload) getDownloadInfo t v = do
Right (PlatformRequest a p mv) <- lift getPlatformReq
(case p of GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
-- non-musl won't work on alpine
Linux Alpine -> with_distro <|> without_distro_ver
_ -> with_distro <|> without_distro_ver <|> without_distro
)
where let distro_preview f g =
with_distro = distro_preview id id let platformVersionSpec =
without_distro_ver = distro_preview id (const Nothing) preview (ix t % ix v % viArch % ix a % ix (f p)) dls
without_distro = distro_preview (set _Linux UnknownLinux) (const Nothing) mv' = g mv
in fmap snd
. find
(\(mverRange, _) -> maybe
(isNothing mv')
(\range -> maybe False (`versionRange` range) mv')
mverRange
)
. M.toList
=<< platformVersionSpec
with_distro = distro_preview id id
without_distro_ver = distro_preview id (const Nothing)
without_distro = distro_preview (set _Linux UnknownLinux) (const Nothing)
distro_preview f g = maybe
let platformVersionSpec = (throwE NoDownload)
preview (ix t % ix v % viArch % ix a % ix (f p)) dls pure
mv' = g mv (case p of
in fmap snd -- non-musl won't work on alpine
. find Linux Alpine -> with_distro <|> without_distro_ver
(\(mverRange, _) -> maybe _ -> with_distro <|> without_distro_ver <|> without_distro
(isNothing mv') )
(\range -> maybe False (`versionRange` range) mv')
mverRange
)
. M.toList
=<< platformVersionSpec
-- | Tries to download from the given http or https url -- | Tries to download from the given http or https url
@@ -321,17 +348,19 @@ getDownloadInfo t v (PlatformRequest a p mv) dls = maybe
-- 2. otherwise create a random file -- 2. otherwise create a random file
-- --
-- The file must not exist. -- The file must not exist.
download :: ( MonadMask m download :: ( MonadReader env m
, HasSettings env
, HasDirs env
, MonadMask m
, MonadThrow m , MonadThrow m
, MonadLogger m , MonadLogger m
, MonadIO m , MonadIO m
) )
=> Settings => DownloadInfo
-> DownloadInfo
-> FilePath -- ^ destination dir -> FilePath -- ^ destination dir
-> Maybe FilePath -- ^ optional filename -> Maybe FilePath -- ^ optional filename
-> Excepts '[DigestError , DownloadFailed] m FilePath -> Excepts '[DigestError , DownloadFailed] m FilePath
download settings@Settings{ downloader } dli dest mfn download dli dest mfn
| scheme == "https" = dl | scheme == "https" = dl
| scheme == "http" = dl | scheme == "http" = dl
| scheme == "file" = cp | scheme == "file" = cp
@@ -362,6 +391,8 @@ download settings@Settings{ downloader } dli dest mfn
liftIO (hideError doesNotExistErrorType $ rmFile destFile) liftIO (hideError doesNotExistErrorType $ rmFile destFile)
>> (throwE . DownloadFailed $ e) >> (throwE . DownloadFailed $ e)
) $ do ) $ do
Settings{ downloader, noNetwork } <- lift getSettings
when noNetwork $ throwE (DownloadFailed (V NoNetwork :: V '[NoNetwork]))
case downloader of case downloader of
Curl -> do Curl -> do
o' <- liftIO getCurlOpts o' <- liftIO getCurlOpts
@@ -377,58 +408,66 @@ download settings@Settings{ downloader } dli dest mfn
liftE $ downloadToFile https host fullPath port destFile liftE $ downloadToFile https host fullPath port destFile
#endif #endif
liftE $ checkDigest settings dli destFile liftE $ checkDigest dli destFile
pure destFile pure destFile
-- Manage to find a file we can write the body into. -- Manage to find a file we can write the body into.
getDestFile :: FilePath getDestFile :: FilePath
getDestFile = maybe (dest </> T.unpack (decUTF8Safe (urlBaseName path))) (dest </>) mfn getDestFile = maybe (dest </> T.unpack (decUTF8Safe (urlBaseName path)))
(dest </>)
mfn
path = view (dlUri % pathL') dli path = view (dlUri % pathL') dli
-- | Download into tmpdir or use cached version, if it exists. If filename -- | Download into tmpdir or use cached version, if it exists. If filename
-- is omitted, infers the filename from the url. -- is omitted, infers the filename from the url.
downloadCached :: ( MonadMask m downloadCached :: ( MonadReader env m
, HasDirs env
, HasSettings env
, MonadMask m
, MonadResource m , MonadResource m
, MonadThrow m , MonadThrow m
, MonadLogger m , MonadLogger m
, MonadIO m , MonadIO m
, MonadUnliftIO m , MonadUnliftIO m
) )
=> Settings => DownloadInfo
-> Dirs
-> DownloadInfo
-> Maybe FilePath -- ^ optional filename -> Maybe FilePath -- ^ optional filename
-> Excepts '[DigestError , DownloadFailed] m FilePath -> Excepts '[DigestError , DownloadFailed] m FilePath
downloadCached settings@Settings{ cache } dirs dli mfn = do downloadCached dli mfn = do
Settings{ cache } <- lift getSettings
case cache of case cache of
True -> downloadCached' settings dirs dli mfn True -> downloadCached' dli mfn Nothing
False -> do False -> do
tmp <- lift withGHCupTmpDir tmp <- lift withGHCupTmpDir
liftE $ download settings dli tmp mfn liftE $ download dli tmp mfn
downloadCached' :: ( MonadMask m downloadCached' :: ( MonadReader env m
, HasDirs env
, HasSettings env
, MonadMask m
, MonadThrow m , MonadThrow m
, MonadLogger m , MonadLogger m
, MonadIO m , MonadIO m
, MonadUnliftIO m , MonadUnliftIO m
) )
=> Settings => DownloadInfo
-> Dirs
-> DownloadInfo
-> Maybe FilePath -- ^ optional filename -> Maybe FilePath -- ^ optional filename
-> Maybe FilePath -- ^ optional destination dir (default: cacheDir)
-> Excepts '[DigestError , DownloadFailed] m FilePath -> Excepts '[DigestError , DownloadFailed] m FilePath
downloadCached' settings Dirs{..} dli mfn = do downloadCached' dli mfn mDestDir = do
Dirs { cacheDir } <- lift getDirs
let destDir = fromMaybe cacheDir mDestDir
let fn = fromMaybe ((T.unpack . decUTF8Safe) $ urlBaseName $ view (dlUri % pathL') dli) mfn let fn = fromMaybe ((T.unpack . decUTF8Safe) $ urlBaseName $ view (dlUri % pathL') dli) mfn
let cachfile = cacheDir </> fn let cachfile = destDir </> fn
fileExists <- liftIO $ doesFileExist cachfile fileExists <- liftIO $ doesFileExist cachfile
if if
| fileExists -> do | fileExists -> do
liftE $ checkDigest settings dli cachfile liftE $ checkDigest dli cachfile
pure cachfile pure cachfile
| otherwise -> liftE $ download settings dli cacheDir mfn | otherwise -> liftE $ download dli destDir mfn
@@ -441,9 +480,13 @@ downloadCached' settings Dirs{..} dli mfn = do
-- | This is used for downloading the JSON. -- | This is used for downloading the JSON.
downloadBS :: (MonadCatch m, MonadIO m, MonadLogger m) downloadBS :: ( MonadReader env m
=> Downloader , HasSettings env
-> URI , MonadCatch m
, MonadIO m
, MonadLogger m
)
=> URI
-> Excepts -> Excepts
'[ FileDoesNotExistError '[ FileDoesNotExistError
, HTTPStatusError , HTTPStatusError
@@ -452,10 +495,11 @@ downloadBS :: (MonadCatch m, MonadIO m, MonadLogger m)
, NoLocationHeader , NoLocationHeader
, TooManyRedirs , TooManyRedirs
, ProcessError , ProcessError
, NoNetwork
] ]
m m
L.ByteString L.ByteString
downloadBS downloader uri' downloadBS uri'
| scheme == "https" | scheme == "https"
= dl True = dl True
| scheme == "http" | scheme == "http"
@@ -475,6 +519,8 @@ downloadBS downloader uri'
dl _ = do dl _ = do
#endif #endif
lift $ $(logDebug) [i|downloading: #{serializeURIRef' uri'}|] lift $ $(logDebug) [i|downloading: #{serializeURIRef' uri'}|]
Settings{ downloader, noNetwork } <- lift getSettings
when noNetwork $ throwE NoNetwork
case downloader of case downloader of
Curl -> do Curl -> do
o' <- liftIO getCurlOpts o' <- liftIO getCurlOpts
@@ -499,12 +545,18 @@ downloadBS downloader uri'
#endif #endif
checkDigest :: (MonadIO m, MonadThrow m, MonadLogger m) checkDigest :: ( MonadReader env m
=> Settings , HasDirs env
-> DownloadInfo , HasSettings env
, MonadIO m
, MonadThrow m
, MonadLogger m
)
=> DownloadInfo
-> FilePath -> FilePath
-> Excepts '[DigestError] m () -> Excepts '[DigestError] m ()
checkDigest Settings{ noVerify } dli file = do checkDigest dli file = do
Settings{ noVerify } <- lift getSettings
let verify = not noVerify let verify = not noVerify
when verify $ do when verify $ do
let p' = takeFileName file let p' = takeFileName file

View File

@@ -233,6 +233,13 @@ instance Pretty NoToolVersionSet where
pPrint (NoToolVersionSet tool) = pPrint (NoToolVersionSet tool) =
text [i|No version is set for tool "#{tool}".|] text [i|No version is set for tool "#{tool}".|]
data NoNetwork = NoNetwork
deriving Show
instance Pretty NoNetwork where
pPrint NoNetwork =
text [i|A download was required or requested, but '--offline' was specified.|]
------------------------- -------------------------
--[ High-level errors ]-- --[ High-level errors ]--

View File

@@ -1,7 +1,12 @@
{-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-| {-|
Module : GHCup.Types Module : GHCup.Types
@@ -21,6 +26,7 @@ module GHCup.Types
where where
import Control.Applicative import Control.Applicative
import Control.DeepSeq ( NFData, rnf )
import Control.Monad.Logger import Control.Monad.Logger
import Data.Map.Strict ( Map ) import Data.Map.Strict ( Map )
import Data.List.NonEmpty ( NonEmpty (..) ) import Data.List.NonEmpty ( NonEmpty (..) )
@@ -60,6 +66,8 @@ data GHCupInfo = GHCupInfo
} }
deriving (Show, GHC.Generic) deriving (Show, GHC.Generic)
instance NFData GHCupInfo
------------------------- -------------------------
@@ -79,6 +87,8 @@ data Requirements = Requirements
} }
deriving (Show, GHC.Generic) deriving (Show, GHC.Generic)
instance NFData Requirements
@@ -105,9 +115,13 @@ data Tool = GHC
| Stack | Stack
deriving (Eq, GHC.Generic, Ord, Show, Enum, Bounded) deriving (Eq, GHC.Generic, Ord, Show, Enum, Bounded)
instance NFData Tool
data GlobalTool = ShimGen data GlobalTool = ShimGen
deriving (Eq, GHC.Generic, Ord, Show, Enum, Bounded) deriving (Eq, GHC.Generic, Ord, Show, Enum, Bounded)
instance NFData GlobalTool
-- | All necessary information of a tool version, including -- | All necessary information of a tool version, including
-- source download and per-architecture downloads. -- source download and per-architecture downloads.
@@ -123,6 +137,8 @@ data VersionInfo = VersionInfo
} }
deriving (Eq, GHC.Generic, Show) deriving (Eq, GHC.Generic, Show)
instance NFData VersionInfo
-- | A tag. These are currently attached to a version of a tool. -- | A tag. These are currently attached to a version of a tool.
data Tag = Latest data Tag = Latest
@@ -133,6 +149,8 @@ data Tag = Latest
| UnknownTag String -- ^ used for upwardscompat | UnknownTag String -- ^ used for upwardscompat
deriving (Ord, Eq, GHC.Generic, Show) -- FIXME: manual JSON instance deriving (Ord, Eq, GHC.Generic, Show) -- FIXME: manual JSON instance
instance NFData Tag
tagToString :: Tag -> String tagToString :: Tag -> String
tagToString Recommended = "recommended" tagToString Recommended = "recommended"
tagToString Latest = "latest" tagToString Latest = "latest"
@@ -159,6 +177,8 @@ data Architecture = A_64
| A_ARM64 | A_ARM64
deriving (Eq, GHC.Generic, Ord, Show) deriving (Eq, GHC.Generic, Ord, Show)
instance NFData Architecture
archToString :: Architecture -> String archToString :: Architecture -> String
archToString A_64 = "x86_64" archToString A_64 = "x86_64"
archToString A_32 = "i386" archToString A_32 = "i386"
@@ -181,6 +201,8 @@ data Platform = Linux LinuxDistro
-- ^ must exit -- ^ must exit
deriving (Eq, GHC.Generic, Ord, Show) deriving (Eq, GHC.Generic, Ord, Show)
instance NFData Platform
platformToString :: Platform -> String platformToString :: Platform -> String
platformToString (Linux distro) = "linux-" ++ distroToString distro platformToString (Linux distro) = "linux-" ++ distroToString distro
platformToString Darwin = "darwin" platformToString Darwin = "darwin"
@@ -206,6 +228,8 @@ data LinuxDistro = Debian
-- ^ must exit -- ^ must exit
deriving (Eq, GHC.Generic, Ord, Show) deriving (Eq, GHC.Generic, Ord, Show)
instance NFData LinuxDistro
distroToString :: LinuxDistro -> String distroToString :: LinuxDistro -> String
distroToString Debian = "debian" distroToString Debian = "debian"
distroToString Ubuntu = "ubuntu" distroToString Ubuntu = "ubuntu"
@@ -232,6 +256,7 @@ data DownloadInfo = DownloadInfo
} }
deriving (Eq, Ord, GHC.Generic, Show) deriving (Eq, Ord, GHC.Generic, Show)
instance NFData DownloadInfo
@@ -245,6 +270,8 @@ data TarDir = RealDir FilePath
| RegexDir String -- ^ will be compiled to regex, the first match will "win" | RegexDir String -- ^ will be compiled to regex, the first match will "win"
deriving (Eq, Ord, GHC.Generic, Show) deriving (Eq, Ord, GHC.Generic, Show)
instance NFData TarDir
instance Pretty TarDir where instance Pretty TarDir where
pPrint (RealDir path) = text path pPrint (RealDir path) = text path
pPrint (RegexDir regex) = text regex pPrint (RegexDir regex) = text regex
@@ -257,6 +284,10 @@ data URLSource = GHCupURL
| AddSource (Either GHCupInfo URI) -- ^ merge with GHCupURL | AddSource (Either GHCupInfo URI) -- ^ merge with GHCupURL
deriving (GHC.Generic, Show) deriving (GHC.Generic, Show)
instance NFData URLSource
instance NFData (URIRef Absolute) where
rnf (URI !_ !_ !_ !_ !_) = ()
data UserSettings = UserSettings data UserSettings = UserSettings
{ uCache :: Maybe Bool { uCache :: Maybe Bool
@@ -266,11 +297,12 @@ data UserSettings = UserSettings
, uDownloader :: Maybe Downloader , uDownloader :: Maybe Downloader
, uKeyBindings :: Maybe UserKeyBindings , uKeyBindings :: Maybe UserKeyBindings
, uUrlSource :: Maybe URLSource , uUrlSource :: Maybe URLSource
, uNoNetwork :: Maybe Bool
} }
deriving (Show, GHC.Generic) deriving (Show, GHC.Generic)
defaultUserSettings :: UserSettings defaultUserSettings :: UserSettings
defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
data UserKeyBindings = UserKeyBindings data UserKeyBindings = UserKeyBindings
{ kUp :: Maybe Key { kUp :: Maybe Key
@@ -298,6 +330,9 @@ data KeyBindings = KeyBindings
} }
deriving (Show, GHC.Generic) deriving (Show, GHC.Generic)
instance NFData KeyBindings
instance NFData Key
defaultKeyBindings :: KeyBindings defaultKeyBindings :: KeyBindings
defaultKeyBindings = KeyBindings defaultKeyBindings = KeyBindings
{ bUp = KUp { bUp = KUp
@@ -317,7 +352,18 @@ data AppState = AppState
, keyBindings :: KeyBindings , keyBindings :: KeyBindings
, ghcupInfo :: GHCupInfo , ghcupInfo :: GHCupInfo
, pfreq :: PlatformRequest , pfreq :: PlatformRequest
} deriving (Show) } deriving (Show, GHC.Generic)
instance NFData AppState
data LeanAppState = LeanAppState
{ settings :: Settings
, dirs :: Dirs
, keyBindings :: KeyBindings
} deriving (Show, GHC.Generic)
instance NFData LeanAppState
data Settings = Settings data Settings = Settings
{ cache :: Bool { cache :: Bool
@@ -326,29 +372,39 @@ data Settings = Settings
, downloader :: Downloader , downloader :: Downloader
, verbose :: Bool , verbose :: Bool
, urlSource :: URLSource , urlSource :: URLSource
, noNetwork :: Bool
} }
deriving (Show, GHC.Generic) deriving (Show, GHC.Generic)
instance NFData Settings
data Dirs = Dirs data Dirs = Dirs
{ baseDir :: FilePath { baseDir :: FilePath
, binDir :: FilePath , binDir :: FilePath
, cacheDir :: FilePath , cacheDir :: FilePath
, logsDir :: FilePath , logsDir :: FilePath
, confDir :: FilePath , confDir :: FilePath
, tmpDir :: FilePath
} }
deriving Show deriving (Show, GHC.Generic)
instance NFData Dirs
data KeepDirs = Always data KeepDirs = Always
| Errors | Errors
| Never | Never
deriving (Eq, Show, Ord) deriving (Eq, Show, Ord, GHC.Generic)
instance NFData KeepDirs
data Downloader = Curl data Downloader = Curl
| Wget | Wget
#if defined(INTERNAL_DOWNLOADER) #if defined(INTERNAL_DOWNLOADER)
| Internal | Internal
#endif #endif
deriving (Eq, Show, Ord) deriving (Eq, Show, Ord, GHC.Generic)
instance NFData Downloader
data DebugInfo = DebugInfo data DebugInfo = DebugInfo
{ diBaseDir :: FilePath { diBaseDir :: FilePath
@@ -371,7 +427,9 @@ data PlatformResult = PlatformResult
{ _platform :: Platform { _platform :: Platform
, _distroVersion :: Maybe Versioning , _distroVersion :: Maybe Versioning
} }
deriving (Eq, Show) deriving (Eq, Show, GHC.Generic)
instance NFData PlatformResult
platResToString :: PlatformResult -> String platResToString :: PlatformResult -> String
platResToString PlatformResult { _platform = plat, _distroVersion = Just v' } platResToString PlatformResult { _platform = plat, _distroVersion = Just v' }
@@ -387,7 +445,9 @@ data PlatformRequest = PlatformRequest
, _rPlatform :: Platform , _rPlatform :: Platform
, _rVersion :: Maybe Versioning , _rVersion :: Maybe Versioning
} }
deriving (Eq, Show) deriving (Eq, Show, GHC.Generic)
instance NFData PlatformRequest
pfReqToString :: PlatformRequest -> String pfReqToString :: PlatformRequest -> String
pfReqToString (PlatformRequest arch plat ver) = pfReqToString (PlatformRequest arch plat ver) =
@@ -434,6 +494,8 @@ data VersionCmp = VR_gt Versioning
| VR_eq Versioning | VR_eq Versioning
deriving (Eq, GHC.Generic, Ord, Show) deriving (Eq, GHC.Generic, Ord, Show)
instance NFData VersionCmp
-- | A version range. Supports && and ||, but not arbitrary -- | A version range. Supports && and ||, but not arbitrary
-- combinations. This is a little simplified. -- combinations. This is a little simplified.
@@ -441,6 +503,7 @@ data VersionRange = SimpleRange (NonEmpty VersionCmp) -- And
| OrRange (NonEmpty VersionCmp) VersionRange | OrRange (NonEmpty VersionCmp) VersionRange
deriving (Eq, GHC.Generic, Ord, Show) deriving (Eq, GHC.Generic, Ord, Show)
instance NFData VersionRange
instance Pretty Versioning where instance Pretty Versioning where
pPrint = text . T.unpack . prettyV pPrint = text . T.unpack . prettyV
@@ -459,4 +522,3 @@ instance (Monad m, Alternative m) => Alternative (LoggingT m) where
instance MonadLogger m => MonadLogger (Excepts e m) where instance MonadLogger m => MonadLogger (Excepts e m) where
monadLoggerLog a b c d = Trans.lift $ monadLoggerLog a b c d monadLoggerLog a b c d = Trans.lift $ monadLoggerLog a b c d

View File

@@ -1,4 +1,9 @@
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-| {-|
Module : GHCup.Types.Optics Module : GHCup.Types.Optics
@@ -13,6 +18,7 @@ module GHCup.Types.Optics where
import GHCup.Types import GHCup.Types
import Control.Monad.Reader
import Data.ByteString ( ByteString ) import Data.ByteString ( ByteString )
import Optics import Optics
import URI.ByteString import URI.ByteString
@@ -58,3 +64,82 @@ pathL' = lensVL pathL
queryL' :: Lens' (URIRef a) Query queryL' :: Lens' (URIRef a) Query
queryL' = lensVL queryL queryL' = lensVL queryL
----------------------
--[ Lens utilities ]--
----------------------
gets :: forall f a env m . (MonadReader env m, LabelOptic' f A_Lens env a)
=> m a
gets = asks (^. labelOptic @f)
getAppState :: MonadReader AppState m => m AppState
getAppState = ask
getLeanAppState :: ( MonadReader env m
, LabelOptic' "settings" A_Lens env Settings
, LabelOptic' "dirs" A_Lens env Dirs
, LabelOptic' "keyBindings" A_Lens env KeyBindings
)
=> m LeanAppState
getLeanAppState = do
s <- gets @"settings"
d <- gets @"dirs"
k <- gets @"keyBindings"
pure (LeanAppState s d k)
getSettings :: ( MonadReader env m
, LabelOptic' "settings" A_Lens env Settings
)
=> m Settings
getSettings = gets @"settings"
getDirs :: ( MonadReader env m
, LabelOptic' "dirs" A_Lens env Dirs
)
=> m Dirs
getDirs = gets @"dirs"
getKeyBindings :: ( MonadReader env m
, LabelOptic' "keyBindings" A_Lens env KeyBindings
)
=> m KeyBindings
getKeyBindings = gets @"keyBindings"
getGHCupInfo :: ( MonadReader env m
, LabelOptic' "ghcupInfo" A_Lens env GHCupInfo
)
=> m GHCupInfo
getGHCupInfo = gets @"ghcupInfo"
getPlatformReq :: ( MonadReader env m
, LabelOptic' "pfreq" A_Lens env PlatformRequest
)
=> m PlatformRequest
getPlatformReq = gets @"pfreq"
type HasSettings env = (LabelOptic' "settings" A_Lens env Settings)
type HasDirs env = (LabelOptic' "dirs" A_Lens env Dirs)
type HasKeyBindings env = (LabelOptic' "keyBindings" A_Lens env KeyBindings)
type HasGHCupInfo env = (LabelOptic' "ghcupInfo" A_Lens env GHCupInfo)
type HasPlatformReq env = (LabelOptic' "pfreq" A_Lens env PlatformRequest)
getCache :: (MonadReader env m, HasSettings env) => m Bool
getCache = getSettings <&> cache
getDownloader :: (MonadReader env m, HasSettings env) => m Downloader
getDownloader = getSettings <&> downloader

View File

@@ -103,28 +103,30 @@ import qualified Text.Megaparsec as MP
-- | The symlink destination of a ghc tool. -- | The symlink destination of a ghc tool.
ghcLinkDestination :: (MonadReader AppState m, MonadThrow m, MonadIO m) ghcLinkDestination :: ( MonadReader env m
, HasDirs env
, MonadThrow m, MonadIO m)
=> FilePath -- ^ the tool, such as 'ghc', 'haddock' etc. => FilePath -- ^ the tool, such as 'ghc', 'haddock' etc.
-> GHCTargetVersion -> GHCTargetVersion
-> m FilePath -> m FilePath
ghcLinkDestination tool ver = do ghcLinkDestination tool ver = do
AppState { dirs = Dirs {..} } <- ask Dirs {..} <- getDirs
ghcd <- ghcupGHCDir ver ghcd <- ghcupGHCDir ver
pure (relativeSymlink binDir (ghcd </> "bin" </> tool)) pure (relativeSymlink binDir (ghcd </> "bin" </> tool))
-- | Removes the minor GHC symlinks, e.g. ghc-8.6.5. -- | Removes the minor GHC symlinks, e.g. ghc-8.6.5.
rmMinorSymlinks :: ( MonadReader AppState m rmMinorSymlinks :: ( MonadReader env m
, HasDirs env
, MonadIO m , MonadIO m
, MonadLogger m , MonadLogger m
, MonadThrow m , MonadThrow m
, MonadFail m , MonadFail m
, MonadReader AppState m
) )
=> GHCTargetVersion => GHCTargetVersion
-> Excepts '[NotInstalled] m () -> Excepts '[NotInstalled] m ()
rmMinorSymlinks tv@GHCTargetVersion{..} = do rmMinorSymlinks tv@GHCTargetVersion{..} = do
AppState { dirs = Dirs {..} } <- lift ask Dirs {..} <- lift getDirs
files <- liftE $ ghcToolFiles tv files <- liftE $ ghcToolFiles tv
forM_ files $ \f -> do forM_ files $ \f -> do
@@ -135,7 +137,8 @@ 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 AppState m rmPlain :: ( MonadReader env m
, HasDirs env
, MonadLogger m , MonadLogger m
, MonadThrow m , MonadThrow m
, MonadFail m , MonadFail m
@@ -144,7 +147,7 @@ rmPlain :: ( MonadReader AppState m
=> Maybe Text -- ^ target => Maybe Text -- ^ target
-> Excepts '[NotInstalled] m () -> Excepts '[NotInstalled] m ()
rmPlain target = do rmPlain target = do
AppState { dirs = Dirs {..} } <- lift ask Dirs {..} <- lift getDirs
mtv <- lift $ ghcSet target mtv <- lift $ ghcSet target
forM_ mtv $ \tv -> do forM_ mtv $ \tv -> do
files <- liftE $ ghcToolFiles tv files <- liftE $ ghcToolFiles tv
@@ -159,17 +162,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 AppState m rmMajorSymlinks :: ( MonadReader env m
, HasDirs env
, MonadIO m , MonadIO m
, MonadLogger m , MonadLogger m
, MonadThrow m , MonadThrow m
, MonadFail m , MonadFail m
, MonadReader AppState m
) )
=> GHCTargetVersion => GHCTargetVersion
-> Excepts '[NotInstalled] m () -> Excepts '[NotInstalled] m ()
rmMajorSymlinks tv@GHCTargetVersion{..} = do rmMajorSymlinks tv@GHCTargetVersion{..} = do
AppState { dirs = Dirs {..} } <- lift ask Dirs {..} <- lift getDirs
(mj, mi) <- getMajorMinorV _tvVersion (mj, mi) <- getMajorMinorV _tvVersion
let v' = intToText mj <> "." <> intToText mi let v' = intToText mj <> "." <> intToText mi
@@ -189,26 +192,26 @@ rmMajorSymlinks tv@GHCTargetVersion{..} = do
-- | Whether the given GHC versin is installed. -- | Whether the given GHC versin is installed.
ghcInstalled :: (MonadIO m, MonadReader AppState m, MonadThrow m) => GHCTargetVersion -> m Bool ghcInstalled :: (MonadIO m, MonadReader env m, HasDirs env, MonadThrow m) => GHCTargetVersion -> m Bool
ghcInstalled ver = do ghcInstalled ver = do
ghcdir <- ghcupGHCDir ver ghcdir <- ghcupGHCDir ver
liftIO $ doesDirectoryExist ghcdir liftIO $ doesDirectoryExist ghcdir
-- | Whether the given GHC version is installed from source. -- | Whether the given GHC version is installed from source.
ghcSrcInstalled :: (MonadIO m, MonadReader AppState m, MonadThrow m) => GHCTargetVersion -> m Bool ghcSrcInstalled :: (MonadIO m, MonadReader env m, HasDirs env, MonadThrow m) => GHCTargetVersion -> m Bool
ghcSrcInstalled ver = do ghcSrcInstalled ver = do
ghcdir <- ghcupGHCDir ver ghcdir <- ghcupGHCDir ver
liftIO $ doesFileExist (ghcdir </> ghcUpSrcBuiltFile) liftIO $ doesFileExist (ghcdir </> ghcUpSrcBuiltFile)
-- | Whether the given GHC version is set as the current. -- | Whether the given GHC version is set as the current.
ghcSet :: (MonadReader AppState m, MonadThrow m, MonadIO m) ghcSet :: (MonadReader env m, HasDirs env, MonadThrow m, MonadIO m)
=> Maybe Text -- ^ the target of the GHC version, if any => Maybe Text -- ^ the target of the GHC version, if any
-- (e.g. armv7-unknown-linux-gnueabihf) -- (e.g. armv7-unknown-linux-gnueabihf)
-> m (Maybe GHCTargetVersion) -> m (Maybe GHCTargetVersion)
ghcSet mtarget = do ghcSet mtarget = do
AppState {dirs = Dirs {..}} <- ask Dirs {..} <- getDirs
let ghc = maybe "ghc" (\t -> T.unpack t <> "-ghc") mtarget let ghc = maybe "ghc" (\t -> T.unpack t <> "-ghc") mtarget
let ghcBin = binDir </> ghc <> exeExt let ghcBin = binDir </> ghc <> exeExt
@@ -239,7 +242,7 @@ ghcSet mtarget = do
-- | Get all installed GHCs by reading ~/.ghcup/ghc/<dir>. -- | Get all installed GHCs by reading ~/.ghcup/ghc/<dir>.
-- If a dir cannot be parsed, returns left. -- If a dir cannot be parsed, returns left.
getInstalledGHCs :: (MonadReader AppState m, MonadIO m) => m [Either FilePath GHCTargetVersion] getInstalledGHCs :: (MonadReader env m, HasDirs env, MonadIO m) => m [Either FilePath GHCTargetVersion]
getInstalledGHCs = do getInstalledGHCs = do
ghcdir <- ghcupGHCBaseDir ghcdir <- ghcupGHCBaseDir
fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectory ghcdir fs <- liftIO $ hideErrorDef [NoSuchThing] [] $ listDirectory ghcdir
@@ -249,10 +252,15 @@ getInstalledGHCs = do
-- | Get all installed cabals, by matching on @~\/.ghcup\/bin/cabal-*@. -- | Get all installed cabals, by matching on @~\/.ghcup\/bin/cabal-*@.
getInstalledCabals :: (MonadLogger m, MonadReader AppState m, MonadIO m, MonadCatch m) getInstalledCabals :: ( MonadLogger m
, MonadReader env m
, HasDirs env
, MonadIO m
, MonadCatch m
)
=> m [Either FilePath Version] => m [Either FilePath Version]
getInstalledCabals = do getInstalledCabals = do
AppState {dirs = Dirs {..}} <- ask Dirs {..} <- getDirs
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
binDir binDir
(makeRegexOpts compExtended execBlank ([s|^cabal-.*$|] :: ByteString)) (makeRegexOpts compExtended execBlank ([s|^cabal-.*$|] :: ByteString))
@@ -264,16 +272,16 @@ getInstalledCabals = do
-- | Whether the given cabal version is installed. -- | Whether the given cabal version is installed.
cabalInstalled :: (MonadLogger m, MonadIO m, MonadReader AppState m, MonadCatch m) => Version -> m Bool cabalInstalled :: (MonadLogger m, MonadIO m, MonadReader env m, HasDirs env, MonadCatch m) => Version -> m Bool
cabalInstalled ver = do cabalInstalled ver = do
vers <- fmap rights getInstalledCabals vers <- fmap rights getInstalledCabals
pure $ elem ver vers pure $ elem ver vers
-- Return the currently set cabal version, if any. -- Return the currently set cabal version, if any.
cabalSet :: (MonadLogger m, MonadReader AppState m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version) cabalSet :: (MonadLogger m, MonadReader env m, HasDirs env, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
cabalSet = do cabalSet = do
AppState {dirs = Dirs {..}} <- ask Dirs {..} <- getDirs
let cabalbin = binDir </> "cabal" <> exeExt let cabalbin = binDir </> "cabal" <> exeExt
handleIO' NoSuchThing (\_ -> pure Nothing) $ do handleIO' NoSuchThing (\_ -> pure Nothing) $ do
@@ -317,10 +325,10 @@ 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\>@.
getInstalledHLSs :: (MonadReader AppState m, 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
AppState { dirs = Dirs {..} } <- ask Dirs {..} <- getDirs
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
binDir binDir
(makeRegexOpts compExtended (makeRegexOpts compExtended
@@ -337,10 +345,10 @@ getInstalledHLSs = do
-- | Get all installed stacks, by matching on -- | Get all installed stacks, by matching on
-- @~\/.ghcup\/bin/stack-<\stackver\>@. -- @~\/.ghcup\/bin/stack-<\stackver\>@.
getInstalledStacks :: (MonadReader AppState m, MonadIO m, MonadCatch m) getInstalledStacks :: (MonadReader env m, HasDirs env, MonadIO m, MonadCatch m)
=> m [Either FilePath Version] => m [Either FilePath Version]
getInstalledStacks = do getInstalledStacks = do
AppState { dirs = Dirs {..} } <- ask Dirs {..} <- getDirs
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
binDir binDir
(makeRegexOpts compExtended (makeRegexOpts compExtended
@@ -355,9 +363,9 @@ getInstalledStacks = do
-- Return the currently set stack version, if any. -- Return the currently set stack version, if any.
-- TODO: there's a lot of code duplication here :> -- TODO: there's a lot of code duplication here :>
stackSet :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadCatch m, MonadLogger m) => m (Maybe Version) stackSet :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m, MonadCatch m, MonadLogger m) => m (Maybe Version)
stackSet = do stackSet = do
AppState {dirs = Dirs {..}} <- ask Dirs {..} <- getDirs
let stackBin = binDir </> "stack" <> exeExt let stackBin = binDir </> "stack" <> exeExt
handleIO' NoSuchThing (\_ -> pure Nothing) $ do handleIO' NoSuchThing (\_ -> pure Nothing) $ do
@@ -395,13 +403,13 @@ stackSet = do
stripRelativePath = MP.many (MP.try stripPathComponet) stripRelativePath = MP.many (MP.try stripPathComponet)
-- | Whether the given Stack version is installed. -- | Whether the given Stack version is installed.
stackInstalled :: (MonadIO m, MonadReader AppState m, MonadCatch m) => Version -> m Bool stackInstalled :: (MonadIO m, MonadReader env m, HasDirs env, MonadCatch m) => Version -> m Bool
stackInstalled ver = do stackInstalled ver = do
vers <- fmap rights getInstalledStacks vers <- fmap rights getInstalledStacks
pure $ elem ver vers pure $ elem ver vers
-- | Whether the given HLS version is installed. -- | Whether the given HLS version is installed.
hlsInstalled :: (MonadIO m, MonadReader AppState m, MonadCatch m) => Version -> m Bool hlsInstalled :: (MonadIO m, MonadReader env m, HasDirs env, MonadCatch m) => Version -> m Bool
hlsInstalled ver = do hlsInstalled ver = do
vers <- fmap rights getInstalledHLSs vers <- fmap rights getInstalledHLSs
pure $ elem ver vers pure $ elem ver vers
@@ -409,9 +417,9 @@ hlsInstalled ver = do
-- Return the currently set hls version, if any. -- Return the currently set hls version, if any.
hlsSet :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version) hlsSet :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
hlsSet = do hlsSet = do
AppState {dirs = Dirs {..}} <- ask Dirs {..} <- getDirs
let hlsBin = binDir </> "haskell-language-server-wrapper" <> exeExt let hlsBin = binDir </> "haskell-language-server-wrapper" <> exeExt
liftIO $ handleIO' NoSuchThing (\_ -> pure Nothing) $ do liftIO $ handleIO' NoSuchThing (\_ -> pure Nothing) $ do
@@ -443,7 +451,8 @@ hlsSet = do
-- | Return the GHC versions the currently selected HLS supports. -- | Return the GHC versions the currently selected HLS supports.
hlsGHCVersions :: ( MonadReader AppState m hlsGHCVersions :: ( MonadReader env m
, HasDirs env
, MonadIO m , MonadIO m
, MonadThrow m , MonadThrow m
, MonadCatch m , MonadCatch m
@@ -466,11 +475,11 @@ hlsGHCVersions = do
-- | Get all server binaries for an hls version, if any. -- | Get all server binaries for an hls version, if any.
hlsServerBinaries :: (MonadReader AppState m, MonadIO m) hlsServerBinaries :: (MonadReader env m, HasDirs env, MonadIO m)
=> Version => Version
-> m [FilePath] -> m [FilePath]
hlsServerBinaries ver = do hlsServerBinaries ver = do
AppState { dirs = Dirs {..} } <- ask Dirs {..} <- getDirs
liftIO $ handleIO (\_ -> pure []) $ findFiles liftIO $ handleIO (\_ -> pure []) $ findFiles
binDir binDir
(makeRegexOpts (makeRegexOpts
@@ -482,12 +491,12 @@ hlsServerBinaries ver = do
-- | Get the wrapper binary for an hls version, if any. -- | Get the wrapper binary for an hls version, if any.
hlsWrapperBinary :: (MonadReader AppState m, MonadThrow m, MonadIO m) hlsWrapperBinary :: (MonadReader env m, HasDirs env, MonadThrow m, MonadIO m)
=> Version => Version
-> m (Maybe FilePath) -> m (Maybe FilePath)
hlsWrapperBinary ver = do hlsWrapperBinary ver = do
AppState { dirs = Dirs {..} } <- ask Dirs {..} <- getDirs
wrapper <- liftIO $ handleIO (\_ -> pure []) $ findFiles wrapper <- liftIO $ handleIO (\_ -> pure []) $ findFiles
binDir binDir
(makeRegexOpts (makeRegexOpts
compExtended compExtended
@@ -503,7 +512,7 @@ hlsWrapperBinary ver = do
-- | Get all binaries for an hls version, if any. -- | Get all binaries for an hls version, if any.
hlsAllBinaries :: (MonadReader AppState m, MonadIO m, MonadThrow m) => Version -> m [FilePath] hlsAllBinaries :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m) => Version -> m [FilePath]
hlsAllBinaries ver = do hlsAllBinaries ver = do
hls <- hlsServerBinaries ver hls <- hlsServerBinaries ver
wrapper <- hlsWrapperBinary ver wrapper <- hlsWrapperBinary ver
@@ -511,9 +520,9 @@ hlsAllBinaries ver = do
-- | Get the active symlinks for hls. -- | Get the active symlinks for hls.
hlsSymlinks :: (MonadReader AppState m, MonadIO m, MonadCatch m) => m [FilePath] hlsSymlinks :: (MonadReader env m, HasDirs env, MonadIO m, MonadCatch m) => m [FilePath]
hlsSymlinks = do hlsSymlinks = do
AppState { dirs = Dirs {..} } <- ask Dirs {..} <- getDirs
oldSyms <- liftIO $ handleIO (\_ -> pure []) $ findFiles oldSyms <- liftIO $ handleIO (\_ -> pure []) $ findFiles
binDir binDir
(makeRegexOpts compExtended (makeRegexOpts compExtended
@@ -549,7 +558,7 @@ matchMajor v' major' minor' = case getMajorMinorV v' of
-- | Get the latest installed full GHC version that satisfies X.Y. -- | Get the latest installed full GHC version that satisfies X.Y.
-- This reads `ghcupGHCBaseDir`. -- This reads `ghcupGHCBaseDir`.
getGHCForMajor :: (MonadReader AppState m, MonadIO m, MonadThrow m) getGHCForMajor :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m)
=> Int -- ^ major version component => Int -- ^ major version component
-> Int -- ^ minor version component -> Int -- ^ minor version component
-> Maybe Text -- ^ the target triple -> Maybe Text -- ^ the target triple
@@ -729,19 +738,6 @@ getLatestBaseVersion av pvpVer =
-----------------------
--[ AppState Getter ]--
-----------------------
getCache :: MonadReader AppState m => m Bool
getCache = ask <&> cache . settings
getDownloader :: MonadReader AppState m => m Downloader
getDownloader = ask <&> downloader . settings
------------- -------------
--[ Other ]-- --[ Other ]--
@@ -754,7 +750,7 @@ getDownloader = ask <&> downloader . settings
-- Returns unversioned relative files without extension, e.g.: -- Returns unversioned relative files without extension, e.g.:
-- --
-- - @["hsc2hs","haddock","hpc","runhaskell","ghc","ghc-pkg","ghci","runghc","hp2ps"]@ -- - @["hsc2hs","haddock","hpc","runhaskell","ghc","ghc-pkg","ghci","runghc","hp2ps"]@
ghcToolFiles :: (MonadReader AppState m, MonadThrow m, MonadFail m, MonadIO m) ghcToolFiles :: (MonadReader env m, HasDirs env, MonadThrow m, MonadFail m, MonadIO m)
=> GHCTargetVersion => GHCTargetVersion
-> Excepts '[NotInstalled] m [FilePath] -> Excepts '[NotInstalled] m [FilePath]
ghcToolFiles ver = do ghcToolFiles ver = do
@@ -817,7 +813,12 @@ ghcUpSrcBuiltFile = ".ghcup_src_built"
-- | Calls gmake if it exists in PATH, otherwise make. -- | Calls gmake if it exists in PATH, otherwise make.
make :: (MonadThrow m, MonadIO m, MonadReader AppState m) make :: ( MonadThrow m
, MonadIO m
, MonadReader env m
, HasDirs env
, HasSettings env
)
=> [String] => [String]
-> Maybe FilePath -> Maybe FilePath
-> m (Either ProcessError ()) -> m (Either ProcessError ())
@@ -827,7 +828,7 @@ make args workdir = do
let mymake = if has_gmake then "gmake" else "make" let mymake = if has_gmake then "gmake" else "make"
execLogged mymake args workdir "ghc-make" Nothing execLogged mymake args workdir "ghc-make" Nothing
makeOut :: (MonadReader AppState m, MonadIO m) makeOut :: (MonadReader env m, HasDirs env, MonadIO m)
=> [String] => [String]
-> Maybe FilePath -> Maybe FilePath
-> m CapturedProcess -> m CapturedProcess
@@ -840,7 +841,7 @@ makeOut args workdir = do
-- | Try to apply patches in order. Fails with 'PatchFailed' -- | Try to apply patches in order. Fails with 'PatchFailed'
-- on first failure. -- on first failure.
applyPatches :: (MonadReader AppState m, MonadLogger m, MonadIO m) applyPatches :: (MonadReader env m, HasDirs env, MonadLogger m, 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 ()
@@ -858,7 +859,7 @@ applyPatches pdir ddir = do
-- | https://gitlab.haskell.org/ghc/ghc/-/issues/17353 -- | https://gitlab.haskell.org/ghc/ghc/-/issues/17353
darwinNotarization :: (MonadReader AppState m, MonadIO m) darwinNotarization :: (MonadReader env m, HasDirs env, MonadIO m)
=> Platform => Platform
-> FilePath -> FilePath
-> m (Either ProcessError ()) -> m (Either ProcessError ())
@@ -881,13 +882,13 @@ getChangeLog dls tool (Right tag) =
-- --
-- 1. the build directory, depending on the KeepDirs setting -- 1. the build directory, depending on the KeepDirs setting
-- 2. the install destination, depending on whether the build failed -- 2. the install destination, depending on whether the build failed
runBuildAction :: (Show (V e), MonadReader AppState m, MonadIO m, MonadMask m) runBuildAction :: (Show (V e), MonadReader env m, HasDirs env, HasSettings env, MonadIO m, MonadMask m)
=> FilePath -- ^ build directory (cleaned up depending on Settings) => FilePath -- ^ build directory (cleaned up depending on Settings)
-> Maybe FilePath -- ^ dir to *always* clean up on exception -> Maybe FilePath -- ^ dir to *always* clean up on exception
-> Excepts e m a -> Excepts e m a
-> Excepts '[BuildFailed] m a -> Excepts '[BuildFailed] m a
runBuildAction bdir instdir action = do runBuildAction bdir instdir action = do
AppState { settings = Settings {..} } <- lift ask Settings {..} <- lift getSettings
let exAction = do let exAction = do
forM_ instdir $ \dir -> forM_ instdir $ \dir ->
liftIO $ hideError doesNotExistErrorType $ rmPath dir liftIO $ hideError doesNotExistErrorType $ rmPath dir
@@ -1016,7 +1017,8 @@ createLink :: ( MonadMask m
, MonadThrow m , MonadThrow m
, MonadLogger m , MonadLogger m
, MonadIO m , MonadIO m
, MonadReader AppState m , MonadReader env m
, HasDirs env
, MonadUnliftIO m , MonadUnliftIO m
, MonadFail m , MonadFail m
) )
@@ -1025,7 +1027,7 @@ createLink :: ( MonadMask m
-> m () -> m ()
createLink link exe = do createLink link exe = do
#if defined(IS_WINDOWS) #if defined(IS_WINDOWS)
AppState { dirs } <- ask dirs <- getDirs
let shimGen = cacheDir dirs </> "gs.exe" let shimGen = cacheDir dirs </> "gs.exe"
let shim = dropExtension exe <.> "shim" let shim = dropExtension exe <.> "shim"
@@ -1054,17 +1056,22 @@ ensureGlobalTools :: ( MonadMask m
, MonadThrow m , MonadThrow m
, MonadLogger m , MonadLogger m
, MonadIO m , MonadIO m
, MonadReader AppState m , MonadReader env m
, HasDirs env
, HasSettings env
, HasGHCupInfo env
, MonadUnliftIO m , MonadUnliftIO m
, MonadFail m , MonadFail m
) )
=> Excepts '[DigestError , DownloadFailed, NoDownload] m () => Excepts '[DigestError , DownloadFailed, NoDownload] m ()
ensureGlobalTools = do ensureGlobalTools = do
#if defined(IS_WINDOWS) #if defined(IS_WINDOWS)
AppState { ghcupInfo = GHCupInfo _ _ gTools, settings, dirs } <- lift ask (GHCupInfo _ _ gTools) <- lift getGHCupInfo
settings <- lift getSettings
dirs <- lift getDirs
shimDownload <- liftE $ lE @_ @'[NoDownload] shimDownload <- liftE $ lE @_ @'[NoDownload]
$ maybe (Left NoDownload) Right $ Map.lookup ShimGen gTools $ maybe (Left NoDownload) Right $ Map.lookup ShimGen gTools
let dl = downloadCached' settings dirs shimDownload (Just "gs.exe") let dl = downloadCached' shimDownload (Just "gs.exe") Nothing
void $ (\(DigestError _ _) -> do void $ (\(DigestError _ _) -> do
lift $ $(logWarn) [i|Digest doesn't match, redownloading gs.exe...|] lift $ $(logWarn) [i|Digest doesn't match, redownloading gs.exe...|]
lift $ $(logDebug) [i|rm -f #{shimDownload}|] lift $ $(logDebug) [i|rm -f #{shimDownload}|]
@@ -1079,17 +1086,25 @@ ensureGlobalTools = do
-- | Ensure ghcup directory structure exists. -- | Ensure ghcup directory structure exists.
ensureDirectories :: Dirs -> IO () ensureDirectories :: Dirs -> IO ()
ensureDirectories dirs = do ensureDirectories (Dirs baseDir binDir cacheDir logsDir confDir tmpDir) = do
let Dirs
{ baseDir
, binDir
, cacheDir
, logsDir
, confDir
} = dirs
createDirRecursive' baseDir createDirRecursive' baseDir
createDirRecursive' (baseDir </> "ghc")
createDirRecursive' binDir createDirRecursive' binDir
createDirRecursive' cacheDir createDirRecursive' cacheDir
createDirRecursive' logsDir createDirRecursive' logsDir
createDirRecursive' confDir createDirRecursive' confDir
createDirRecursive' tmpDir
pure () pure ()
-- | For ghc without arch triple, this is:
--
-- - ghc-<ver> (e.g. ghc-8.10.4)
--
-- For ghc with arch triple:
--
-- - <triple>-ghc-<ver> (e.g. arm-linux-gnueabihf-ghc-8.10.4)
ghcBinaryName :: GHCTargetVersion -> String
ghcBinaryName (GHCTargetVersion (Just t) v') = T.unpack (t <> "-ghc-" <> prettyVer v' <> T.pack exeExt)
ghcBinaryName (GHCTargetVersion Nothing v') = T.unpack ("ghc-" <> prettyVer v' <> T.pack exeExt)

View File

@@ -16,7 +16,7 @@ Stability : experimental
Portability : portable Portability : portable
-} -}
module GHCup.Utils.Dirs module GHCup.Utils.Dirs
( getDirs ( getAllDirs
, ghcupBaseDir , ghcupBaseDir
, ghcupConfigFile , ghcupConfigFile
, ghcupCacheDir , ghcupCacheDir
@@ -37,6 +37,7 @@ where
import GHCup.Errors import GHCup.Errors
import GHCup.Types import GHCup.Types
import GHCup.Types.JSON ( ) import GHCup.Types.JSON ( )
import GHCup.Types.Optics
import GHCup.Utils.MegaParsec import GHCup.Utils.MegaParsec
import GHCup.Utils.Prelude import GHCup.Utils.Prelude
@@ -190,13 +191,23 @@ ghcupLogsDir = do
#endif #endif
getDirs :: IO Dirs -- | Defaults to '~/.ghcup/tmp.
getDirs = do --
-- If 'GHCUP_USE_XDG_DIRS' is set (to anything),
-- then uses 'XDG_DATA_HOME/ghcup/tmp' as per xdg spec.
ghcupTmpDir :: IO FilePath
ghcupTmpDir = ghcupBaseDir <&> (</> "tmp")
getAllDirs :: IO Dirs
getAllDirs = do
baseDir <- ghcupBaseDir baseDir <- ghcupBaseDir
binDir <- ghcupBinDir binDir <- ghcupBinDir
cacheDir <- ghcupCacheDir cacheDir <- ghcupCacheDir
logsDir <- ghcupLogsDir logsDir <- ghcupLogsDir
confDir <- ghcupConfigDir confDir <- ghcupConfigDir
tmpDir <- ghcupTmpDir
pure Dirs { .. } pure Dirs { .. }
@@ -226,9 +237,9 @@ ghcupConfigFile = do
-- | ~/.ghcup/ghc by default. -- | ~/.ghcup/ghc by default.
ghcupGHCBaseDir :: (MonadReader AppState m) => m FilePath ghcupGHCBaseDir :: (MonadReader env m, HasDirs env) => m FilePath
ghcupGHCBaseDir = do ghcupGHCBaseDir = do
AppState { dirs = Dirs {..} } <- ask Dirs {..} <- getDirs
pure (baseDir </> "ghc") pure (baseDir </> "ghc")
@@ -236,7 +247,7 @@ ghcupGHCBaseDir = do
-- The dir may be of the form -- The dir may be of the form
-- * armv7-unknown-linux-gnueabihf-8.8.3 -- * armv7-unknown-linux-gnueabihf-8.8.3
-- * 8.8.4 -- * 8.8.4
ghcupGHCDir :: (MonadReader AppState m, MonadThrow m) ghcupGHCDir :: (MonadReader env m, HasDirs env, MonadThrow m)
=> GHCTargetVersion => GHCTargetVersion
-> m FilePath -> m FilePath
ghcupGHCDir ver = do ghcupGHCDir ver = do

View File

@@ -21,6 +21,7 @@ module GHCup.Utils.File.Posix where
import GHCup.Utils.File.Common import GHCup.Utils.File.Common
import GHCup.Utils.Prelude import GHCup.Utils.Prelude
import GHCup.Types import GHCup.Types
import GHCup.Types.Optics
import Control.Concurrent import Control.Concurrent
import Control.Concurrent.Async import Control.Concurrent.Async
@@ -74,7 +75,11 @@ executeOut path args chdir = liftIO $ captureOutStreams $ do
SPP.executeFile path True args Nothing SPP.executeFile path True args Nothing
execLogged :: (MonadReader AppState m, MonadIO m, MonadThrow m) execLogged :: ( MonadReader env m
, HasSettings env
, HasDirs env
, MonadIO m
, MonadThrow m)
=> FilePath -- ^ thing to execute => FilePath -- ^ thing to execute
-> [String] -- ^ args for the thing -> [String] -- ^ args for the thing
-> Maybe FilePath -- ^ optionally chdir into this -> Maybe FilePath -- ^ optionally chdir into this
@@ -82,7 +87,8 @@ execLogged :: (MonadReader AppState m, MonadIO m, MonadThrow m)
-> Maybe [(String, String)] -- ^ optional environment -> Maybe [(String, String)] -- ^ optional environment
-> m (Either ProcessError ()) -> m (Either ProcessError ())
execLogged exe args chdir lfile env = do execLogged exe args chdir lfile env = do
AppState { settings = Settings {..}, dirs = Dirs {..} } <- ask Settings {..} <- getSettings
Dirs {..} <- getDirs
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

View File

@@ -19,6 +19,7 @@ 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.Types import GHCup.Types
import GHCup.Types.Optics
import Control.Concurrent import Control.Concurrent
import Control.DeepSeq import Control.DeepSeq
@@ -146,7 +147,11 @@ executeOut path args chdir = do
pure $ CapturedProcess exit out err pure $ CapturedProcess exit out err
execLogged :: (MonadReader AppState m, MonadIO m, MonadThrow m) execLogged :: ( MonadReader env m
, HasDirs env
, HasSettings env
, MonadIO m
, MonadThrow m)
=> FilePath -- ^ thing to execute => FilePath -- ^ thing to execute
-> [String] -- ^ args for the thing -> [String] -- ^ args for the thing
-> Maybe FilePath -- ^ optionally chdir into this -> Maybe FilePath -- ^ optionally chdir into this
@@ -154,7 +159,7 @@ execLogged :: (MonadReader AppState m, MonadIO m, MonadThrow m)
-> Maybe [(String, String)] -- ^ optional environment -> Maybe [(String, String)] -- ^ optional environment
-> m (Either ProcessError ()) -> m (Either ProcessError ())
execLogged exe args chdir lfile env = do execLogged exe args chdir lfile env = do
AppState { dirs = Dirs {..} } <- ask Dirs {..} <- getDirs
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)

View File

@@ -20,6 +20,7 @@ import GHCup.Utils.String.QQ
import Control.Monad import Control.Monad
import Control.Monad.IO.Class import Control.Monad.IO.Class
import Control.Monad.Logger import Control.Monad.Logger
import Data.Char ( ord )
import Prelude hiding ( appendFile ) import Prelude hiding ( appendFile )
import System.Console.Pretty import System.Console.Pretty
import System.FilePath import System.FilePath
@@ -43,20 +44,33 @@ myLoggerT LoggerConfig {..} loggingt = runLoggingT loggingt mylogger
mylogger :: Loc -> LogSource -> LogLevel -> LogStr -> IO () mylogger :: Loc -> LogSource -> LogLevel -> LogStr -> IO ()
mylogger _ _ level str' = do mylogger _ _ level str' = do
-- color output -- color output
let style' = case level of
LevelDebug -> style Bold . color Blue
LevelInfo -> style Bold . color Green
LevelWarn -> style Bold . color Yellow
LevelError -> style Bold . color Red
LevelOther _ -> id
let l = case level of let l = case level of
LevelDebug -> toLogStr (style Bold $ color Blue "[ Debug ]") LevelDebug -> toLogStr (style' "[ Debug ]")
LevelInfo -> toLogStr (style Bold $ color Green "[ Info ]") LevelInfo -> toLogStr (style' "[ Info ]")
LevelWarn -> toLogStr (style Bold $ color Yellow "[ Warn ]") LevelWarn -> toLogStr (style' "[ Warn ]")
LevelError -> toLogStr (style Bold $ color Red "[ Error ]") LevelError -> toLogStr (style' "[ Error ]")
LevelOther t -> toLogStr "[ " <> toLogStr t <> toLogStr " ]" LevelOther t -> toLogStr "[ " <> toLogStr t <> toLogStr " ]"
let out = fromLogStr (l <> toLogStr " " <> str' <> toLogStr "\n") let strs = fmap toLogStr . B.split (fromIntegral $ ord '\n') . fromLogStr $ str'
let out = case strs of
[] -> B.empty
(x:xs) -> fromLogStr
. foldr (\a b -> a <> toLogStr "\n" <> b) mempty
. ((l <> toLogStr " " <> x) :)
. fmap (\line' -> toLogStr (style' "[ ... ] ") <> line' )
$ xs
when (lcPrintDebug || (not lcPrintDebug && (level /= LevelDebug))) when (lcPrintDebug || (not lcPrintDebug && (level /= LevelDebug)))
$ colorOutter out $ colorOutter out
-- raw output -- raw output
let lr = case level of let lr = case level of
LevelDebug -> toLogStr "Debug: " LevelDebug -> toLogStr "Debug:"
LevelInfo -> toLogStr "Info:" LevelInfo -> toLogStr "Info:"
LevelWarn -> toLogStr "Warn:" LevelWarn -> toLogStr "Warn:"
LevelError -> toLogStr "Error:" LevelError -> toLogStr "Error:"

27
refreeze.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
set -xue
rm -f cabal.*.project
rm -f cabal.*.project.freeze
for ghc_ver in "$@" ; do
# shellcheck disable=SC3060
project_file=cabal.ghc${ghc_ver//./}.project
cp cabal.project "${project_file}"
case "$(uname -s)" in
MSYS*|MINGW*)
cabal freeze --project-file="${project_file}" -w "ghc-${ghc_ver}"
;;
*)
cabal freeze --project-file="${project_file}" -w "ghc-${ghc_ver}" -ftui -finternal-downloader
;;
esac
echo "" >> "${project_file}"
echo "with-compiler: ghc-${ghc_ver}" >> "${project_file}"
sed -i -e '/ghcup/d' "${project_file}".freeze
done

View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) 2019 Grégoire Geis
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,10 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

View File

@@ -0,0 +1,71 @@
# `shim.c`
[`shim.c`](./shim.c) is a simple Windows program that, when started:
1. Looks for a file with the exact same name as the running program, but with
the extension `shim` (e.g. `C:\bin\foo.exe` will read the file `C:\bin\foo.shim`).
2. Reads and [parses](#shim-format) the files into a
[Scoop](https://github.com/lukesampson/scoop) shim format.
3. Executes the target executable with the given arguments.
`shim.c` was originally made to replace [Scoop](https://github.com/lukesampson/scoop)'s
[`shim.cs`](https://github.com/lukesampson/scoop/blob/96de9c14bb483f9278e4b0a9e22b1923ee752901/supporting/shimexe/shim.cs)
since it had several important flaws:
1. [It was made in C#](https://github.com/lukesampson/scoop/tree/96de9c14bb483f9278e4b0a9e22b1923ee752901/supporting/shimexe),
and thus required an instantiation of a .NET command line app everytime it was started,
which can make a command run much slower than if it had been ran directly;
2. [It](https://github.com/lukesampson/scoop/issues/2339) [did](https://github.com/lukesampson/scoop/issues/1896)
[not](https://github.com/felixse/FluentTerminal/issues/221) handle Ctrl+C and other
signals correctly, which could be quite infuriating (and essentially killing REPLs and long-running apps).
[`shim.c`](./shim.c) is:
- **Faster**, because it does not use the .NET Framework, and parses the `.shim` file in a simpler way.
- **More efficient**, because by the time the target of the shim is started, all allocated memory will have been freed.
- And more importantly, it **works better**:
- Signals originating from pressing `Ctrl+C` are ignored, and therefore handled directly by the spawned child.
Your processes and REPLs will no longer close when pressing `Ctrl+C`.
- Children are automatically killed when the shim process is killed. No more orphaned processes and weird behaviors.
> **Note**: This project is not affiliated with [Scoop](https://github.com/lukesampson/scoop).
## Installation for Scoop
- In a Visual Studio command prompt, run `cl /O1 shim.c`.
- Replace any `.exe` in `scoop\shims` by `shim.exe`.
An additional script, `repshims.bat`, is provided. It will replace all `.exe`s in the user's Scoop directory
by `shim.exe`.
## Example
Given the following shim `gs.shim`:
```
path = C:\Program Files\Git\git.exe
args = status -u
```
In this directory, where `gs.exe` is the compiled `shim.c`:
```
C:\Bin\
gs.exe
gs.shim
```
Then calling `gs -s` will run the program `C:\Program Files\Git\git.exe status -u -s`.
## Shim format
Shims follow the same format as Scoop's shims: line-separated `key = value` pairs.
```
path = C:\Program Files\Git\git.exe
args = status -uno
```
`path` is a required value, but `args` can be omitted. Also, do note that lines **must** end with a line feed.
## License
`SPDX-License-Identifier: MIT OR Unlicense`

View File

@@ -0,0 +1,15 @@
@echo off
if not defined SCOOP set SCOOP=%USERPROFILE%\scoop
for %%x in ("%SCOOP%\shims\*.exe") do (
echo Replacing %%x by new shim.
copy /B /Y shim.exe "%%~x" >NUL
)
if not defined SCOOP_GLOBAL set SCOOP_GLOBAL=%ProgramData%\scoop
for %%x in ("%SCOOP_GLOBAL%\shims\*.exe") do (
echo Replacing %%x by new shim.
copy /B /Y shim.exe "%%~x" >NUL
)

256
scoop-better-shimexe/shim.c Normal file
View File

@@ -0,0 +1,256 @@
#pragma comment(lib, "SHELL32.LIB")
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <Windows.h>
#ifndef ERROR_ELEVATION_REQUIRED
# define ERROR_ELEVATION_REQUIRED 740
#endif
#define MAX_FILENAME_SIZE 512
BOOL WINAPI ctrlhandler(DWORD fdwCtrlType)
{
switch (fdwCtrlType) {
// Ignore all events, and let the child process
// handle them.
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_SHUTDOWN_EVENT:
return TRUE;
default:
return FALSE;
}
}
int compute_program_length(const wchar_t* commandline)
{
int i = 0;
if (commandline[0] == L'"') {
// Wait till end of string
i++;
for (;;) {
wchar_t c = commandline[i++];
if (c == 0)
return i - 1;
else if (c == L'\\')
i++;
else if (c == L'"')
return i;
}
} else {
for (;;) {
wchar_t c = commandline[i++];
if (c == 0)
return i - 1;
else if (c == L'\\')
i++;
else if (c == L' ')
return i;
}
}
}
int main()
{
DWORD exit_code = 0;
wchar_t* path = NULL;
wchar_t* args = NULL;
wchar_t* cmd = NULL;
// Find filename of current executable.
wchar_t filename[MAX_FILENAME_SIZE + 2];
const unsigned int filename_size = GetModuleFileNameW(NULL, filename, MAX_FILENAME_SIZE);
if (filename_size >= MAX_FILENAME_SIZE) {
fprintf(stderr, "The filename of the program is too long to handle.\n");
exit_code = 1;
goto cleanup;
}
// Use filename of current executable to find .shim
filename[filename_size - 3] = L's';
filename[filename_size - 2] = L'h';
filename[filename_size - 1] = L'i';
filename[filename_size - 0] = L'm';
filename[filename_size + 1] = 0 ;
FILE* shim_file;
if ((shim_file = _wfsopen(filename, L"r,ccs=UTF-8", _SH_DENYNO)) == NULL) {
fprintf(stderr, "Cannot open shim file for read.\n");
exit_code = 1;
goto cleanup;
}
size_t command_length = 256;
size_t path_length;
size_t args_length;
// Read shim
wchar_t linebuf[8192];
for (;;) {
const wchar_t* line = fgetws(linebuf, 8192, shim_file);
if (line == NULL)
break;
if (line[4] != L' ' || line[5] != L'=' || line[6] != L' ')
continue;
const int linelen = wcslen(line);
const int len = linelen - 8 + (line[linelen - 1] != '\n');
if (line[0] == L'p' && line[1] == L'a' && line[2] == L't' && line[3] == L'h') {
// Reading path
path = calloc(len + 1, sizeof(wchar_t));
wmemcpy(path, line + 7, len);
command_length += len;
path_length = len;
continue;
}
if (line[0] == L'a' && line[1] == L'r' && line[2] == L'g' && line[3] == L's') {
// Reading args
args = calloc(len + 1, sizeof(wchar_t));
wmemcpy(args, line + 7, len);
command_length += len + 1;
args_length = len;
continue;
}
continue;
}
fclose(shim_file);
if (path == NULL) {
fprintf(stderr, "Could not read shim file.\n");
exit_code = 1;
goto cleanup;
}
// Find length of command to run
wchar_t* given_cmd = GetCommandLineW();
const int program_length = compute_program_length(given_cmd);
given_cmd += program_length;
const int given_length = wcslen(given_cmd);
command_length += given_length;
// Start building command to run, using '[path] [args]', as given by shim.
cmd = calloc(command_length, sizeof(wchar_t));
int cmd_i = 0;
wmemcpy(cmd, path, path_length);
cmd[path_length] = ' ';
cmd_i += path_length + 1;
if (args != NULL) {
wmemcpy(cmd + path_length + 1, args, args_length);
cmd[path_length + args_length + 1] = ' ';
cmd_i += args_length + 1;
}
// Copy all given arguments to command
wmemcpy(cmd + cmd_i, given_cmd, given_length);
// Find out if the target program is a console app
SHFILEINFOW sfi = {0};
const BOOL is_windows_app = HIWORD(SHGetFileInfoW(path, -1, &sfi, sizeof(sfi), SHGFI_EXETYPE));
if (is_windows_app)
// Unfortunately, this technique will still show a window for a fraction of time,
// but there's just no workaround.
FreeConsole();
// Create job object, which can be attached to child processes
// to make sure they terminate when the parent terminates as well.
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0};
HANDLE jobHandle = CreateJobObject(NULL, NULL);
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
SetInformationJobObject(jobHandle, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli));
// Start subprocess
STARTUPINFOW si = {0};
PROCESS_INFORMATION pi = {0};
if (CreateProcessW(NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
AssignProcessToJobObject(jobHandle, pi.hProcess);
ResumeThread(pi.hThread);
} else {
if (GetLastError() == ERROR_ELEVATION_REQUIRED) {
// We must elevate the process, which is (basically) impossible with
// CreateProcess, and therefore we fallback to ShellExecuteEx,
// which CAN create elevated processes, at the cost of opening a new separate
// window.
// Theorically, this could be fixed (or rather, worked around) using pipes
// and IPC, but... this is a question for another day.
SHELLEXECUTEINFOW sei = {0};
sei.cbSize = sizeof(SHELLEXECUTEINFOW);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.lpFile = path;
sei.lpParameters = cmd + path_length + 1;
sei.nShow = SW_SHOW;
if (!ShellExecuteExW(&sei)) {
fprintf(stderr, "Unable to create elevated process: error %li.", GetLastError());
exit_code = 1;
goto cleanup;
}
pi.hProcess = sei.hProcess;
} else {
fprintf(stderr, "Could not create process with command '%ls'.\n", cmd);
exit_code = 1;
goto cleanup;
}
}
// Ignore Ctrl-C and other signals
if (!SetConsoleCtrlHandler(ctrlhandler, TRUE))
fprintf(stderr, "Could not set control handler; Ctrl-C behavior may be invalid.\n");
// Wait till end of process
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &exit_code);
// Dispose of everything
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(jobHandle);
cleanup:
// Free obsolete buffers
free(path);
free(args);
free(cmd);
return (int)exit_code;
}

View File

@@ -1,4 +1,4 @@
resolver: lts-17.11 resolver: lts-18.2
packages: packages:
- . - .
@@ -12,6 +12,7 @@ extra-deps:
- IfElse-0.85@sha256:6939b94acc6a55f545f63a168a349dd2fbe4b9a7cca73bf60282db5cc6aa47d2,445 - IfElse-0.85@sha256:6939b94acc6a55f545f63a168a349dd2fbe4b9a7cca73bf60282db5cc6aa47d2,445
- ascii-string-1.0.1.4@sha256:fa34f1d9ba57e8e89c0d4c9cef5e01ba32cb2d4373d13f92dcc0b531a6c6749b,2582 - ascii-string-1.0.1.4@sha256:fa34f1d9ba57e8e89c0d4c9cef5e01ba32cb2d4373d13f92dcc0b531a6c6749b,2582
- base16-bytestring-0.1.1.7@sha256:0021256a9628971c08da95cb8f4d0d72192f3bb8a7b30b55c080562d17c43dd3,2231
- brotli-0.0.0.0@sha256:2bf383a4cd308745740986be0b18381c5a0784393fe69b91456aacb2d603de46,2964 - brotli-0.0.0.0@sha256:2bf383a4cd308745740986be0b18381c5a0784393fe69b91456aacb2d603de46,2964
- brotli-streams-0.0.0.0@sha256:1af1e22f67b8bfd6ad0d05e61825e7a178d738f689ebbb21c1aab5f1bbcae176,2331 - brotli-streams-0.0.0.0@sha256:1af1e22f67b8bfd6ad0d05e61825e7a178d738f689ebbb21c1aab5f1bbcae176,2331
- chs-cabal-0.1.1.0@sha256:20ec6a9fb5ab6991f1a4adf157c537bd5d3b98d08d3c09c387c954c7c50bd011,1153 - chs-cabal-0.1.1.0@sha256:20ec6a9fb5ab6991f1a4adf157c537bd5d3b98d08d3c09c387c954c7c50bd011,1153
@@ -20,17 +21,21 @@ extra-deps:
- haskus-utils-data-1.3@sha256:f62c4e49021b463185d043f7b69c727b63af641a71d7edd582d9f4f98e80e500,1466 - haskus-utils-data-1.3@sha256:f62c4e49021b463185d043f7b69c727b63af641a71d7edd582d9f4f98e80e500,1466
- haskus-utils-types-1.5.1@sha256:991c472f4e751e2f0d7aab6ad4220ef151d6160876dcf0511bbf876bbd432020,1298 - haskus-utils-types-1.5.1@sha256:991c472f4e751e2f0d7aab6ad4220ef151d6160876dcf0511bbf876bbd432020,1298
- haskus-utils-variant-3.0@sha256:8d51e45d3b664e61ccc25a58b37c0ccc4ee7537138b9fee21cd15c356906dd34,2159 - haskus-utils-variant-3.0@sha256:8d51e45d3b664e61ccc25a58b37c0ccc4ee7537138b9fee21cd15c356906dd34,2159
- http-io-streams-0.1.6.0@sha256:53f5bab177efb52cd65ec396fd04ed59b93e5f919fb3700cd7dacd6cfce6f06d,3582
- 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
- hspec-2.7.10@sha256:c9e82c90086acebac576552a06f3cabd249bba048edd1667c7fae0b1313d5bce,1712 - hspec-2.7.10@sha256:c9e82c90086acebac576552a06f3cabd249bba048edd1667c7fae0b1313d5bce,1712
- hspec-core-2.7.10@sha256:2aba6ea126442b29e8183ab27f1c811706b19b1d83b02f193a896f6fc1589d13,4621 - hspec-core-2.7.10@sha256:2aba6ea126442b29e8183ab27f1c811706b19b1d83b02f193a896f6fc1589d13,4621
- hspec-discover-2.7.10@sha256:d08bf5dd785629f589571477d9beb7cd91529471bd89f39517c1cb4b9b38160f,2184 - hspec-discover-2.7.10@sha256:d08bf5dd785629f589571477d9beb7cd91529471bd89f39517c1cb4b9b38160f,2184
- hspec-golden-aeson-0.9.0.0@sha256:aa17274114026661ba4dfc9c60c230673c8f408bd86482fd611d2d5cb6aff996,2179 - hspec-golden-aeson-0.9.0.0@sha256:aa17274114026661ba4dfc9c60c230673c8f408bd86482fd611d2d5cb6aff996,2179
- http-io-streams-0.1.6.0@sha256:53f5bab177efb52cd65ec396fd04ed59b93e5f919fb3700cd7dacd6cfce6f06d,3582
- libarchive-3.0.2.1@sha256:40ebf2a278e585802427bc58826867208bb33822f63d56107a1fcc3ca04d691d,10990 - libarchive-3.0.2.1@sha256:40ebf2a278e585802427bc58826867208bb33822f63d56107a1fcc3ca04d691d,10990
- lzma-static-5.2.5.3@sha256:2758ee58c35992fcf7db78e98684c357a16a82fa2a4e7c352a6c210c08c555d8,7308 - lzma-static-5.2.5.3@sha256:2758ee58c35992fcf7db78e98684c357a16a82fa2a4e7c352a6c210c08c555d8,7308
- os-release-1.0.1@sha256:1281c62081f438fc3f0874d3bae6a4887d5964ac25261ba06e29d368ab173467,2716 - os-release-1.0.1@sha256:1281c62081f438fc3f0874d3bae6a4887d5964ac25261ba06e29d368ab173467,2716
- primitive-0.7.0.1@sha256:a381571c36edc7dca28b77fe8159b43c14c640087ec5946adacf949feec64231,3433 - optics-0.4@sha256:9fb69bf0195b8d8f1f8cd0098000946868b8a3c3ffb51e5b64f79fc600c3eb4c,6568
- optics-core-0.4@sha256:59e04aebca536bd011ae50c781937f45af4c1456af1eb9fb578f9a69eee293cd,4995
- optics-extra-0.4@sha256:b9914f38aa7d5c92f231060d9168447f9f5a367c07df9bf47a003e3e786d5e05,3432
- optics-th-0.4@sha256:7c838b5b1d6998133bf8f0641c36197ed6cb468dc69515e1952f33f0bbe8e11d,2009
- primitive-0.7.1.0@sha256:29de6bfd0cf8ba023ceb806203dfbec0e51e3524e75ffe41056f70b4229c6f0f,2728
- regex-posix-clib-2.7 - regex-posix-clib-2.7
- streamly-0.7.3@sha256:ad2a488fe802692ed47cab9fd0416c2904aac9e51cf2d8aafd1c3a40064c42f5,27421 - streamly-0.7.3@sha256:ad2a488fe802692ed47cab9fd0416c2904aac9e51cf2d8aafd1c3a40064c42f5,27421
- streamly-bytestring-0.1.2@sha256:cc828f41d1c714c711d38fb213b4ed186febabba598ab080e13255f69c20b13c,2469 - streamly-bytestring-0.1.2@sha256:cc828f41d1c714c711d38fb213b4ed186febabba598ab080e13255f69c20b13c,2469

View File

@@ -45,9 +45,9 @@
<p> <p>
To install Haskell,<br/>run the following in a powershell session (as a non-admin user). To install Haskell,<br/>run the following in a powershell session (as a non-admin user).
<div> <div>
<div class="command-button"><pre><span class='ghcup-command' id="ghcup-command-powershell">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</span></span></pre><button class="tooltip" onclick="copyToClipboardPowershell()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button> <div class="command-button"><pre><span class='ghcup-command' id="ghcup-command-powershell">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 $true</span></span></pre><button class="tooltip" onclick="copyToClipboardPowershell()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button>
</div> </div>
<p class="other-help">If you want to run an interactive installation, change <span class='code'>$false</span> to <span class='code'>$true</span> at the end of the script.</p> <p class="other-help">If you want to run a non-interactive installation, change <span class='code'>$true</span> to <span class='code'>$false</span> at the end of the script.</p>
</div> </div>
<p>If you're a Windows Subsystem 2 for Linux user run the following in your terminal, then follow the onscreen instructions to install Haskell. <p>If you're a Windows Subsystem 2 for Linux user run the following in your terminal, then follow the onscreen instructions to install Haskell.
</p> </p>
@@ -65,9 +65,9 @@
<p> <p>
To install Haskell,<br/>run the following in a powershell session (as a non-admin user). To install Haskell,<br/>run the following in a powershell session (as a non-admin user).
<div> <div>
<div class="command-button"><pre><span class='ghcup-command'>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</span></span></pre><button class="tooltip" onclick="copyToClipboardPowershell()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button> <div class="command-button"><pre><span class='ghcup-command'>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 $true</span></span></pre><button class="tooltip" onclick="copyToClipboardPowershell()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button>
</div> </div>
<p class="other-help">If you want to run an interactive installation, change <span class='code'>$false</span> to <span class='code'>$true</span> at the end of the script.</p> <p class="other-help">If you want to run an non-interactive installation, change <span class='code'>$true</span> to <span class='code'>$false</span> at the end of the script.</p>
</div> </div>
</p> </p>
<p>If you're a Windows Subsystem 2 for Linux user run the following in your terminal, then follow the onscreen instructions to install Haskell. <p>If you're a Windows Subsystem 2 for Linux user run the following in your terminal, then follow the onscreen instructions to install Haskell.