Compare commits
1 Commits
stack-2.7.
...
windows-su
| Author | SHA1 | Date | |
|---|---|---|---|
|
2c3ebe706d
|
109
.github/release.yaml
vendored
109
.github/release.yaml
vendored
@@ -1,109 +0,0 @@
|
|||||||
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
109
.github/workflows/release.yaml
vendored
@@ -1,109 +0,0 @@
|
|||||||
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
29
.github/workflows/shimgen.yaml
vendored
@@ -1,29 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
231
.gitlab-ci.yml
231
.gitlab-ci.yml
@@ -7,7 +7,7 @@ variables:
|
|||||||
GIT_SSL_NO_VERIFY: "1"
|
GIT_SSL_NO_VERIFY: "1"
|
||||||
|
|
||||||
# Commit of ghc/ci-images repository from which to pull Docker images
|
# Commit of ghc/ci-images repository from which to pull Docker images
|
||||||
DOCKER_REV: 8d0224e6b2a08157649651e69302380b2bd24e11
|
DOCKER_REV: 1ac7f435c9312f10422a82d304194778378e2a1a
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# CI Step
|
# CI Step
|
||||||
@@ -20,8 +20,6 @@ variables:
|
|||||||
variables:
|
variables:
|
||||||
OS: "LINUX"
|
OS: "LINUX"
|
||||||
ARCH: "64"
|
ARCH: "64"
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
CROSS: ""
|
|
||||||
|
|
||||||
.alpine:64bit:
|
.alpine:64bit:
|
||||||
image: "alpine:3.12"
|
image: "alpine:3.12"
|
||||||
@@ -30,7 +28,6 @@ variables:
|
|||||||
variables:
|
variables:
|
||||||
OS: "LINUX"
|
OS: "LINUX"
|
||||||
ARCH: "64"
|
ARCH: "64"
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
|
|
||||||
.alpine:32bit:
|
.alpine:32bit:
|
||||||
image: "i386/alpine:3.12"
|
image: "i386/alpine:3.12"
|
||||||
@@ -39,25 +36,22 @@ variables:
|
|||||||
variables:
|
variables:
|
||||||
OS: "LINUX"
|
OS: "LINUX"
|
||||||
ARCH: "32"
|
ARCH: "32"
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
|
|
||||||
.linux:armv7:
|
.linux:armv7:
|
||||||
image: "registry.gitlab.haskell.org/ghc/ci-images/armv7-linux-deb10:$DOCKER_REV"
|
image: "arm32v7/fedora"
|
||||||
tags:
|
tags:
|
||||||
- armv7-linux
|
- armv7-linux
|
||||||
variables:
|
variables:
|
||||||
OS: "LINUX"
|
OS: "LINUX"
|
||||||
ARCH: "ARM"
|
ARCH: "ARM"
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
|
|
||||||
.linux:aarch64:
|
.linux:aarch64:
|
||||||
image: "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb10:$DOCKER_REV"
|
image: "arm64v8/fedora"
|
||||||
tags:
|
tags:
|
||||||
- aarch64-linux
|
- aarch64-linux
|
||||||
variables:
|
variables:
|
||||||
OS: "LINUX"
|
OS: "LINUX"
|
||||||
ARCH: "ARM64"
|
ARCH: "ARM64"
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
|
|
||||||
.darwin:
|
.darwin:
|
||||||
tags:
|
tags:
|
||||||
@@ -65,15 +59,6 @@ variables:
|
|||||||
variables:
|
variables:
|
||||||
OS: "DARWIN"
|
OS: "DARWIN"
|
||||||
ARCH: "64"
|
ARCH: "64"
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
|
|
||||||
.darwin:aarch64:
|
|
||||||
tags:
|
|
||||||
- aarch64-darwin-m1
|
|
||||||
variables:
|
|
||||||
OS: "DARWIN"
|
|
||||||
ARCH: "ARM64"
|
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
|
|
||||||
.freebsd:
|
.freebsd:
|
||||||
tags:
|
tags:
|
||||||
@@ -81,35 +66,28 @@ variables:
|
|||||||
variables:
|
variables:
|
||||||
OS: "FREEBSD"
|
OS: "FREEBSD"
|
||||||
ARCH: "64"
|
ARCH: "64"
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
|
|
||||||
.windows:
|
|
||||||
tags:
|
|
||||||
- new-x86_64-windows
|
|
||||||
variables:
|
|
||||||
OS: "WINDOWS"
|
|
||||||
ARCH: "64"
|
|
||||||
CABAL_DIR: "$CI_PROJECT_DIR/cabal"
|
|
||||||
|
|
||||||
.root_cleanup:
|
.root_cleanup:
|
||||||
after_script:
|
after_script:
|
||||||
- bash ./.gitlab/after_script.sh
|
- BUILD_DIR=$CI_PROJECT_DIR
|
||||||
|
- echo "Cleaning $BUILD_DIR"
|
||||||
|
- cd $HOME
|
||||||
|
- test -n "$BUILD_DIR"
|
||||||
|
- shopt -s extglob
|
||||||
|
- rm -Rf "$BUILD_DIR"/!(out)
|
||||||
|
- exit 0
|
||||||
|
|
||||||
.test_ghcup_version:
|
.test_ghcup_version:
|
||||||
script:
|
script:
|
||||||
- bash ./.gitlab/script/ghcup_version.sh
|
- ./.gitlab/script/ghcup_version.sh
|
||||||
variables:
|
variables:
|
||||||
JSON_VERSION: "0.0.5"
|
JSON_VERSION: "0.0.4"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 2 week
|
expire_in: 2 week
|
||||||
paths:
|
paths:
|
||||||
- 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
|
||||||
@@ -129,14 +107,14 @@ variables:
|
|||||||
- .test_ghcup_version
|
- .test_ghcup_version
|
||||||
- .linux:armv7
|
- .linux:armv7
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/linux/install_deps.sh
|
- ./.gitlab/before_script/linux/install_deps_manual.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.sh
|
- ./.gitlab/before_script/linux/install_deps_manual.sh
|
||||||
|
|
||||||
.test_ghcup_version:darwin:
|
.test_ghcup_version:darwin:
|
||||||
extends:
|
extends:
|
||||||
@@ -146,32 +124,6 @@ variables:
|
|||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/darwin/install_deps.sh
|
- ./.gitlab/before_script/darwin/install_deps.sh
|
||||||
|
|
||||||
.test_ghcup_version:darwin:aarch64:
|
|
||||||
extends:
|
|
||||||
- .test_ghcup_version
|
|
||||||
- .darwin:aarch64
|
|
||||||
- .root_cleanup
|
|
||||||
script: |
|
|
||||||
set -Eeuo pipefail
|
|
||||||
function runInNixShell() {
|
|
||||||
time nix-shell $CI_PROJECT_DIR/.gitlab/shell.nix \
|
|
||||||
-I nixpkgs=https://github.com/angerman/nixpkgs/archive/75f7281738b.tar.gz \
|
|
||||||
--argstr system "aarch64-darwin" \
|
|
||||||
--pure \
|
|
||||||
--keep CI_PROJECT_DIR \
|
|
||||||
--keep MACOSX_DEPLOYMENT_TARGET \
|
|
||||||
--keep JSON_VERSION \
|
|
||||||
--keep ARTIFACT \
|
|
||||||
--keep OS \
|
|
||||||
--keep ARCH \
|
|
||||||
--keep CABAL_DIR \
|
|
||||||
--keep GHC_VERSION \
|
|
||||||
--keep CABAL_VERSION \
|
|
||||||
--run "$1" 2>&1
|
|
||||||
}
|
|
||||||
runInNixShell ./.gitlab/before_script/darwin/install_deps.sh 2>&1
|
|
||||||
runInNixShell ./.gitlab/script/ghcup_version.sh 2>&1
|
|
||||||
|
|
||||||
.test_ghcup_version:freebsd:
|
.test_ghcup_version:freebsd:
|
||||||
extends:
|
extends:
|
||||||
- .test_ghcup_version
|
- .test_ghcup_version
|
||||||
@@ -180,24 +132,9 @@ variables:
|
|||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/freebsd/install_deps.sh
|
- ./.gitlab/before_script/freebsd/install_deps.sh
|
||||||
|
|
||||||
.test_ghcup_version:windows:
|
|
||||||
extends:
|
|
||||||
- .test_ghcup_version
|
|
||||||
- .windows
|
|
||||||
- .root_cleanup
|
|
||||||
before_script:
|
|
||||||
- set CABAL_DIR="$CI_PROJECT_DIR/cabal"
|
|
||||||
- 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
|
- ./.gitlab/script/ghcup_release.sh
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 2 week
|
expire_in: 2 week
|
||||||
paths:
|
paths:
|
||||||
@@ -205,7 +142,7 @@ variables:
|
|||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
variables:
|
variables:
|
||||||
JSON_VERSION: "0.0.5"
|
JSON_VERSION: "0.0.4"
|
||||||
|
|
||||||
######## stack test ########
|
######## stack test ########
|
||||||
|
|
||||||
@@ -228,27 +165,10 @@ test:linux:bootstrap_script:
|
|||||||
script:
|
script:
|
||||||
- ./.gitlab/script/ghcup_bootstrap.sh
|
- ./.gitlab/script/ghcup_bootstrap.sh
|
||||||
variables:
|
variables:
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
extends:
|
extends:
|
||||||
- .debian
|
- .debian
|
||||||
- .root_cleanup
|
|
||||||
needs: []
|
|
||||||
|
|
||||||
test:windows:bootstrap_powershell_script:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- ./bootstrap-haskell.ps1 -InstallDir $CI_PROJECT_DIR -BootstrapUrl $CI_PROJECT_DIR/bootstrap-haskell -InBash
|
|
||||||
after_script:
|
|
||||||
- "[Environment]::SetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', $null, [System.EnvironmentVariableTarget]::User)"
|
|
||||||
- "[Environment]::SetEnvironmentVariable('GHCUP_MSYS2', $null, [System.EnvironmentVariableTarget]::User)"
|
|
||||||
- "[Environment]::SetEnvironmentVariable('CABAL_DIR', $null, [System.EnvironmentVariableTarget]::User)"
|
|
||||||
- bash ./.gitlab/after_script.sh
|
|
||||||
variables:
|
|
||||||
GHC_VERSION: "8.10.5"
|
|
||||||
CABAL_VERSION: "3.4.0.0"
|
|
||||||
extends:
|
|
||||||
- .windows
|
|
||||||
needs: []
|
needs: []
|
||||||
|
|
||||||
######## linux test ########
|
######## linux test ########
|
||||||
@@ -257,35 +177,17 @@ test:linux:recommended:
|
|||||||
stage: test
|
stage: test
|
||||||
extends: .test_ghcup_version:linux
|
extends: .test_ghcup_version:linux
|
||||||
variables:
|
variables:
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
needs: []
|
needs: []
|
||||||
|
|
||||||
test:linux:latest:
|
test:linux:latest:
|
||||||
stage: test
|
stage: test
|
||||||
extends: .test_ghcup_version:linux
|
extends: .test_ghcup_version:linux
|
||||||
variables:
|
|
||||||
GHC_VERSION: "9.0.1"
|
|
||||||
CABAL_VERSION: "3.4.0.0"
|
|
||||||
needs: []
|
|
||||||
|
|
||||||
test:linux:cross-armv7:
|
|
||||||
stage: test
|
|
||||||
extends:
|
|
||||||
- .test_ghcup_version
|
|
||||||
- .debian
|
|
||||||
variables:
|
variables:
|
||||||
GHC_VERSION: "8.10.4"
|
GHC_VERSION: "8.10.4"
|
||||||
GHC_TARGET_VERSION: "8.10.5"
|
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
CROSS: "arm-linux-gnueabihf"
|
|
||||||
needs: []
|
needs: []
|
||||||
when: manual
|
|
||||||
before_script:
|
|
||||||
- ./.gitlab/before_script/linux/install_deps.sh
|
|
||||||
script:
|
|
||||||
- ./.gitlab/script/ghcup_cross.sh
|
|
||||||
|
|
||||||
|
|
||||||
######## linux 32bit test ########
|
######## linux 32bit test ########
|
||||||
|
|
||||||
@@ -293,7 +195,7 @@ test:linux:recommended:32bit:
|
|||||||
stage: test
|
stage: test
|
||||||
extends: .test_ghcup_version:linux32
|
extends: .test_ghcup_version:linux32
|
||||||
variables:
|
variables:
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.2.0.0"
|
CABAL_VERSION: "3.2.0.0"
|
||||||
needs: []
|
needs: []
|
||||||
|
|
||||||
@@ -305,7 +207,6 @@ 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: []
|
||||||
|
|
||||||
@@ -315,7 +216,6 @@ 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: []
|
||||||
|
|
||||||
@@ -333,19 +233,10 @@ test:mac:latest:
|
|||||||
stage: test
|
stage: test
|
||||||
extends: .test_ghcup_version:darwin
|
extends: .test_ghcup_version:darwin
|
||||||
variables:
|
variables:
|
||||||
GHC_VERSION: "9.0.1"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
needs: []
|
needs: []
|
||||||
|
|
||||||
test:mac:recommended:aarch64:
|
|
||||||
stage: test
|
|
||||||
extends: .test_ghcup_version:darwin:aarch64
|
|
||||||
variables:
|
|
||||||
GHC_VERSION: "8.10.5"
|
|
||||||
CABAL_VERSION: "3.4.0.0"
|
|
||||||
needs: []
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
|
|
||||||
######## freebsd test ########
|
######## freebsd test ########
|
||||||
|
|
||||||
@@ -359,20 +250,16 @@ test:freebsd:recommended:
|
|||||||
when: manual
|
when: manual
|
||||||
needs: []
|
needs: []
|
||||||
|
|
||||||
######## windows test ########
|
test:freebsd:latest:
|
||||||
|
|
||||||
test:windows:recommended:
|
|
||||||
stage: test
|
stage: test
|
||||||
extends: .test_ghcup_version:windows
|
extends: .test_ghcup_version:freebsd
|
||||||
variables:
|
variables:
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
|
allow_failure: true # freebsd runners are unreliable
|
||||||
|
when: manual
|
||||||
needs: []
|
needs: []
|
||||||
|
|
||||||
# test:windows:scoop:
|
|
||||||
# stage: test
|
|
||||||
# extends: .test_ghcup_scoop:windows
|
|
||||||
# needs: []
|
|
||||||
|
|
||||||
######## linux release ########
|
######## linux release ########
|
||||||
|
|
||||||
@@ -386,7 +273,7 @@ release:linux:64bit:
|
|||||||
- ./.gitlab/before_script/linux/alpine/install_deps.sh
|
- ./.gitlab/before_script/linux/alpine/install_deps.sh
|
||||||
variables:
|
variables:
|
||||||
ARTIFACT: "x86_64-linux-ghcup"
|
ARTIFACT: "x86_64-linux-ghcup"
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
|
|
||||||
|
|
||||||
@@ -400,7 +287,7 @@ release:linux:32bit:
|
|||||||
- ./.gitlab/before_script/linux/alpine/install_deps.sh
|
- ./.gitlab/before_script/linux/alpine/install_deps.sh
|
||||||
variables:
|
variables:
|
||||||
ARTIFACT: "i386-linux-ghcup"
|
ARTIFACT: "i386-linux-ghcup"
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.2.0.0"
|
CABAL_VERSION: "3.2.0.0"
|
||||||
|
|
||||||
release:linux:armv7:
|
release:linux:armv7:
|
||||||
@@ -410,12 +297,11 @@ release:linux:armv7:
|
|||||||
- .linux:armv7
|
- .linux:armv7
|
||||||
- .release_ghcup
|
- .release_ghcup
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/linux/install_deps.sh
|
- ./.gitlab/before_script/linux/install_deps_manual.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
|
||||||
@@ -424,12 +310,11 @@ release:linux:aarch64:
|
|||||||
- .linux:aarch64
|
- .linux:aarch64
|
||||||
- .release_ghcup
|
- .release_ghcup
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/linux/install_deps.sh
|
- ./.gitlab/before_script/linux/install_deps_manual.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 ########
|
||||||
|
|
||||||
@@ -444,50 +329,16 @@ release:darwin:
|
|||||||
- ./.gitlab/before_script/darwin/install_deps.sh
|
- ./.gitlab/before_script/darwin/install_deps.sh
|
||||||
variables:
|
variables:
|
||||||
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
MACOSX_DEPLOYMENT_TARGET: "10.7"
|
MACOSX_DEPLOYMENT_TARGET: "10.7"
|
||||||
|
|
||||||
release:darwin:aarch64:
|
|
||||||
stage: release
|
|
||||||
needs: ["test:mac:recommended:aarch64"]
|
|
||||||
extends:
|
|
||||||
- .darwin:aarch64
|
|
||||||
- .release_ghcup
|
|
||||||
- .root_cleanup
|
|
||||||
script: |
|
|
||||||
set -Eeuo pipefail
|
|
||||||
function runInNixShell() {
|
|
||||||
time nix-shell $CI_PROJECT_DIR/.gitlab/shell.nix \
|
|
||||||
-I nixpkgs=https://github.com/angerman/nixpkgs/archive/75f7281738b.tar.gz \
|
|
||||||
--argstr system "aarch64-darwin" \
|
|
||||||
--pure \
|
|
||||||
--keep CI_PROJECT_DIR \
|
|
||||||
--keep MACOSX_DEPLOYMENT_TARGET \
|
|
||||||
--keep JSON_VERSION \
|
|
||||||
--keep ARTIFACT \
|
|
||||||
--keep OS \
|
|
||||||
--keep ARCH \
|
|
||||||
--keep CABAL_DIR \
|
|
||||||
--keep GHC_VERSION \
|
|
||||||
--keep CABAL_VERSION \
|
|
||||||
--run "$1" 2>&1
|
|
||||||
}
|
|
||||||
runInNixShell ./.gitlab/before_script/darwin/install_deps.sh 2>&1
|
|
||||||
runInNixShell ./.gitlab/script/ghcup_release.sh 2>&1
|
|
||||||
variables:
|
|
||||||
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
|
||||||
GHC_VERSION: "8.10.5"
|
|
||||||
CABAL_VERSION: "3.4.0.0"
|
|
||||||
MACOSX_DEPLOYMENT_TARGET: "10.7"
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
|
|
||||||
######## freebsd release ########
|
######## freebsd release ########
|
||||||
|
|
||||||
release:freebsd:
|
release:freebsd:
|
||||||
stage: release
|
stage: release
|
||||||
needs: ["test:freebsd:recommended"]
|
needs: ["test:freebsd:recommended", "test:freebsd:latest"]
|
||||||
extends:
|
extends:
|
||||||
- .freebsd
|
- .freebsd
|
||||||
- .release_ghcup
|
- .release_ghcup
|
||||||
@@ -496,25 +347,9 @@ release:freebsd:
|
|||||||
- ./.gitlab/before_script/freebsd/install_deps.sh
|
- ./.gitlab/before_script/freebsd/install_deps.sh
|
||||||
variables:
|
variables:
|
||||||
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
######## windows release ########
|
|
||||||
|
|
||||||
release:windows:
|
|
||||||
stage: release
|
|
||||||
needs: ["test:windows:recommended"]
|
|
||||||
extends:
|
|
||||||
- .windows
|
|
||||||
- .release_ghcup
|
|
||||||
- .root_cleanup
|
|
||||||
before_script:
|
|
||||||
- bash ./.gitlab/before_script/windows/install_deps.sh
|
|
||||||
variables:
|
|
||||||
ARTIFACT: "x86_64-mingw64-ghcup"
|
|
||||||
GHC_VERSION: "8.10.5"
|
|
||||||
CABAL_VERSION: "3.4.0.0"
|
|
||||||
|
|
||||||
######## hlint ########
|
######## hlint ########
|
||||||
|
|
||||||
@@ -527,7 +362,7 @@ hlint:
|
|||||||
script:
|
script:
|
||||||
- ./.gitlab/script/hlint.sh
|
- ./.gitlab/script/hlint.sh
|
||||||
variables:
|
variables:
|
||||||
GHC_VERSION: "8.10.5"
|
GHC_VERSION: "8.10.4"
|
||||||
CABAL_VERSION: "3.4.0.0"
|
CABAL_VERSION: "3.4.0.0"
|
||||||
JSON_VERSION: "0.0.4"
|
JSON_VERSION: "0.0.4"
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -eux
|
|
||||||
|
|
||||||
BUILD_DIR=$CI_PROJECT_DIR
|
|
||||||
echo "Cleaning $BUILD_DIR"
|
|
||||||
cd $HOME
|
|
||||||
test -n "$BUILD_DIR"
|
|
||||||
shopt -s extglob
|
|
||||||
rm -Rf "$BUILD_DIR"/!(out)
|
|
||||||
if [ "${OS}" = "WINDOWS" ] ; then
|
|
||||||
rm -Rf /c/ghcup
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -6,27 +6,12 @@ set -eux
|
|||||||
|
|
||||||
mkdir -p "${TMPDIR}"
|
mkdir -p "${TMPDIR}"
|
||||||
|
|
||||||
if [ $ARCH = 'ARM64' ] ; then
|
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-apple-darwin-ghcup > ./ghcup-bin
|
||||||
curl -sSfL https://downloads.haskell.org/~ghcup/0.1.15.1/aarch64-apple-darwin-ghcup-0.1.15.1 > ./ghcup-bin
|
chmod +x ghcup-bin
|
||||||
chmod +x ghcup-bin
|
|
||||||
else
|
|
||||||
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-apple-darwin-ghcup > ./ghcup-bin
|
|
||||||
chmod +x ghcup-bin
|
|
||||||
./ghcup-bin upgrade -i -f
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
./ghcup-bin upgrade -i -f
|
||||||
./ghcup-bin install ${GHC_VERSION}
|
./ghcup-bin install ${GHC_VERSION}
|
||||||
./ghcup-bin set ${GHC_VERSION}
|
./ghcup-bin set ${GHC_VERSION}
|
||||||
./ghcup-bin install-cabal ${CABAL_VERSION}
|
./ghcup-bin install-cabal ${CABAL_VERSION}
|
||||||
|
|
||||||
if [ $ARCH = 'ARM64' ] ; then
|
|
||||||
cabal update
|
|
||||||
mkdir vendored
|
|
||||||
cd vendored
|
|
||||||
cabal unpack network-3.1.2.1
|
|
||||||
cd network*
|
|
||||||
autoreconf -fi
|
|
||||||
cd ../..
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -7,67 +7,13 @@ 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 lsb-release software-properties-common gnupg2 apt-transport-https
|
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget
|
||||||
|
|
||||||
if [ "${CROSS}" = "arm-linux-gnueabihf" ] ; then
|
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-linux-ghcup > ./ghcup-bin
|
||||||
sudo apt-get install -y autoconf build-essential gcc-arm-linux-gnueabihf
|
chmod +x ghcup-bin
|
||||||
sudo dpkg --add-architecture armhf
|
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get install -y libncurses-dev:armhf
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "${ARCH}" in
|
./ghcup-bin upgrade -i -f
|
||||||
ARM*)
|
./ghcup-bin install ${GHC_VERSION}
|
||||||
case "${ARCH}" in
|
./ghcup-bin set ${GHC_VERSION}
|
||||||
"ARM")
|
./ghcup-bin install-cabal ${CABAL_VERSION}
|
||||||
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
|
|
||||||
|
|
||||||
|
|||||||
64
.gitlab/before_script/linux/install_deps_manual.sh
Executable file
64
.gitlab/before_script/linux/install_deps_manual.sh
Executable file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/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
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -eux
|
|
||||||
|
|
||||||
. "$( cd "$(dirname "$0")" ; pwd -P )/../../ghcup_env"
|
|
||||||
|
|
||||||
mkdir -p "${TMPDIR}" "${CABAL_DIR}"
|
|
||||||
|
|
||||||
mkdir -p "$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin"
|
|
||||||
|
|
||||||
CI_PROJECT_DIR=$(pwd)
|
|
||||||
curl -o ghcup.exe https://downloads.haskell.org/~ghcup/0.1.15.1/x86_64-mingw64-ghcup-0.1.15.1.exe
|
|
||||||
chmod +x ghcup.exe
|
|
||||||
|
|
||||||
./ghcup.exe install ${GHC_VERSION}
|
|
||||||
./ghcup.exe set ${GHC_VERSION}
|
|
||||||
./ghcup.exe install-cabal ${CABAL_VERSION}
|
|
||||||
|
|
||||||
rm ./ghcup.exe
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,9 +1,3 @@
|
|||||||
if [ "${OS}" = "WINDOWS" ] ; then
|
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="$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin:$CI_PROJECT_DIR/.local/bin:$PATH"
|
export TMPDIR="$CI_PROJECT_DIR/tmp"
|
||||||
export TMPDIR="$CI_PROJECT_DIR/tmp"
|
|
||||||
else
|
|
||||||
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
|
||||||
export PATH="$CI_PROJECT_DIR/.ghcup/bin:$CI_PROJECT_DIR/.local/bin:/opt/llvm/bin:$PATH"
|
|
||||||
export TMPDIR="$CI_PROJECT_DIR/tmp"
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ set -eux
|
|||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
|
|
||||||
ecabal() {
|
ecabal() {
|
||||||
cabal "$@"
|
cabal --store-dir="$(pwd)"/.store "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
eghcup() {
|
eghcup() {
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
#!/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" ]
|
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ set -eux
|
|||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
|
|
||||||
ecabal() {
|
ecabal() {
|
||||||
cabal "$@"
|
cabal --store-dir="$(pwd)"/.store "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
git describe
|
git describe
|
||||||
@@ -15,6 +15,10 @@ 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
|
||||||
@@ -25,20 +29,18 @@ if [ "${OS}" = "LINUX" ] ; then
|
|||||||
ecabal build -w ghc-${GHC_VERSION} -ftui
|
ecabal build -w ghc-${GHC_VERSION} -ftui
|
||||||
fi
|
fi
|
||||||
elif [ "${OS}" = "FREEBSD" ] ; then
|
elif [ "${OS}" = "FREEBSD" ] ; then
|
||||||
ecabal build -w ghc-${GHC_VERSION} --ghc-options='-split-sections' --constraint="zlib +bundled-c-zlib" --constraint="zip +disable-zstd" -ftui
|
ecabal build -w ghc-${GHC_VERSION} --ghc-options='-split-sections' --constraint="zlib +bundled-c-zlib" -ftui
|
||||||
elif [ "${OS}" = "WINDOWS" ] ; then
|
|
||||||
ecabal build -w ghc-${GHC_VERSION} --constraint="zlib +bundled-c-zlib" --constraint="lzma +static"
|
|
||||||
else
|
else
|
||||||
ecabal build -w ghc-${GHC_VERSION} --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" -ftui
|
ecabal build -w ghc-${GHC_VERSION} --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" -ftui
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir out
|
mkdir out
|
||||||
binary=$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')
|
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" .
|
||||||
ver=$("${binary}" --numeric-version)
|
ver=$(./ghcup --numeric-version)
|
||||||
if [ "${OS}" = "DARWIN" ] ; then
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
strip "${binary}"
|
strip ./ghcup
|
||||||
else
|
else
|
||||||
strip -s "${binary}"
|
strip -s ./ghcup
|
||||||
fi
|
fi
|
||||||
cp "${binary}" out/${ARTIFACT}-${ver}
|
cp ghcup out/${ARTIFACT}-${ver}
|
||||||
|
|
||||||
|
|||||||
@@ -6,18 +6,12 @@ set -eux
|
|||||||
|
|
||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
|
|
||||||
CI_PROJECT_DIR=$(pwd)
|
|
||||||
|
|
||||||
ecabal() {
|
ecabal() {
|
||||||
cabal "$@"
|
cabal --store-dir="$CI_PROJECT_DIR"/.store "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
eghcup() {
|
eghcup() {
|
||||||
if [ "${OS}" = "WINDOWS" ] ; then
|
ghcup -v -c -s file://$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml "$@"
|
||||||
ghcup -v -c -s file:/$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml "$@"
|
|
||||||
else
|
|
||||||
ghcup -v -c -s file://$CI_PROJECT_DIR/ghcup-${JSON_VERSION}.yaml "$@"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
git describe --always
|
git describe --always
|
||||||
@@ -26,50 +20,39 @@ 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
|
||||||
ecabal haddock -w ghc-${GHC_VERSION} -ftui
|
|
||||||
elif [ "${OS}" = "LINUX" ] ; then
|
elif [ "${OS}" = "LINUX" ] ; then
|
||||||
if [ "${ARCH}" = "32" ] ; then
|
if [ "${ARCH}" = "32" ] ; then
|
||||||
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader -ftui -ftar
|
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader -ftui -ftar
|
||||||
ecabal test -w ghc-${GHC_VERSION} -finternal-downloader -ftui -ftar ghcup-test
|
ecabal test -w ghc-${GHC_VERSION} -finternal-downloader -ftui -ftar ghcup-test
|
||||||
ecabal haddock -w ghc-${GHC_VERSION} -finternal-downloader -ftui -ftar
|
|
||||||
else
|
else
|
||||||
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader -ftui
|
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader -ftui
|
||||||
ecabal test -w ghc-${GHC_VERSION} -finternal-downloader -ftui ghcup-test
|
ecabal test -w ghc-${GHC_VERSION} -finternal-downloader -ftui ghcup-test
|
||||||
ecabal haddock -w ghc-${GHC_VERSION} -finternal-downloader -ftui
|
|
||||||
fi
|
fi
|
||||||
elif [ "${OS}" = "FREEBSD" ] ; then
|
|
||||||
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader -ftui --constraint="zip +disable-zstd"
|
|
||||||
ecabal test -w ghc-${GHC_VERSION} -finternal-downloader -ftui --constraint="zip +disable-zstd" ghcup-test
|
|
||||||
ecabal haddock -w ghc-${GHC_VERSION} -finternal-downloader -ftui --constraint="zip +disable-zstd"
|
|
||||||
elif [ "${OS}" = "WINDOWS" ] ; then
|
|
||||||
ecabal build -w ghc-${GHC_VERSION}
|
|
||||||
ecabal test -w ghc-${GHC_VERSION} ghcup-test
|
|
||||||
ecabal haddock -w ghc-${GHC_VERSION}
|
|
||||||
else
|
else
|
||||||
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader -ftui
|
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader -ftui
|
||||||
ecabal test -w ghc-${GHC_VERSION} -finternal-downloader -ftui ghcup-test
|
ecabal test -w ghc-${GHC_VERSION} -finternal-downloader -ftui ghcup-test
|
||||||
ecabal haddock -w ghc-${GHC_VERSION} -finternal-downloader -ftui
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ecabal haddock -w ghc-${GHC_VERSION} -ftar
|
||||||
|
|
||||||
if [ "${OS}" = "WINDOWS" ] ; then
|
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" .
|
||||||
ext=".exe"
|
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup-gen')" .
|
||||||
else
|
|
||||||
ext=''
|
cp ./ghcup "$CI_PROJECT_DIR"/.local/bin/ghcup
|
||||||
fi
|
cp ./ghcup-gen "$CI_PROJECT_DIR"/.local/bin/ghcup-gen
|
||||||
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" "$CI_PROJECT_DIR"/.local/bin/ghcup${ext}
|
|
||||||
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup-gen')" "$CI_PROJECT_DIR"/.local/bin/ghcup-gen${ext}
|
|
||||||
|
|
||||||
### cleanup
|
### cleanup
|
||||||
|
|
||||||
if [ "${OS}" = "WINDOWS" ] ; then
|
rm -rf "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup
|
||||||
rm -rf "${GHCUP_INSTALL_BASE_PREFIX}"/ghcup
|
|
||||||
else
|
|
||||||
rm -rf "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup
|
|
||||||
fi
|
|
||||||
|
|
||||||
### manual cli based testing
|
### manual cli based testing
|
||||||
|
|
||||||
@@ -78,11 +61,9 @@ ghcup-gen check -f ghcup-${JSON_VERSION}.yaml
|
|||||||
|
|
||||||
eghcup --numeric-version
|
eghcup --numeric-version
|
||||||
|
|
||||||
eghcup install ghc ${GHC_VERSION}
|
eghcup install ${GHC_VERSION}
|
||||||
[ `$(eghcup whereis ghc ${GHC_VERSION}) --numeric-version` = "${GHC_VERSION}" ]
|
eghcup set ${GHC_VERSION}
|
||||||
eghcup set ghc ${GHC_VERSION}
|
eghcup install-cabal ${CABAL_VERSION}
|
||||||
eghcup install cabal ${CABAL_VERSION}
|
|
||||||
[ `$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version` = "${CABAL_VERSION}" ]
|
|
||||||
|
|
||||||
cabal --version
|
cabal --version
|
||||||
|
|
||||||
@@ -94,56 +75,43 @@ eghcup list -t cabal
|
|||||||
|
|
||||||
ghc_ver=$(ghc --numeric-version)
|
ghc_ver=$(ghc --numeric-version)
|
||||||
ghc --version
|
ghc --version
|
||||||
ghc-${ghc_ver} --version
|
ghci --version
|
||||||
if [ "${OS}" != "WINDOWS" ] ; then
|
ghc-$(ghc --numeric-version) --version
|
||||||
ghci --version
|
ghci-$(ghc --numeric-version) --version
|
||||||
ghci-${ghc_ver} --version
|
|
||||||
|
|
||||||
|
# test installing new ghc doesn't mess with currently set GHC
|
||||||
|
# https://gitlab.haskell.org/haskell/ghcup-hs/issues/7
|
||||||
|
if [ "${OS}" = "LINUX" ] ; then
|
||||||
|
eghcup --downloader=wget install 8.10.3
|
||||||
|
else # test wget a bit
|
||||||
|
eghcup install 8.10.3
|
||||||
fi
|
fi
|
||||||
|
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||||
|
eghcup set 8.10.3
|
||||||
|
eghcup set 8.10.3
|
||||||
|
[ "$(ghc --numeric-version)" = "8.10.3" ]
|
||||||
|
eghcup set ${GHC_VERSION}
|
||||||
|
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||||
|
eghcup rm 8.10.3
|
||||||
|
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||||
|
|
||||||
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
|
eghcup install hls
|
||||||
|
haskell-language-server-wrapper --version
|
||||||
|
|
||||||
if [ "${OS}" = "DARWIN" ] && [ "${ARCH}" = "ARM64" ] ; then
|
eghcup install stack
|
||||||
echo
|
stack --version
|
||||||
else
|
elif [ "${OS}" = "LINUX" ] ; then
|
||||||
# test installing new ghc doesn't mess with currently set GHC
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
# https://gitlab.haskell.org/haskell/ghcup-hs/issues/7
|
|
||||||
if [ "${OS}" = "LINUX" ] ; then
|
|
||||||
eghcup --downloader=wget prefetch ghc 8.10.3
|
|
||||||
eghcup --offline install ghc 8.10.3
|
|
||||||
else # test wget a bit
|
|
||||||
eghcup prefetch ghc 8.10.3
|
|
||||||
eghcup --offline install ghc 8.10.3
|
|
||||||
fi
|
|
||||||
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
|
||||||
eghcup --offline set 8.10.3
|
|
||||||
eghcup set 8.10.3
|
|
||||||
[ "$(ghc --numeric-version)" = "8.10.3" ]
|
|
||||||
eghcup set ${GHC_VERSION}
|
|
||||||
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
|
||||||
eghcup --offline rm 8.10.3
|
|
||||||
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
|
||||||
|
|
||||||
if [ "${OS}" = "DARWIN" ] ; then
|
|
||||||
eghcup install hls
|
eghcup install hls
|
||||||
$(eghcup whereis hls) --version
|
haskell-language-server-wrapper --version
|
||||||
|
|
||||||
eghcup install stack
|
eghcup install stack
|
||||||
$(eghcup whereis stack) --version
|
stack --version
|
||||||
elif [ "${OS}" = "LINUX" ] ; then
|
|
||||||
if [ "${ARCH}" = "64" ] ; then
|
|
||||||
eghcup install hls
|
|
||||||
haskell-language-server-wrapper --version
|
|
||||||
|
|
||||||
eghcup install stack
|
|
||||||
stack --version
|
|
||||||
fi
|
|
||||||
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)
|
||||||
|
|
||||||
@@ -155,15 +123,6 @@ if [ "${OS}" = "LINUX" ] ; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
eghcup upgrade
|
eghcup upgrade
|
||||||
eghcup upgrade -f
|
eghcup upgrade -f
|
||||||
|
|
||||||
|
|
||||||
# nuke
|
|
||||||
eghcup nuke
|
|
||||||
if [ "${OS}" = "WINDOWS" ] ; then
|
|
||||||
[ ! -e "${GHCUP_INSTALL_BASE_PREFIX}/ghcup" ]
|
|
||||||
else
|
|
||||||
[ ! -e "${GHCUP_INSTALL_BASE_PREFIX}/.ghcup" ]
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
{ system ? "aarch64-darwin"
|
|
||||||
#, nixpkgs ? fetchTarball https://github.com/angerman/nixpkgs/archive/257cb120334.tar.gz #apple-silicon.tar.gz
|
|
||||||
, pkgs ? import <nixpkgs> { inherit system; }
|
|
||||||
, compiler ? if system == "aarch64-darwin" then "ghc8103Binary" else "ghc8103"
|
|
||||||
}: pkgs.mkShell {
|
|
||||||
# this prevents nix from trying to write the env-vars file.
|
|
||||||
# we can't really, as NIX_BUILD_TOP/env-vars is not set.
|
|
||||||
noDumpEnvVars=1;
|
|
||||||
|
|
||||||
# stop polluting LDFLAGS with -liconv
|
|
||||||
dontAddExtraLibs = true;
|
|
||||||
|
|
||||||
# we need to inject ncurses into --with-curses-libraries.
|
|
||||||
# the real fix is to teach terminfo to use libcurses on macOS.
|
|
||||||
# CONFIGURE_ARGS = "--with-intree-gmp --with-curses-libraries=${pkgs.ncurses.out}/lib";
|
|
||||||
CONFIGURE_ARGS = "--with-intree-gmp --with-curses-libraries=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib --with-iconv-includes=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include --with-iconv-libraries=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib SH=/bin/bash";
|
|
||||||
|
|
||||||
# magic speedup pony :facepalm:
|
|
||||||
#
|
|
||||||
# nix has the ugly habbit of duplicating ld flags more than necessary. This
|
|
||||||
# somewhat consolidates this.
|
|
||||||
shellHook = ''
|
|
||||||
export NIX_LDFLAGS=$(for a in $NIX_LDFLAGS; do echo $a; done |sort|uniq|xargs)
|
|
||||||
export NIX_LDFLAGS_FOR_TARGET=$(for a in $NIX_LDFLAGS_FOR_TARGET; do echo $a; done |sort|uniq|xargs)
|
|
||||||
export NIX_LDFLAGS_FOR_TARGET=$(comm -3 <(for l in $NIX_LDFLAGS_FOR_TARGET; do echo $l; done) <(for l in $NIX_LDFLAGS; do echo $l; done))
|
|
||||||
|
|
||||||
|
|
||||||
# Impurity hack for GHC releases.
|
|
||||||
#################################
|
|
||||||
# We don't want binary releases to depend on nix, thus we'll need to make sure we don't leak in references.
|
|
||||||
# GHC externally depends only on iconv and curses. However we can't force a specific curses library for
|
|
||||||
# the terminfo package, as such we'll need to make sure we only look in the system path for the curses library
|
|
||||||
# and not pick up the tinfo from the nix provided ncurses package.
|
|
||||||
#
|
|
||||||
# We also need to force us to use the systems COREFOUNDATION, not the one that nix builds. Again this is impure,
|
|
||||||
# but it will allow us to have proper binary distributions.
|
|
||||||
#
|
|
||||||
# do not use nixpkgs provided core foundation
|
|
||||||
export NIX_COREFOUNDATION_RPATH=/System/Library/Frameworks
|
|
||||||
# drop curses from the LDFLAGS, we really want the system ones, not the nix ones.
|
|
||||||
export NIX_LDFLAGS=$(for lib in $NIX_LDFLAGS; do case "$lib" in *curses*);; *) echo -n "$lib ";; esac; done;)
|
|
||||||
export NIX_CFLAGS_COMPILE+=" -Wno-nullability-completeness -Wno-availability -Wno-expansion-to-defined -Wno-builtin-requires-header -Wno-unused-command-line-argument"
|
|
||||||
|
|
||||||
# unconditionally add the MacOSX.sdk and TargetConditional.h
|
|
||||||
export NIX_CFLAGS_COMPILE+=" -isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include"
|
|
||||||
|
|
||||||
'';
|
|
||||||
|
|
||||||
nativeBuildInputs = (with pkgs; [
|
|
||||||
# This needs to come *before* ghc,
|
|
||||||
# otherwise we migth end up with the clang from
|
|
||||||
# the bootstrap GHC in PATH with higher priority.
|
|
||||||
clang_11
|
|
||||||
llvm_11
|
|
||||||
|
|
||||||
haskell.compiler.${compiler}
|
|
||||||
haskell.packages.${compiler}.cabal-install
|
|
||||||
haskell.packages.${compiler}.alex
|
|
||||||
haskell.packages.${compiler}.happy # _1_19_12 is needed for older GHCs.
|
|
||||||
|
|
||||||
automake
|
|
||||||
autoconf
|
|
||||||
m4
|
|
||||||
|
|
||||||
gmp
|
|
||||||
zlib.out
|
|
||||||
zlib.dev
|
|
||||||
glibcLocales
|
|
||||||
# locale doesn't build yet :-/
|
|
||||||
# locale
|
|
||||||
|
|
||||||
git
|
|
||||||
|
|
||||||
python3
|
|
||||||
# python3Full
|
|
||||||
# python3Packages.sphinx
|
|
||||||
perl
|
|
||||||
|
|
||||||
which
|
|
||||||
wget
|
|
||||||
curl
|
|
||||||
file
|
|
||||||
|
|
||||||
xz
|
|
||||||
xlibs.lndir
|
|
||||||
|
|
||||||
cacert ])
|
|
||||||
++ (with pkgs.darwin.apple_sdk.frameworks; [ Foundation Security ]);
|
|
||||||
}
|
|
||||||
37
.travis.yml
Normal file
37
.travis.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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
|
||||||
|
|
||||||
28
.travis/build.sh
Executable file
28
.travis/build.sh
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/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}"
|
||||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,26 +1,11 @@
|
|||||||
# Revision history for ghcup
|
# Revision history for ghcup
|
||||||
|
|
||||||
## 0.1.16 -- ????-??-??
|
## 0.1.15 -- ????-??-??
|
||||||
|
|
||||||
* Add 'nuke' subcommand wrt [#135](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/135), implemented by Arjun Kathuria
|
* Add date to GHC bindist names created by ghcup
|
||||||
|
|
||||||
## 0.1.15.2 -- 2021-06-13
|
|
||||||
|
|
||||||
* Remove legacy handling of cabal binary and be more graceful about binaries not installed by ghcup (e.g. stack)
|
|
||||||
* Fix GHC compilation from git
|
|
||||||
* Fix 'ghcup upgrade' on windows
|
|
||||||
* Allow to skip update checks via `GHCUP_SKIP_UPDATE_CHECK`
|
|
||||||
* Use libarchive on windows as well, fixing unpack errors wrt [#147](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/147)
|
|
||||||
|
|
||||||
## 0.1.15.1 -- 2021-06-11
|
|
||||||
|
|
||||||
* Add Apple Silicon support
|
|
||||||
* Add windows support wrt [#130](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/130)
|
|
||||||
* Add stack support
|
|
||||||
* Warn when /tmp doesn't have 5GB or more of disk space
|
* Warn when /tmp doesn't have 5GB or more of disk space
|
||||||
* Allow to compile GHC from git repo wrt [#126](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/126)
|
* Allow to compile GHC from git repo wrt [#126](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/126)
|
||||||
* Allow to set custom ghc version when running 'ghcup compile ghc' wrt [#136](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/136)
|
* Add stack support
|
||||||
* Add date to GHC bindist names created by ghcup
|
|
||||||
|
|
||||||
## 0.1.14.2 -- 2021-05-12
|
## 0.1.14.2 -- 2021-05-12
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,3 @@ yaml files: `ghcup-<yaml-ver>.yaml`.
|
|||||||
Most of the `Version` parameters to functions had to be replaced with
|
Most of the `Version` parameters to functions had to be replaced with
|
||||||
that and ensured the logic is consistent for cross and non-cross
|
that and ensured the logic is consistent for cross and non-cross
|
||||||
installs.
|
installs.
|
||||||
2. This refactor added windows support wrt [#130](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/130).
|
|
||||||
The major changes here were switching `hpath` library out for `filepath`/`directory` (sadly) and
|
|
||||||
introducing a non-unix way of handling processes via the `process` library. It also introduced considerable
|
|
||||||
amounts of CPP wrt file handling, installation etc.
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
`ghcup` makes it easy to install specific versions of `ghc` on GNU/Linux,
|
`ghcup` makes it easy to install specific versions of `ghc` on GNU/Linux,
|
||||||
macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh Haskell developer environment from scratch.
|
macOS (aka Darwin) and FreeBSD and can also bootstrap a fresh Haskell developer environment from scratch.
|
||||||
It follows the unix UNIX philosophy of [do one thing and do it well](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well).
|
It follows the unix UNIX philosophy of [do one thing and do it well](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well).
|
||||||
|
|
||||||
Similar in scope to [rustup](https://github.com/rust-lang-nursery/rustup.rs), [pyenv](https://github.com/pyenv/pyenv) and [jenv](http://www.jenv.be).
|
Similar in scope to [rustup](https://github.com/rust-lang-nursery/rustup.rs), [pyenv](https://github.com/pyenv/pyenv) and [jenv](http://www.jenv.be).
|
||||||
@@ -85,7 +85,7 @@ handles your haskell packages and can demand that [a specific version](https://c
|
|||||||
A configuration file can be put in `~/.ghcup/config.yaml`. The default config file
|
A configuration file can be put in `~/.ghcup/config.yaml`. The default config file
|
||||||
explaining all possible configurations can be found in this repo: [config.yaml](./config.yaml).
|
explaining all possible configurations can be found in this repo: [config.yaml](./config.yaml).
|
||||||
|
|
||||||
Partial configuration is fine. Command line options always override the config file settings.
|
Partial configuration is fine. Command line options always overwrite the config file settings.
|
||||||
|
|
||||||
### Manpages
|
### Manpages
|
||||||
|
|
||||||
@@ -123,9 +123,6 @@ Then you can control the locations via XDG environment variables as such:
|
|||||||
* `XDG_BIN_HOME`: binaries end up here (default: `~/.local/bin`)
|
* `XDG_BIN_HOME`: binaries end up here (default: `~/.local/bin`)
|
||||||
* `XDG_CONFIG_HOME`: the config file is stored in `ghcup` subdir as `config.yaml` (default: `~/.config`)
|
* `XDG_CONFIG_HOME`: the config file is stored in `ghcup` subdir as `config.yaml` (default: `~/.config`)
|
||||||
|
|
||||||
**Note that `ghcup` makes some assumptions about structure of files in `XDG_BIN_HOME`. So if you have other tools
|
|
||||||
installing e.g. stack/cabal/ghc into it, this will likely clash. In that case consider disabling XDG support.**
|
|
||||||
|
|
||||||
### Env variables
|
### Env variables
|
||||||
|
|
||||||
This is the complete list of env variables that change GHCup behavior:
|
This is the complete list of env variables that change GHCup behavior:
|
||||||
@@ -135,7 +132,6 @@ This is the complete list of env variables that change GHCup behavior:
|
|||||||
* `GHCUP_INSTALL_BASE_PREFIX`: the base of ghcup (default: `$HOME`)
|
* `GHCUP_INSTALL_BASE_PREFIX`: the base of ghcup (default: `$HOME`)
|
||||||
* `GHCUP_CURL_OPTS`: additional options that can be passed to curl
|
* `GHCUP_CURL_OPTS`: additional options that can be passed to curl
|
||||||
* `GHCUP_WGET_OPTS`: additional options that can be passed to wget
|
* `GHCUP_WGET_OPTS`: additional options that can be passed to wget
|
||||||
* `GHCUP_SKIP_UPDATE_CHECK`: Skip the (possibly annoying) update check when you run a command
|
|
||||||
* `CC`/`LD` etc.: full environment is passed to the build system when compiling GHC via GHCup
|
* `CC`/`LD` etc.: full environment is passed to the build system when compiling GHC via GHCup
|
||||||
|
|
||||||
### Installing custom bindists
|
### Installing custom bindists
|
||||||
|
|||||||
@@ -69,15 +69,13 @@ tarballFilterP = option readm $
|
|||||||
long "tarball-filter" <> short 'u' <> metavar "<tool>-<version>" <> value def
|
long "tarball-filter" <> short 'u' <> metavar "<tool>-<version>" <> value def
|
||||||
<> help "Only check certain tarballs (format: <tool>-<version>)"
|
<> help "Only check certain tarballs (format: <tool>-<version>)"
|
||||||
where
|
where
|
||||||
def = TarballFilter (Right Nothing) (makeRegex ("" :: String))
|
def = TarballFilter Nothing (makeRegex ("" :: String))
|
||||||
readm = do
|
readm = do
|
||||||
s <- str
|
s <- str
|
||||||
case span (/= '-') s of
|
case span (/= '-') s of
|
||||||
(_, []) -> fail "invalid format, missing '-' after the tool name"
|
(_, []) -> fail "invalid format, missing '-' after the tool name"
|
||||||
(t, v) | [tool] <- [ tool | tool <- [minBound..maxBound], low (show tool) == low t ] ->
|
(t, v) | [tool] <- [ tool | tool <- [minBound..maxBound], low (show tool) == low t ] ->
|
||||||
pure (TarballFilter $ Right $ Just tool) <*> makeRegexOptsM compIgnoreCase execBlank (drop 1 v)
|
pure (TarballFilter $ Just tool) <*> makeRegexOptsM compIgnoreCase execBlank (drop 1 v)
|
||||||
(t, v) | [tool] <- [ tool | tool <- [minBound..maxBound], low (show tool) == low t ] ->
|
|
||||||
pure (TarballFilter $ Left tool) <*> makeRegexOptsM compIgnoreCase execBlank (drop 1 v)
|
|
||||||
_ -> fail "invalid tool"
|
_ -> fail "invalid tool"
|
||||||
low = fmap toLower
|
low = fmap toLower
|
||||||
|
|
||||||
@@ -107,21 +105,26 @@ main :: IO ()
|
|||||||
main = do
|
main = do
|
||||||
_ <- customExecParser (prefs showHelpOnError) (info (opts <**> helper) idm)
|
_ <- customExecParser (prefs showHelpOnError) (info (opts <**> helper) idm)
|
||||||
>>= \Options {..} -> case optCommand of
|
>>= \Options {..} -> case optCommand of
|
||||||
ValidateYAML vopts -> withValidateYamlOpts vopts validate
|
ValidateYAML vopts -> case vopts of
|
||||||
ValidateTarballs vopts tarballFilter -> withValidateYamlOpts vopts (validateTarballs tarballFilter)
|
ValidateYAMLOpts { vInput = Nothing } ->
|
||||||
|
B.getContents >>= valAndExit validate
|
||||||
|
ValidateYAMLOpts { vInput = Just StdInput } ->
|
||||||
|
B.getContents >>= valAndExit validate
|
||||||
|
ValidateYAMLOpts { vInput = Just (FileInput file) } ->
|
||||||
|
B.readFile file >>= valAndExit validate
|
||||||
|
ValidateTarballs vopts tarballFilter -> case vopts of
|
||||||
|
ValidateYAMLOpts { vInput = Nothing } ->
|
||||||
|
B.getContents >>= valAndExit (validateTarballs tarballFilter)
|
||||||
|
ValidateYAMLOpts { vInput = Just StdInput } ->
|
||||||
|
B.getContents >>= valAndExit (validateTarballs tarballFilter)
|
||||||
|
ValidateYAMLOpts { vInput = Just (FileInput file) } ->
|
||||||
|
B.readFile file >>= valAndExit (validateTarballs tarballFilter)
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
where
|
where
|
||||||
withValidateYamlOpts vopts f = case vopts of
|
|
||||||
ValidateYAMLOpts { vInput = Nothing } ->
|
|
||||||
B.getContents >>= valAndExit f
|
|
||||||
ValidateYAMLOpts { vInput = Just StdInput } ->
|
|
||||||
B.getContents >>= valAndExit f
|
|
||||||
ValidateYAMLOpts { vInput = Just (FileInput file) } ->
|
|
||||||
B.readFile file >>= valAndExit f
|
|
||||||
valAndExit f contents = do
|
valAndExit f contents = do
|
||||||
(GHCupInfo _ av gt) <- case Y.decodeEither' contents of
|
(GHCupInfo _ av) <- case Y.decodeEither' contents of
|
||||||
Right r -> pure r
|
Right r -> pure r
|
||||||
Left e -> die (color Red $ show e)
|
Left e -> die (color Red $ show e)
|
||||||
myLoggerT (LoggerConfig True (B.hPut stdout) (\_ -> pure ())) (f av gt)
|
myLoggerT (LoggerConfig True (B.hPut stdout) (\_ -> pure ())) (f av)
|
||||||
>>= exitWith
|
>>= exitWith
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ module Validate where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
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
|
||||||
@@ -23,7 +22,6 @@ import qualified Codec.Archive.Tar as Tar
|
|||||||
#else
|
#else
|
||||||
import Codec.Archive
|
import Codec.Archive
|
||||||
#endif
|
#endif
|
||||||
import Control.Applicative
|
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.IO.Class
|
import Control.Monad.IO.Class
|
||||||
@@ -68,9 +66,8 @@ addError = do
|
|||||||
|
|
||||||
validate :: (Monad m, MonadLogger m, MonadThrow m, MonadIO m, MonadUnliftIO m)
|
validate :: (Monad m, MonadLogger m, MonadThrow m, MonadIO m, MonadUnliftIO m)
|
||||||
=> GHCupDownloads
|
=> GHCupDownloads
|
||||||
-> M.Map GlobalTool DownloadInfo
|
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
validate dls _ = do
|
validate dls = do
|
||||||
ref <- liftIO $ newIORef 0
|
ref <- liftIO $ newIORef 0
|
||||||
|
|
||||||
-- verify binary downloads --
|
-- verify binary downloads --
|
||||||
@@ -184,7 +181,7 @@ validate dls _ = do
|
|||||||
isBase _ = False
|
isBase _ = False
|
||||||
|
|
||||||
data TarballFilter = TarballFilter
|
data TarballFilter = TarballFilter
|
||||||
{ tfTool :: Either GlobalTool (Maybe Tool)
|
{ tfTool :: Maybe Tool
|
||||||
, tfVersion :: Regex
|
, tfVersion :: Regex
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,23 +191,22 @@ validateTarballs :: ( Monad m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
, Alternative m
|
|
||||||
, MonadFail m
|
|
||||||
)
|
)
|
||||||
=> TarballFilter
|
=> TarballFilter
|
||||||
-> GHCupDownloads
|
-> GHCupDownloads
|
||||||
-> M.Map GlobalTool DownloadInfo
|
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
validateTarballs (TarballFilter etool versionRegex) dls gt = do
|
validateTarballs (TarballFilter tool versionRegex) dls = do
|
||||||
ref <- liftIO $ newIORef 0
|
ref <- liftIO $ newIORef 0
|
||||||
|
|
||||||
flip runReaderT ref $ do
|
flip runReaderT ref $ do
|
||||||
-- download/verify all tarballs
|
-- download/verify all tarballs
|
||||||
let dlis = either (const []) (\tool -> nubOrd $ dls ^.. each %& indices (maybe (const True) (==) tool) %> each %& indices (matchTest versionRegex . T.unpack . prettyVer) % (viSourceDL % _Just `summing` viArch % each % each % each)) etool
|
let dlis = nubOrd $ dls ^.. each
|
||||||
let gdlis = nubOrd $ gt ^.. each
|
%& indices (maybe (const True) (==) tool) %> each
|
||||||
let allDls = either (const gdlis) (const dlis) etool
|
%& indices (matchTest versionRegex . T.unpack . prettyVer)
|
||||||
when (null allDls) $ $(logError) [i|no tarballs selected by filter|] *> addError
|
% (viSourceDL % _Just `summing` viArch % each % each % each)
|
||||||
forM_ allDls downloadAll
|
when (null dlis) $ $(logError) [i|no tarballs selected by filter|] *> addError
|
||||||
|
|
||||||
|
forM_ dlis downloadAll
|
||||||
|
|
||||||
-- exit
|
-- exit
|
||||||
e <- liftIO $ readIORef ref
|
e <- liftIO $ readIORef ref
|
||||||
@@ -226,22 +222,12 @@ validateTarballs (TarballFilter etool versionRegex) dls gt = do
|
|||||||
, rawOutter = \_ -> pure ()
|
, rawOutter = \_ -> pure ()
|
||||||
}
|
}
|
||||||
downloadAll dli = do
|
downloadAll dli = do
|
||||||
dirs <- liftIO getAllDirs
|
dirs <- liftIO getDirs
|
||||||
|
let settings = AppState (Settings True False Never Curl False GHCupURL) dirs defaultKeyBindings
|
||||||
pfreq <- (
|
|
||||||
runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest
|
|
||||||
) >>= \case
|
|
||||||
VRight r -> pure r
|
|
||||||
VLeft e -> do
|
|
||||||
lift $ runLogger
|
|
||||||
($(logError) $ T.pack $ prettyShow e)
|
|
||||||
liftIO $ exitWith (ExitFailure 2)
|
|
||||||
|
|
||||||
let appstate = AppState (Settings True False Never Curl False GHCupURL False) dirs defaultKeyBindings (GHCupInfo mempty mempty mempty) pfreq
|
|
||||||
|
|
||||||
r <-
|
r <-
|
||||||
runLogger
|
runLogger
|
||||||
. flip runReaderT appstate
|
. flip runReaderT settings
|
||||||
. runResourceT
|
. runResourceT
|
||||||
. runE @'[DigestError
|
. runE @'[DigestError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
@@ -253,21 +239,19 @@ validateTarballs (TarballFilter etool versionRegex) dls gt = do
|
|||||||
#endif
|
#endif
|
||||||
]
|
]
|
||||||
$ do
|
$ do
|
||||||
case etool of
|
case tool of
|
||||||
Right (Just GHCup) -> do
|
Just GHCup -> do
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
let fn = "ghcup"
|
||||||
_ <- liftE $ download dli tmpUnpack Nothing
|
dir <- liftIO ghcupCacheDir
|
||||||
|
p <- liftE $ download dli dir (Just fn)
|
||||||
|
liftE $ checkDigest dli p
|
||||||
pure Nothing
|
pure Nothing
|
||||||
Right _ -> do
|
_ -> do
|
||||||
p <- liftE $ downloadCached 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
|
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
|
||||||
_ <- liftE $ download dli tmpUnpack Nothing
|
|
||||||
pure Nothing
|
|
||||||
case r of
|
case r of
|
||||||
VRight (Just basePath) -> do
|
VRight (Just basePath) -> do
|
||||||
case _dlSubdir dli of
|
case _dlSubdir dli of
|
||||||
|
|||||||
@@ -6,14 +6,13 @@
|
|||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
{-# LANGUAGE TypeApplications #-}
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
{-# LANGUAGE RankNTypes #-}
|
|
||||||
|
|
||||||
module BrickMain where
|
module BrickMain where
|
||||||
|
|
||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types hiding ( LeanAppState(..) )
|
import GHCup.Types
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Prelude ( decUTF8Safe )
|
import GHCup.Utils.Prelude ( decUTF8Safe )
|
||||||
import GHCup.Utils.File
|
import GHCup.Utils.File
|
||||||
@@ -33,7 +32,6 @@ import Codec.Archive
|
|||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
import Control.Monad.Logger
|
import Control.Monad.Logger
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Trans.Except
|
|
||||||
import Control.Monad.Trans.Resource
|
import Control.Monad.Trans.Resource
|
||||||
import Data.Bool
|
import Data.Bool
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
@@ -53,17 +51,18 @@ 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
|
||||||
|
|
||||||
|
|
||||||
hiddenTools :: [Tool]
|
|
||||||
hiddenTools = [Stack]
|
|
||||||
|
|
||||||
|
|
||||||
data BrickData = BrickData
|
data BrickData = BrickData
|
||||||
{ lr :: [ListResult]
|
{ lr :: [ListResult]
|
||||||
|
, dls :: GHCupDownloads
|
||||||
|
, pfreq :: PlatformRequest
|
||||||
}
|
}
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
@@ -98,7 +97,7 @@ keyHandlers KeyBindings {..} =
|
|||||||
[ (bQuit, const "Quit" , halt)
|
[ (bQuit, const "Quit" , halt)
|
||||||
, (bInstall, const "Install" , withIOAction install')
|
, (bInstall, const "Install" , withIOAction install')
|
||||||
, (bUninstall, const "Uninstall", withIOAction del')
|
, (bUninstall, const "Uninstall", withIOAction del')
|
||||||
, (bSet, const "Set" , withIOAction ((liftIO .) . set'))
|
, (bSet, const "Set" , withIOAction set')
|
||||||
, (bChangelog, const "ChangeLog", withIOAction changelog')
|
, (bChangelog, const "ChangeLog", withIOAction changelog')
|
||||||
, ( bShowAllVersions
|
, ( bShowAllVersions
|
||||||
, \BrickSettings {..} ->
|
, \BrickSettings {..} ->
|
||||||
@@ -150,7 +149,12 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
<+> minHSize 15 (str "Version")
|
<+> minHSize 15 (str "Version")
|
||||||
<+> padLeft (Pad 1) (minHSize 25 $ str "Tags")
|
<+> padLeft (Pad 1) (minHSize 25 $ str "Tags")
|
||||||
<+> padLeft (Pad 5) (str "Notes")
|
<+> padLeft (Pad 5) (str "Notes")
|
||||||
renderList' = withDefAttr listAttr . drawListElements renderItem True
|
renderList' = withDefAttr listAttr . drawListElements renderItem True . filterStack
|
||||||
|
filterStack appState'
|
||||||
|
| showAllTools as = appState'
|
||||||
|
| let v = clr appState'
|
||||||
|
nv = V.filter (\ListResult{..} -> lTool /= Stack) v
|
||||||
|
, otherwise = BrickInternalState { clr = nv, ix = ix appState' }
|
||||||
renderItem _ b listResult@ListResult{..} =
|
renderItem _ b listResult@ListResult{..} =
|
||||||
let marks = if
|
let marks = if
|
||||||
| lSet -> (withAttr "set" $ str "✔✔")
|
| lSet -> (withAttr "set" $ str "✔✔")
|
||||||
@@ -325,25 +329,21 @@ moveCursor steps ais@BrickInternalState{..} direction =
|
|||||||
|
|
||||||
-- | Suspend the current UI and run an IO action in terminal. If the
|
-- | Suspend the current UI and run an IO action in terminal. If the
|
||||||
-- IO action returns a Left value, then it's thrown as userError.
|
-- IO action returns a Left value, then it's thrown as userError.
|
||||||
withIOAction :: (BrickState
|
withIOAction :: (BrickState -> (Int, ListResult) -> IO (Either String a))
|
||||||
-> (Int, ListResult)
|
|
||||||
-> ReaderT AppState IO (Either String a))
|
|
||||||
-> BrickState
|
-> BrickState
|
||||||
-> EventM n (Next BrickState)
|
-> EventM n (Next BrickState)
|
||||||
withIOAction action as = case listSelectedElement' (appState as) of
|
withIOAction action as = case listSelectedElement' (appState as) of
|
||||||
Nothing -> continue as
|
Nothing -> continue as
|
||||||
Just (ix, e) -> do
|
Just (ix, e) -> suspendAndResume $ do
|
||||||
suspendAndResume $ do
|
action as (ix, e) >>= \case
|
||||||
settings <- readIORef settings'
|
Left err -> putStrLn ("Error: " <> err)
|
||||||
flip runReaderT settings $ action as (ix, e) >>= \case
|
Right _ -> putStrLn "Success"
|
||||||
Left err -> liftIO $ putStrLn ("Error: " <> err)
|
getAppData Nothing (pfreq . appData $ as) >>= \case
|
||||||
Right _ -> liftIO $ putStrLn "Success"
|
Right data' -> do
|
||||||
getAppData Nothing >>= \case
|
putStrLn "Press enter to continue"
|
||||||
Right data' -> do
|
_ <- getLine
|
||||||
putStrLn "Press enter to continue"
|
pure (updateList data' as)
|
||||||
_ <- getLine
|
Left err -> throwIO $ userError err
|
||||||
pure (updateList data' as)
|
|
||||||
Left err -> throwIO $ userError err
|
|
||||||
|
|
||||||
|
|
||||||
-- | Update app data and list internal state based on new evidence.
|
-- | Update app data and list internal state based on new evidence.
|
||||||
@@ -364,9 +364,7 @@ constructList :: BrickData
|
|||||||
-> Maybe BrickInternalState
|
-> Maybe BrickInternalState
|
||||||
-> BrickInternalState
|
-> BrickInternalState
|
||||||
constructList appD appSettings =
|
constructList appD appSettings =
|
||||||
replaceLR (filterVisible (showAllVersions appSettings)
|
replaceLR (filterVisible (showAllVersions appSettings)) (lr appD)
|
||||||
(showAllTools appSettings))
|
|
||||||
(lr appD)
|
|
||||||
|
|
||||||
listSelectedElement' :: BrickInternalState -> Maybe (Int, ListResult)
|
listSelectedElement' :: BrickInternalState -> Maybe (Int, ListResult)
|
||||||
listSelectedElement' BrickInternalState{..} = fmap (ix, ) $ clr !? ix
|
listSelectedElement' BrickInternalState{..} = fmap (ix, ) $ clr !? ix
|
||||||
@@ -399,32 +397,21 @@ replaceLR filterF lr s =
|
|||||||
lTool e1 == lTool e2 && lVer e1 == lVer e2 && lCross e1 == lCross e2
|
lTool e1 == lTool e2 && lVer e1 == lVer e2 && lCross e1 == lCross e2
|
||||||
|
|
||||||
|
|
||||||
filterVisible :: Bool -> Bool -> ListResult -> Bool
|
filterVisible :: Bool -> ListResult -> Bool
|
||||||
filterVisible v t e | lInstalled e = True
|
filterVisible showAllVersions e | lInstalled e = True
|
||||||
| v
|
| showAllVersions = True
|
||||||
, not t
|
| otherwise = not (elem Old (lTag e))
|
||||||
, not (elem (lTool e) hiddenTools) = True
|
|
||||||
| not v
|
|
||||||
, t
|
|
||||||
, not (elem Old (lTag e)) = True
|
|
||||||
| v
|
|
||||||
, t = True
|
|
||||||
| otherwise = not (elem Old (lTag e)) &&
|
|
||||||
not (elem (lTool e) hiddenTools)
|
|
||||||
|
|
||||||
|
|
||||||
install' :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m, MonadMask m, MonadUnliftIO m)
|
install' :: BrickState -> (Int, ListResult) -> IO (Either String ())
|
||||||
=> BrickState
|
install' BrickState { appData = BrickData {..} } (_, ListResult {..}) = do
|
||||||
-> (Int, ListResult)
|
settings <- readIORef settings'
|
||||||
-> m (Either String ())
|
l <- readIORef logger'
|
||||||
install' _ (_, ListResult {..}) = do
|
|
||||||
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
|
||||||
|
|
||||||
l <- liftIO $ readIORef logger'
|
|
||||||
let runLogger = myLoggerT l
|
let runLogger = myLoggerT l
|
||||||
|
|
||||||
let run =
|
let run =
|
||||||
runLogger
|
runLogger
|
||||||
|
. flip runReaderT settings
|
||||||
. runResourceT
|
. runResourceT
|
||||||
. runE
|
. runE
|
||||||
@'[ AlreadyInstalled
|
@'[ AlreadyInstalled
|
||||||
@@ -448,24 +435,24 @@ install' _ (_, ListResult {..}) = do
|
|||||||
case lTool of
|
case lTool of
|
||||||
GHC -> do
|
GHC -> do
|
||||||
let vi = getVersionInfo lVer GHC dls
|
let vi = getVersionInfo lVer GHC dls
|
||||||
liftE $ installGHCBin lVer $> vi
|
liftE $ installGHCBin dls lVer pfreq $> vi
|
||||||
Cabal -> do
|
Cabal -> do
|
||||||
let vi = getVersionInfo lVer Cabal dls
|
let vi = getVersionInfo lVer Cabal dls
|
||||||
liftE $ installCabalBin lVer $> vi
|
liftE $ installCabalBin dls lVer pfreq $> vi
|
||||||
GHCup -> do
|
GHCup -> do
|
||||||
let vi = snd <$> getLatest dls GHCup
|
let vi = snd <$> getLatest dls GHCup
|
||||||
liftE $ upgradeGHCup Nothing False $> vi
|
liftE $ upgradeGHCup dls Nothing False pfreq $> vi
|
||||||
HLS -> do
|
HLS -> do
|
||||||
let vi = getVersionInfo lVer HLS dls
|
let vi = getVersionInfo lVer HLS dls
|
||||||
liftE $ installHLSBin lVer $> vi
|
liftE $ installHLSBin dls lVer pfreq $> vi
|
||||||
Stack -> do
|
Stack -> do
|
||||||
let vi = getVersionInfo lVer Stack dls
|
let vi = getVersionInfo lVer Stack dls
|
||||||
liftE $ installStackBin lVer $> vi
|
liftE $ installStackBin dls lVer pfreq $> vi
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg ->
|
||||||
myLoggerT l $ $(logInfo) msg
|
runLogger $ $(logInfo) msg
|
||||||
pure $ Right ()
|
pure $ Right ()
|
||||||
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
||||||
VLeft (V NoUpdate) -> pure $ Right ()
|
VLeft (V NoUpdate) -> pure $ Right ()
|
||||||
@@ -497,16 +484,13 @@ set' _ (_, ListResult {..}) = do
|
|||||||
VLeft e -> pure $ Left (prettyShow e)
|
VLeft e -> pure $ Left (prettyShow e)
|
||||||
|
|
||||||
|
|
||||||
del' :: (MonadReader AppState m, MonadIO m, MonadFail m, MonadMask m, MonadUnliftIO m)
|
del' :: BrickState -> (Int, ListResult) -> IO (Either String ())
|
||||||
=> BrickState
|
del' BrickState { appData = BrickData {..} } (_, ListResult {..}) = do
|
||||||
-> (Int, ListResult)
|
settings <- readIORef settings'
|
||||||
-> m (Either String ())
|
l <- readIORef logger'
|
||||||
del' _ (_, ListResult {..}) = do
|
|
||||||
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
|
||||||
|
|
||||||
l <- liftIO $ readIORef logger'
|
|
||||||
let runLogger = myLoggerT l
|
let runLogger = myLoggerT l
|
||||||
let run = myLoggerT l . runE @'[NotInstalled]
|
|
||||||
|
let run = runLogger . flip runReaderT settings . runE @'[NotInstalled]
|
||||||
|
|
||||||
run (do
|
run (do
|
||||||
let vi = getVersionInfo lVer lTool dls
|
let vi = getVersionInfo lVer lTool dls
|
||||||
@@ -525,12 +509,8 @@ del' _ (_, ListResult {..}) = do
|
|||||||
VLeft e -> pure $ Left (prettyShow e)
|
VLeft e -> pure $ Left (prettyShow e)
|
||||||
|
|
||||||
|
|
||||||
changelog' :: (MonadReader AppState m, MonadIO m)
|
changelog' :: BrickState -> (Int, ListResult) -> IO (Either String ())
|
||||||
=> BrickState
|
changelog' BrickState { appData = BrickData {..} } (_, ListResult {..}) = do
|
||||||
-> (Int, ListResult)
|
|
||||||
-> m (Either String ())
|
|
||||||
changelog' _ (_, ListResult {..}) = do
|
|
||||||
AppState { pfreq, ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
|
||||||
case getChangeLog dls lTool (Left lVer) of
|
case getChangeLog dls lTool (Left lVer) of
|
||||||
Nothing -> pure $ Left
|
Nothing -> pure $ Left
|
||||||
[i|Could not find ChangeLog for #{lTool}, version #{prettyVer lVer}|]
|
[i|Could not find ChangeLog for #{lTool}, version #{prettyVer lVer}|]
|
||||||
@@ -548,20 +528,17 @@ changelog' _ (_, ListResult {..}) = do
|
|||||||
settings' :: IORef AppState
|
settings' :: IORef AppState
|
||||||
{-# NOINLINE settings' #-}
|
{-# NOINLINE settings' #-}
|
||||||
settings' = unsafePerformIO $ do
|
settings' = unsafePerformIO $ do
|
||||||
dirs <- getAllDirs
|
dirs <- getDirs
|
||||||
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
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
(GHCupInfo mempty mempty mempty)
|
|
||||||
(PlatformRequest A_64 Darwin Nothing)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -577,8 +554,10 @@ logger' = unsafePerformIO
|
|||||||
|
|
||||||
brickMain :: AppState
|
brickMain :: AppState
|
||||||
-> LoggerConfig
|
-> LoggerConfig
|
||||||
|
-> GHCupDownloads
|
||||||
|
-> PlatformRequest
|
||||||
-> IO ()
|
-> IO ()
|
||||||
brickMain s l = do
|
brickMain s l av pfreq' = do
|
||||||
writeIORef settings' s
|
writeIORef settings' s
|
||||||
-- logger interpreter
|
-- logger interpreter
|
||||||
writeIORef logger' l
|
writeIORef logger' l
|
||||||
@@ -586,7 +565,7 @@ brickMain s l = do
|
|||||||
|
|
||||||
no_color <- isJust <$> lookupEnv "NO_COLOR"
|
no_color <- isJust <$> lookupEnv "NO_COLOR"
|
||||||
|
|
||||||
eAppData <- getAppData (Just $ ghcupInfo s)
|
eAppData <- getAppData (Just av) pfreq'
|
||||||
case eAppData of
|
case eAppData of
|
||||||
Right ad ->
|
Right ad ->
|
||||||
defaultMain
|
defaultMain
|
||||||
@@ -594,7 +573,7 @@ brickMain s l = do
|
|||||||
(BrickState ad
|
(BrickState ad
|
||||||
defaultAppSettings
|
defaultAppSettings
|
||||||
(constructList ad defaultAppSettings Nothing)
|
(constructList ad defaultAppSettings Nothing)
|
||||||
(keyBindings (s :: AppState))
|
(keyBindings s)
|
||||||
|
|
||||||
)
|
)
|
||||||
$> ()
|
$> ()
|
||||||
@@ -607,8 +586,8 @@ defaultAppSettings :: BrickSettings
|
|||||||
defaultAppSettings = BrickSettings { showAllVersions = False, showAllTools = False }
|
defaultAppSettings = BrickSettings { showAllVersions = False, showAllTools = False }
|
||||||
|
|
||||||
|
|
||||||
getGHCupInfo :: IO (Either String GHCupInfo)
|
getDownloads' :: IO (Either String GHCupDownloads)
|
||||||
getGHCupInfo = do
|
getDownloads' = do
|
||||||
settings <- readIORef settings'
|
settings <- readIORef settings'
|
||||||
l <- readIORef logger'
|
l <- readIORef logger'
|
||||||
let runLogger = myLoggerT l
|
let runLogger = myLoggerT l
|
||||||
@@ -617,25 +596,29 @@ getGHCupInfo = do
|
|||||||
runLogger
|
runLogger
|
||||||
. flip runReaderT settings
|
. flip runReaderT settings
|
||||||
. runE @'[JSONError , DownloadFailed , FileDoesNotExistError]
|
. runE @'[JSONError , DownloadFailed , FileDoesNotExistError]
|
||||||
|
$ fmap _ghcupDownloads
|
||||||
$ liftE
|
$ liftE
|
||||||
$ getDownloadsF
|
$ getDownloadsF (urlSource . GT.settings $ settings)
|
||||||
|
|
||||||
case r of
|
case r of
|
||||||
VRight a -> pure $ Right a
|
VRight a -> pure $ Right a
|
||||||
VLeft e -> pure $ Left (prettyShow e)
|
VLeft e -> pure $ Left (prettyShow e)
|
||||||
|
|
||||||
|
|
||||||
getAppData :: Maybe GHCupInfo
|
getAppData :: Maybe GHCupDownloads
|
||||||
|
-> PlatformRequest
|
||||||
-> IO (Either String BrickData)
|
-> IO (Either String BrickData)
|
||||||
getAppData mgi = runExceptT $ do
|
getAppData mg pfreq' = do
|
||||||
l <- liftIO $ readIORef logger'
|
settings <- readIORef settings'
|
||||||
|
l <- readIORef logger'
|
||||||
let runLogger = myLoggerT l
|
let runLogger = myLoggerT l
|
||||||
|
|
||||||
r <- ExceptT $ maybe getGHCupInfo (pure . Right) mgi
|
r <- maybe getDownloads' (pure . Right) mg
|
||||||
liftIO $ modifyIORef settings' (\s -> s { ghcupInfo = r })
|
|
||||||
settings <- liftIO $ readIORef settings'
|
|
||||||
|
|
||||||
runLogger . flip runReaderT settings $ do
|
runLogger . flip runReaderT settings $ do
|
||||||
lV <- listVersions Nothing Nothing
|
case r of
|
||||||
pure $ BrickData (reverse lV)
|
Right dls -> do
|
||||||
|
lV <- listVersions dls Nothing Nothing pfreq'
|
||||||
|
pure $ Right $ BrickData (reverse lV) dls pfreq'
|
||||||
|
Left e -> pure $ Left [i|#{e}|]
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,12 +5,8 @@
|
|||||||
# * 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 - the ghc version to install
|
# * BOOTSTRAP_HASKELL_GHC_VERSION
|
||||||
# * BOOTSTRAP_HASKELL_CABAL_VERSION - the cabal version to install
|
# * BOOTSTRAP_HASKELL_CABAL_VERSION
|
||||||
# * 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
|
||||||
|
|
||||||
@@ -18,76 +14,26 @@
|
|||||||
# safety subshell to avoid executing anything in case this script is not downloaded properly
|
# safety subshell to avoid executing anything in case this script is not downloaded properly
|
||||||
(
|
(
|
||||||
|
|
||||||
plat="$(uname -s)"
|
: "${GHCUP_INSTALL_BASE_PREFIX:=$HOME}"
|
||||||
arch=$(uname -m)
|
|
||||||
ghver="0.1.15.2"
|
|
||||||
base_url="https://downloads.haskell.org/~ghcup"
|
|
||||||
|
|
||||||
export GHCUP_SKIP_UPDATE_CHECK=yes
|
export GHCUP_USE_XDG_DIRS
|
||||||
|
|
||||||
case "${plat}" in
|
if [ -n "${GHCUP_USE_XDG_DIRS}" ] ; then
|
||||||
MSYS*|MINGW*)
|
GHCUP_DIR=${XDG_DATA_HOME:=$HOME/.local/share}/ghcup
|
||||||
: "${GHCUP_INSTALL_BASE_PREFIX:=/c}"
|
GHCUP_BIN=${XDG_BIN_HOME:=$HOME/.local/bin}
|
||||||
GHCUP_DIR=$(cygpath -u "${GHCUP_INSTALL_BASE_PREFIX}/ghcup")
|
else
|
||||||
GHCUP_BIN=$(cygpath -u "${GHCUP_INSTALL_BASE_PREFIX}/ghcup/bin")
|
GHCUP_DIR=${GHCUP_INSTALL_BASE_PREFIX}/.ghcup
|
||||||
: "${GHCUP_MSYS2:=${GHCUP_DIR}/msys64}"
|
GHCUP_BIN=${GHCUP_INSTALL_BASE_PREFIX}/.ghcup/bin
|
||||||
;;
|
fi
|
||||||
*)
|
|
||||||
: "${GHCUP_INSTALL_BASE_PREFIX:=$HOME}"
|
|
||||||
export GHCUP_USE_XDG_DIRS
|
|
||||||
|
|
||||||
if [ -n "${GHCUP_USE_XDG_DIRS}" ] ; then
|
|
||||||
GHCUP_DIR=${XDG_DATA_HOME:=$HOME/.local/share}/ghcup
|
|
||||||
GHCUP_BIN=${XDG_BIN_HOME:=$HOME/.local/bin}
|
|
||||||
else
|
|
||||||
GHCUP_DIR=${GHCUP_INSTALL_BASE_PREFIX}/.ghcup
|
|
||||||
GHCUP_BIN=${GHCUP_INSTALL_BASE_PREFIX}/.ghcup/bin
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
: "${BOOTSTRAP_HASKELL_GHC_VERSION:=recommended}"
|
: "${BOOTSTRAP_HASKELL_GHC_VERSION:=recommended}"
|
||||||
: "${BOOTSTRAP_HASKELL_CABAL_VERSION:=recommended}"
|
: "${BOOTSTRAP_HASKELL_CABAL_VERSION:=recommended}"
|
||||||
|
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
(>&2 printf "\\033[0;31m%s\\033[0m\\n" "$1")
|
(>&2 printf "\\033[0;31m%s\\033[0m\\n" "$1")
|
||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
|
|
||||||
warn() {
|
|
||||||
case "${plat}" in
|
|
||||||
MSYS*|MINGW*)
|
|
||||||
echo -e "\\033[0;35m$1\\033[0m"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
printf "\\033[0;35m%s\\033[0m\\n" "$1"
|
|
||||||
;;
|
|
||||||
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!"
|
||||||
}
|
}
|
||||||
@@ -97,155 +43,196 @@ eghcup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_eghcup() {
|
_eghcup() {
|
||||||
if [ -n "${BOOTSTRAP_HASKELL_YAML}" ] ; then
|
|
||||||
args="-s ${BOOTSTRAP_HASKELL_YAML}"
|
|
||||||
fi
|
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_VERBOSE}" ] ; then
|
if [ -z "${BOOTSTRAP_HASKELL_VERBOSE}" ] ; then
|
||||||
"${GHCUP_BIN}/ghcup" ${args} "$@"
|
ghcup "$@"
|
||||||
else
|
else
|
||||||
"${GHCUP_BIN}/ghcup" ${args} --verbose "$@"
|
ghcup --verbose "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_done() {
|
_done() {
|
||||||
echo
|
echo
|
||||||
echo "==============================================================================="
|
echo "All done!"
|
||||||
case "${plat}" in
|
echo
|
||||||
MSYS*|MINGW*)
|
echo "To start a simple repl, run:"
|
||||||
green
|
echo " ghci"
|
||||||
green "All done!"
|
echo
|
||||||
green
|
echo "To start a new haskell project in the current directory, run:"
|
||||||
green "In a new powershell or cmd.exe session, now you can..."
|
echo " cabal init --interactive"
|
||||||
green
|
echo
|
||||||
green "Start a simple repl via:"
|
echo "To install other GHC versions, run:"
|
||||||
green " ghci"
|
echo " ghcup tui"
|
||||||
green
|
|
||||||
green "Start a new haskell project in the current directory via:"
|
|
||||||
green " cabal init --interactive"
|
|
||||||
green
|
|
||||||
green "Install other GHC versions and tools via:"
|
|
||||||
green " ghcup list"
|
|
||||||
green " ghcup install <tool> <version>"
|
|
||||||
green
|
|
||||||
green "To install system libraries and update msys2/mingw64,"
|
|
||||||
green "open the \"Mingw haskell shell\""
|
|
||||||
green "and the \"Mingw package management docs\""
|
|
||||||
green "desktop shortcuts."
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
green
|
|
||||||
green "All done!"
|
|
||||||
green
|
|
||||||
green "To start a simple repl, run:"
|
|
||||||
green " ghci"
|
|
||||||
green
|
|
||||||
green "To start a new haskell project in the current directory, run:"
|
|
||||||
green " cabal init --interactive"
|
|
||||||
green
|
|
||||||
green "To install other GHC versions and tools, run:"
|
|
||||||
green " ghcup tui"
|
|
||||||
;;
|
|
||||||
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
download_ghcup() {
|
download_ghcup() {
|
||||||
|
_plat="$(uname -s)"
|
||||||
|
_arch=$(uname -m)
|
||||||
|
_ghver="0.1.14.1"
|
||||||
|
_base_url="https://downloads.haskell.org/~ghcup"
|
||||||
|
|
||||||
case "${plat}" in
|
case "${_plat}" in
|
||||||
"linux"|"Linux")
|
"linux"|"Linux")
|
||||||
case "${arch}" in
|
case "${_arch}" in
|
||||||
x86_64|amd64)
|
x86_64|amd64)
|
||||||
# we could be in a 32bit docker container, in which
|
# we could be in a 32bit docker container, in which
|
||||||
# case uname doesn't give us what we want
|
# case uname doesn't give us what we want
|
||||||
if [ "$(getconf LONG_BIT)" = "32" ] ; then
|
if [ "$(getconf LONG_BIT)" = "32" ] ; then
|
||||||
_url=${base_url}/${ghver}/i386-linux-ghcup-${ghver}
|
_url=${_base_url}/${_ghver}/i386-linux-ghcup-${_ghver}
|
||||||
elif [ "$(getconf LONG_BIT)" = "64" ] ; then
|
elif [ "$(getconf LONG_BIT)" = "64" ] ; then
|
||||||
_url=${base_url}/${ghver}/x86_64-linux-ghcup-${ghver}
|
_url=${_base_url}/${_ghver}/x86_64-linux-ghcup-${_ghver}
|
||||||
else
|
else
|
||||||
die "Unknown long bit size: $(getconf LONG_BIT)"
|
die "Unknown long bit size: $(getconf LONG_BIT)"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
i*86)
|
i*86)
|
||||||
_url=${base_url}/${ghver}/i386-linux-ghcup-${ghver}
|
_url=${_base_url}/${_ghver}/i386-linux-ghcup-${_ghver}
|
||||||
;;
|
;;
|
||||||
armv7*)
|
armv7*)
|
||||||
_url=${base_url}/${ghver}/armv7-linux-ghcup-${ghver}
|
_url=${_base_url}/${_ghver}/armv7-linux-ghcup-${_ghver}
|
||||||
;;
|
;;
|
||||||
aarch64|arm64|armv8l)
|
aarch64|arm64|armv8l)
|
||||||
_url=${base_url}/${ghver}/aarch64-linux-ghcup-${ghver}
|
_url=${_base_url}/${_ghver}/aarch64-linux-ghcup-${_ghver}
|
||||||
;;
|
;;
|
||||||
*) die "Unknown architecture: ${arch}"
|
*) die "Unknown architecture: ${_arch}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
"FreeBSD"|"freebsd")
|
"FreeBSD"|"freebsd")
|
||||||
case "${arch}" in
|
case "${_arch}" in
|
||||||
x86_64|amd64)
|
x86_64|amd64)
|
||||||
;;
|
;;
|
||||||
i*86)
|
i*86)
|
||||||
die "i386 currently not supported!"
|
die "i386 currently not supported!"
|
||||||
;;
|
;;
|
||||||
*) die "Unknown architecture: ${arch}"
|
*) die "Unknown architecture: ${_arch}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
_url=${base_url}/${ghver}/x86_64-portbld-freebsd-ghcup-${ghver}
|
_url=${_base_url}/${_ghver}/x86_64-portbld-freebsd-ghcup-${_ghver}
|
||||||
;;
|
;;
|
||||||
"Darwin"|"darwin")
|
"Darwin"|"darwin")
|
||||||
case "${arch}" in
|
case "${_arch}" in
|
||||||
x86_64|amd64)
|
x86_64|amd64)
|
||||||
_url=${base_url}/${ghver}/x86_64-apple-darwin-ghcup-${ghver}
|
|
||||||
;;
|
|
||||||
aarch64|arm64|armv8l)
|
|
||||||
_url=${base_url}/${ghver}/aarch64-apple-darwin-ghcup-${ghver}
|
|
||||||
;;
|
;;
|
||||||
i*86)
|
i*86)
|
||||||
die "i386 currently not supported!"
|
die "i386 currently not supported!"
|
||||||
;;
|
;;
|
||||||
*) die "Unknown architecture: ${arch}"
|
*) die "Unknown architecture: ${_arch}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
_url=${_base_url}/${_ghver}/x86_64-apple-darwin-ghcup-${_ghver} ;;
|
||||||
MSYS*|MINGW*)
|
*) die "Unknown platform: ${_plat}"
|
||||||
case "${arch}" in
|
|
||||||
x86_64|amd64)
|
|
||||||
_url=${base_url}/${ghver}/x86_64-mingw64-ghcup-${ghver}.exe
|
|
||||||
;;
|
|
||||||
*) die "Unknown architecture: ${arch}"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
*) die "Unknown platform: ${plat}"
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
case "${plat}" in
|
|
||||||
MSYS*|MINGW*)
|
|
||||||
edo curl -Lf "${_url}" > "${GHCUP_BIN}"/ghcup.exe
|
|
||||||
edo chmod +x "${GHCUP_BIN}"/ghcup.exe
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
edo curl -Lf "${_url}" > "${GHCUP_BIN}"/ghcup
|
|
||||||
edo chmod +x "${GHCUP_BIN}"/ghcup
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
edo mkdir -p "${GHCUP_DIR}"
|
edo curl -Lf "${_url}" > "${GHCUP_BIN}"/ghcup
|
||||||
|
|
||||||
# we may overwrite this in adjust_bashrc
|
edo chmod +x "${GHCUP_BIN}"/ghcup
|
||||||
|
|
||||||
|
edo mkdir -p "${GHCUP_DIR}"
|
||||||
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
|
||||||
|
|
||||||
|
unset _plat _arch _url _ghver _base_url
|
||||||
}
|
}
|
||||||
|
|
||||||
# Figures out the users login shell and sets
|
|
||||||
# GHCUP_PROFILE_FILE and MY_SHELL variables.
|
echo
|
||||||
find_shell() {
|
echo "Welcome to Haskell!"
|
||||||
|
echo
|
||||||
|
echo "This script will download and install the following binaries:"
|
||||||
|
echo " * ghcup - The Haskell toolchain installer"
|
||||||
|
echo " (for managing GHC/cabal versions)"
|
||||||
|
echo " * ghc - The Glasgow Haskell Compiler"
|
||||||
|
echo " * cabal - The Cabal build tool"
|
||||||
|
echo
|
||||||
|
if [ -z "${GHCUP_USE_XDG_DIRS}" ] ; then
|
||||||
|
echo "ghcup installs only into the following directory,"
|
||||||
|
echo "which can be removed anytime:"
|
||||||
|
echo " $GHCUP_INSTALL_BASE_PREFIX/.ghcup"
|
||||||
|
else
|
||||||
|
echo "ghcup installs into XDG directories as long as"
|
||||||
|
echo "'GHCUP_USE_XDG_DIRS' is set."
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Press ENTER to proceed or ctrl-c to abort."
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Note that this script can be re-run at any given time."
|
||||||
|
echo
|
||||||
|
# Wait for user input to continue.
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
read -r answer </dev/tty
|
||||||
|
fi
|
||||||
|
|
||||||
|
edo mkdir -p "${GHCUP_BIN}"
|
||||||
|
|
||||||
|
if command -V "ghcup" >/dev/null 2>&1 ; then
|
||||||
|
if [ -z "${BOOTSTRAP_HASKELL_NO_UPGRADE}" ] ; then
|
||||||
|
_eghcup upgrade || download_ghcup
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
download_ghcup
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "$(ghcup tool-requirements)"
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Press ENTER to proceed or ctrl-c to abort."
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Installation may take a while."
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Wait for user input to continue.
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
read -r answer </dev/tty
|
||||||
|
fi
|
||||||
|
|
||||||
|
eghcup --cache install ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}"
|
||||||
|
|
||||||
|
eghcup set ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}"
|
||||||
|
eghcup --cache install cabal "${BOOTSTRAP_HASKELL_CABAL_VERSION}"
|
||||||
|
|
||||||
|
edo cabal new-update
|
||||||
|
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" ""
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Installation done!"
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" ""
|
||||||
|
|
||||||
|
|
||||||
|
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Do you want to install haskell-language-server (HLS) now?"
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "HLS is a language-server that provides IDE-like functionality"
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "and can integrate with different editors, such as Vim, Emacs, VS Code, Atom, ..."
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Also see https://github.com/haskell/haskell-language-server/blob/master/README.md"
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" ""
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Answer with YES or NO and press ENTER."
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" ""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -r hls_answer </dev/tty
|
||||||
|
|
||||||
|
case $hls_answer in
|
||||||
|
[Yy]*)
|
||||||
|
eghcup --cache install hls
|
||||||
|
break ;;
|
||||||
|
[Nn]*)
|
||||||
|
break ;;
|
||||||
|
*)
|
||||||
|
echo "Please type YES or NO and press enter.";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "In order to run ghc and cabal, you need to adjust your PATH variable."
|
||||||
|
echo "You may want to source '$GHCUP_DIR/env' in your shell"
|
||||||
|
echo "configuration to do so (e.g. ~/.bashrc)."
|
||||||
|
|
||||||
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"
|
||||||
@@ -261,393 +248,67 @@ find_shell() {
|
|||||||
GHCUP_PROFILE_FILE="$HOME/.zshrc"
|
GHCUP_PROFILE_FILE="$HOME/.zshrc"
|
||||||
MY_SHELL="zsh"
|
MY_SHELL="zsh"
|
||||||
else
|
else
|
||||||
return
|
_done
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*/fish) # login shell is fish
|
*/fish) # login shell is fish
|
||||||
GHCUP_PROFILE_FILE="$HOME/.config/fish/config.fish"
|
GHCUP_PROFILE_FILE="$HOME/.config/fish/config.fish"
|
||||||
MY_SHELL="fish" ;;
|
MY_SHELL="fish" ;;
|
||||||
*) return ;;
|
*) _done ;;
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ask user if they want to adjust the bashrc.
|
|
||||||
ask_bashrc() {
|
|
||||||
if [ -n "${BOOTSTRAP_HASKELL_ADJUST_BASHRC}" ] ; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
|
||||||
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
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
case $bashrc_answer in
|
|
||||||
[Pp]* | "")
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
[Aa]*)
|
|
||||||
return 2
|
|
||||||
;;
|
|
||||||
[Nn]*)
|
|
||||||
return 0;;
|
|
||||||
*)
|
|
||||||
echo "Possible choices are:"
|
|
||||||
echo
|
|
||||||
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
|
|
||||||
echo "Please make your choice and press ENTER."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
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
|
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)
|
printf "\\033[0;35m%s\\033[0m\\n" ""
|
||||||
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
|
printf "\\033[0;35m%s\\033[0m\\n" "Detected ${MY_SHELL} shell on your system..."
|
||||||
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
printf "\\033[0;35m%s\\033[0m\\n" "If you want ghcup to automatically add the required PATH variable to \"${GHCUP_PROFILE_FILE}\""
|
||||||
break ;;
|
printf "\\033[0;35m%s\\033[0m\\n" "answer with YES, otherwise with NO and press ENTER."
|
||||||
esac
|
printf "\\033[0;35m%s\\033[0m\\n" ""
|
||||||
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() {
|
while true; do
|
||||||
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
|
read -r next_answer </dev/tty
|
||||||
}
|
|
||||||
|
|
||||||
ask_cabal_config_init() {
|
case $next_answer in
|
||||||
case "${plat}" in
|
[Yy]*)
|
||||||
MSYS*|MINGW*)
|
case $MY_SHELL in
|
||||||
if [ -n "${BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG}" ] ; then
|
"") break ;;
|
||||||
return 1
|
fish)
|
||||||
fi
|
if ! grep -q "ghcup-env" "${GHCUP_PROFILE_FILE}" ; then
|
||||||
|
mkdir -p "${GHCUP_PROFILE_FILE%/*}"
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
echo "# ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
||||||
echo "-------------------------------------------------------------------------------"
|
echo "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME" >> "${GHCUP_PROFILE_FILE}"
|
||||||
warn "Create an initial cabal.config including relevant msys2 paths (recommended)?"
|
echo "test -f $GHCUP_DIR/env ; and set -gx PATH \$HOME/.cabal/bin $GHCUP_BIN \$PATH" >> "${GHCUP_PROFILE_FILE}"
|
||||||
warn "[Y] Yes [N] No [?] Help (default is \"Y\")."
|
fi
|
||||||
echo
|
break ;;
|
||||||
while true; do
|
bash)
|
||||||
read -r mingw_answer </dev/tty
|
if ! grep -q "ghcup-env" "${GHCUP_PROFILE_FILE}" ; then
|
||||||
|
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
||||||
case $mingw_answer in
|
fi
|
||||||
[Yy]* | "")
|
case "$(uname -s)" in
|
||||||
return 1 ;;
|
"Darwin"|"darwin")
|
||||||
[Nn]*)
|
if ! grep -q "ghcup-env" "${HOME}/.bash_profile" ; then
|
||||||
return 0 ;;
|
echo "[[ -f ~/.bashrc ]] && source ~/.bashrc # ghcup-env" >> "${HOME}/.bash_profile"
|
||||||
*)
|
fi
|
||||||
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
|
esac
|
||||||
done
|
break ;;
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
unset mingw_answer
|
zsh)
|
||||||
|
if ! grep -q "ghcup-env" "${GHCUP_PROFILE_FILE}" ; then
|
||||||
return 0
|
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
||||||
}
|
fi
|
||||||
|
break ;;
|
||||||
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 "Welcome to Haskell!"
|
|
||||||
echo
|
|
||||||
echo "This script will download and install the following binaries:"
|
|
||||||
echo " * ghcup - The Haskell toolchain installer"
|
|
||||||
echo " * ghc - The Glasgow Haskell Compiler"
|
|
||||||
echo " * cabal - The Cabal build tool for managing Haskell software"
|
|
||||||
echo " * stack - (optional) A cross-platform program for developing Haskell projects"
|
|
||||||
echo " * hls - (optional) A language server for developers to integrate with their editor/IDE"
|
|
||||||
echo
|
|
||||||
if [ -z "${GHCUP_USE_XDG_DIRS}" ] ; then
|
|
||||||
echo "ghcup installs only into the following directory,"
|
|
||||||
echo "which can be removed anytime:"
|
|
||||||
case "${plat}" in
|
|
||||||
MSYS*|MINGW*)
|
|
||||||
echo " $(cygpath -w "$GHCUP_DIR")"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo " $GHCUP_DIR"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo "ghcup installs into XDG directories as long as"
|
|
||||||
echo "'GHCUP_USE_XDG_DIRS' is set."
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
|
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
|
||||||
warn "Press ENTER to proceed or ctrl-c to abort."
|
|
||||||
warn "Note that this script can be re-run at any given time."
|
|
||||||
# Wait for user input to continue.
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
read -r answer </dev/tty
|
|
||||||
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}"
|
|
||||||
|
|
||||||
if command -V "ghcup" >/dev/null 2>&1 ; then
|
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_NO_UPGRADE}" ] ; then
|
|
||||||
_eghcup upgrade || download_ghcup
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
download_ghcup
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "$(if [ -n "${BOOTSTRAP_HASKELL_YAML}" ] ; then ghcup -s "${BOOTSTRAP_HASKELL_YAML}" tool-requirements ; else ghcup tool-requirements ; fi)"
|
|
||||||
echo
|
|
||||||
|
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
|
||||||
warn "Press ENTER to proceed or ctrl-c to abort."
|
|
||||||
warn "Installation may take a while."
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Wait for user input to continue.
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
read -r answer </dev/tty
|
|
||||||
fi
|
|
||||||
|
|
||||||
eghcup --cache install ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}"
|
|
||||||
|
|
||||||
eghcup set ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}"
|
|
||||||
eghcup --cache install cabal "${BOOTSTRAP_HASKELL_CABAL_VERSION}"
|
|
||||||
|
|
||||||
do_cabal_config_init $ask_cabal_config_init_answer
|
|
||||||
|
|
||||||
edo cabal new-update
|
|
||||||
|
|
||||||
case $ask_hls_answer in
|
|
||||||
1)
|
|
||||||
_eghcup --cache install hls || warn "HLS installation failed, continuing anyway"
|
|
||||||
;;
|
|
||||||
*) ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case $ask_stack_answer in
|
|
||||||
1)
|
|
||||||
_eghcup --cache install stack || warn "Stack installation failed, continuing anyway"
|
|
||||||
;;
|
|
||||||
*) ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# short-circuit script based on platform
|
|
||||||
case "${plat}" in
|
|
||||||
MSYS*|MINGW*)
|
|
||||||
# For windows we always adjust bashrc, since it's inside msys2
|
|
||||||
adjust_bashrc $adjust_bashrc_answer
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
|
||||||
case $ask_bashrc_answer in
|
|
||||||
1 | 2)
|
|
||||||
echo
|
|
||||||
echo "==============================================================================="
|
|
||||||
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
|
esac
|
||||||
fi
|
printf "\\033[0;35m%s\\033[0m\\n" "OK! ${GHCUP_PROFILE_FILE} has been modified. Restart your terminal for the changes to take effect,"
|
||||||
;;
|
printf "\\033[0;35m%s\\033[0m\\n" "or type \"source ${GHCUP_DIR}/env\" to apply them in your current terminal session."
|
||||||
esac
|
_done
|
||||||
|
;;
|
||||||
_done
|
[Nn]*)
|
||||||
|
_done ;;
|
||||||
|
*)
|
||||||
|
echo "Please type YES or NO and press enter.";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
)
|
)
|
||||||
|
|
||||||
# vim: tabstop=4 shiftwidth=4 expandtab
|
# vim: tabstop=4 shiftwidth=4 expandtab
|
||||||
|
|||||||
@@ -1,485 +0,0 @@
|
|||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Script to bootstrap a Haskell environment
|
|
||||||
|
|
||||||
.DESCRIPTION
|
|
||||||
This is the windows GHCup installer, installing:
|
|
||||||
|
|
||||||
* ghcup - The Haskell toolchain installer"
|
|
||||||
* ghc - The Glasgow Haskell Compiler"
|
|
||||||
* msys2 - Unix-style toolchain needed for dependencies and tools
|
|
||||||
* cabal - The Cabal build tool for managing Haskell software"
|
|
||||||
* stack - (optional) A cross-platform program for developing Haskell projects"
|
|
||||||
* hls - (optional) A language server for developers to integrate with their editor/IDE"
|
|
||||||
#>
|
|
||||||
param (
|
|
||||||
# Run an interactive installation
|
|
||||||
[switch]$Interactive,
|
|
||||||
# Specify the install root (default: 'C:\')
|
|
||||||
[string]$InstallDir,
|
|
||||||
# Instead of installing a new MSys2, use an existing installation
|
|
||||||
[string]$ExistingMsys2Dir,
|
|
||||||
# Specify the cabal root directory (default: '$InstallDir\cabal')
|
|
||||||
[string]$CabalDir,
|
|
||||||
# Overwrite (or rather backup) a previous install
|
|
||||||
[switch]$Overwrite,
|
|
||||||
# Specify the bootstrap url (default: 'https://www.haskell.org/ghcup/sh/bootstrap-haskell')
|
|
||||||
[string]$BootstrapUrl,
|
|
||||||
# Run the final bootstrap script via 'bash' instead of a full newly spawned msys2 shell
|
|
||||||
[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
|
|
||||||
|
|
||||||
function Print-Msg {
|
|
||||||
param ( [Parameter(Mandatory=$true, HelpMessage='String to output')][string]$msg, [string]$color = "Green" )
|
|
||||||
Write-Host ('{0}' -f $msg) -ForegroundColor $color
|
|
||||||
}
|
|
||||||
|
|
||||||
function Create-Shortcut {
|
|
||||||
param ( [Parameter(Mandatory=$true,HelpMessage='Target path')][string]$SourceExe, [Parameter(Mandatory=$true,HelpMessage='Arguments to the path/exe')][AllowEmptyString()]$ArgumentsToSourceExe, [Parameter(Mandatory=$true,HelpMessage='The destination of the desktop link')][string]$DestinationPath )
|
|
||||||
$WshShell = New-Object -comObject WScript.Shell
|
|
||||||
$Shortcut = $WshShell.CreateShortcut($DestinationPath)
|
|
||||||
$Shortcut.TargetPath = $SourceExe
|
|
||||||
if($ArgumentsToSourceExe) {
|
|
||||||
$Shortcut.Arguments = $ArgumentsToSourceExe
|
|
||||||
}
|
|
||||||
$Shortcut.Save()
|
|
||||||
}
|
|
||||||
|
|
||||||
function Add-EnvPath {
|
|
||||||
param(
|
|
||||||
[Parameter(Mandatory=$true,HelpMessage='The Path to add to Users environment')]
|
|
||||||
[string] $Path,
|
|
||||||
|
|
||||||
[ValidateSet('Machine', 'User', 'Session')]
|
|
||||||
[string] $Container = 'Session'
|
|
||||||
)
|
|
||||||
|
|
||||||
if ($Container -eq 'Session') {
|
|
||||||
$envPaths = [Collections.Generic.List[String]]($env:Path -split ([IO.Path]::PathSeparator))
|
|
||||||
if ($envPaths -notcontains $Path) {
|
|
||||||
$envPaths.Add($Path)
|
|
||||||
$env:PATH = $envPaths -join ([IO.Path]::PathSeparator)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
[Microsoft.Win32.RegistryHive]$hive, $keyPath = switch ($Container) {
|
|
||||||
'Machine' { 'LocalMachine', 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment' }
|
|
||||||
'User' { 'CurrentUser', 'Environment' }
|
|
||||||
}
|
|
||||||
|
|
||||||
$hiveKey = $envKey = $null
|
|
||||||
try {
|
|
||||||
$hiveKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive, '')
|
|
||||||
$envKey = $hiveKey.OpenSubKey($keyPath, $true)
|
|
||||||
$rawPath = $envKey.GetValue('PATH', '', 'DoNotExpandEnvironmentNames')
|
|
||||||
|
|
||||||
$envPaths = [Collections.Generic.List[String]]($rawPath -split ([IO.Path]::PathSeparator))
|
|
||||||
if ($envPaths -notcontains $Path) {
|
|
||||||
$envPaths.Add($Path)
|
|
||||||
$envKey.SetValue('PATH', ($envPaths -join ([IO.Path]::PathSeparator)), 'ExpandString')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if ($envKey) { $envKey.Close() }
|
|
||||||
if ($hiveKey) { $hiveKey.Close() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
filter Get-FileSize {
|
|
||||||
'{0:N2} {1}' -f $(
|
|
||||||
if ($_ -lt 1kb) { $_, 'Bytes' }
|
|
||||||
elseif ($_ -lt 1mb) { ($_/1kb), 'KB' }
|
|
||||||
elseif ($_ -lt 1gb) { ($_/1mb), 'MB' }
|
|
||||||
elseif ($_ -lt 1tb) { ($_/1gb), 'GB' }
|
|
||||||
elseif ($_ -lt 1pb) { ($_/1tb), 'TB' }
|
|
||||||
else { ($_/1pb), 'PB' }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-FileWCSynchronous{
|
|
||||||
param(
|
|
||||||
[Parameter(Mandatory=$true)]
|
|
||||||
[string]$url,
|
|
||||||
[string]$destinationFolder="$env:USERPROFILE\Downloads",
|
|
||||||
[switch]$includeStats
|
|
||||||
)
|
|
||||||
$wc = New-Object -TypeName Net.WebClient
|
|
||||||
$wc.UseDefaultCredentials = $true
|
|
||||||
$destination = Join-Path -Path $destinationFolder -ChildPath ($url | Split-Path -Leaf)
|
|
||||||
$start = Get-Date
|
|
||||||
$wc.DownloadFile($url, $destination)
|
|
||||||
$elapsed = ((Get-Date) - $start).ToString('hh\:mm\:ss')
|
|
||||||
$totalSize = (Get-Item -Path $destination).Length | Get-FileSize
|
|
||||||
if ($includeStats.IsPresent){
|
|
||||||
[PSCustomObject]@{Name=$MyInvocation.MyCommand;TotalSize=$totalSize;Time=$elapsed}
|
|
||||||
}
|
|
||||||
Get-Item -Path $destination | Unblock-File
|
|
||||||
}
|
|
||||||
|
|
||||||
function Test-AbsolutePath {
|
|
||||||
Param (
|
|
||||||
[Parameter(Mandatory=$True)]
|
|
||||||
[ValidateScript({[System.IO.Path]::IsPathRooted($_)})]
|
|
||||||
[String]$Path
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function Exec
|
|
||||||
{
|
|
||||||
[CmdletBinding()]
|
|
||||||
param(
|
|
||||||
[Parameter(Position = 0, Mandatory = 1)][string]$cmd,
|
|
||||||
[Parameter()][string]$errorMessage,
|
|
||||||
[parameter(ValueFromRemainingArguments = $true)]
|
|
||||||
[string[]]$Passthrough
|
|
||||||
)
|
|
||||||
& $cmd @Passthrough
|
|
||||||
if ($lastexitcode -ne 0) {
|
|
||||||
if (!($errorMessage)) {
|
|
||||||
throw ('Exec: Error executing command {0} with arguments ''{1}''' -f $cmd, "$Passthrough")
|
|
||||||
} else {
|
|
||||||
throw ('Exec: ' + $errorMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
|
||||||
|
|
||||||
$GhcupBasePrefixEnv = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user')
|
|
||||||
|
|
||||||
if ($GhcupBasePrefixEnv) {
|
|
||||||
$defaultGhcupBasePrefix = $GhcupBasePrefixEnv
|
|
||||||
} else {
|
|
||||||
$partitions = Get-CimInstance win32_logicaldisk
|
|
||||||
$defaultGhcupBasePrefix = $null
|
|
||||||
foreach ($p in $partitions){
|
|
||||||
try {
|
|
||||||
if ($p."FreeSpace" -lt 5368709120) { # at least 5 GB are needed
|
|
||||||
throw ("Not enough free space on {0}" -f $p."DeviceId")
|
|
||||||
}
|
|
||||||
$null = New-Item -Path ('{0}\' -f $p."DeviceId") -Name "ghcup.test" -ItemType "directory" -Force
|
|
||||||
$defaultGhcupBasePrefix = ('{0}\' -f $p."DeviceId")
|
|
||||||
Remove-Item -LiteralPath ('{0}\ghcup.test' -f $p."DeviceId")
|
|
||||||
break
|
|
||||||
} catch {
|
|
||||||
Print-Msg -color Yellow -msg ("{0} not writable or not enough disk space, trying next device" -f $p."DeviceId")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($defaultGhcupBasePrefix) {
|
|
||||||
Print-Msg -color Green -msg ("Picked {0} as default Install prefix!" -f $defaultGhcupBasePrefix)
|
|
||||||
} else {
|
|
||||||
Print-Msg -color Red -msg "Couldn't find a writable partition with at least 5GB free disk space!"
|
|
||||||
Exit 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ask for base install prefix
|
|
||||||
if ($Silent -and !($InstallDir)) {
|
|
||||||
$GhcupBasePrefix = $defaultGhcupBasePrefix
|
|
||||||
} elseif ($InstallDir) {
|
|
||||||
if (!(Test-Path -LiteralPath ('{0}' -f $InstallDir) -IsValid)) {
|
|
||||||
Print-Msg -color Red -msg "Not a valid directory!"
|
|
||||||
Exit 1
|
|
||||||
} elseif (!(Split-Path -IsAbsolute -Path "$InstallDir")) {
|
|
||||||
Print-Msg -color Red -msg "Non-absolute Path specified!"
|
|
||||||
Exit 1
|
|
||||||
} else {
|
|
||||||
$GhcupBasePrefix = $InstallDir
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ($true) {
|
|
||||||
Print-Msg -color Magenta -msg ('Where to install to (this should be a short Path, preferably a Drive like ''C:\''){1}Press enter to accept the default [{0}]:' -f $defaultGhcupBasePrefix, "`n")
|
|
||||||
$basePrefixPrompt = Read-Host
|
|
||||||
$GhcupBasePrefix = ($defaultGhcupBasePrefix,$basePrefixPrompt)[[bool]$basePrefixPrompt]
|
|
||||||
if (!($GhcupBasePrefix.EndsWith('\'))) {
|
|
||||||
$GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!($GhcupBasePrefix)) {
|
|
||||||
Print-Msg -color Red -msg "No directory specified!"
|
|
||||||
} elseif (!(Test-Path -LiteralPath ('{0}' -f $GhcupBasePrefix))) {
|
|
||||||
Print-Msg -color Red -msg "Directory does not exist, need to specify an existing Drive/Directory"
|
|
||||||
} elseif (!(Split-Path -IsAbsolute -Path "$GhcupBasePrefix")) {
|
|
||||||
Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
|
|
||||||
} else {
|
|
||||||
Break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Print-Msg -msg ('Setting env variable GHCUP_INSTALL_BASE_PREFIX to ''{0}''' -f $GhcupBasePrefix)
|
|
||||||
$null = [Environment]::SetEnvironmentVariable("GHCUP_INSTALL_BASE_PREFIX", $GhcupBasePrefix, [System.EnvironmentVariableTarget]::User)
|
|
||||||
|
|
||||||
|
|
||||||
$GhcupDir = ('{0}\ghcup' -f $GhcupBasePrefix)
|
|
||||||
$MsysDir = ('{0}\msys64' -f $GhcupDir)
|
|
||||||
$Bash = ('{0}\usr\bin\bash' -f $MsysDir)
|
|
||||||
if (!($BootstrapUrl)) {
|
|
||||||
$BootstrapUrl = 'https://www.haskell.org/ghcup/sh/bootstrap-haskell'
|
|
||||||
}
|
|
||||||
$GhcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user')
|
|
||||||
|
|
||||||
Print-Msg -msg 'Preparing for GHCup installation...'
|
|
||||||
|
|
||||||
# ask what to do in case ghcup is already installed
|
|
||||||
if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) {
|
|
||||||
Print-Msg -msg ('GHCup already installed at ''{0}''...' -f $GhcupDir)
|
|
||||||
if ($Overwrite) {
|
|
||||||
$decision = 0
|
|
||||||
} elseif (!($Silent)) {
|
|
||||||
$decision = $Host.UI.PromptForChoice('Install GHCup'
|
|
||||||
, 'GHCup is already installed, what do you want to do?'
|
|
||||||
, [System.Management.Automation.Host.ChoiceDescription[]] @('&Reinstall'
|
|
||||||
'&Continue'
|
|
||||||
'&Abort'), 1)
|
|
||||||
} else {
|
|
||||||
$decision = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($decision -eq 0) {
|
|
||||||
$suffix = [IO.Path]::GetRandomFileName()
|
|
||||||
Print-Msg -msg ('Backing up {0} to {0}-{1} ...' -f $GhcupDir, $suffix)
|
|
||||||
Rename-Item -Path ('{0}' -f $GhcupDir) -NewName ('{0}-{1}' -f $GhcupDir, $suffix)
|
|
||||||
} elseif ($decision -eq 1) {
|
|
||||||
Print-Msg -msg 'Continuing installation...'
|
|
||||||
} elseif ($decision -eq 2) {
|
|
||||||
Exit 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$null = New-Item -Path ('{0}' -f $GhcupDir) -ItemType 'directory' -ErrorAction SilentlyContinue
|
|
||||||
$null = New-Item -Path ('{0}' -f $GhcupDir) -Name 'bin' -ItemType 'directory' -ErrorAction SilentlyContinue
|
|
||||||
|
|
||||||
# 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 ($Silent) {
|
|
||||||
$msys2Decision = 0
|
|
||||||
} else {
|
|
||||||
$msys2Decision = $Host.UI.PromptForChoice('Install MSys2'
|
|
||||||
, 'Do you want GHCup to install a default MSys2 toolchain (recommended)?'
|
|
||||||
, [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes'
|
|
||||||
'&No'), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($msys2Decision -eq 0) {
|
|
||||||
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
|
|
||||||
Print-Msg -msg 'Downloading Msys2 archive...'
|
|
||||||
$archive = 'msys2-x86_64-latest.sfx.exe'
|
|
||||||
|
|
||||||
if (Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) {
|
|
||||||
Exec "curl.exe" '-o' ('{0}\{1}' -f $env:TEMP, $archive) ('https://repo.msys2.org/distrib/{0}' -f $archive)
|
|
||||||
} else {
|
|
||||||
Get-FileWCSynchronous -url ('https://repo.msys2.org/distrib/{0}' -f $archive) -destinationFolder "$env:TEMP" -includeStats
|
|
||||||
}
|
|
||||||
|
|
||||||
Print-Msg -msg 'Extracting Msys2 archive...'
|
|
||||||
$null = & "$env:TEMP\$archive" '-y' ('-o{0}' -f $GhcupDir) # Extract
|
|
||||||
Remove-Item -Path ('{0}/{1}' -f $env:TEMP, $archive)
|
|
||||||
|
|
||||||
Print-Msg -msg 'Processing MSYS2 bash for first time use...'
|
|
||||||
Exec "$Bash" '-lc' 'exit'
|
|
||||||
|
|
||||||
Exec "$env:windir\system32\taskkill.exe" /F /FI `"MODULES eq msys-2.0.dll`"
|
|
||||||
|
|
||||||
Print-Msg -msg 'Upgrading full system...'
|
|
||||||
Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu'
|
|
||||||
|
|
||||||
Print-Msg -msg 'Upgrading full system twice...'
|
|
||||||
Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu'
|
|
||||||
|
|
||||||
Print-Msg -msg 'Installing Dependencies...'
|
|
||||||
Exec "$Bash" '-lc' 'pacman --noconfirm -S --needed curl mingw-w64-x86_64-pkgconf'
|
|
||||||
|
|
||||||
Print-Msg -msg 'Updating SSL root certificate authorities...'
|
|
||||||
Exec "$Bash" '-lc' 'pacman --noconfirm -S ca-certificates'
|
|
||||||
|
|
||||||
Print-Msg -msg 'Setting default home directory...'
|
|
||||||
Exec "$Bash" '-lc' "sed -i -e 's/db_home:.*$/db_home: windows/' /etc/nsswitch.conf"
|
|
||||||
} elseif ($msys2Decision -eq 1) {
|
|
||||||
Print-Msg -color Yellow -msg 'Skipping MSys2 installation.'
|
|
||||||
while ($true) {
|
|
||||||
if ($GhcupMsys2) {
|
|
||||||
$defaultMsys2Dir = $GhcupMsys2
|
|
||||||
Print-Msg -color Magenta -msg ('Input existing MSys2 toolchain directory. Press enter to accept the default [{0}]:' -f $defaultMsys2Dir)
|
|
||||||
$MsysDirPrompt = Read-Host
|
|
||||||
$MsysDir = ($defaultMsys2Dir,$MsysDirPrompt)[[bool]$MsysDirPrompt]
|
|
||||||
} else {
|
|
||||||
Print-Msg -color Magenta -msg 'Input existing MSys2 toolchain directory:'
|
|
||||||
$MsysDir = Read-Host
|
|
||||||
}
|
|
||||||
if (!($MsysDir)) {
|
|
||||||
Print-Msg -color Red -msg "No directory specified!"
|
|
||||||
} elseif (!(Test-Path -LiteralPath ('{0}' -f $MsysDir))) {
|
|
||||||
Print-Msg -color Red -msg ('MSys2 installation at ''{0}'' could not be found!' -f $MsysDir)
|
|
||||||
} elseif (!(Split-Path -IsAbsolute -Path "$MsysDir")) {
|
|
||||||
Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
|
|
||||||
} else {
|
|
||||||
Break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Print-Msg -msg ('Setting GHCUP_MSYS2 env var to ''{0}''' -f $MsysDir)
|
|
||||||
$null = [Environment]::SetEnvironmentVariable("GHCUP_MSYS2", $MsysDir, [System.EnvironmentVariableTarget]::User)
|
|
||||||
$Bash = ('{0}\usr\bin\bash' -f $MsysDir)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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...'
|
|
||||||
$DesktopDir = [Environment]::GetFolderPath("Desktop")
|
|
||||||
$GhcInstArgs = '-mingw64 -mintty -c "pacman --noconfirm -S --needed base-devel gettext autoconf make libtool automake python p7zip patch unzip"'
|
|
||||||
Create-Shortcut -SourceExe ('{0}\msys2_shell.cmd' -f $MsysDir) -ArgumentsToSourceExe $GhcInstArgs -DestinationPath ('{0}\Install GHC dev dependencies.lnk' -f $DesktopDir)
|
|
||||||
Create-Shortcut -SourceExe ('{0}\msys2_shell.cmd' -f $MsysDir) -ArgumentsToSourceExe '-mingw64' -DestinationPath ('{0}\Mingw haskell shell.lnk' -f $DesktopDir)
|
|
||||||
Create-Shortcut -SourceExe 'https://www.msys2.org/docs/package-management' -ArgumentsToSourceExe '' -DestinationPath ('{0}\Mingw package management docs.url' -f $DesktopDir)
|
|
||||||
|
|
||||||
Print-Msg -msg ('Adding {0}\bin to Users Path...' -f $GhcupDir)
|
|
||||||
Add-EnvPath -Path ('{0}\bin' -f ([System.IO.Path]::GetFullPath("$GhcupDir"))) -Container 'User'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$CabalDirFull = [System.IO.Path]::GetFullPath("$CabDirEnv")
|
|
||||||
Print-Msg -msg ('Setting CABAL_DIR to ''{0}''' -f $CabalDirFull)
|
|
||||||
$null = [Environment]::SetEnvironmentVariable("CABAL_DIR", $CabalDirFull, [System.EnvironmentVariableTarget]::User)
|
|
||||||
|
|
||||||
Print-Msg -msg 'Starting GHCup installer...'
|
|
||||||
|
|
||||||
$Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir)
|
|
||||||
|
|
||||||
# The bootstrap script is always silent, since we ask relevant questions here
|
|
||||||
$SilentExport = 'export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 ;'
|
|
||||||
|
|
||||||
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) {
|
|
||||||
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 {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# SIG # Begin signature block
|
|
||||||
# MIID4QYJKoZIhvcNAQcCoIID0jCCA84CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
|
|
||||||
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
|
|
||||||
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUVqKek181kF/Jx/P7z176herc
|
|
||||||
# ZyCgggH/MIIB+zCCAWSgAwIBAgIQGOezhGS1A5tHh9VubW0liDANBgkqhkiG9w0B
|
|
||||||
# AQUFADAYMRYwFAYDVQQDDA1KdWxpYW4gT3NwYWxkMB4XDTIxMDUzMDE4Mzk1OVoX
|
|
||||||
# DTI1MDUzMDAwMDAwMFowGDEWMBQGA1UEAwwNSnVsaWFuIE9zcGFsZDCBnzANBgkq
|
|
||||||
# hkiG9w0BAQEFAAOBjQAwgYkCgYEAs76XCXYPM14buR1RkVKhOB8pyM4Df6kPaz75
|
|
||||||
# nkbA0nq1VmMhBfCYFWyYHd7jniqTH0LoAKGGquN1bniREaCP9j2pFWpMIgLpQH3H
|
|
||||||
# +jpsfmxV2BTG8q+Jok88gTXS1FlAk72E85zO/Jhr6Fja1aFYAdibBRsRxcVMTVh7
|
|
||||||
# 4AGLNGUCAwEAAaNGMEQwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFC+R
|
|
||||||
# hdhPo0Ty5HnzHyo1pN35IfZQMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUF
|
|
||||||
# AAOBgQAl3IdBVIwbJJDp7BksMYPeM4ivB3UyNvlw8aVxGwAzNgdSaezYIdMFtKXV
|
|
||||||
# CSv5bd4VnFRAPDJW9dhW0h3SkeJUoklUxMjKXhR3qygQhSxPDjIatAuOCffGACba
|
|
||||||
# ZZ7Om40b+pKXc6i/HnlApk9DGbXJ59bFcLGGcZ9QjoUae6Ex1DGCAUwwggFIAgEB
|
|
||||||
# MCwwGDEWMBQGA1UEAwwNSnVsaWFuIE9zcGFsZAIQGOezhGS1A5tHh9VubW0liDAJ
|
|
||||||
# BgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0B
|
|
||||||
# CQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAj
|
|
||||||
# BgkqhkiG9w0BCQQxFgQUosm9nN1JgajqSBa1cUwxxhLrAsYwDQYJKoZIhvcNAQEB
|
|
||||||
# BQAEgYCnKzfsH1aDjS6xkC/uymjaBowHSnh6nFu2AkjcKu8RgcBZzP5SLBXgU9wm
|
|
||||||
# aED5Ujwyq3Qre+TGVRUqwkEauDhQiX2A008G00fRO6+di6yJRCRn5eaRAbdU3Xww
|
|
||||||
# E5VhEwLBnwzWrvLKtdEclhgUCo5Tq87QMXVdgX4aRmunl4ZE+Q==
|
|
||||||
# SIG # End signature block
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
20
cabal.ghc8104.project
Normal file
20
cabal.ghc8104.project
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
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.HsOpenSSL ==0.11.7,
|
any.IfElse ==0.85,
|
||||||
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,
|
||||||
@@ -17,32 +18,31 @@ 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.2.0,
|
any.base ==4.14.1.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.1.0.0,
|
any.base64-bytestring ==1.2.0.1,
|
||||||
any.bifunctors ==5.5.11,
|
any.bifunctors ==5.5.10,
|
||||||
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.bzlib-conduit ==0.3.0.2,
|
any.c2hs ==0.28.7,
|
||||||
any.c2hs ==0.28.8,
|
|
||||||
c2hs +base3 -regression,
|
c2hs +base3 -regression,
|
||||||
any.call-stack ==0.4.0,
|
any.call-stack ==0.3.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.6,
|
any.colour ==2.3.5,
|
||||||
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,25 +62,16 @@ 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.conduit-zstd ==0.0.2.0,
|
any.containers ==0.6.2.1,
|
||||||
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.digest ==0.0.1.3,
|
any.deferred-folds ==0.9.17,
|
||||||
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,
|
||||||
@@ -88,55 +79,62 @@ 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.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.free ==5.1.7,
|
any.focus ==1.0.2,
|
||||||
|
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.5,
|
any.ghc-boot-th ==8.10.4,
|
||||||
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.2.0,
|
any.hashable ==1.3.1.0,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable +integer-gmp,
|
||||||
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-posix ==0.13.3,
|
any.hpath-io ==0.14.1,
|
||||||
|
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.10,
|
any.hspec ==2.7.8,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.7.8,
|
||||||
any.hspec-discover ==2.7.10,
|
any.hspec-discover ==2.7.8,
|
||||||
any.hspec-expectations ==0.8.2,
|
any.hspec-expectations ==0.8.2,
|
||||||
any.hspec-golden-aeson ==0.9.0.0,
|
any.hspec-golden-aeson ==0.7.0.0,
|
||||||
any.http-io-streams ==0.1.6.0,
|
any.indexed-profunctors ==0.1,
|
||||||
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.io-streams ==1.5.2.1,
|
any.language-c ==0.8.3,
|
||||||
io-streams +network -nointeractivetests +zlib,
|
language-c -allwarnings +iecfpextension +separatesyb +usebytestrings,
|
||||||
any.language-c ==0.9.0.1,
|
any.libarchive ==3.0.2.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.lzma-static ==5.2.5.4,
|
any.list-t ==1.0.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.10,
|
any.microlens-th ==0.4.3.9,
|
||||||
|
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,
|
||||||
@@ -144,12 +142,11 @@ 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.network ==3.1.2.2,
|
any.mwc-random ==0.15.0.1,
|
||||||
|
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,
|
||||||
@@ -164,25 +161,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.1,
|
any.recursion-schemes ==5.2.2,
|
||||||
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.1,
|
any.rts ==1.0,
|
||||||
any.safe ==0.3.19,
|
any.safe ==0.3.19,
|
||||||
any.safe-exceptions ==0.1.7.2,
|
any.safe-exceptions ==0.1.7.1,
|
||||||
any.scientific ==0.3.7.0,
|
any.scientific ==0.3.6.2,
|
||||||
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,
|
||||||
@@ -191,31 +188,36 @@ 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.1,
|
any.stm ==2.5.0.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.1,
|
any.string-interpolate ==0.3.1.0,
|
||||||
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.tar ==0.6.0.0,
|
any.tasty ==1.3.1,
|
||||||
|
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-zipper ==0.11,
|
any.text-short ==0.1.3,
|
||||||
|
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.2,
|
any.th-compat ==0.1.1,
|
||||||
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,
|
||||||
@@ -223,7 +225,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.6,
|
any.time-compat ==1.9.5,
|
||||||
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,
|
||||||
@@ -231,34 +233,29 @@ 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.14.0,
|
any.unordered-containers ==0.2.13.0,
|
||||||
unordered-containers -debug,
|
unordered-containers -debug,
|
||||||
any.uri-bytestring ==0.3.3.1,
|
any.uri-bytestring ==0.3.3.0,
|
||||||
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.5,
|
any.uuid-types ==1.0.4,
|
||||||
any.vector ==0.12.3.0,
|
any.vector ==0.12.2.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 ==5.0.0,
|
any.versions ==4.0.3,
|
||||||
any.vty ==5.33,
|
any.vty ==5.33,
|
||||||
any.word-wrap ==0.4.1,
|
any.wcwidth ==0.0.2,
|
||||||
|
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,
|
||||||
any.zip ==1.7.1,
|
zlib -non-blocking-ffi -pkg-config -static
|
||||||
zip -dev -disable-bzip2 -disable-zstd,
|
index-state: hackage.haskell.org 2021-03-07T18:36:25Z
|
||||||
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
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
packages: ./ghcup.cabal
|
|
||||||
|
|
||||||
optional-packages: ./vendored/*/*.cabal
|
|
||||||
|
|
||||||
optimization: 2
|
|
||||||
|
|
||||||
package ghcup
|
|
||||||
tests: True
|
|
||||||
flags: +tui
|
|
||||||
|
|
||||||
source-repository-package
|
|
||||||
type: git
|
|
||||||
location: https://github.com/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
|
|
||||||
20
cabal.ghc884.project
Normal file
20
cabal.ghc884.project
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
active-repositories: hackage.haskell.org:merge
|
active-repositories: hackage.haskell.org:merge
|
||||||
constraints: any.Cabal ==3.4.0.0,
|
constraints: any.Cabal ==3.0.1.0,
|
||||||
any.HUnit ==1.6.2.0,
|
any.HUnit ==1.6.2.0,
|
||||||
any.HsOpenSSL ==0.11.7,
|
any.IfElse ==0.85,
|
||||||
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,
|
||||||
@@ -17,32 +18,31 @@ constraints: any.Cabal ==3.4.0.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.15.0.0,
|
any.base ==4.13.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.1.0.0,
|
any.base64-bytestring ==1.2.0.1,
|
||||||
any.bifunctors ==5.5.11,
|
any.bifunctors ==5.5.10,
|
||||||
bifunctors +semigroups +tagged,
|
bifunctors +semigroups +tagged,
|
||||||
any.binary ==0.8.8.0,
|
any.binary ==0.8.7.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,
|
any.bytestring ==0.10.10.1,
|
||||||
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.bzlib-conduit ==0.3.0.2,
|
any.c2hs ==0.28.7,
|
||||||
any.c2hs ==0.28.8,
|
|
||||||
c2hs +base3 -regression,
|
c2hs +base3 -regression,
|
||||||
any.call-stack ==0.4.0,
|
any.call-stack ==0.3.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.4.0.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.6,
|
any.colour ==2.3.5,
|
||||||
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,25 +62,16 @@ constraints: any.Cabal ==3.4.0.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.conduit-zstd ==0.0.2.0,
|
any.containers ==0.6.2.1,
|
||||||
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.5.0,
|
any.deepseq ==1.4.4.0,
|
||||||
any.digest ==0.0.1.3,
|
any.deferred-folds ==0.9.17,
|
||||||
digest -bytestring-in-base,
|
any.directory ==1.3.6.0,
|
||||||
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,
|
||||||
@@ -88,55 +79,63 @@ constraints: any.Cabal ==3.4.0.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.extra ==1.7.9,
|
exceptions +transformers-0-4,
|
||||||
any.fast-logger ==3.0.5,
|
any.fast-logger ==3.0.3,
|
||||||
any.filepath ==1.4.2.1,
|
any.filepath ==1.4.2.1,
|
||||||
any.free ==5.1.7,
|
any.focus ==1.0.2,
|
||||||
|
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-bignum ==1.0,
|
any.ghc-boot-th ==8.8.4,
|
||||||
any.ghc-boot-th ==9.0.1,
|
any.ghc-prim ==0.5.3,
|
||||||
any.ghc-byteorder ==4.11.0.0.10,
|
ghcup -internal-downloader -tar -tui,
|
||||||
any.ghc-prim ==0.7.0,
|
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.3.2.0,
|
any.hashable ==1.3.1.0,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable +integer-gmp,
|
||||||
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-posix ==0.13.3,
|
any.hpath-io ==0.14.1,
|
||||||
|
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.10,
|
any.hspec ==2.7.8,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.7.8,
|
||||||
any.hspec-discover ==2.7.10,
|
any.hspec-discover ==2.7.8,
|
||||||
any.hspec-expectations ==0.8.2,
|
any.hspec-expectations ==0.8.2,
|
||||||
any.hspec-golden-aeson ==0.9.0.0,
|
any.hspec-golden-aeson ==0.7.0.0,
|
||||||
any.http-io-streams ==0.1.6.0,
|
any.indexed-profunctors ==0.1,
|
||||||
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.io-streams ==1.5.2.1,
|
any.language-c ==0.8.3,
|
||||||
io-streams +network -nointeractivetests +zlib,
|
language-c -allwarnings +iecfpextension +separatesyb +usebytestrings,
|
||||||
any.language-c ==0.9.0.1,
|
any.libarchive ==3.0.2.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.lzma-static ==5.2.5.4,
|
any.list-t ==1.0.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.10,
|
any.microlens-th ==0.4.3.9,
|
||||||
|
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,
|
||||||
@@ -144,12 +143,11 @@ constraints: any.Cabal ==3.4.0.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.network ==3.1.2.2,
|
any.mwc-random ==0.15.0.1,
|
||||||
|
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,
|
||||||
@@ -164,25 +162,25 @@ constraints: any.Cabal ==3.4.0.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.process ==1.6.11.0,
|
any.primitive-extras ==0.8.2,
|
||||||
|
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.1,
|
any.recursion-schemes ==5.2.2,
|
||||||
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.2,
|
any.safe-exceptions ==0.1.7.1,
|
||||||
any.scientific ==0.3.7.0,
|
any.scientific ==0.3.6.2,
|
||||||
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,
|
||||||
@@ -195,27 +193,32 @@ constraints: any.Cabal ==3.4.0.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.1,
|
any.string-interpolate ==0.3.1.0,
|
||||||
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.tar ==0.6.0.0,
|
any.tasty ==1.3.1,
|
||||||
any.template-haskell ==2.17.0.0,
|
tasty +clock,
|
||||||
any.temporary ==1.3,
|
any.tasty-hunit ==0.10.0.3,
|
||||||
any.terminal-progress-bar ==0.4.1,
|
any.tasty-quickcheck ==0.10.1.2,
|
||||||
|
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.1,
|
any.text ==1.2.4.0,
|
||||||
any.text-conversions ==0.3.1,
|
any.text-conversions ==0.3.1,
|
||||||
any.text-zipper ==0.11,
|
any.text-short ==0.1.3,
|
||||||
|
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.2,
|
any.th-compat ==0.1.1,
|
||||||
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,
|
||||||
@@ -223,7 +226,7 @@ constraints: any.Cabal ==3.4.0.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.6,
|
any.time-compat ==1.9.5,
|
||||||
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,
|
||||||
@@ -231,34 +234,29 @@ constraints: any.Cabal ==3.4.0.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.14.0,
|
any.unordered-containers ==0.2.13.0,
|
||||||
unordered-containers -debug,
|
unordered-containers -debug,
|
||||||
any.uri-bytestring ==0.3.3.1,
|
any.uri-bytestring ==0.3.3.0,
|
||||||
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.5,
|
any.uuid-types ==1.0.4,
|
||||||
any.vector ==0.12.3.0,
|
any.vector ==0.12.2.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 ==5.0.0,
|
any.versions ==4.0.3,
|
||||||
any.vty ==5.33,
|
any.vty ==5.33,
|
||||||
any.word-wrap ==0.4.1,
|
any.wcwidth ==0.0.2,
|
||||||
|
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,
|
||||||
any.zip ==1.7.1,
|
zlib -non-blocking-ffi -pkg-config -static
|
||||||
zip -dev -disable-bzip2 -disable-zstd,
|
index-state: hackage.haskell.org 2021-03-07T18:36:25Z
|
||||||
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
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
packages: ./ghcup.cabal
|
|
||||||
|
|
||||||
optional-packages: ./vendored/*/*.cabal
|
|
||||||
|
|
||||||
optimization: 2
|
|
||||||
|
|
||||||
package ghcup
|
|
||||||
tests: True
|
|
||||||
flags: +tui
|
|
||||||
|
|
||||||
source-repository-package
|
|
||||||
type: git
|
|
||||||
location: https://github.com/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
|
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
packages: ./ghcup.cabal
|
packages: ./ghcup.cabal
|
||||||
|
|
||||||
optional-packages: ./vendored/*/*.cabal
|
|
||||||
|
|
||||||
optimization: 2
|
optimization: 2
|
||||||
|
|
||||||
|
package streamly
|
||||||
|
ghc-options: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
|
||||||
|
|
||||||
package ghcup
|
package ghcup
|
||||||
|
ghc-options: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
|
||||||
tests: True
|
tests: True
|
||||||
flags: +tui
|
flags: +tui
|
||||||
|
|
||||||
@@ -13,14 +15,9 @@ source-repository-package
|
|||||||
location: https://github.com/Bodigrim/tar
|
location: https://github.com/Bodigrim/tar
|
||||||
tag: ac197ec7ea4838dc2b4e22b9b888b080cedf29cf
|
tag: ac197ec7ea4838dc2b4e22b9b888b080cedf29cf
|
||||||
|
|
||||||
source-repository-package
|
|
||||||
type: git
|
|
||||||
location: https://github.com/bgamari/terminal-size
|
|
||||||
tag: 34ea816bd63f75f800eedac12c6908c6f3736036
|
|
||||||
|
|
||||||
constraints: http-io-streams -brotli
|
constraints: http-io-streams -brotli
|
||||||
|
|
||||||
package libarchive
|
package libarchive
|
||||||
flags: -system-libarchive
|
flags: -system-libarchive
|
||||||
|
|
||||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
allow-newer: base, ghc-prim, template-haskell
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
-- windows picks weird version
|
|
||||||
constraints: any.hsc2hs ==0.68.7
|
|
||||||
317
ghcup-0.0.4.yaml
317
ghcup-0.0.4.yaml
@@ -170,6 +170,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-portbld-freebsd.tar.bz2
|
dlUri: https://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-portbld-freebsd.tar.bz2
|
||||||
dlSubdir: ghc-7.10.3
|
dlSubdir: ghc-7.10.3
|
||||||
dlHash: 2aa396edd2bb651f4bc7eef7a396913ea24923de5aafdc76df6295333e487e48
|
dlHash: 2aa396edd2bb651f4bc7eef7a396913ea24923de5aafdc76df6295333e487e48
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-7.10.3
|
||||||
|
dlHash: 63e1689fc9e2809ae4d7f422b4dc810052e54c9aa2afd08746e234180e711dde
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-7103-32-deb8
|
unknown_versioning: &ghc-7103-32-deb8
|
||||||
@@ -236,6 +241,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.0.2
|
dlSubdir: ghc-8.0.2
|
||||||
dlHash: b36a20e5cae24d70bbb6116ae486f21811e9384f15d3892d260f02fba3e3bb8c
|
dlHash: b36a20e5cae24d70bbb6116ae486f21811e9384f15d3892d260f02fba3e3bb8c
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.0.2
|
||||||
|
dlHash: 8c42c1f4af995205b9816a1e97e2752fe758544c1f5fe77958cdcd319c9c2d53
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
'( >= 7 && < 8 )':
|
'( >= 7 && < 8 )':
|
||||||
@@ -300,6 +310,11 @@ ghcupDownloads:
|
|||||||
dlSubdir: ghc-8.2.2
|
dlSubdir: ghc-8.2.2
|
||||||
dlHash: cd351c704b92b9af23994024df07de8ca7090ea7675d5c8b14b2be857a46d804
|
dlHash: cd351c704b92b9af23994024df07de8ca7090ea7675d5c8b14b2be857a46d804
|
||||||
unknown_versioning: *ghc-822-64-fbsd11
|
unknown_versioning: *ghc-822-64-fbsd11
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.2.2/ghc-8.2.2-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.2.2
|
||||||
|
dlHash: 1e033df2092aa546e763e7be63167720b32df64f76673ea1ce7ae7c9f564b223
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
'( >= 7 && < 8 )':
|
'( >= 7 && < 8 )':
|
||||||
@@ -359,6 +374,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.4.1/ghc-8.4.1-x86_64-portbld11-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.4.1/ghc-8.4.1-x86_64-portbld11-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.4.1
|
dlSubdir: ghc-8.4.1
|
||||||
dlHash: e748daec098445c6190090fe32bb2817a1140553be5acd2188e1af05ad24e5aa
|
dlHash: e748daec098445c6190090fe32bb2817a1140553be5acd2188e1af05ad24e5aa
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.4.1/ghc-8.4.1-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.4.1
|
||||||
|
dlHash: 328b013fc651d34e075019107e58bb6c8a578f0155cf3ad4557e6f2661b03131
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-841-32-deb8
|
unknown_versioning: &ghc-841-32-deb8
|
||||||
@@ -414,6 +434,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.4.2/ghc-8.4.2-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.4.2/ghc-8.4.2-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.4.2
|
dlSubdir: ghc-8.4.2
|
||||||
dlHash: e9ed417fdf94c2ff2c6e344ed16f332bf6b591511f6442c0d9ea94854882b66c
|
dlHash: e9ed417fdf94c2ff2c6e344ed16f332bf6b591511f6442c0d9ea94854882b66c
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.4.2/ghc-8.4.2-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.4.2
|
||||||
|
dlHash: 797634aa9812fc6b2084a24ddb4fde44fa83a2f59daea82e0af81ca3dd323fde
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-842-32-deb8
|
unknown_versioning: &ghc-842-32-deb8
|
||||||
@@ -464,6 +489,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.4.3/ghc-8.4.3-x86_64-apple-darwin.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.4.3/ghc-8.4.3-x86_64-apple-darwin.tar.xz
|
||||||
dlSubdir: ghc-8.4.3
|
dlSubdir: ghc-8.4.3
|
||||||
dlHash: af0b455f6c46b9802b4b48dad996619cfa27cc6e2bf2ce5532387b4a8c00aa64
|
dlHash: af0b455f6c46b9802b4b48dad996619cfa27cc6e2bf2ce5532387b4a8c00aa64
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.4.3/ghc-8.4.3-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.4.3
|
||||||
|
dlHash: 8a83cfbf9ae84de0443c39c93b931693bdf2a6d4bf163ffb41855f80f4bf883e
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-843-32-deb8
|
unknown_versioning: &ghc-843-32-deb8
|
||||||
@@ -532,6 +562,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.4.4/ghc-8.4.4-x86_64-portbld-freebsd11.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.4.4/ghc-8.4.4-x86_64-portbld-freebsd11.tar.xz
|
||||||
dlSubdir: ghc-8.4.4
|
dlSubdir: ghc-8.4.4
|
||||||
dlHash: 44fbd142d1c355d6110595c59c760e2c73866ff9259ec85ebf814edb244d1940
|
dlHash: 44fbd142d1c355d6110595c59c760e2c73866ff9259ec85ebf814edb244d1940
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.4.4/ghc-8.4.4-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.4.4
|
||||||
|
dlHash: da29dbb0f1199611c7d5bb7b0dd6a7426ca98f67dfd6da1526b033cd3830dc05
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-844-32-deb8
|
unknown_versioning: &ghc-844-32-deb8
|
||||||
@@ -592,6 +627,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.6.1/ghc-8.6.1-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.6.1/ghc-8.6.1-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.6.1
|
dlSubdir: ghc-8.6.1
|
||||||
dlHash: 51403b054a3a649039ac988e1d1112561f96750bfced63df864091a3fab36f08
|
dlHash: 51403b054a3a649039ac988e1d1112561f96750bfced63df864091a3fab36f08
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.6.1/ghc-8.6.1-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.6.1
|
||||||
|
dlHash: 7316d9cb5e486460476754f872c7bac30ee2082e42f46da4342f872d10b88099
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-861-32-deb8
|
unknown_versioning: &ghc-861-32-deb8
|
||||||
@@ -638,6 +678,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.6.2/ghc-8.6.2-x86_64-apple-darwin.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.6.2/ghc-8.6.2-x86_64-apple-darwin.tar.xz
|
||||||
dlSubdir: ghc-8.6.2
|
dlSubdir: ghc-8.6.2
|
||||||
dlHash: 8ec46a25872226dd7e5cf7271e3f3450c05f32144b96e6b9cb44cc4079db50dc
|
dlHash: 8ec46a25872226dd7e5cf7271e3f3450c05f32144b96e6b9cb44cc4079db50dc
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.6.2/ghc-8.6.2-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.6.2
|
||||||
|
dlHash: 9a398e133cab09ff2610834337355d4e26c35e0665403fb9ff8db79315f74d3d
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-862-32-deb8
|
unknown_versioning: &ghc-862-32-deb8
|
||||||
@@ -702,6 +747,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.6.3/ghc-8.6.3-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.6.3/ghc-8.6.3-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.6.3
|
dlSubdir: ghc-8.6.3
|
||||||
dlHash: bc2419fa180f8a7808c49775987866435995df9bdd9ce08bcd38352d63ba6031
|
dlHash: bc2419fa180f8a7808c49775987866435995df9bdd9ce08bcd38352d63ba6031
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.6.3/ghc-8.6.3-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.6.3
|
||||||
|
dlHash: 2fec383904e5fa79413e9afd328faf9bc700006c8c3d4bcdd8d4f2ccf0f7fa2a
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-863-32-deb8
|
unknown_versioning: &ghc-863-32-deb8
|
||||||
@@ -752,6 +802,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.6.4/ghc-8.6.4-x86_64-apple-darwin.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.6.4/ghc-8.6.4-x86_64-apple-darwin.tar.xz
|
||||||
dlSubdir: ghc-8.6.4
|
dlSubdir: ghc-8.6.4
|
||||||
dlHash: cccb58f142fe41b601d73690809f6089f7715b6a50a09aa3d0104176ab4db09e
|
dlHash: cccb58f142fe41b601d73690809f6089f7715b6a50a09aa3d0104176ab4db09e
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.6.4/ghc-8.6.4-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.6.4
|
||||||
|
dlHash: e8d021b7a90772fc559862079da20538498d991956d7557b468ca19ddda22a08
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-864-32-deb9
|
unknown_versioning: &ghc-864-32-deb9
|
||||||
@@ -820,6 +875,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/ghc/8.6.5/ghc-8.6.5-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/ghc/8.6.5/ghc-8.6.5-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.6.5
|
dlSubdir: ghc-8.6.5
|
||||||
dlHash: 83a3059a630d40a98e26cb5b520354e12094a96e36ba2f5ab002dad94cf2fb37
|
dlHash: 83a3059a630d40a98e26cb5b520354e12094a96e36ba2f5ab002dad94cf2fb37
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.6.5/ghc-8.6.5-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.6.5
|
||||||
|
dlHash: 457024c6ea43bdce340af428d86319931f267089398b859b00efdfe2fd4ce93f
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-865-32-deb9
|
unknown_versioning: &ghc-865-32-deb9
|
||||||
@@ -890,6 +950,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.8.1/ghc-8.8.1-x86_64-apple-darwin.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.8.1/ghc-8.8.1-x86_64-apple-darwin.tar.xz
|
||||||
dlSubdir: ghc-8.8.1
|
dlSubdir: ghc-8.8.1
|
||||||
dlHash: 38c8917b47c31bedf58c9305dfca3abe198d8d35570366f0773c4e2948bd8abe
|
dlHash: 38c8917b47c31bedf58c9305dfca3abe198d8d35570366f0773c4e2948bd8abe
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.8.1/ghc-8.8.1-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.8.1
|
||||||
|
dlHash: 29e56e6af38017a5a76b2b6995a39d3988fa58131e4b55b62dd317ba7186ac9b
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-881-32-deb9
|
unknown_versioning: &ghc-881-32-deb9
|
||||||
@@ -949,6 +1014,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.8.2/ghc-8.8.2-x86_64-apple-darwin.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.8.2/ghc-8.8.2-x86_64-apple-darwin.tar.xz
|
||||||
dlSubdir: ghc-8.8.2
|
dlSubdir: ghc-8.8.2
|
||||||
dlHash: 25c5c1a70036abf3f22b2b19c10d26adfdb08e8f8574f89d4b2042de5947f990
|
dlHash: 25c5c1a70036abf3f22b2b19c10d26adfdb08e8f8574f89d4b2042de5947f990
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.8.2/ghc-8.8.2-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.8.2
|
||||||
|
dlHash: e25d9b16ee62cafc7387af2cd021eea676a99cd2c32b83533b016162c63065d9
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-882-32-deb9
|
unknown_versioning: &ghc-882-32-deb9
|
||||||
@@ -1013,6 +1083,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/ghc/8.8.3/ghc-8.8.3-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/ghc/8.8.3/ghc-8.8.3-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.8.3
|
dlSubdir: ghc-8.8.3
|
||||||
dlHash: 569719075b4d14b3875a899df522090ae31e6fe085e6dffe518e875b09a2f0be
|
dlHash: 569719075b4d14b3875a899df522090ae31e6fe085e6dffe518e875b09a2f0be
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.8.3/ghc-8.8.3-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.8.3
|
||||||
|
dlHash: e22586762af0911c06e8140f1792e3ca381a3a482a20d67b9054883038b3a422
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-883-32-deb9
|
unknown_versioning: &ghc-883-32-deb9
|
||||||
@@ -1087,6 +1162,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/ghc/8.8.4/ghc-8.8.4-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/ghc/8.8.4/ghc-8.8.4-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.8.4
|
dlSubdir: ghc-8.8.4
|
||||||
dlHash: 8cebe5ccf454e82acd1ff52ca57590d1ab0f3f44a981b46257ec12158c8c447e
|
dlHash: 8cebe5ccf454e82acd1ff52ca57590d1ab0f3f44a981b46257ec12158c8c447e
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.8.4/ghc-8.8.4-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.8.4
|
||||||
|
dlHash: d185055d2c8dc3bfe5b88afd59d6877eb1e722b672d1c9649f18296e148ed71f
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
unknown_versioning: &ghc-884-32-deb9
|
unknown_versioning: &ghc-884-32-deb9
|
||||||
@@ -1164,6 +1244,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/ghc/8.10.1/ghc-8.10.1-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/ghc/8.10.1/ghc-8.10.1-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.10.1
|
dlSubdir: ghc-8.10.1
|
||||||
dlHash: e8646ec9b60fd40aa9505ee055f22f04601290ab7a1342c2cf37c34de9d3f142
|
dlHash: e8646ec9b60fd40aa9505ee055f22f04601290ab7a1342c2cf37c34de9d3f142
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.10.1/ghc-8.10.1-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.10.1
|
||||||
|
dlHash: 38a3166ea50cccd5bae7e1680eae3aae2b4ae31b61f82a1d8168fb821f43bd67
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
'( >= 9 && < 10 )': &ghc-8101-32-deb9
|
'( >= 9 && < 10 )': &ghc-8101-32-deb9
|
||||||
@@ -1254,6 +1339,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.2/ghc-8.10.2-x86_64-unknown-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.10.2/ghc-8.10.2-x86_64-unknown-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.10.2
|
dlSubdir: ghc-8.10.2
|
||||||
dlHash: 9e5957f3497f4b58ecd3699568d9caaa11a47a6d7e902032c261e450fa0f6686
|
dlHash: 9e5957f3497f4b58ecd3699568d9caaa11a47a6d7e902032c261e450fa0f6686
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.10.2/ghc-8.10.2-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.10.2
|
||||||
|
dlHash: dcae4c173b9896e07ff048de5509aa0a4537233150e06e5ce8848303dfadc176
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
'( >= 9 && < 10 )': &ghc-8102-32-deb9
|
'( >= 9 && < 10 )': &ghc-8102-32-deb9
|
||||||
@@ -1286,7 +1376,6 @@ ghcupDownloads:
|
|||||||
dlHash: bb9c97826b1f4d7a8ef8bce0616b612f1ded10480ef10fcf7fb4e6d10a6681c8
|
dlHash: bb9c97826b1f4d7a8ef8bce0616b612f1ded10480ef10fcf7fb4e6d10a6681c8
|
||||||
8.10.3:
|
8.10.3:
|
||||||
viTags:
|
viTags:
|
||||||
- old
|
|
||||||
- base-4.14.1.0
|
- base-4.14.1.0
|
||||||
viChangeLog: https://downloads.haskell.org/~ghc/8.10.3/docs/html/users_guide/8.10.3-notes.html
|
viChangeLog: https://downloads.haskell.org/~ghc/8.10.3/docs/html/users_guide/8.10.3-notes.html
|
||||||
viSourceDL:
|
viSourceDL:
|
||||||
@@ -1344,6 +1433,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.3/ghc-8.10.3-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.10.3/ghc-8.10.3-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.10.3
|
dlSubdir: ghc-8.10.3
|
||||||
dlHash: 749007e995104db05cf6e3ad5bc36238cab8afac8055145661e5730e8f8af040
|
dlHash: 749007e995104db05cf6e3ad5bc36238cab8afac8055145661e5730e8f8af040
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.10.3/ghc-8.10.3-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.10.3
|
||||||
|
dlHash: 927a6c699533a115cd49772ef2c753d9af2c13bf9f0b2d3bd13645cc6a144ee3
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
'( >= 9 && < 10 )': &ghc-8103-32-deb9
|
'( >= 9 && < 10 )': &ghc-8103-32-deb9
|
||||||
@@ -1376,6 +1470,7 @@ ghcupDownloads:
|
|||||||
dlHash: b823b58cae36fbac0741680ca7605180fa4cf4c6ae439123d282184b94d32fd6
|
dlHash: b823b58cae36fbac0741680ca7605180fa4cf4c6ae439123d282184b94d32fd6
|
||||||
8.10.4:
|
8.10.4:
|
||||||
viTags:
|
viTags:
|
||||||
|
- Recommended
|
||||||
- base-4.14.1.0
|
- base-4.14.1.0
|
||||||
viChangeLog: https://downloads.haskell.org/~ghc/8.10.4/docs/html/users_guide/8.10.4-notes.html
|
viChangeLog: https://downloads.haskell.org/~ghc/8.10.4/docs/html/users_guide/8.10.4-notes.html
|
||||||
viSourceDL:
|
viSourceDL:
|
||||||
@@ -1383,7 +1478,7 @@ ghcupDownloads:
|
|||||||
dlSubdir: ghc-8.10.4
|
dlSubdir: ghc-8.10.4
|
||||||
dlHash: 52af871b4e08550257d720c2944ac85727d0b948407cef1bebfe7508c224910e
|
dlHash: 52af871b4e08550257d720c2944ac85727d0b948407cef1bebfe7508c224910e
|
||||||
viPostRemove: *ghc-post-remove
|
viPostRemove: *ghc-post-remove
|
||||||
viPreCompile: &ghc-pre-compile "If you have autoconf >= 2.70 you'll need this patch https://gitlab.haskell.org/ghc/ghc/-/snippets/2040 (see the --patchdir option)"
|
viPreCompile: "If you have autoconf >= 2.70 you'll need this patch https://gitlab.haskell.org/ghc/ghc/-/snippets/2040 (see the --patchdir option)"
|
||||||
viArch:
|
viArch:
|
||||||
A_64:
|
A_64:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
@@ -1434,6 +1529,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.4/ghc-8.10.4-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.10.4/ghc-8.10.4-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-8.10.4
|
dlSubdir: ghc-8.10.4
|
||||||
dlHash: c9776a2ccf9629b03e967206a507fcdcb6c5189800a626e9461ababf6733c357
|
dlHash: c9776a2ccf9629b03e967206a507fcdcb6c5189800a626e9461ababf6733c357
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/8.10.4/ghc-8.10.4-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-8.10.4
|
||||||
|
dlHash: e9175a276504c3390a5e0084954e6997d56078737dbe7158049518892cf6bfb2
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
'( >= 9 && < 10 )': &ghc-8104-32-deb9
|
'( >= 9 && < 10 )': &ghc-8104-32-deb9
|
||||||
@@ -1464,97 +1564,6 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.4/ghc-8.10.4-armv7-deb10-linux.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/8.10.4/ghc-8.10.4-armv7-deb10-linux.tar.xz
|
||||||
dlSubdir: ghc-8.10.4
|
dlSubdir: ghc-8.10.4
|
||||||
dlHash: 0d18ef83593272f6196a41cc3abdc48dfe5e14372db75d71ea19fe35320c4e81
|
dlHash: 0d18ef83593272f6196a41cc3abdc48dfe5e14372db75d71ea19fe35320c4e81
|
||||||
8.10.5:
|
|
||||||
viTags:
|
|
||||||
- Recommended
|
|
||||||
- base-4.14.2.0
|
|
||||||
viChangeLog: https://downloads.haskell.org/~ghc/8.10.5/docs/html/users_guide/8.10.5-notes.html
|
|
||||||
viSourceDL:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-src.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: f10941f16e4fbd98580ab5241b9271bb0851304560c4d5ca127e3b0e20e3076f
|
|
||||||
viPostRemove: *ghc-post-remove
|
|
||||||
viPreCompile: *ghc-pre-compile
|
|
||||||
viArch:
|
|
||||||
A_64:
|
|
||||||
Linux_Debian:
|
|
||||||
'( >= 9 && < 10 )': &ghc-8105-64-deb9
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-x86_64-deb9-linux.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: 15e71325c3bdfe3804be0f84c2fc5c913d811322d19b0f4d4cff20f29cdd804d
|
|
||||||
'( >= 10 && < 11 )': &ghc-8105-64-deb10
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-x86_64-deb10-linux.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: bc623c20ca4c5c18e952071ba14aa0cfc5c94d34219bffaa615f7b491f376787
|
|
||||||
unknown_versioning: *ghc-8105-64-deb9
|
|
||||||
Linux_Ubuntu:
|
|
||||||
unknown_versioning: &ghc-8105-64-fedora
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-x86_64-fedora27-linux.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: 73528ebfb219b50aa9042ee51a0a2bd764828d605f058404989d0b645752d210
|
|
||||||
'( >= 16 && < 19 )': *ghc-8105-64-deb9
|
|
||||||
Linux_Mint:
|
|
||||||
unknown_versioning: *ghc-8105-64-deb10
|
|
||||||
Linux_Fedora:
|
|
||||||
'( >= 27 && < 28 )': *ghc-8105-64-fedora
|
|
||||||
unknown_versioning: *ghc-8105-64-fedora
|
|
||||||
Linux_CentOS:
|
|
||||||
'( >= 7 && < 8 )': &ghc-8105-64-centos
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-x86_64-centos7-linux.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: 4cdb259ec74d1408dab45dab20dcedc21690f39921c2ea4546486fb3e81f4fbd
|
|
||||||
unknown_versioning: *ghc-8105-64-centos
|
|
||||||
Linux_RedHat:
|
|
||||||
unknown_versioning: *ghc-8105-64-centos
|
|
||||||
Linux_Alpine:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-x86_64-alpine3.10-linux-integer-simple.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5-x86_64-unknown-linux
|
|
||||||
dlHash: f4d7cd9ed12a4b8592219c9a63a86db1a256a09fa9e6ed755a60afc57dc782e2
|
|
||||||
Linux_AmazonLinux:
|
|
||||||
unknown_versioning: *ghc-8105-64-centos
|
|
||||||
Linux_UnknownLinux:
|
|
||||||
unknown_versioning: *ghc-8105-64-fedora
|
|
||||||
Darwin:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-x86_64-apple-darwin.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: ef0f47eff8962d58fa447123636cf8ef31c1e5b2d0ae90177d3388861ddf4a22
|
|
||||||
FreeBSD:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/unofficial-bindists/ghc/8.10.5/ghc-8.10.5-x86_64-portbld-freebsd.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: 11a0b490bfb2f57b5bc87c69c197542eafce1b4991cc22f625179a6c6e567834
|
|
||||||
A_32:
|
|
||||||
Linux_Debian:
|
|
||||||
'( >= 9 && < 10 )': &ghc-8105-32-deb9
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-i386-deb9-linux.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: 0ccb5b2c1222374874795c35410754dd650f649b774872abbea2a4ef21ac9c9d
|
|
||||||
unknown_versioning: *ghc-8105-32-deb9
|
|
||||||
Linux_Ubuntu:
|
|
||||||
unknown_versioning: *ghc-8105-32-deb9
|
|
||||||
Linux_Mint:
|
|
||||||
unknown_versioning: *ghc-8105-32-deb9
|
|
||||||
Linux_UnknownLinux:
|
|
||||||
unknown_versioning: *ghc-8105-32-deb9
|
|
||||||
Linux_Alpine:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/unofficial-bindists/ghc/8.10.5/ghc-8.10.5-i386-alpine-linux.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: 0e91abe61607f9375d4e252ee9c261e4856df396f60641bb1b880ab8a3a83ea7
|
|
||||||
A_ARM64:
|
|
||||||
Linux_UnknownLinux:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-aarch64-deb10-linux.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: 9a085cd8a7f8e0ace21ac67dbf659a56fcf41564b48817ba42cd8a1aac7f0ddc
|
|
||||||
A_ARM:
|
|
||||||
Linux_UnknownLinux:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-armv7-deb10-linux.tar.xz
|
|
||||||
dlSubdir: ghc-8.10.5
|
|
||||||
dlHash: 56170d1a8450e18b7eb9c23c94723da352815b27ec250bb23742a62f16dcab6c
|
|
||||||
9.0.1:
|
9.0.1:
|
||||||
viTags:
|
viTags:
|
||||||
- Latest
|
- Latest
|
||||||
@@ -1615,6 +1624,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/9.0.1/ghc-9.0.1-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/9.0.1/ghc-9.0.1-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir: ghc-9.0.1
|
dlSubdir: ghc-9.0.1
|
||||||
dlHash: 9dbc06d8832cae5c9f86dd7b2db729b3748a47beb4fd4b1e62bb66119817c3c1
|
dlHash: 9dbc06d8832cae5c9f86dd7b2db729b3748a47beb4fd4b1e62bb66119817c3c1
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/9.0.1/ghc-9.0.1-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-9.0.1-x86_64-unknown-mingw32
|
||||||
|
dlHash: 4f4ab118df01cbc7e7c510096deca0cb25025339a97730de0466416296202493
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
'( >= 9 && < 10 )': &ghc-901-32-deb9
|
'( >= 9 && < 10 )': &ghc-901-32-deb9
|
||||||
@@ -1705,6 +1719,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghc/9.2.1-alpha2/ghc-9.2.0.20210422-x86_64-apple-darwin.tar.xz
|
dlUri: https://downloads.haskell.org/~ghc/9.2.1-alpha2/ghc-9.2.0.20210422-x86_64-apple-darwin.tar.xz
|
||||||
dlSubdir: ghc-9.2.0.20210422
|
dlSubdir: ghc-9.2.0.20210422
|
||||||
dlHash: 8884c059f2b76e4c4309ff6bd7a7dde37663f751fd26220e9a2bcabb4d69a401
|
dlHash: 8884c059f2b76e4c4309ff6bd7a7dde37663f751fd26220e9a2bcabb4d69a401
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~ghc/9.2.1-alpha2/ghc-9.2.0.20210422-x86_64-unknown-mingw32.tar.xz
|
||||||
|
dlSubdir: ghc-9.0.1-x86_64-unknown-mingw32
|
||||||
|
dlHash: 33f173b754d18f26bb27f52bb77a92fd22a48675daa2b43a1879bf01dddd7e8f
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Debian:
|
Linux_Debian:
|
||||||
'( >= 9 && < 10 )': &ghc-921-alpha2-32-deb9
|
'( >= 9 && < 10 )': &ghc-921-alpha2-32-deb9
|
||||||
@@ -1757,6 +1776,11 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~cabal/cabal-install-2.4.1.0/cabal-install-2.4.1.0-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~cabal/cabal-install-2.4.1.0/cabal-install-2.4.1.0-x86_64-portbld-freebsd.tar.xz
|
||||||
dlSubdir:
|
dlSubdir:
|
||||||
dlHash: 33b7d37ea0688c93436eac9ec139d9967687875aa1fa13f2bb73bf05a9a59a1d
|
dlHash: 33b7d37ea0688c93436eac9ec139d9967687875aa1fa13f2bb73bf05a9a59a1d
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~cabal/cabal-install-2.4.1.0/cabal-install-2.4.1.0-x86_64-unknown-mingw32.zip
|
||||||
|
dlSubdir:
|
||||||
|
dlHash: 95f233efedb1ebf0e6db015fa2f55c1ed00b9938d207ec63c066f706fb4b6373
|
||||||
A_32:
|
A_32:
|
||||||
Linux_UnknownLinux:
|
Linux_UnknownLinux:
|
||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
@@ -1785,6 +1809,11 @@ ghcupDownloads:
|
|||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.0.0.0/cabal-install-3.0.0.0-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.0.0.0/cabal-install-3.0.0.0-x86_64-portbld-freebsd.tar.xz
|
||||||
dlHash: 2240842ab2ae7b955feb8b526aba1c7991248c803383107adf39990441294d2a
|
dlHash: 2240842ab2ae7b955feb8b526aba1c7991248c803383107adf39990441294d2a
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.0.0.0/cabal-install-3.0.0.0-x86_64-unknown-mingw32.zip
|
||||||
|
dlSubdir:
|
||||||
|
dlHash: 8889963ebef5e829d86329fdb59832c107efd117cf7862a605f2fe2d2360de1f
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Alpine:
|
Linux_Alpine:
|
||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
@@ -1816,6 +1845,11 @@ ghcupDownloads:
|
|||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-portbld-freebsd.tar.xz
|
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-portbld-freebsd.tar.xz
|
||||||
dlHash: f1e35151cca91541b0fb4bdb3ed18f3c348038eab751845ad19c11307d66c273
|
dlHash: f1e35151cca91541b0fb4bdb3ed18f3c348038eab751845ad19c11307d66c273
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-unknown-mingw32.zip
|
||||||
|
dlSubdir:
|
||||||
|
dlHash: 17778c3ade0482bc37f451eec326f8fce8fbe1f12b1d6aacb2e2b9e34786c054
|
||||||
A_32:
|
A_32:
|
||||||
Linux_Alpine:
|
Linux_Alpine:
|
||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
@@ -1850,6 +1884,11 @@ ghcupDownloads:
|
|||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.4.0.0/cabal-install-3.4.0.0-x86_64-freebsd-12.1-release.tar.xz
|
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.4.0.0/cabal-install-3.4.0.0-x86_64-freebsd-12.1-release.tar.xz
|
||||||
dlHash: a1e2db664ec00e42a1e071a4181f6476f6e0bad321f1ddc0cf27831119f4c6d4
|
dlHash: a1e2db664ec00e42a1e071a4181f6476f6e0bad321f1ddc0cf27831119f4c6d4
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/~cabal/cabal-install-3.4.0.0/cabal-install-3.4.0.0-x86_64-windows.zip
|
||||||
|
dlSubdir:
|
||||||
|
dlHash: 860fff2d39a82d1dc0ca924a77164d0988af49c2c5f45e15d615144122beb647
|
||||||
A_32:
|
A_32:
|
||||||
Linux_UnknownLinux:
|
Linux_UnknownLinux:
|
||||||
unknown_versioning: &cabal-3400-32
|
unknown_versioning: &cabal-3400-32
|
||||||
@@ -1868,7 +1907,7 @@ ghcupDownloads:
|
|||||||
dlUri: https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal/3.4.0.0/cabal-install-3.4.0.0-armv7-linux-bootstrapped.tar.xz
|
dlUri: https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal/3.4.0.0/cabal-install-3.4.0.0-armv7-linux-bootstrapped.tar.xz
|
||||||
dlHash: 16c0d1eaba24bed14f3e152970179a45d9f9bb5cc839b2c210ad06eb7d4826ed
|
dlHash: 16c0d1eaba24bed14f3e152970179a45d9f9bb5cc839b2c210ad06eb7d4826ed
|
||||||
GHCup:
|
GHCup:
|
||||||
0.1.15.2:
|
0.1.14.1:
|
||||||
viTags:
|
viTags:
|
||||||
- Recommended
|
- Recommended
|
||||||
- Latest
|
- Latest
|
||||||
@@ -1878,39 +1917,39 @@ ghcupDownloads:
|
|||||||
A_64:
|
A_64:
|
||||||
Linux_UnknownLinux:
|
Linux_UnknownLinux:
|
||||||
unknown_versioning: &ghcup-64
|
unknown_versioning: &ghcup-64
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/x86_64-linux-ghcup-0.1.15.2
|
dlUri: https://downloads.haskell.org/~ghcup/0.1.14.1/x86_64-linux-ghcup-0.1.14.1
|
||||||
dlHash: 1eb1bb318a327754f42eaa2245bc81fe53be7c791160d28a186893ded3004ed7
|
dlHash: 59e31b2ede3ed20f79dce0f8ba0a68b6fb25e5f00ba2d7243f6a8af68d979ff5
|
||||||
Darwin:
|
Darwin:
|
||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/x86_64-apple-darwin-ghcup-0.1.15.2
|
dlUri: https://downloads.haskell.org/~ghcup/0.1.14.1/x86_64-apple-darwin-ghcup-0.1.14.1
|
||||||
dlHash: c2a6436a49f19f108493954d4a3efcb27503e343dd6288c2641784d32320b1ea
|
dlHash: 3e1dd173b3e7b5d90dcdece423c3ddd3efb4c83e964967b0fb574c9b7b2c44e1
|
||||||
FreeBSD:
|
FreeBSD:
|
||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/x86_64-portbld-freebsd-ghcup-0.1.15.2
|
dlUri: https://downloads.haskell.org/~ghcup/0.1.14.1/x86_64-portbld-freebsd-ghcup-0.1.14.1
|
||||||
dlHash: 7e0c17dd78ebd9fd03e6ecea278c192bac31ca333721bde5b0ef99438b847a20
|
dlHash: 89a70980d77888dae8b9fd0f05e7a7920f421bc3bb5192da8e73fd4e7b4cb86f
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://TODO
|
||||||
|
dlHash: 89a70980d77888dae8b9fd0f05e7a7920f421bc3bb5192da8e73fd4e7b4cb86f
|
||||||
Linux_Alpine:
|
Linux_Alpine:
|
||||||
unknown_versioning: *ghcup-64
|
unknown_versioning: *ghcup-64
|
||||||
A_32:
|
A_32:
|
||||||
Linux_UnknownLinux:
|
Linux_UnknownLinux:
|
||||||
unknown_versioning: &ghcup-32
|
unknown_versioning: &ghcup-32
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/i386-linux-ghcup-0.1.15.2
|
dlUri: https://downloads.haskell.org/~ghcup/0.1.14.1/i386-linux-ghcup-0.1.14.1
|
||||||
dlHash: 3b1fe710cded0398e920ec9716089ba65226abf181741897f387e7c539a619c2
|
dlHash: 610aac7c3be3ba3874c07b9cae5b2ca0da9a92bf381afc2597bd2dc9c70aae0c
|
||||||
Linux_Alpine:
|
Linux_Alpine:
|
||||||
unknown_versioning: *ghcup-32
|
unknown_versioning: *ghcup-32
|
||||||
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
|
dlUri: https://downloads.haskell.org/~ghcup/0.1.14.1/aarch64-linux-ghcup-0.1.14.1
|
||||||
dlHash: d91b7a5416f292f2cf813824eb419f76ad9976d258cee3581123cb6eb01db9a7
|
dlHash: e9ae07b7d41ea03e6af9c1f3587f61287827c4e29478b6a5d46ea1ce5af4cee5
|
||||||
Darwin:
|
|
||||||
unknown_versioning:
|
|
||||||
dlUri: https://downloads.haskell.org/~ghcup/0.1.15.2/aarch64-apple-darwin-ghcup-0.1.15.2
|
|
||||||
dlHash: 20625ba5e7488f2a6155331750ecead3815ea16b2695c20521633c1412f012cc
|
|
||||||
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.14.1/armv7-linux-ghcup-0.1.14.1
|
||||||
dlHash: 03a4af5ed895ada1dd21f4cc3f64dc9078a5bf4268313021d004c04bea7f9c2e
|
dlHash: 646832030efbc0a848df24c08b5eb7507bd15d1c2eb95fea6d9d03890f3662be
|
||||||
HLS:
|
HLS:
|
||||||
1.1.0:
|
1.1.0:
|
||||||
viTags:
|
viTags:
|
||||||
@@ -1928,5 +1967,63 @@ ghcupDownloads:
|
|||||||
unknown_versioning:
|
unknown_versioning:
|
||||||
dlUri: https://github.com/haskell/haskell-language-server/releases/download/1.1.0/haskell-language-server-macOS-1.1.0.tar.gz
|
dlUri: https://github.com/haskell/haskell-language-server/releases/download/1.1.0/haskell-language-server-macOS-1.1.0.tar.gz
|
||||||
dlHash: 4e89b192e2f49637d772e974f2c17b16da067ecd5912575eaa542551de97681b
|
dlHash: 4e89b192e2f49637d772e974f2c17b16da067ecd5912575eaa542551de97681b
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://downloads.haskell.org/ghcup/unofficial-bindists/hls/1.1.0/haskell-language-server-Windows-1.1.0.tar.gz
|
||||||
|
dlHash: a1d3f451e64a041aa527a25da29e4716a2de6ae347cef4ef9312fc7611e168cc
|
||||||
Linux_Alpine:
|
Linux_Alpine:
|
||||||
unknown_versioning: *hls-64
|
unknown_versioning: *hls-64
|
||||||
|
Stack:
|
||||||
|
2.5.1:
|
||||||
|
viTags: []
|
||||||
|
viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v251
|
||||||
|
viArch:
|
||||||
|
A_64:
|
||||||
|
Linux_UnknownLinux:
|
||||||
|
unknown_versioning: &stack-251-64
|
||||||
|
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.5.1/stack-2.5.1-linux-x86_64.tar.gz
|
||||||
|
dlHash: c83b6c93d6541c0bce2175085a04062020f4160a86116e20f3b343b562f2d1e8
|
||||||
|
dlSubdir:
|
||||||
|
RegexDir: "stack-.*"
|
||||||
|
Darwin:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.5.1/stack-2.5.1-osx-x86_64.tar.gz
|
||||||
|
dlHash: f4aedfa8fbe371f77286ee97ec5c3c553842e7ae15b2952a8b8442dccba04bf0
|
||||||
|
dlSubdir:
|
||||||
|
RegexDir: "stack-.*"
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.5.1/stack-2.5.1-windows-x86_64.tar.gz
|
||||||
|
dlHash: 57150b422cfd42249f5e629d0eb678df6d95dabe486ced57e8298d300b940d41
|
||||||
|
dlSubdir:
|
||||||
|
RegexDir: "stack-.*"
|
||||||
|
Linux_Alpine:
|
||||||
|
unknown_versioning: *stack-251-64
|
||||||
|
2.7.1:
|
||||||
|
viTags:
|
||||||
|
- Recommended
|
||||||
|
- Latest
|
||||||
|
viChangeLog: https://github.com/commercialhaskell/stack/blob/master/ChangeLog.md#v271
|
||||||
|
viArch:
|
||||||
|
A_64:
|
||||||
|
Linux_UnknownLinux:
|
||||||
|
unknown_versioning: &stack-64
|
||||||
|
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.7.1/stack-2.7.1-linux-x86_64.tar.gz
|
||||||
|
dlHash: 2bc47749ee4be5eccb52a2d4a6a00b0f3b28b92517742b40c675836d7db2777d
|
||||||
|
dlSubdir:
|
||||||
|
RegexDir: "stack-.*"
|
||||||
|
Darwin:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.7.1/stack-2.7.1-osx-x86_64.tar.gz
|
||||||
|
dlHash: 4248c6fbc87e8a2c06f39e867eb5ef28eae0d99470137cb415356c631c0dcbf2
|
||||||
|
dlSubdir:
|
||||||
|
RegexDir: "stack-.*"
|
||||||
|
Windows:
|
||||||
|
unknown_versioning:
|
||||||
|
dlUri: https://github.com/commercialhaskell/stack/releases/download/v2.7.1/stack-2.7.1-windows-x86_64.tar.gz
|
||||||
|
dlHash: 8452f5fc9235620a84863f2f68e5f681c72d0d181cde50482f178a966ee0ceb9
|
||||||
|
dlSubdir:
|
||||||
|
RegexDir: "stack-.*"
|
||||||
|
Linux_Alpine:
|
||||||
|
unknown_versioning: *stack-64
|
||||||
|
|
||||||
|
|||||||
2211
ghcup-0.0.5.yaml
2211
ghcup-0.0.5.yaml
File diff suppressed because it is too large
Load Diff
82
ghcup.cabal
82
ghcup.cabal
@@ -1,6 +1,6 @@
|
|||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: ghcup
|
name: ghcup
|
||||||
version: 0.1.15.2
|
version: 0.1.14.2
|
||||||
license: LGPL-3.0-only
|
license: LGPL-3.0-only
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
copyright: Julian Ospald 2020
|
copyright: Julian Ospald 2020
|
||||||
@@ -19,7 +19,6 @@ extra-doc-files:
|
|||||||
CHANGELOG.md
|
CHANGELOG.md
|
||||||
config.yaml
|
config.yaml
|
||||||
ghcup-0.0.4.yaml
|
ghcup-0.0.4.yaml
|
||||||
ghcup-0.0.5.yaml
|
|
||||||
HACKING.md
|
HACKING.md
|
||||||
README.md
|
README.md
|
||||||
RELEASING.md
|
RELEASING.md
|
||||||
@@ -43,7 +42,9 @@ flag internal-downloader
|
|||||||
manual: True
|
manual: True
|
||||||
|
|
||||||
flag tar
|
flag tar
|
||||||
description: Use tar-bytestring instead of libarchive.
|
description:
|
||||||
|
Use tar-bytestring instead of libarchive. This is always enabled on windows.
|
||||||
|
|
||||||
default: False
|
default: False
|
||||||
manual: True
|
manual: True
|
||||||
|
|
||||||
@@ -74,19 +75,14 @@ library
|
|||||||
autogen-modules: Paths_ghcup
|
autogen-modules: Paths_ghcup
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
default-extensions:
|
default-extensions:
|
||||||
DeriveGeneric
|
|
||||||
LambdaCase
|
LambdaCase
|
||||||
MultiWayIf
|
MultiWayIf
|
||||||
NamedFieldPuns
|
|
||||||
PackageImports
|
PackageImports
|
||||||
QuasiQuotes
|
|
||||||
RecordWildCards
|
RecordWildCards
|
||||||
ScopedTypeVariables
|
ScopedTypeVariables
|
||||||
|
Strict
|
||||||
StrictData
|
StrictData
|
||||||
TupleSections
|
TupleSections
|
||||||
TypeApplications
|
|
||||||
TypeFamilies
|
|
||||||
ViewPatterns
|
|
||||||
|
|
||||||
ghc-options:
|
ghc-options:
|
||||||
-Wall -fwarn-tabs -fwarn-incomplete-uni-patterns
|
-Wall -fwarn-tabs -fwarn-incomplete-uni-patterns
|
||||||
@@ -112,24 +108,27 @@ library
|
|||||||
, generics-sop ^>=0.5
|
, generics-sop ^>=0.5
|
||||||
, haskus-utils-types ^>=1.5
|
, haskus-utils-types ^>=1.5
|
||||||
, haskus-utils-variant >=3.0 && <3.2
|
, haskus-utils-variant >=3.0 && <3.2
|
||||||
, lzma-static ^>=5.2.5.3
|
, lzma-static ^>=5.2.5.2
|
||||||
, 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.4
|
, optics >=0.2 && <0.5
|
||||||
, optics-vl ^>=0.2
|
, optics-vl ^>=0.2
|
||||||
, os-release ^>=1.0.0
|
, os-release ^>=1.0.0
|
||||||
, parsec ^>=3.1
|
, parsec ^>=3.1
|
||||||
, pretty ^>=1.1.3.1
|
, pretty ^>=1.1.3.1
|
||||||
, pretty-terminal ^>=0.1.0.0
|
, pretty-terminal ^>=0.1.0.0
|
||||||
|
, process ^>=1.6.9.0
|
||||||
, regex-posix ^>=0.96
|
, regex-posix ^>=0.96
|
||||||
, resourcet ^>=1.2.2
|
, resourcet ^>=1.2.2
|
||||||
, safe ^>=0.3.18
|
, safe ^>=0.3.18
|
||||||
, safe-exceptions ^>=0.1
|
, safe-exceptions ^>=0.1
|
||||||
, split ^>=0.2.3.4
|
, split ^>=0.2.3.4
|
||||||
|
, streamly ^>=0.7.3
|
||||||
|
, streamly-bytestring ^>=0.1.2
|
||||||
, strict-base ^>=0.4
|
, strict-base ^>=0.4
|
||||||
, string-interpolate >=0.2.0.0 && <0.4
|
, string-interpolate >=0.2.0.0 && <0.4
|
||||||
, template-haskell >=2.7 && <2.18
|
, template-haskell >=2.7 && <2.17
|
||||||
, temporary ^>=1.3
|
, temporary ^>=1.3
|
||||||
, text ^>=1.2.4.0
|
, text ^>=1.2.4.0
|
||||||
, time ^>=1.9.3
|
, time ^>=1.9.3
|
||||||
@@ -139,10 +138,10 @@ library
|
|||||||
, uri-bytestring ^>=0.3.2.2
|
, uri-bytestring ^>=0.3.2.2
|
||||||
, utf8-string ^>=1.0
|
, utf8-string ^>=1.0
|
||||||
, vector ^>=0.12
|
, vector ^>=0.12
|
||||||
, versions >=4.0.1 && <5.1
|
, versions ^>=4.0.1
|
||||||
, word8 ^>=0.1.3
|
, word8 ^>=0.1.3
|
||||||
, yaml ^>=0.11.4.0
|
, yaml ^>=0.11.4.0
|
||||||
, zip ^>=1.7.1
|
, zip ^>=1.7.0
|
||||||
, zlib ^>=0.6.2.2
|
, zlib ^>=0.6.2.2
|
||||||
|
|
||||||
if (flag(internal-downloader) && !os(windows))
|
if (flag(internal-downloader) && !os(windows))
|
||||||
@@ -151,10 +150,10 @@ library
|
|||||||
build-depends:
|
build-depends:
|
||||||
, HsOpenSSL >=0.11.4.18
|
, HsOpenSSL >=0.11.4.18
|
||||||
, http-io-streams >=0.1.2.0
|
, http-io-streams >=0.1.2.0
|
||||||
, io-streams >=1.5.2.1
|
, io-streams >=1.5
|
||||||
, terminal-progress-bar >=0.4.1
|
, terminal-progress-bar >=0.4.1
|
||||||
|
|
||||||
if flag(tar)
|
if (flag(tar) || os(windows))
|
||||||
cpp-options: -DTAR
|
cpp-options: -DTAR
|
||||||
build-depends: tar
|
build-depends: tar
|
||||||
|
|
||||||
@@ -164,18 +163,14 @@ library
|
|||||||
if os(windows)
|
if os(windows)
|
||||||
cpp-options: -DIS_WINDOWS
|
cpp-options: -DIS_WINDOWS
|
||||||
other-modules: GHCup.Utils.File.Windows
|
other-modules: GHCup.Utils.File.Windows
|
||||||
build-depends:
|
build-depends: bzlib
|
||||||
, bzlib
|
|
||||||
, process ^>=1.6.11.0
|
|
||||||
, retry ^>=0.8.1.2
|
|
||||||
, Win32 ^>=2.10
|
|
||||||
|
|
||||||
else
|
else
|
||||||
other-modules: GHCup.Utils.File.Posix
|
other-modules: GHCup.Utils.File.Posix
|
||||||
build-depends:
|
build-depends:
|
||||||
, bz2 >=0.5.0.5 && <1.1
|
bz2 >=0.5.0.5 && <1.1
|
||||||
, hpath-posix ^>=0.13.3
|
, hpath-posix ^>=0.13.3
|
||||||
, process ^>=1.6.9
|
, streamly-posix ^>=0.1.0.0
|
||||||
, unix ^>=2.7
|
, unix ^>=2.7
|
||||||
, unix-bytestring ^>=0.3.7.3
|
, unix-bytestring ^>=0.3.7.3
|
||||||
|
|
||||||
@@ -190,10 +185,10 @@ executable ghcup
|
|||||||
default-extensions:
|
default-extensions:
|
||||||
LambdaCase
|
LambdaCase
|
||||||
MultiWayIf
|
MultiWayIf
|
||||||
NamedFieldPuns
|
|
||||||
PackageImports
|
PackageImports
|
||||||
RecordWildCards
|
RecordWildCards
|
||||||
ScopedTypeVariables
|
ScopedTypeVariables
|
||||||
|
Strict
|
||||||
StrictData
|
StrictData
|
||||||
TupleSections
|
TupleSections
|
||||||
|
|
||||||
@@ -202,10 +197,10 @@ executable ghcup
|
|||||||
-fwarn-incomplete-record-updates -threaded
|
-fwarn-incomplete-record-updates -threaded
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
|
, aeson >=1.4 && <1.6
|
||||||
, 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
|
||||||
@@ -219,11 +214,11 @@ executable ghcup
|
|||||||
, safe ^>=0.3.18
|
, safe ^>=0.3.18
|
||||||
, safe-exceptions ^>=0.1
|
, safe-exceptions ^>=0.1
|
||||||
, string-interpolate >=0.2.0.0 && <0.4
|
, string-interpolate >=0.2.0.0 && <0.4
|
||||||
, template-haskell >=2.7 && <2.18
|
, template-haskell >=2.7 && <2.17
|
||||||
, text ^>=1.2.4.0
|
, text ^>=1.2.4.0
|
||||||
, uri-bytestring ^>=0.3.2.2
|
, uri-bytestring ^>=0.3.2.2
|
||||||
, utf8-string ^>=1.0
|
, utf8-string ^>=1.0
|
||||||
, versions >=4.0.1 && <5.1
|
, versions ^>=4.0.1
|
||||||
|
|
||||||
if flag(internal-downloader)
|
if flag(internal-downloader)
|
||||||
cpp-options: -DINTERNAL_DOWNLOADER
|
cpp-options: -DINTERNAL_DOWNLOADER
|
||||||
@@ -232,15 +227,11 @@ executable ghcup
|
|||||||
cpp-options: -DBRICK
|
cpp-options: -DBRICK
|
||||||
other-modules: BrickMain
|
other-modules: BrickMain
|
||||||
build-depends:
|
build-depends:
|
||||||
, brick >=0.5 && <0.62
|
, brick >=0.5 && <0.62
|
||||||
, transformers ^>=0.5
|
, vector ^>=0.12
|
||||||
, vector ^>=0.12
|
, vty >=5.28.2 && <5.34
|
||||||
, vty >=5.28.2 && <5.34
|
|
||||||
|
|
||||||
if os(windows)
|
if (flag(tar) || os(windows))
|
||||||
cpp-options: -DIS_WINDOWS
|
|
||||||
|
|
||||||
if flag(tar)
|
|
||||||
cpp-options: -DTAR
|
cpp-options: -DTAR
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -252,25 +243,20 @@ executable ghcup-gen
|
|||||||
other-modules: Validate
|
other-modules: Validate
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
default-extensions:
|
default-extensions:
|
||||||
DeriveGeneric
|
|
||||||
LambdaCase
|
LambdaCase
|
||||||
MultiWayIf
|
MultiWayIf
|
||||||
NamedFieldPuns
|
|
||||||
PackageImports
|
PackageImports
|
||||||
QuasiQuotes
|
|
||||||
RecordWildCards
|
RecordWildCards
|
||||||
ScopedTypeVariables
|
ScopedTypeVariables
|
||||||
StrictData
|
|
||||||
TupleSections
|
TupleSections
|
||||||
TypeApplications
|
|
||||||
TypeFamilies
|
|
||||||
ViewPatterns
|
|
||||||
|
|
||||||
ghc-options:
|
ghc-options:
|
||||||
-Wall -fwarn-tabs -fwarn-incomplete-uni-patterns
|
-Wall -fwarn-tabs -fwarn-incomplete-uni-patterns
|
||||||
-fwarn-incomplete-record-updates -threaded
|
-fwarn-incomplete-record-updates -threaded
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
|
, aeson >=1.4 && <1.6
|
||||||
|
, aeson-pretty ^>=0.8.8
|
||||||
, base >=4.13 && <5
|
, base >=4.13 && <5
|
||||||
, bytestring ^>=0.10
|
, bytestring ^>=0.10
|
||||||
, containers ^>=0.6
|
, containers ^>=0.6
|
||||||
@@ -279,7 +265,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.4
|
, optics >=0.2 && <0.5
|
||||||
, 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
|
||||||
@@ -290,10 +276,11 @@ executable ghcup-gen
|
|||||||
, text ^>=1.2.4.0
|
, text ^>=1.2.4.0
|
||||||
, transformers ^>=0.5
|
, transformers ^>=0.5
|
||||||
, uri-bytestring ^>=0.3.2.2
|
, uri-bytestring ^>=0.3.2.2
|
||||||
, versions >=4.0.1 && <5.1
|
, utf8-string ^>=1.0
|
||||||
|
, versions ^>=4.0.1
|
||||||
, yaml ^>=0.11.4.0
|
, yaml ^>=0.11.4.0
|
||||||
|
|
||||||
if flag(tar)
|
if (flag(tar) || os(windows))
|
||||||
cpp-options: -DTAR
|
cpp-options: -DTAR
|
||||||
build-depends: tar
|
build-depends: tar
|
||||||
|
|
||||||
@@ -303,7 +290,6 @@ 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
|
||||||
@@ -330,9 +316,9 @@ test-suite ghcup-test
|
|||||||
, generic-arbitrary ^>=0.1.0
|
, generic-arbitrary ^>=0.1.0
|
||||||
, ghcup
|
, ghcup
|
||||||
, hspec ^>=2.7.10
|
, hspec ^>=2.7.10
|
||||||
, hspec-golden-aeson ^>=0.9
|
, hspec-golden-aeson >=0.9 && <0.10
|
||||||
, QuickCheck ^>=2.14.1
|
, QuickCheck ^>=2.14.1
|
||||||
, quickcheck-arbitrary-adt ^>=0.3.1.0
|
, quickcheck-arbitrary-adt ^>=0.3.1.0
|
||||||
, text ^>=1.2.4.0
|
, text ^>=1.2.4.0
|
||||||
, uri-bytestring ^>=0.3.2.2
|
, uri-bytestring ^>=0.3.2.2
|
||||||
, versions >=4.0.1 && <5.1
|
, versions ^>=4.0.1
|
||||||
|
|||||||
26912
golden/GHCupInfo.json
26912
golden/GHCupInfo.json
File diff suppressed because it is too large
Load Diff
1042
lib/GHCup.hs
1042
lib/GHCup.hs
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@ import GHCup.Errors
|
|||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.JSON ( )
|
import GHCup.Types.JSON ( )
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
import GHCup.Utils.Dirs
|
import GHCup.Utils
|
||||||
import GHCup.Utils.File
|
import GHCup.Utils.File
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Utils.Prelude
|
||||||
import GHCup.Version
|
import GHCup.Version
|
||||||
@@ -53,8 +53,8 @@ import Control.Monad.Trans.Resource
|
|||||||
hiding ( throwM )
|
hiding ( throwM )
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.ByteString ( ByteString )
|
|
||||||
#if defined(INTERNAL_DOWNLOADER)
|
#if defined(INTERNAL_DOWNLOADER)
|
||||||
|
import Data.ByteString ( ByteString )
|
||||||
import Data.CaseInsensitive ( CI )
|
import Data.CaseInsensitive ( CI )
|
||||||
#endif
|
#endif
|
||||||
import Data.List.Extra
|
import Data.List.Extra
|
||||||
@@ -66,7 +66,6 @@ import Data.Time.Clock.POSIX
|
|||||||
import Data.Time.Format
|
import Data.Time.Format
|
||||||
#endif
|
#endif
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
import Data.Word8
|
|
||||||
import GHC.IO.Exception
|
import GHC.IO.Exception
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Optics
|
import Optics
|
||||||
@@ -81,7 +80,6 @@ import System.IO.Error
|
|||||||
import URI.ByteString
|
import URI.ByteString
|
||||||
|
|
||||||
import qualified Crypto.Hash.SHA256 as SHA256
|
import qualified Crypto.Hash.SHA256 as SHA256
|
||||||
import qualified Data.ByteString as B
|
|
||||||
import qualified Data.ByteString.Base16 as B16
|
import qualified Data.ByteString.Base16 as B16
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Data.Map.Strict as M
|
import qualified Data.Map.Strict as M
|
||||||
@@ -107,31 +105,32 @@ 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
|
||||||
|
, MonadReader AppState m
|
||||||
)
|
)
|
||||||
=> Excepts
|
=> URLSource
|
||||||
|
-> Excepts
|
||||||
'[JSONError , DownloadFailed , FileDoesNotExistError]
|
'[JSONError , DownloadFailed , FileDoesNotExistError]
|
||||||
m
|
m
|
||||||
GHCupInfo
|
GHCupInfo
|
||||||
getDownloadsF = do
|
getDownloadsF urlSource = do
|
||||||
Settings { urlSource } <- lift getSettings
|
|
||||||
case urlSource of
|
case urlSource of
|
||||||
GHCupURL -> liftE $ getBase ghcupURL
|
GHCupURL -> liftE getBase
|
||||||
(OwnSource url) -> liftE $ getBase url
|
(OwnSource url) -> do
|
||||||
|
bs <- reThrowAll DownloadFailed $ downloadBS 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 ghcupURL
|
base <- liftE getBase
|
||||||
pure (mergeGhcupInfo base ext)
|
pure (mergeGhcupInfo base ext)
|
||||||
(AddSource (Right uri)) -> do
|
(AddSource (Right uri)) -> do
|
||||||
base <- liftE $ getBase ghcupURL
|
base <- liftE getBase
|
||||||
ext <- liftE $ getBase uri
|
bsExt <- reThrowAll DownloadFailed $ downloadBS uri
|
||||||
|
ext <- lE' JSONDecodeError $ first show $ Y.decodeEither' (L.toStrict bsExt)
|
||||||
pure (mergeGhcupInfo base ext)
|
pure (mergeGhcupInfo base ext)
|
||||||
|
|
||||||
where
|
where
|
||||||
@@ -139,58 +138,39 @@ getDownloadsF = do
|
|||||||
mergeGhcupInfo :: GHCupInfo -- ^ base to merge with
|
mergeGhcupInfo :: GHCupInfo -- ^ base to merge with
|
||||||
-> GHCupInfo -- ^ extension overwriting the base
|
-> GHCupInfo -- ^ extension overwriting the base
|
||||||
-> GHCupInfo
|
-> GHCupInfo
|
||||||
mergeGhcupInfo (GHCupInfo tr base base2) (GHCupInfo _ ext ext2) =
|
mergeGhcupInfo (GHCupInfo tr base) (GHCupInfo _ ext) =
|
||||||
let newDownloads = M.mapWithKey (\k a -> case M.lookup k ext of
|
let new = M.mapWithKey (\k a -> case M.lookup k ext of
|
||||||
Just a' -> M.union a' a
|
Just a' -> M.union a' a
|
||||||
Nothing -> a
|
Nothing -> a
|
||||||
) base
|
) base
|
||||||
newGlobalTools = M.union base2 ext2
|
in GHCupInfo tr new
|
||||||
in GHCupInfo tr newDownloads newGlobalTools
|
|
||||||
|
|
||||||
|
|
||||||
readFromCache :: ( MonadReader env m
|
readFromCache :: (MonadIO m, MonadCatch m, MonadLogger m, MonadReader AppState m)
|
||||||
, HasDirs env
|
=> Excepts '[JSONError, FileDoesNotExistError] m GHCupInfo
|
||||||
, MonadIO m
|
readFromCache = do
|
||||||
, MonadCatch m)
|
AppState {dirs = Dirs {..}} <- lift ask
|
||||||
=> URI
|
lift $ $(logWarn)
|
||||||
-> Excepts '[JSONError, FileDoesNotExistError] m L.ByteString
|
[i|Could not get download info, trying cached version (this may not be recent!)|]
|
||||||
readFromCache uri = do
|
let path = view pathL' ghcupURL
|
||||||
Dirs{..} <- lift getDirs
|
let yaml_file = cacheDir </> (T.unpack . decUTF8Safe . urlBaseName $ path)
|
||||||
let yaml_file = cacheDir </> (T.unpack . decUTF8Safe . urlBaseName . view pathL' $ uri)
|
bs <-
|
||||||
handleIO' NoSuchThing (\_ -> throwE $ FileDoesNotExistError yaml_file)
|
handleIO' NoSuchThing
|
||||||
. liftIO
|
(\_ -> throwE $ FileDoesNotExistError yaml_file)
|
||||||
. L.readFile
|
$ liftIO
|
||||||
$ yaml_file
|
$ L.readFile yaml_file
|
||||||
|
lE' JSONDecodeError $ first show $ Y.decodeEither' (L.toStrict bs)
|
||||||
|
|
||||||
|
|
||||||
getBase :: ( MonadReader env m
|
getBase :: (MonadFail m, MonadIO m, MonadCatch m, MonadLogger m, MonadReader AppState m)
|
||||||
, HasDirs env
|
=> Excepts '[JSONError , FileDoesNotExistError] m GHCupInfo
|
||||||
, HasSettings env
|
getBase =
|
||||||
, MonadFail m
|
handleIO (\_ -> readFromCache)
|
||||||
, MonadIO m
|
$ catchE @_ @'[JSONError, FileDoesNotExistError]
|
||||||
, MonadCatch m
|
(\(DownloadFailed _) -> readFromCache)
|
||||||
, MonadLogger m
|
(reThrowAll @_ @_ @'[JSONError, DownloadFailed] DownloadFailed (smartDl ghcupURL)
|
||||||
)
|
>>= (liftE . lE' @_ @_ @'[JSONError] JSONDecodeError . first show . Y.decodeEither' . L.toStrict))
|
||||||
=> URI
|
where
|
||||||
-> Excepts '[JSONError , FileDoesNotExistError] m GHCupInfo
|
|
||||||
getBase uri = do
|
|
||||||
Settings { noNetwork } <- lift getSettings
|
|
||||||
bs <- if noNetwork
|
|
||||||
then readFromCache uri
|
|
||||||
else handleIO (\_ -> warnCache >> readFromCache uri)
|
|
||||||
. catchE @_ @'[JSONError, FileDoesNotExistError] (\(DownloadFailed _) -> warnCache >> readFromCache uri)
|
|
||||||
. 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.
|
||||||
@@ -200,14 +180,12 @@ getBase uri = do
|
|||||||
-- 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 env1
|
smartDl :: forall m1
|
||||||
. ( MonadReader env1 m1
|
. ( MonadCatch m1
|
||||||
, HasDirs env1
|
|
||||||
, HasSettings env1
|
|
||||||
, MonadCatch m1
|
|
||||||
, MonadIO m1
|
, MonadIO m1
|
||||||
, MonadFail m1
|
, MonadFail m1
|
||||||
, MonadLogger m1
|
, MonadLogger m1
|
||||||
|
, MonadReader AppState m1
|
||||||
)
|
)
|
||||||
=> URI
|
=> URI
|
||||||
-> Excepts
|
-> Excepts
|
||||||
@@ -218,15 +196,14 @@ getBase uri = do
|
|||||||
, NoLocationHeader
|
, NoLocationHeader
|
||||||
, TooManyRedirs
|
, TooManyRedirs
|
||||||
, ProcessError
|
, ProcessError
|
||||||
, NoNetwork
|
|
||||||
]
|
]
|
||||||
m1
|
m1
|
||||||
L.ByteString
|
L.ByteString
|
||||||
smartDl uri' = do
|
smartDl uri' = do
|
||||||
Dirs{..} <- lift getDirs
|
AppState {dirs = Dirs {..}} <- lift ask
|
||||||
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
|
||||||
@@ -247,6 +224,7 @@ getBase uri = do
|
|||||||
else -- access in less than 5 minutes, re-use file
|
else -- access in less than 5 minutes, re-use file
|
||||||
liftIO $ L.readFile json_file
|
liftIO $ L.readFile json_file
|
||||||
else do
|
else do
|
||||||
|
liftIO $ createDirRecursive' cacheDir
|
||||||
getModTime >>= \case
|
getModTime >>= \case
|
||||||
Just modTime -> dlWithMod modTime json_file
|
Just modTime -> dlWithMod modTime json_file
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
@@ -262,7 +240,7 @@ getBase uri = do
|
|||||||
pure bs
|
pure bs
|
||||||
dlWithoutMod json_file = do
|
dlWithoutMod json_file = do
|
||||||
bs <- liftE $ downloadBS uri'
|
bs <- liftE $ downloadBS uri'
|
||||||
liftIO $ hideError doesNotExistErrorType $ rmFile json_file
|
liftIO $ hideError doesNotExistErrorType $ removeFile 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))
|
||||||
pure bs
|
pure bs
|
||||||
@@ -299,46 +277,39 @@ getBase uri = do
|
|||||||
setModificationTime path utctime
|
setModificationTime path utctime
|
||||||
|
|
||||||
|
|
||||||
getDownloadInfo :: ( MonadReader env m
|
getDownloadInfo :: Tool
|
||||||
, HasPlatformReq env
|
|
||||||
, HasGHCupInfo env
|
|
||||||
)
|
|
||||||
=> Tool
|
|
||||||
-> Version
|
-> Version
|
||||||
-- ^ tool version
|
-- ^ tool version
|
||||||
-> Excepts
|
-> PlatformRequest
|
||||||
'[NoDownload]
|
-> GHCupDownloads
|
||||||
m
|
-> Either NoDownload DownloadInfo
|
||||||
DownloadInfo
|
getDownloadInfo t v (PlatformRequest a p mv) dls = maybe
|
||||||
getDownloadInfo t v = do
|
(Left NoDownload)
|
||||||
(PlatformRequest a p mv) <- lift getPlatformReq
|
Right
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
(case p of
|
||||||
|
-- non-musl won't work on alpine
|
||||||
|
Linux Alpine -> with_distro <|> without_distro_ver
|
||||||
|
_ -> with_distro <|> without_distro_ver <|> without_distro
|
||||||
|
)
|
||||||
|
|
||||||
let distro_preview f g =
|
where
|
||||||
let platformVersionSpec =
|
with_distro = distro_preview id id
|
||||||
preview (ix t % ix v % viArch % ix a % ix (f p)) dls
|
without_distro_ver = distro_preview id (const Nothing)
|
||||||
mv' = g mv
|
without_distro = distro_preview (set _Linux UnknownLinux) (const Nothing)
|
||||||
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)
|
|
||||||
|
|
||||||
maybe
|
distro_preview f g =
|
||||||
(throwE NoDownload)
|
let platformVersionSpec =
|
||||||
pure
|
preview (ix t % ix v % viArch % ix a % ix (f p)) dls
|
||||||
(case p of
|
mv' = g mv
|
||||||
-- non-musl won't work on alpine
|
in fmap snd
|
||||||
Linux Alpine -> with_distro <|> without_distro_ver
|
. find
|
||||||
_ -> with_distro <|> without_distro_ver <|> without_distro
|
(\(mverRange, _) -> maybe
|
||||||
)
|
(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
|
||||||
@@ -348,10 +319,8 @@ getDownloadInfo t v = do
|
|||||||
-- 2. otherwise create a random file
|
-- 2. otherwise create a random file
|
||||||
--
|
--
|
||||||
-- The file must not exist.
|
-- The file must not exist.
|
||||||
download :: ( MonadReader env m
|
download :: ( MonadMask m
|
||||||
, HasSettings env
|
, MonadReader AppState m
|
||||||
, HasDirs env
|
|
||||||
, MonadMask m
|
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, MonadLogger m
|
, MonadLogger m
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
@@ -385,22 +354,20 @@ download dli dest mfn
|
|||||||
|
|
||||||
-- download
|
-- download
|
||||||
flip onException
|
flip onException
|
||||||
(liftIO $ hideError doesNotExistErrorType $ rmFile destFile)
|
(liftIO $ hideError doesNotExistErrorType $ removeFile destFile)
|
||||||
$ catchAllE @_ @'[ProcessError, DownloadFailed, UnsupportedScheme]
|
$ catchAllE @_ @'[ProcessError, DownloadFailed, UnsupportedScheme]
|
||||||
(\e ->
|
(\e ->
|
||||||
liftIO (hideError doesNotExistErrorType $ rmFile destFile)
|
liftIO (hideError doesNotExistErrorType $ removeFile destFile)
|
||||||
>> (throwE . DownloadFailed $ e)
|
>> (throwE . DownloadFailed $ e)
|
||||||
) $ do
|
) $ do
|
||||||
Settings{ downloader, noNetwork } <- lift getSettings
|
lift getDownloader >>= \case
|
||||||
when noNetwork $ throwE (DownloadFailed (V NoNetwork :: V '[NoNetwork]))
|
|
||||||
case downloader of
|
|
||||||
Curl -> do
|
Curl -> do
|
||||||
o' <- liftIO getCurlOpts
|
o' <- liftIO getCurlOpts
|
||||||
liftE $ lEM @_ @'[ProcessError] $ exec "curl"
|
liftE $ lEM @_ @'[ProcessError] $ liftIO $ exec "curl"
|
||||||
(o' ++ ["-fL", "-o", destFile, (T.unpack . decUTF8Safe) $ serializeURIRef' $ view dlUri dli]) Nothing Nothing
|
(o' ++ ["-fL", "-o", destFile, (T.unpack . decUTF8Safe) $ serializeURIRef' $ view dlUri dli]) Nothing Nothing
|
||||||
Wget -> do
|
Wget -> do
|
||||||
o' <- liftIO getWgetOpts
|
o' <- liftIO getWgetOpts
|
||||||
liftE $ lEM @_ @'[ProcessError] $ exec "wget"
|
liftE $ lEM @_ @'[ProcessError] $ liftIO $ exec "wget"
|
||||||
(o' ++ ["-O", destFile , (T.unpack . decUTF8Safe) $ serializeURIRef' $ view dlUri dli]) Nothing Nothing
|
(o' ++ ["-O", destFile , (T.unpack . decUTF8Safe) $ serializeURIRef' $ view dlUri dli]) Nothing Nothing
|
||||||
#if defined(INTERNAL_DOWNLOADER)
|
#if defined(INTERNAL_DOWNLOADER)
|
||||||
Internal -> do
|
Internal -> do
|
||||||
@@ -413,63 +380,42 @@ download dli dest mfn
|
|||||||
|
|
||||||
-- 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)))
|
getDestFile = maybe (dest </> T.unpack (decUTF8Safe (urlBaseName path))) (dest </>) mfn
|
||||||
(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 :: ( MonadReader env m
|
downloadCached :: ( MonadMask 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
|
||||||
|
, MonadReader AppState m
|
||||||
)
|
)
|
||||||
=> DownloadInfo
|
=> DownloadInfo
|
||||||
-> Maybe FilePath -- ^ optional filename
|
-> Maybe FilePath -- ^ optional filename
|
||||||
-> Excepts '[DigestError , DownloadFailed] m FilePath
|
-> Excepts '[DigestError , DownloadFailed] m FilePath
|
||||||
downloadCached dli mfn = do
|
downloadCached dli mfn = do
|
||||||
Settings{ cache } <- lift getSettings
|
cache <- lift getCache
|
||||||
case cache of
|
case cache of
|
||||||
True -> downloadCached' dli mfn Nothing
|
True -> do
|
||||||
|
AppState {dirs = Dirs {..}} <- lift ask
|
||||||
|
let fn = fromMaybe ((T.unpack . decUTF8Safe) $ urlBaseName $ view (dlUri % pathL') dli) mfn
|
||||||
|
let cachfile = cacheDir </> fn
|
||||||
|
fileExists <- liftIO $ doesFileExist cachfile
|
||||||
|
if
|
||||||
|
| fileExists -> do
|
||||||
|
liftE $ checkDigest dli cachfile
|
||||||
|
pure cachfile
|
||||||
|
| otherwise -> liftE $ download dli cacheDir mfn
|
||||||
False -> do
|
False -> do
|
||||||
tmp <- lift withGHCupTmpDir
|
tmp <- lift withGHCupTmpDir
|
||||||
liftE $ download dli tmp mfn
|
liftE $ download dli tmp mfn
|
||||||
|
|
||||||
|
|
||||||
downloadCached' :: ( MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, MonadMask m
|
|
||||||
, MonadThrow m
|
|
||||||
, MonadLogger m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadUnliftIO m
|
|
||||||
)
|
|
||||||
=> DownloadInfo
|
|
||||||
-> Maybe FilePath -- ^ optional filename
|
|
||||||
-> Maybe FilePath -- ^ optional destination dir (default: cacheDir)
|
|
||||||
-> Excepts '[DigestError , DownloadFailed] m FilePath
|
|
||||||
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 cachfile = destDir </> fn
|
|
||||||
fileExists <- liftIO $ doesFileExist cachfile
|
|
||||||
if
|
|
||||||
| fileExists -> do
|
|
||||||
liftE $ checkDigest dli cachfile
|
|
||||||
pure cachfile
|
|
||||||
| otherwise -> liftE $ download dli destDir mfn
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------
|
------------------
|
||||||
@@ -480,12 +426,7 @@ downloadCached' dli mfn mDestDir = do
|
|||||||
|
|
||||||
|
|
||||||
-- | This is used for downloading the JSON.
|
-- | This is used for downloading the JSON.
|
||||||
downloadBS :: ( MonadReader env m
|
downloadBS :: (MonadReader AppState m, MonadCatch m, MonadIO m, MonadLogger m)
|
||||||
, HasSettings env
|
|
||||||
, MonadCatch m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadLogger m
|
|
||||||
)
|
|
||||||
=> URI
|
=> URI
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ FileDoesNotExistError
|
'[ FileDoesNotExistError
|
||||||
@@ -495,7 +436,6 @@ downloadBS :: ( MonadReader env m
|
|||||||
, NoLocationHeader
|
, NoLocationHeader
|
||||||
, TooManyRedirs
|
, TooManyRedirs
|
||||||
, ProcessError
|
, ProcessError
|
||||||
, NoNetwork
|
|
||||||
]
|
]
|
||||||
m
|
m
|
||||||
L.ByteString
|
L.ByteString
|
||||||
@@ -519,14 +459,12 @@ downloadBS uri'
|
|||||||
dl _ = do
|
dl _ = do
|
||||||
#endif
|
#endif
|
||||||
lift $ $(logDebug) [i|downloading: #{serializeURIRef' uri'}|]
|
lift $ $(logDebug) [i|downloading: #{serializeURIRef' uri'}|]
|
||||||
Settings{ downloader, noNetwork } <- lift getSettings
|
lift getDownloader >>= \case
|
||||||
when noNetwork $ throwE NoNetwork
|
|
||||||
case downloader of
|
|
||||||
Curl -> do
|
Curl -> do
|
||||||
o' <- liftIO getCurlOpts
|
o' <- liftIO getCurlOpts
|
||||||
let exe = "curl"
|
let exe = "curl"
|
||||||
args = o' ++ ["-sSfL", T.unpack $ decUTF8Safe $ serializeURIRef' uri']
|
args = o' ++ ["-sSfL", T.unpack $ decUTF8Safe $ serializeURIRef' uri']
|
||||||
lift (executeOut exe args Nothing) >>= \case
|
liftIO (executeOut exe args Nothing) >>= \case
|
||||||
CapturedProcess ExitSuccess stdout _ -> do
|
CapturedProcess ExitSuccess stdout _ -> do
|
||||||
pure stdout
|
pure stdout
|
||||||
CapturedProcess (ExitFailure i') _ _ -> throwE $ NonZeroExit i' exe args
|
CapturedProcess (ExitFailure i') _ _ -> throwE $ NonZeroExit i' exe args
|
||||||
@@ -534,7 +472,7 @@ downloadBS uri'
|
|||||||
o' <- liftIO getWgetOpts
|
o' <- liftIO getWgetOpts
|
||||||
let exe = "wget"
|
let exe = "wget"
|
||||||
args = o' ++ ["-qO-", T.unpack $ decUTF8Safe $ serializeURIRef' uri']
|
args = o' ++ ["-qO-", T.unpack $ decUTF8Safe $ serializeURIRef' uri']
|
||||||
lift (executeOut exe args Nothing) >>= \case
|
liftIO (executeOut exe args Nothing) >>= \case
|
||||||
CapturedProcess ExitSuccess stdout _ -> do
|
CapturedProcess ExitSuccess stdout _ -> do
|
||||||
pure stdout
|
pure stdout
|
||||||
CapturedProcess (ExitFailure i') _ _ -> throwE $ NonZeroExit i' exe args
|
CapturedProcess (ExitFailure i') _ _ -> throwE $ NonZeroExit i' exe args
|
||||||
@@ -545,19 +483,12 @@ downloadBS uri'
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
checkDigest :: ( MonadReader env m
|
checkDigest :: (MonadIO m, MonadThrow m, MonadLogger m, MonadReader AppState m)
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, MonadIO m
|
|
||||||
, MonadThrow m
|
|
||||||
, MonadLogger m
|
|
||||||
)
|
|
||||||
=> DownloadInfo
|
=> DownloadInfo
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> Excepts '[DigestError] m ()
|
-> Excepts '[DigestError] m ()
|
||||||
checkDigest dli file = do
|
checkDigest dli file = do
|
||||||
Settings{ noVerify } <- lift getSettings
|
verify <- lift ask <&> (not . noVerify . settings)
|
||||||
let verify = not noVerify
|
|
||||||
when verify $ do
|
when verify $ do
|
||||||
let p' = takeFileName file
|
let p' = takeFileName file
|
||||||
lift $ $(logInfo) [i|verifying digest of: #{p'}|]
|
lift $ $(logInfo) [i|verifying digest of: #{p'}|]
|
||||||
@@ -582,8 +513,3 @@ getWgetOpts =
|
|||||||
Just r -> pure $ splitOn " " r
|
Just r -> pure $ splitOn " " r
|
||||||
Nothing -> pure []
|
Nothing -> pure []
|
||||||
|
|
||||||
|
|
||||||
urlBaseName :: ByteString -- ^ the url path (without scheme and host)
|
|
||||||
-> ByteString
|
|
||||||
urlBaseName = snd . B.breakEnd (== _slash) . urlDecode False
|
|
||||||
|
|
||||||
|
|||||||
@@ -233,13 +233,6 @@ 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 ]--
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ import Prelude hiding ( abs
|
|||||||
import System.Info
|
import System.Info
|
||||||
import System.Directory
|
import System.Directory
|
||||||
import System.OsRelease
|
import System.OsRelease
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
import Text.Regex.Posix
|
import Text.Regex.Posix
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
@@ -58,7 +57,7 @@ import qualified Data.Text.IO as T
|
|||||||
|
|
||||||
|
|
||||||
-- | Get the full platform request, consisting of architecture, distro, ...
|
-- | Get the full platform request, consisting of architecture, distro, ...
|
||||||
platformRequest :: (Alternative m, MonadFail m, MonadLogger m, MonadCatch m, MonadIO m)
|
platformRequest :: (MonadLogger m, MonadCatch m, MonadIO m)
|
||||||
=> Excepts
|
=> Excepts
|
||||||
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
|
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
|
||||||
m
|
m
|
||||||
@@ -83,7 +82,7 @@ getArchitecture = case arch of
|
|||||||
what -> Left (NoCompatibleArch what)
|
what -> Left (NoCompatibleArch what)
|
||||||
|
|
||||||
|
|
||||||
getPlatform :: (Alternative m, MonadLogger m, MonadCatch m, MonadIO m, MonadFail m)
|
getPlatform :: (MonadLogger m, MonadCatch m, MonadIO m)
|
||||||
=> Excepts
|
=> Excepts
|
||||||
'[NoCompatiblePlatform, DistroNotFound]
|
'[NoCompatiblePlatform, DistroNotFound]
|
||||||
m
|
m
|
||||||
@@ -98,6 +97,7 @@ getPlatform = do
|
|||||||
either (const Nothing) Just
|
either (const Nothing) Just
|
||||||
. versioning
|
. versioning
|
||||||
-- TODO: maybe do this somewhere else
|
-- TODO: maybe do this somewhere else
|
||||||
|
. getMajorVersion
|
||||||
. decUTF8Safe'
|
. decUTF8Safe'
|
||||||
<$> getDarwinVersion
|
<$> getDarwinVersion
|
||||||
pure $ PlatformResult { _platform = Darwin, _distroVersion = ver }
|
pure $ PlatformResult { _platform = Darwin, _distroVersion = ver }
|
||||||
@@ -108,24 +108,26 @@ getPlatform = do
|
|||||||
pure $ PlatformResult { _platform = FreeBSD, _distroVersion = ver }
|
pure $ PlatformResult { _platform = FreeBSD, _distroVersion = ver }
|
||||||
"mingw32" -> pure PlatformResult { _platform = Windows, _distroVersion = Nothing }
|
"mingw32" -> pure PlatformResult { _platform = Windows, _distroVersion = Nothing }
|
||||||
what -> throwE $ NoCompatiblePlatform what
|
what -> throwE $ NoCompatiblePlatform what
|
||||||
lift $ $(logDebug) [i|Identified Platform as: #{prettyShow pfr}|]
|
lift $ $(logDebug) [i|Identified Platform as: #{pfr}|]
|
||||||
pure pfr
|
pure pfr
|
||||||
where
|
where
|
||||||
getFreeBSDVersion = lift $ fmap _stdOut $ executeOut "freebsd-version" [] Nothing
|
getMajorVersion = T.intercalate "." . take 2 . T.split (== '.')
|
||||||
getDarwinVersion = lift $ fmap _stdOut $ executeOut "sw_vers"
|
getFreeBSDVersion =
|
||||||
|
liftIO $ fmap _stdOut $ executeOut "freebsd-version" [] Nothing
|
||||||
|
getDarwinVersion = liftIO $ fmap _stdOut $ executeOut "sw_vers"
|
||||||
["-productVersion"]
|
["-productVersion"]
|
||||||
Nothing
|
Nothing
|
||||||
|
|
||||||
|
|
||||||
getLinuxDistro :: (Alternative m, MonadCatch m, MonadIO m, MonadFail m)
|
getLinuxDistro :: (MonadCatch m, MonadIO m)
|
||||||
=> Excepts '[DistroNotFound] m (LinuxDistro, Maybe Versioning)
|
=> Excepts '[DistroNotFound] m (LinuxDistro, Maybe Versioning)
|
||||||
getLinuxDistro = do
|
getLinuxDistro = do
|
||||||
-- TODO: don't do alternative on IO, because it hides bugs
|
-- TODO: don't do alternative on IO, because it hides bugs
|
||||||
(name, ver) <- handleIO (\_ -> throwE DistroNotFound) $ lift $ asum
|
(name, ver) <- handleIO (\_ -> throwE DistroNotFound) $ liftIO $ asum
|
||||||
[ liftIO try_os_release
|
[ try_os_release
|
||||||
, try_lsb_release_cmd
|
, try_lsb_release_cmd
|
||||||
, liftIO try_redhat_release
|
, try_redhat_release
|
||||||
, liftIO try_debian_version
|
, try_debian_version
|
||||||
]
|
]
|
||||||
let parsedVer = ver >>= either (const Nothing) Just . versioning
|
let parsedVer = ver >>= either (const Nothing) Just . versioning
|
||||||
distro = if
|
distro = if
|
||||||
@@ -161,10 +163,9 @@ getLinuxDistro = do
|
|||||||
fmap osRelease <$> parseOsRelease
|
fmap osRelease <$> parseOsRelease
|
||||||
pure (T.pack name, fmap T.pack version_id)
|
pure (T.pack name, fmap T.pack version_id)
|
||||||
|
|
||||||
try_lsb_release_cmd :: (MonadFail m, MonadIO m)
|
try_lsb_release_cmd :: IO (Text, Maybe Text)
|
||||||
=> m (Text, Maybe Text)
|
|
||||||
try_lsb_release_cmd = do
|
try_lsb_release_cmd = do
|
||||||
(Just _) <- liftIO $ findExecutable lsb_release_cmd
|
(Just _) <- findExecutable lsb_release_cmd
|
||||||
name <- fmap _stdOut $ executeOut lsb_release_cmd ["-si"] Nothing
|
name <- fmap _stdOut $ executeOut lsb_release_cmd ["-si"] Nothing
|
||||||
ver <- fmap _stdOut $ executeOut lsb_release_cmd ["-sr"] Nothing
|
ver <- fmap _stdOut $ executeOut lsb_release_cmd ["-sr"] Nothing
|
||||||
pure (decUTF8Safe' name, Just $ decUTF8Safe' ver)
|
pure (decUTF8Safe' name, Just $ decUTF8Safe' ver)
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
{-# 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
|
||||||
@@ -25,21 +20,16 @@ module GHCup.Types
|
|||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Control.Applicative
|
|
||||||
import Control.DeepSeq ( NFData, rnf )
|
|
||||||
import Control.Monad.Logger
|
|
||||||
import Data.Map.Strict ( Map )
|
import Data.Map.Strict ( Map )
|
||||||
import Data.List.NonEmpty ( NonEmpty (..) )
|
import Data.List.NonEmpty ( NonEmpty (..) )
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
import Haskus.Utils.Variant.Excepts
|
|
||||||
import Text.PrettyPrint.HughesPJClass (Pretty, pPrint, text)
|
import Text.PrettyPrint.HughesPJClass (Pretty, pPrint, text)
|
||||||
import URI.ByteString
|
import URI.ByteString
|
||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
import Graphics.Vty ( Key(..) )
|
import Graphics.Vty ( Key(..) )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
import qualified Control.Monad.Trans.Class as Trans
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified GHC.Generics as GHC
|
import qualified GHC.Generics as GHC
|
||||||
|
|
||||||
@@ -62,12 +52,9 @@ data Key = KEsc | KChar Char | KBS | KEnter
|
|||||||
data GHCupInfo = GHCupInfo
|
data GHCupInfo = GHCupInfo
|
||||||
{ _toolRequirements :: ToolRequirements
|
{ _toolRequirements :: ToolRequirements
|
||||||
, _ghcupDownloads :: GHCupDownloads
|
, _ghcupDownloads :: GHCupDownloads
|
||||||
, _globalTools :: Map GlobalTool DownloadInfo
|
|
||||||
}
|
}
|
||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
instance NFData GHCupInfo
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------
|
-------------------------
|
||||||
@@ -87,8 +74,6 @@ data Requirements = Requirements
|
|||||||
}
|
}
|
||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
instance NFData Requirements
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -115,13 +100,6 @@ 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
|
|
||||||
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.
|
||||||
@@ -137,8 +115,6 @@ 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
|
||||||
@@ -149,8 +125,6 @@ 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"
|
||||||
@@ -177,8 +151,6 @@ 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"
|
||||||
@@ -201,8 +173,6 @@ 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"
|
||||||
@@ -228,8 +198,6 @@ 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"
|
||||||
@@ -256,7 +224,6 @@ data DownloadInfo = DownloadInfo
|
|||||||
}
|
}
|
||||||
deriving (Eq, Ord, GHC.Generic, Show)
|
deriving (Eq, Ord, GHC.Generic, Show)
|
||||||
|
|
||||||
instance NFData DownloadInfo
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -270,8 +237,6 @@ 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
|
||||||
@@ -284,10 +249,6 @@ 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
|
||||||
@@ -297,12 +258,11 @@ 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 Nothing
|
defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
||||||
|
|
||||||
data UserKeyBindings = UserKeyBindings
|
data UserKeyBindings = UserKeyBindings
|
||||||
{ kUp :: Maybe Key
|
{ kUp :: Maybe Key
|
||||||
@@ -330,9 +290,6 @@ 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
|
||||||
@@ -350,20 +307,7 @@ data AppState = AppState
|
|||||||
{ settings :: Settings
|
{ settings :: Settings
|
||||||
, dirs :: Dirs
|
, dirs :: Dirs
|
||||||
, keyBindings :: KeyBindings
|
, keyBindings :: KeyBindings
|
||||||
, ghcupInfo :: GHCupInfo
|
} deriving (Show)
|
||||||
, pfreq :: PlatformRequest
|
|
||||||
} 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
|
||||||
@@ -372,39 +316,29 @@ 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, GHC.Generic)
|
deriving Show
|
||||||
|
|
||||||
instance NFData Dirs
|
|
||||||
|
|
||||||
data KeepDirs = Always
|
data KeepDirs = Always
|
||||||
| Errors
|
| Errors
|
||||||
| Never
|
| Never
|
||||||
deriving (Eq, Show, Ord, GHC.Generic)
|
deriving (Eq, Show, Ord)
|
||||||
|
|
||||||
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, GHC.Generic)
|
deriving (Eq, Show, Ord)
|
||||||
|
|
||||||
instance NFData Downloader
|
|
||||||
|
|
||||||
data DebugInfo = DebugInfo
|
data DebugInfo = DebugInfo
|
||||||
{ diBaseDir :: FilePath
|
{ diBaseDir :: FilePath
|
||||||
@@ -427,9 +361,7 @@ data PlatformResult = PlatformResult
|
|||||||
{ _platform :: Platform
|
{ _platform :: Platform
|
||||||
, _distroVersion :: Maybe Versioning
|
, _distroVersion :: Maybe Versioning
|
||||||
}
|
}
|
||||||
deriving (Eq, Show, GHC.Generic)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
instance NFData PlatformResult
|
|
||||||
|
|
||||||
platResToString :: PlatformResult -> String
|
platResToString :: PlatformResult -> String
|
||||||
platResToString PlatformResult { _platform = plat, _distroVersion = Just v' }
|
platResToString PlatformResult { _platform = plat, _distroVersion = Just v' }
|
||||||
@@ -445,9 +377,7 @@ data PlatformRequest = PlatformRequest
|
|||||||
, _rPlatform :: Platform
|
, _rPlatform :: Platform
|
||||||
, _rVersion :: Maybe Versioning
|
, _rVersion :: Maybe Versioning
|
||||||
}
|
}
|
||||||
deriving (Eq, Show, GHC.Generic)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
instance NFData PlatformRequest
|
|
||||||
|
|
||||||
pfReqToString :: PlatformRequest -> String
|
pfReqToString :: PlatformRequest -> String
|
||||||
pfReqToString (PlatformRequest arch plat ver) =
|
pfReqToString (PlatformRequest arch plat ver) =
|
||||||
@@ -494,8 +424,6 @@ 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.
|
||||||
@@ -503,22 +431,9 @@ 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
|
||||||
|
|
||||||
instance Pretty Version where
|
instance Pretty Version where
|
||||||
pPrint = text . T.unpack . prettyVer
|
pPrint = text . T.unpack . prettyVer
|
||||||
|
|
||||||
|
|
||||||
instance (Monad m, Alternative m) => Alternative (LoggingT m) where
|
|
||||||
empty = Trans.lift empty
|
|
||||||
{-# INLINE empty #-}
|
|
||||||
m <|> n = LoggingT $ \ r -> runLoggingT m r <|> runLoggingT n r
|
|
||||||
{-# INLINE (<|>) #-}
|
|
||||||
|
|
||||||
|
|
||||||
instance MonadLogger m => MonadLogger (Excepts e m) where
|
|
||||||
monadLoggerLog a b c d = Trans.lift $ monadLoggerLog a b c d
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,16 +44,23 @@ import qualified Text.Megaparsec.Char as MPC
|
|||||||
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } { fieldLabelModifier = removeLensFieldLabel } ''Architecture
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } { fieldLabelModifier = removeLensFieldLabel } ''Architecture
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''LinuxDistro
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''LinuxDistro
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VSep
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Mess
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VUnit
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''MChunk
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''MChunk
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Platform
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Platform
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Mess
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''SemVer
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''SemVer
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Tool
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Tool
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''GlobalTool
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VSep
|
||||||
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VUnit
|
||||||
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VersionInfo
|
||||||
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''DownloadInfo
|
||||||
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''GHCupInfo
|
||||||
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Requirements
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''KeepDirs
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''KeepDirs
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Downloader
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Downloader
|
||||||
|
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''URLSource
|
||||||
|
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "u-") . T.pack . kebab $ str' } ''UserSettings
|
||||||
|
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "k-") . T.pack . kebab $ str' } ''UserKeyBindings
|
||||||
|
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''Key
|
||||||
|
|
||||||
instance ToJSON Tag where
|
instance ToJSON Tag where
|
||||||
toJSON Latest = String "Latest"
|
toJSON Latest = String "Latest"
|
||||||
@@ -190,12 +197,6 @@ instance ToJSONKey Tool where
|
|||||||
instance FromJSONKey Tool where
|
instance FromJSONKey Tool where
|
||||||
fromJSONKey = genericFromJSONKey defaultJSONKeyOptions
|
fromJSONKey = genericFromJSONKey defaultJSONKeyOptions
|
||||||
|
|
||||||
instance ToJSONKey GlobalTool where
|
|
||||||
toJSONKey = genericToJSONKey defaultJSONKeyOptions
|
|
||||||
|
|
||||||
instance FromJSONKey GlobalTool where
|
|
||||||
fromJSONKey = genericFromJSONKey defaultJSONKeyOptions
|
|
||||||
|
|
||||||
instance ToJSON TarDir where
|
instance ToJSON TarDir where
|
||||||
toJSON (RealDir p) = toJSON p
|
toJSON (RealDir p) = toJSON p
|
||||||
toJSON (RegexDir r) = object ["RegexDir" .= r]
|
toJSON (RegexDir r) = object ["RegexDir" .= r]
|
||||||
@@ -305,14 +306,3 @@ instance FromJSONKey (Maybe VersionRange) where
|
|||||||
just t = case MP.parse versionRangeP "" t of
|
just t = case MP.parse versionRangeP "" t of
|
||||||
Right x -> pure $ Just x
|
Right x -> pure $ Just x
|
||||||
Left e -> fail $ "Failure in (Maybe VersionRange) (FromJSONKey)" <> MP.errorBundlePretty e
|
Left e -> fail $ "Failure in (Maybe VersionRange) (FromJSONKey)" <> MP.errorBundlePretty e
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Requirements
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''DownloadInfo
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VersionInfo
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''GHCupInfo
|
|
||||||
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''URLSource
|
|
||||||
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''Key
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "k-") . T.pack . kebab $ str' } ''UserKeyBindings
|
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "u-") . T.pack . kebab $ str' } ''UserSettings
|
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE ConstraintKinds #-}
|
|
||||||
{-# LANGUAGE DataKinds #-}
|
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
|
||||||
{-# LANGUAGE AllowAmbiguousTypes #-}
|
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
Module : GHCup.Types.Optics
|
Module : GHCup.Types.Optics
|
||||||
@@ -18,7 +13,6 @@ 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
|
||||||
@@ -64,82 +58,3 @@ 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
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ module GHCup.Utils
|
|||||||
where
|
where
|
||||||
|
|
||||||
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
import GHCup.Download
|
|
||||||
#endif
|
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
@@ -51,11 +48,6 @@ import Control.Monad.Fail ( MonadFail )
|
|||||||
#endif
|
#endif
|
||||||
import Control.Monad.Logger
|
import Control.Monad.Logger
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Trans.Resource
|
|
||||||
hiding ( throwM )
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
import Data.Bits
|
|
||||||
#endif
|
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Foldable
|
import Data.Foldable
|
||||||
@@ -66,6 +58,7 @@ import Data.Maybe
|
|||||||
import Data.String.Interpolate
|
import Data.String.Interpolate
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
|
import Data.Word8
|
||||||
import GHC.IO.Exception
|
import GHC.IO.Exception
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Optics
|
import Optics
|
||||||
@@ -73,11 +66,7 @@ import Safe
|
|||||||
import System.Directory hiding ( findFiles )
|
import System.Directory hiding ( findFiles )
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.IO.Error
|
import System.IO.Error
|
||||||
#if defined(IS_WINDOWS)
|
import System.IO.Unsafe ( unsafeInterleaveIO )
|
||||||
import System.Win32.Console
|
|
||||||
import System.Win32.File hiding ( copyFile )
|
|
||||||
import System.Win32.Types
|
|
||||||
#endif
|
|
||||||
import Text.Regex.Posix
|
import Text.Regex.Posix
|
||||||
import URI.ByteString
|
import URI.ByteString
|
||||||
|
|
||||||
@@ -87,6 +76,7 @@ import qualified Codec.Archive.Tar as Tar
|
|||||||
import qualified Codec.Compression.BZip as BZip
|
import qualified Codec.Compression.BZip as BZip
|
||||||
import qualified Codec.Compression.GZip as GZip
|
import qualified Codec.Compression.GZip as GZip
|
||||||
import qualified Codec.Compression.Lzma as Lzma
|
import qualified Codec.Compression.Lzma as Lzma
|
||||||
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
@@ -103,42 +93,39 @@ import qualified Text.Megaparsec as MP
|
|||||||
|
|
||||||
|
|
||||||
-- | The symlink destination of a ghc tool.
|
-- | The symlink destination of a ghc tool.
|
||||||
ghcLinkDestination :: ( MonadReader env m
|
ghcLinkDestination :: (MonadReader AppState m, MonadThrow m, MonadIO 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
|
||||||
Dirs {..} <- getDirs
|
AppState { dirs = Dirs {..} } <- ask
|
||||||
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 env m
|
rmMinorSymlinks :: ( MonadReader AppState 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
|
||||||
Dirs {..} <- lift getDirs
|
AppState { dirs = Dirs {..} } <- lift ask
|
||||||
|
|
||||||
files <- liftE $ ghcToolFiles tv
|
files <- liftE $ ghcToolFiles tv
|
||||||
forM_ files $ \f -> do
|
forM_ files $ \f -> do
|
||||||
let f_xyz = f <> "-" <> T.unpack (prettyVer _tvVersion) <> exeExt
|
let f_xyz = f <> "-" <> T.unpack (prettyVer _tvVersion) <> exeExt
|
||||||
let fullF = binDir </> f_xyz
|
let fullF = binDir </> f_xyz
|
||||||
lift $ $(logDebug) [i|rm -f #{fullF}|]
|
lift $ $(logDebug) [i|rm -f #{fullF}|]
|
||||||
liftIO $ hideError doesNotExistErrorType $ rmLink fullF
|
liftIO $ hideError doesNotExistErrorType $ removeFile fullF
|
||||||
|
|
||||||
|
|
||||||
-- | Removes the set ghc version for the given target, if any.
|
-- | Removes the set ghc version for the given target, if any.
|
||||||
rmPlain :: ( MonadReader env m
|
rmPlain :: ( MonadReader AppState m
|
||||||
, HasDirs env
|
|
||||||
, MonadLogger m
|
, MonadLogger m
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
@@ -147,32 +134,32 @@ rmPlain :: ( MonadReader env m
|
|||||||
=> Maybe Text -- ^ target
|
=> Maybe Text -- ^ target
|
||||||
-> Excepts '[NotInstalled] m ()
|
-> Excepts '[NotInstalled] m ()
|
||||||
rmPlain target = do
|
rmPlain target = do
|
||||||
Dirs {..} <- lift getDirs
|
AppState { dirs = Dirs {..} } <- lift ask
|
||||||
mtv <- lift $ ghcSet target
|
mtv <- lift $ ghcSet target
|
||||||
forM_ mtv $ \tv -> do
|
forM_ mtv $ \tv -> do
|
||||||
files <- liftE $ ghcToolFiles tv
|
files <- liftE $ ghcToolFiles tv
|
||||||
forM_ files $ \f -> do
|
forM_ files $ \f -> do
|
||||||
let fullF = binDir </> f <> exeExt
|
let fullF = binDir </> f <> exeExt
|
||||||
lift $ $(logDebug) [i|rm -f #{fullF}|]
|
lift $ $(logDebug) [i|rm -f #{fullF}|]
|
||||||
liftIO $ hideError doesNotExistErrorType $ rmLink fullF
|
liftIO $ hideError doesNotExistErrorType $ removeFile fullF
|
||||||
-- old ghcup
|
-- old ghcup
|
||||||
let hdc_file = binDir </> "haddock-ghc" <> exeExt
|
let hdc_file = binDir </> "haddock-ghc" <> exeExt
|
||||||
lift $ $(logDebug) [i|rm -f #{hdc_file}|]
|
lift $ $(logDebug) [i|rm -f #{hdc_file}|]
|
||||||
liftIO $ hideError doesNotExistErrorType $ rmLink hdc_file
|
liftIO $ hideError doesNotExistErrorType $ removeFile hdc_file
|
||||||
|
|
||||||
|
|
||||||
-- | Remove the major GHC symlink, e.g. ghc-8.6.
|
-- | Remove the major GHC symlink, e.g. ghc-8.6.
|
||||||
rmMajorSymlinks :: ( MonadReader env m
|
rmMajorSymlinks :: ( MonadReader AppState 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
|
||||||
Dirs {..} <- lift getDirs
|
AppState { dirs = Dirs {..} } <- lift ask
|
||||||
(mj, mi) <- getMajorMinorV _tvVersion
|
(mj, mi) <- getMajorMinorV _tvVersion
|
||||||
let v' = intToText mj <> "." <> intToText mi
|
let v' = intToText mj <> "." <> intToText mi
|
||||||
|
|
||||||
@@ -181,7 +168,7 @@ rmMajorSymlinks tv@GHCTargetVersion{..} = do
|
|||||||
let f_xy = f <> "-" <> T.unpack v' <> exeExt
|
let f_xy = f <> "-" <> T.unpack v' <> exeExt
|
||||||
let fullF = binDir </> f_xy
|
let fullF = binDir </> f_xy
|
||||||
lift $ $(logDebug) [i|rm -f #{fullF}|]
|
lift $ $(logDebug) [i|rm -f #{fullF}|]
|
||||||
liftIO $ hideError doesNotExistErrorType $ rmLink fullF
|
liftIO $ hideError doesNotExistErrorType $ removeFile fullF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -192,57 +179,57 @@ rmMajorSymlinks tv@GHCTargetVersion{..} = do
|
|||||||
|
|
||||||
|
|
||||||
-- | Whether the given GHC versin is installed.
|
-- | Whether the given GHC versin is installed.
|
||||||
ghcInstalled :: (MonadIO m, MonadReader env m, HasDirs env, MonadThrow m) => GHCTargetVersion -> m Bool
|
ghcInstalled :: (MonadIO m, MonadReader AppState m, 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 env m, HasDirs env, MonadThrow m) => GHCTargetVersion -> m Bool
|
ghcSrcInstalled :: (MonadIO m, MonadReader AppState m, 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 env m, HasDirs env, MonadThrow m, MonadIO m)
|
ghcSet :: (MonadReader AppState m, 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
|
||||||
Dirs {..} <- getDirs
|
AppState {dirs = Dirs {..}} <- ask
|
||||||
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
|
||||||
|
|
||||||
-- link destination is of the form ../ghc/<ver>/bin/ghc
|
-- link destination is of the form ../ghc/<ver>/bin/ghc
|
||||||
-- for old ghcup, it is ../ghc/<ver>/bin/ghc-<ver>
|
-- for old ghcup, it is ../ghc/<ver>/bin/ghc-<ver>
|
||||||
liftIO $ handleIO' NoSuchThing (\_ -> pure Nothing) $ do
|
liftIO $ handleIO' NoSuchThing (\_ -> pure Nothing) $ do
|
||||||
link <- liftIO $ getLinkTarget ghcBin
|
link <- liftIO $ getSymbolicLinkTarget ghcBin
|
||||||
Just <$> ghcLinkVersion link
|
Just <$> ghcLinkVersion link
|
||||||
|
|
||||||
|
ghcLinkVersion :: MonadThrow m => FilePath -> m GHCTargetVersion
|
||||||
|
ghcLinkVersion (T.pack . dropSuffix exeExt -> t) = throwEither $ MP.parse parser "ghcLinkVersion" t
|
||||||
where
|
where
|
||||||
ghcLinkVersion :: MonadThrow m => FilePath -> m GHCTargetVersion
|
parser =
|
||||||
ghcLinkVersion (T.pack . dropSuffix exeExt -> t) = throwEither $ MP.parse parser "ghcLinkVersion" t
|
(do
|
||||||
where
|
_ <- parseUntil1 ghcSubPath
|
||||||
parser =
|
_ <- ghcSubPath
|
||||||
(do
|
r <- parseUntil1 pathSep
|
||||||
_ <- parseUntil1 ghcSubPath
|
rest <- MP.getInput
|
||||||
_ <- ghcSubPath
|
MP.setInput r
|
||||||
r <- parseUntil1 pathSep
|
x <- ghcTargetVerP
|
||||||
rest <- MP.getInput
|
MP.setInput rest
|
||||||
MP.setInput r
|
pure x
|
||||||
x <- ghcTargetVerP
|
)
|
||||||
MP.setInput rest
|
<* pathSep
|
||||||
pure x
|
<* MP.takeRest
|
||||||
)
|
<* MP.eof
|
||||||
<* pathSep
|
ghcSubPath = pathSep <* MP.chunk "ghc" *> pathSep
|
||||||
<* MP.takeRest
|
|
||||||
<* MP.eof
|
|
||||||
ghcSubPath = pathSep <* MP.chunk "ghc" *> pathSep
|
|
||||||
|
|
||||||
-- | 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 env m, HasDirs env, MonadIO m) => m [Either FilePath GHCTargetVersion]
|
getInstalledGHCs :: (MonadReader AppState m, 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
|
||||||
@@ -252,58 +239,72 @@ 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
|
getInstalledCabals :: (MonadLogger m, MonadReader AppState m, MonadIO m, MonadCatch m)
|
||||||
, MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, MonadIO m
|
|
||||||
, MonadCatch m
|
|
||||||
)
|
|
||||||
=> m [Either FilePath Version]
|
=> m [Either FilePath Version]
|
||||||
getInstalledCabals = do
|
getInstalledCabals = do
|
||||||
Dirs {..} <- getDirs
|
cs <- cabalSet -- for legacy cabal
|
||||||
|
getInstalledCabals' cs
|
||||||
|
|
||||||
|
|
||||||
|
getInstalledCabals' :: (MonadLogger m, MonadReader AppState m, MonadIO m, MonadCatch m)
|
||||||
|
=> Maybe Version
|
||||||
|
-> m [Either FilePath Version]
|
||||||
|
getInstalledCabals' cs = do
|
||||||
|
AppState {dirs = Dirs {..}} <- ask
|
||||||
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
||||||
binDir
|
binDir
|
||||||
(makeRegexOpts compExtended execBlank ([s|^cabal-.*$|] :: ByteString))
|
(makeRegexOpts compExtended execBlank ([s|^cabal-.*$|] :: ByteString))
|
||||||
vs <- forM bins $ \f -> case version . T.pack <$> (stripSuffix exeExt =<< stripPrefix "cabal-" f) of
|
vs <- forM bins $ \f -> case fmap (version . T.pack . dropSuffix exeExt) . stripPrefix "cabal-" $ f of
|
||||||
Just (Right r) -> pure $ Right r
|
Just (Right r) -> pure $ Right r
|
||||||
Just (Left _) -> pure $ Left f
|
Just (Left _) -> pure $ Left f
|
||||||
Nothing -> pure $ Left f
|
Nothing -> pure $ Left f
|
||||||
pure $ nub vs
|
pure $ maybe vs (\x -> nub $ Right x:vs) cs
|
||||||
|
|
||||||
|
|
||||||
-- | Whether the given cabal version is installed.
|
-- | Whether the given cabal version is installed.
|
||||||
cabalInstalled :: (MonadLogger m, MonadIO m, MonadReader env m, HasDirs env, MonadCatch m) => Version -> m Bool
|
cabalInstalled :: (MonadLogger m, MonadIO m, MonadReader AppState m, 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 env m, HasDirs env, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
|
cabalSet :: (MonadLogger m, MonadReader AppState m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
|
||||||
cabalSet = do
|
cabalSet = do
|
||||||
Dirs {..} <- getDirs
|
AppState {dirs = Dirs {..}} <- ask
|
||||||
let cabalbin = binDir </> "cabal" <> exeExt
|
let cabalbin = binDir </> "cabal" <> exeExt
|
||||||
|
b <- handleIO (\_ -> pure False) $ liftIO $ pathIsSymbolicLink cabalbin
|
||||||
handleIO' NoSuchThing (\_ -> pure Nothing) $ do
|
if
|
||||||
broken <- liftIO $ isBrokenSymlink cabalbin
|
| b -> do
|
||||||
if broken
|
handleIO' NoSuchThing (\_ -> pure Nothing) $ do
|
||||||
then pure Nothing
|
broken <- liftIO $ isBrokenSymlink cabalbin
|
||||||
else do
|
if broken
|
||||||
link <- liftIO
|
then pure Nothing
|
||||||
$ handleIO' InvalidArgument
|
else do
|
||||||
(\e -> pure $ Left (toException e))
|
link <- liftIO $ getSymbolicLinkTarget cabalbin
|
||||||
$ fmap Right $ getLinkTarget cabalbin
|
case linkVersion link of
|
||||||
case linkVersion =<< link of
|
Right v -> pure $ Just v
|
||||||
Right v -> pure $ Just v
|
Left err -> do
|
||||||
Left err -> do
|
$(logWarn) [i|Failed to parse cabal symlink target with: "#{err}". The symlink #{cabalbin} needs to point to valid cabal binary, such as 'cabal-3.4.0.0'.|]
|
||||||
$(logWarn) [i|Failed to parse cabal symlink target with: "#{err}". The symlink #{cabalbin} needs to point to valid cabal binary, such as 'cabal-3.4.0.0'.|]
|
pure Nothing
|
||||||
pure Nothing
|
| otherwise -> do -- legacy behavior
|
||||||
|
mc <- liftIO $ handleIO (\_ -> pure Nothing) $ fmap Just $ executeOut
|
||||||
|
cabalbin
|
||||||
|
["--numeric-version"]
|
||||||
|
Nothing
|
||||||
|
fmap join $ forM mc $ \c -> if
|
||||||
|
| not (BL.null (_stdOut c)), _exitCode c == ExitSuccess -> do
|
||||||
|
let reportedVer = fst . B.spanEnd (== _lf) . BL.toStrict . _stdOut $ c
|
||||||
|
case version $ decUTF8Safe reportedVer of
|
||||||
|
Left e -> throwM e
|
||||||
|
Right r -> pure $ Just r
|
||||||
|
| otherwise -> pure Nothing
|
||||||
where
|
where
|
||||||
-- We try to be extra permissive with link destination parsing,
|
-- We try to be extra permissive with link destination parsing,
|
||||||
-- because of:
|
-- because of:
|
||||||
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/119
|
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/119
|
||||||
linkVersion :: MonadThrow m => FilePath -> m Version
|
linkVersion :: MonadThrow m => FilePath -> m Version
|
||||||
linkVersion = throwEither . MP.parse parser "linkVersion" . T.pack . dropSuffix exeExt
|
linkVersion = throwEither . MP.parse parser "" . T.pack . dropSuffix exeExt
|
||||||
|
|
||||||
parser
|
parser
|
||||||
= MP.try (stripAbsolutePath *> cabalParse)
|
= MP.try (stripAbsolutePath *> cabalParse)
|
||||||
@@ -325,10 +326,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 env m, HasDirs env, MonadIO m, MonadCatch m)
|
getInstalledHLSs :: (MonadReader AppState m, MonadIO m, MonadCatch m)
|
||||||
=> m [Either FilePath Version]
|
=> m [Either FilePath Version]
|
||||||
getInstalledHLSs = do
|
getInstalledHLSs = do
|
||||||
Dirs {..} <- getDirs
|
AppState { dirs = Dirs {..} } <- ask
|
||||||
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
||||||
binDir
|
binDir
|
||||||
(makeRegexOpts compExtended
|
(makeRegexOpts compExtended
|
||||||
@@ -337,7 +338,7 @@ getInstalledHLSs = do
|
|||||||
)
|
)
|
||||||
forM bins $ \f ->
|
forM bins $ \f ->
|
||||||
case
|
case
|
||||||
version . T.pack <$> (stripSuffix exeExt =<< stripPrefix "haskell-language-server-wrapper-" f)
|
fmap (version . T.pack . dropSuffix exeExt) . stripPrefix "haskell-language-server-wrapper-" $ f
|
||||||
of
|
of
|
||||||
Just (Right r) -> pure $ Right r
|
Just (Right r) -> pure $ Right r
|
||||||
Just (Left _) -> pure $ Left f
|
Just (Left _) -> pure $ Left f
|
||||||
@@ -345,10 +346,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 env m, HasDirs env, MonadIO m, MonadCatch m)
|
getInstalledStacks :: (MonadReader AppState m, MonadIO m, MonadCatch m)
|
||||||
=> m [Either FilePath Version]
|
=> m [Either FilePath Version]
|
||||||
getInstalledStacks = do
|
getInstalledStacks = do
|
||||||
Dirs {..} <- getDirs
|
AppState { dirs = Dirs {..} } <- ask
|
||||||
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
||||||
binDir
|
binDir
|
||||||
(makeRegexOpts compExtended
|
(makeRegexOpts compExtended
|
||||||
@@ -356,60 +357,42 @@ getInstalledStacks = do
|
|||||||
([s|^stack-.*$|] :: ByteString)
|
([s|^stack-.*$|] :: ByteString)
|
||||||
)
|
)
|
||||||
forM bins $ \f ->
|
forM bins $ \f ->
|
||||||
case version . T.pack <$> (stripSuffix exeExt =<< stripPrefix "stack-" f) of
|
case
|
||||||
|
fmap (version . T.pack . dropSuffix exeExt) . stripPrefix "stack-" $ f
|
||||||
|
of
|
||||||
Just (Right r) -> pure $ Right r
|
Just (Right r) -> pure $ Right r
|
||||||
Just (Left _) -> pure $ Left f
|
Just (Left _) -> pure $ Left f
|
||||||
Nothing -> pure $ Left f
|
Nothing -> pure $ Left f
|
||||||
|
|
||||||
-- 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 env m, HasDirs env, MonadIO m, MonadThrow m, MonadCatch m, MonadLogger m) => m (Maybe Version)
|
stackSet :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
|
||||||
stackSet = do
|
stackSet = do
|
||||||
Dirs {..} <- getDirs
|
AppState {dirs = Dirs {..}} <- ask
|
||||||
let stackBin = binDir </> "stack" <> exeExt
|
let stackBin = binDir </> "stack" <> exeExt
|
||||||
|
|
||||||
handleIO' NoSuchThing (\_ -> pure Nothing) $ do
|
liftIO $ handleIO' NoSuchThing (\_ -> pure Nothing) $ do
|
||||||
broken <- liftIO $ isBrokenSymlink stackBin
|
broken <- isBrokenSymlink stackBin
|
||||||
if broken
|
if broken
|
||||||
then pure Nothing
|
then pure Nothing
|
||||||
else do
|
else do
|
||||||
link <- liftIO
|
link <- liftIO $ getSymbolicLinkTarget stackBin
|
||||||
$ handleIO' InvalidArgument
|
Just <$> linkVersion link
|
||||||
(\e -> pure $ Left (toException e))
|
|
||||||
$ fmap Right $ getLinkTarget stackBin
|
|
||||||
case linkVersion =<< link of
|
|
||||||
Right v -> pure $ Just v
|
|
||||||
Left err -> do
|
|
||||||
$(logWarn) [i|Failed to parse stack symlink target with: "#{err}". The symlink #{stackBin} needs to point to valid stack binary, such as 'stack-2.7.1'.|]
|
|
||||||
pure Nothing
|
|
||||||
where
|
where
|
||||||
linkVersion :: MonadThrow m => FilePath -> m Version
|
linkVersion :: MonadThrow m => FilePath -> m Version
|
||||||
linkVersion = throwEither . MP.parse parser "" . T.pack . dropSuffix exeExt
|
linkVersion = throwEither . MP.parse parser "" . T.pack . dropSuffix exeExt
|
||||||
where
|
where
|
||||||
parser
|
parser =
|
||||||
= MP.try (stripAbsolutePath *> cabalParse)
|
MP.chunk "stack-" *> version'
|
||||||
<|> MP.try (stripRelativePath *> cabalParse)
|
|
||||||
<|> cabalParse
|
|
||||||
-- parses the version of "stack-2.7.1" -> "2.7.1"
|
|
||||||
cabalParse = MP.chunk "stack-" *> version'
|
|
||||||
-- parses any path component ending with path separator,
|
|
||||||
-- e.g. "foo/"
|
|
||||||
stripPathComponet = parseUntil1 pathSep *> pathSep
|
|
||||||
-- parses an absolute path up until the last path separator,
|
|
||||||
-- e.g. "/bar/baz/foo" -> "/bar/baz/", leaving "foo"
|
|
||||||
stripAbsolutePath = pathSep *> MP.many (MP.try stripPathComponet)
|
|
||||||
-- parses a relative path up until the last path separator,
|
|
||||||
-- e.g. "bar/baz/foo" -> "bar/baz/", leaving "foo"
|
|
||||||
stripRelativePath = MP.many (MP.try stripPathComponet)
|
|
||||||
|
|
||||||
-- | Whether the given Stack version is installed.
|
-- | Whether the given Stack version is installed.
|
||||||
stackInstalled :: (MonadIO m, MonadReader env m, HasDirs env, MonadCatch m) => Version -> m Bool
|
stackInstalled :: (MonadIO m, MonadReader AppState m, 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 env m, HasDirs env, MonadCatch m) => Version -> m Bool
|
hlsInstalled :: (MonadIO m, MonadReader AppState m, 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
|
||||||
@@ -417,9 +400,9 @@ hlsInstalled ver = do
|
|||||||
|
|
||||||
|
|
||||||
-- Return the currently set hls version, if any.
|
-- Return the currently set hls version, if any.
|
||||||
hlsSet :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
|
hlsSet :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
|
||||||
hlsSet = do
|
hlsSet = do
|
||||||
Dirs {..} <- getDirs
|
AppState {dirs = Dirs {..}} <- ask
|
||||||
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
|
||||||
@@ -427,32 +410,18 @@ hlsSet = do
|
|||||||
if broken
|
if broken
|
||||||
then pure Nothing
|
then pure Nothing
|
||||||
else do
|
else do
|
||||||
link <- liftIO $ getLinkTarget hlsBin
|
link <- liftIO $ getSymbolicLinkTarget hlsBin
|
||||||
Just <$> linkVersion link
|
Just <$> linkVersion link
|
||||||
where
|
where
|
||||||
linkVersion :: MonadThrow m => FilePath -> m Version
|
linkVersion :: MonadThrow m => FilePath -> m Version
|
||||||
linkVersion = throwEither . MP.parse parser "" . T.pack . dropSuffix exeExt
|
linkVersion = throwEither . MP.parse parser "" . T.pack . dropSuffix exeExt
|
||||||
where
|
where
|
||||||
parser
|
parser =
|
||||||
= MP.try (stripAbsolutePath *> cabalParse)
|
MP.chunk "haskell-language-server-wrapper-" *> version'
|
||||||
<|> MP.try (stripRelativePath *> cabalParse)
|
|
||||||
<|> cabalParse
|
|
||||||
-- parses the version of "haskell-language-server-wrapper-1.1.0" -> "1.1.0"
|
|
||||||
cabalParse = MP.chunk "haskell-language-server-wrapper-" *> version'
|
|
||||||
-- parses any path component ending with path separator,
|
|
||||||
-- e.g. "foo/"
|
|
||||||
stripPathComponet = parseUntil1 pathSep *> pathSep
|
|
||||||
-- parses an absolute path up until the last path separator,
|
|
||||||
-- e.g. "/bar/baz/foo" -> "/bar/baz/", leaving "foo"
|
|
||||||
stripAbsolutePath = pathSep *> MP.many (MP.try stripPathComponet)
|
|
||||||
-- parses a relative path up until the last path separator,
|
|
||||||
-- e.g. "bar/baz/foo" -> "bar/baz/", leaving "foo"
|
|
||||||
stripRelativePath = MP.many (MP.try stripPathComponet)
|
|
||||||
|
|
||||||
|
|
||||||
-- | Return the GHC versions the currently selected HLS supports.
|
-- | Return the GHC versions the currently selected HLS supports.
|
||||||
hlsGHCVersions :: ( MonadReader env m
|
hlsGHCVersions :: ( MonadReader AppState m
|
||||||
, HasDirs env
|
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, MonadCatch m
|
, MonadCatch m
|
||||||
@@ -475,11 +444,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 env m, HasDirs env, MonadIO m)
|
hlsServerBinaries :: (MonadReader AppState m, MonadIO m)
|
||||||
=> Version
|
=> Version
|
||||||
-> m [FilePath]
|
-> m [FilePath]
|
||||||
hlsServerBinaries ver = do
|
hlsServerBinaries ver = do
|
||||||
Dirs {..} <- getDirs
|
AppState { dirs = Dirs {..} } <- ask
|
||||||
liftIO $ handleIO (\_ -> pure []) $ findFiles
|
liftIO $ handleIO (\_ -> pure []) $ findFiles
|
||||||
binDir
|
binDir
|
||||||
(makeRegexOpts
|
(makeRegexOpts
|
||||||
@@ -491,12 +460,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 env m, HasDirs env, MonadThrow m, MonadIO m)
|
hlsWrapperBinary :: (MonadReader AppState m, MonadThrow m, MonadIO m)
|
||||||
=> Version
|
=> Version
|
||||||
-> m (Maybe FilePath)
|
-> m (Maybe FilePath)
|
||||||
hlsWrapperBinary ver = do
|
hlsWrapperBinary ver = do
|
||||||
Dirs {..} <- getDirs
|
AppState { dirs = Dirs {..} } <- ask
|
||||||
wrapper <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
wrapper <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
||||||
binDir
|
binDir
|
||||||
(makeRegexOpts
|
(makeRegexOpts
|
||||||
compExtended
|
compExtended
|
||||||
@@ -512,7 +481,7 @@ hlsWrapperBinary ver = do
|
|||||||
|
|
||||||
|
|
||||||
-- | Get all binaries for an hls version, if any.
|
-- | Get all binaries for an hls version, if any.
|
||||||
hlsAllBinaries :: (MonadReader env m, HasDirs env, MonadIO m, MonadThrow m) => Version -> m [FilePath]
|
hlsAllBinaries :: (MonadReader AppState m, 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
|
||||||
@@ -520,9 +489,9 @@ hlsAllBinaries ver = do
|
|||||||
|
|
||||||
|
|
||||||
-- | Get the active symlinks for hls.
|
-- | Get the active symlinks for hls.
|
||||||
hlsSymlinks :: (MonadReader env m, HasDirs env, MonadIO m, MonadCatch m) => m [FilePath]
|
hlsSymlinks :: (MonadReader AppState m, MonadIO m, MonadCatch m) => m [FilePath]
|
||||||
hlsSymlinks = do
|
hlsSymlinks = do
|
||||||
Dirs {..} <- getDirs
|
AppState { dirs = Dirs {..} } <- ask
|
||||||
oldSyms <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
oldSyms <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
||||||
binDir
|
binDir
|
||||||
(makeRegexOpts compExtended
|
(makeRegexOpts compExtended
|
||||||
@@ -531,7 +500,7 @@ hlsSymlinks = do
|
|||||||
)
|
)
|
||||||
filterM
|
filterM
|
||||||
( liftIO
|
( liftIO
|
||||||
. pathIsLink
|
. pathIsSymbolicLink
|
||||||
. (binDir </>)
|
. (binDir </>)
|
||||||
)
|
)
|
||||||
oldSyms
|
oldSyms
|
||||||
@@ -558,7 +527,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 env m, HasDirs env, MonadIO m, MonadThrow m)
|
getGHCForMajor :: (MonadReader AppState m, 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
|
||||||
@@ -738,19 +707,37 @@ 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 ]--
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
||||||
|
urlBaseName :: ByteString -- ^ the url path (without scheme and host)
|
||||||
|
-> ByteString
|
||||||
|
urlBaseName = snd . B.breakEnd (== _slash) . urlDecode False
|
||||||
|
|
||||||
|
|
||||||
-- | Get tool files from @~\/.ghcup\/bin\/ghc\/\<ver\>\/bin\/\*@
|
-- | Get tool files from @~\/.ghcup\/bin\/ghc\/\<ver\>\/bin\/\*@
|
||||||
-- while ignoring @*-\<ver\>@ symlinks and accounting for cross triple prefix.
|
-- while ignoring @*-\<ver\>@ symlinks and accounting for cross triple prefix.
|
||||||
--
|
--
|
||||||
-- Returns unversioned relative files without extension, e.g.:
|
-- Returns unversioned relative files without extension, e.g.:
|
||||||
--
|
--
|
||||||
-- - @["hsc2hs","haddock","hpc","runhaskell","ghc","ghc-pkg","ghci","runghc","hp2ps"]@
|
-- - @["hsc2hs","haddock","hpc","runhaskell","ghc","ghc-pkg","ghci","runghc","hp2ps"]@
|
||||||
ghcToolFiles :: (MonadReader env m, HasDirs env, MonadThrow m, MonadFail m, MonadIO m)
|
ghcToolFiles :: (MonadReader AppState m, MonadThrow m, MonadFail m, MonadIO m)
|
||||||
=> GHCTargetVersion
|
=> GHCTargetVersion
|
||||||
-> Excepts '[NotInstalled] m [FilePath]
|
-> Excepts '[NotInstalled] m [FilePath]
|
||||||
ghcToolFiles ver = do
|
ghcToolFiles ver = do
|
||||||
@@ -813,12 +800,7 @@ 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
|
make :: (MonadThrow m, MonadIO m, MonadReader AppState m)
|
||||||
, MonadIO m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
)
|
|
||||||
=> [String]
|
=> [String]
|
||||||
-> Maybe FilePath
|
-> Maybe FilePath
|
||||||
-> m (Either ProcessError ())
|
-> m (Either ProcessError ())
|
||||||
@@ -828,20 +810,19 @@ 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 env m, HasDirs env, MonadIO m)
|
makeOut :: [String]
|
||||||
=> [String]
|
|
||||||
-> Maybe FilePath
|
-> Maybe FilePath
|
||||||
-> m CapturedProcess
|
-> IO CapturedProcess
|
||||||
makeOut args workdir = do
|
makeOut args workdir = do
|
||||||
spaths <- liftIO getSearchPath
|
spaths <- liftIO getSearchPath
|
||||||
has_gmake <- isJust <$> liftIO (searchPath spaths "gmake")
|
has_gmake <- isJust <$> liftIO (searchPath spaths "gmake")
|
||||||
let mymake = if has_gmake then "gmake" else "make"
|
let mymake = if has_gmake then "gmake" else "make"
|
||||||
executeOut mymake args workdir
|
liftIO $ executeOut mymake args workdir
|
||||||
|
|
||||||
|
|
||||||
-- | 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 env m, HasDirs env, MonadLogger m, MonadIO m)
|
applyPatches :: (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 ()
|
||||||
@@ -850,7 +831,7 @@ applyPatches pdir ddir = do
|
|||||||
forM_ (sort patches) $ \patch' -> do
|
forM_ (sort patches) $ \patch' -> do
|
||||||
lift $ $(logInfo) [i|Applying patch #{patch'}|]
|
lift $ $(logInfo) [i|Applying patch #{patch'}|]
|
||||||
fmap (either (const Nothing) Just)
|
fmap (either (const Nothing) Just)
|
||||||
(exec
|
(liftIO $ exec
|
||||||
"patch"
|
"patch"
|
||||||
["-p1", "-i", patch']
|
["-p1", "-i", patch']
|
||||||
(Just ddir)
|
(Just ddir)
|
||||||
@@ -859,10 +840,7 @@ applyPatches pdir ddir = do
|
|||||||
|
|
||||||
|
|
||||||
-- | https://gitlab.haskell.org/ghc/ghc/-/issues/17353
|
-- | https://gitlab.haskell.org/ghc/ghc/-/issues/17353
|
||||||
darwinNotarization :: (MonadReader env m, HasDirs env, MonadIO m)
|
darwinNotarization :: Platform -> FilePath -> IO (Either ProcessError ())
|
||||||
=> Platform
|
|
||||||
-> FilePath
|
|
||||||
-> m (Either ProcessError ())
|
|
||||||
darwinNotarization Darwin path = exec
|
darwinNotarization Darwin path = exec
|
||||||
"xattr"
|
"xattr"
|
||||||
["-r", "-d", "com.apple.quarantine", path]
|
["-r", "-d", "com.apple.quarantine", path]
|
||||||
@@ -882,20 +860,20 @@ 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 env m, HasDirs env, HasSettings env, MonadIO m, MonadMask m)
|
runBuildAction :: (Show (V e), MonadReader AppState m, 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
|
||||||
Settings {..} <- lift getSettings
|
AppState { settings = Settings {..} } <- lift ask
|
||||||
let exAction = do
|
let exAction = do
|
||||||
forM_ instdir $ \dir ->
|
forM_ instdir $ \dir ->
|
||||||
liftIO $ hideError doesNotExistErrorType $ rmPath dir
|
liftIO $ hideError doesNotExistErrorType $ removeDirectoryRecursive dir
|
||||||
when (keepDirs == Never)
|
when (keepDirs == Never)
|
||||||
$ liftIO
|
$ liftIO
|
||||||
$ hideError doesNotExistErrorType
|
$ hideError doesNotExistErrorType
|
||||||
$ rmPath bdir
|
$ removeDirectoryRecursive bdir
|
||||||
v <-
|
v <-
|
||||||
flip onException exAction
|
flip onException exAction
|
||||||
$ catchAllE
|
$ catchAllE
|
||||||
@@ -904,10 +882,90 @@ runBuildAction bdir instdir action = do
|
|||||||
throwE (BuildFailed bdir es)
|
throwE (BuildFailed bdir es)
|
||||||
) action
|
) action
|
||||||
|
|
||||||
when (keepDirs == Never || keepDirs == Errors) $ liftIO $ rmPath bdir
|
when (keepDirs == Never || keepDirs == Errors) $ liftIO $ removeDirectoryRecursive
|
||||||
|
bdir
|
||||||
pure v
|
pure v
|
||||||
|
|
||||||
|
|
||||||
|
-- | More permissive version of 'createDirRecursive'. This doesn't
|
||||||
|
-- error when the destination is a symlink to a directory.
|
||||||
|
createDirRecursive' :: FilePath -> IO ()
|
||||||
|
createDirRecursive' p =
|
||||||
|
handleIO (\e -> if isAlreadyExistsError e then isSymlinkDir e else throwIO e)
|
||||||
|
. createDirectoryIfMissing True
|
||||||
|
$ p
|
||||||
|
|
||||||
|
where
|
||||||
|
isSymlinkDir e = do
|
||||||
|
ft <- pathIsSymbolicLink p
|
||||||
|
case ft of
|
||||||
|
True -> do
|
||||||
|
rp <- canonicalizePath p
|
||||||
|
rft <- doesDirectoryExist rp
|
||||||
|
case rft of
|
||||||
|
True -> pure ()
|
||||||
|
_ -> throwIO e
|
||||||
|
_ -> throwIO e
|
||||||
|
|
||||||
|
|
||||||
|
-- | Recursively copy the contents of one directory to another path.
|
||||||
|
--
|
||||||
|
-- This is a rip-off of Cabal library.
|
||||||
|
copyDirectoryRecursive :: FilePath -> FilePath -> IO ()
|
||||||
|
copyDirectoryRecursive srcDir destDir = do
|
||||||
|
srcFiles <- getDirectoryContentsRecursive srcDir
|
||||||
|
copyFilesWith copyFile destDir [ (srcDir, f)
|
||||||
|
| f <- srcFiles ]
|
||||||
|
where
|
||||||
|
-- | Common implementation of 'copyFiles', 'installOrdinaryFiles',
|
||||||
|
-- 'installExecutableFiles' and 'installMaybeExecutableFiles'.
|
||||||
|
copyFilesWith :: (FilePath -> FilePath -> IO ())
|
||||||
|
-> FilePath -> [(FilePath, FilePath)] -> IO ()
|
||||||
|
copyFilesWith doCopy targetDir srcFiles = do
|
||||||
|
|
||||||
|
-- Create parent directories for everything
|
||||||
|
let dirs = map (targetDir </>) . nub . map (takeDirectory . snd) $ srcFiles
|
||||||
|
traverse_ (createDirectoryIfMissing True) dirs
|
||||||
|
|
||||||
|
-- Copy all the files
|
||||||
|
sequence_ [ let src = srcBase </> srcFile
|
||||||
|
dest = targetDir </> srcFile
|
||||||
|
in doCopy src dest
|
||||||
|
| (srcBase, srcFile) <- srcFiles ]
|
||||||
|
|
||||||
|
-- | List all the files in a directory and all subdirectories.
|
||||||
|
--
|
||||||
|
-- The order places files in sub-directories after all the files in their
|
||||||
|
-- parent directories. The list is generated lazily so is not well defined if
|
||||||
|
-- the source directory structure changes before the list is used.
|
||||||
|
--
|
||||||
|
getDirectoryContentsRecursive :: FilePath -> IO [FilePath]
|
||||||
|
getDirectoryContentsRecursive topdir = recurseDirectories [""]
|
||||||
|
where
|
||||||
|
recurseDirectories :: [FilePath] -> IO [FilePath]
|
||||||
|
recurseDirectories [] = return []
|
||||||
|
recurseDirectories (dir:dirs) = unsafeInterleaveIO $ do
|
||||||
|
(files, dirs') <- collect [] [] =<< getDirectoryContents (topdir </> dir)
|
||||||
|
files' <- recurseDirectories (dirs' ++ dirs)
|
||||||
|
return (files ++ files')
|
||||||
|
|
||||||
|
where
|
||||||
|
collect files dirs' [] = return (reverse files
|
||||||
|
,reverse dirs')
|
||||||
|
collect files dirs' (entry:entries) | ignore entry
|
||||||
|
= collect files dirs' entries
|
||||||
|
collect files dirs' (entry:entries) = do
|
||||||
|
let dirEntry = dir </> entry
|
||||||
|
isDirectory <- doesDirectoryExist (topdir </> dirEntry)
|
||||||
|
if isDirectory
|
||||||
|
then collect files (dirEntry:dirs') entries
|
||||||
|
else collect (dirEntry:files) dirs' entries
|
||||||
|
|
||||||
|
ignore ['.'] = True
|
||||||
|
ignore ['.', '.'] = True
|
||||||
|
ignore _ = False
|
||||||
|
|
||||||
|
|
||||||
getVersionInfo :: Version
|
getVersionInfo :: Version
|
||||||
-> Tool
|
-> Tool
|
||||||
-> GHCupDownloads
|
-> GHCupDownloads
|
||||||
@@ -921,6 +979,15 @@ getVersionInfo v' tool =
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
-- Gathering monoidal values
|
||||||
|
traverseFold :: (Foldable t, Applicative m, Monoid b) => (a -> m b) -> t a -> m b
|
||||||
|
traverseFold f = foldl (\mb a -> (<>) <$> mb <*> f a) (pure mempty)
|
||||||
|
|
||||||
|
-- | Gathering monoidal values
|
||||||
|
forFold :: (Foldable t, Applicative m, Monoid b) => t a -> (a -> m b) -> m b
|
||||||
|
forFold = \t -> (`traverseFold` t)
|
||||||
|
|
||||||
|
|
||||||
-- | The file extension for executables.
|
-- | The file extension for executables.
|
||||||
exeExt :: String
|
exeExt :: String
|
||||||
#if defined(IS_WINDOWS)
|
#if defined(IS_WINDOWS)
|
||||||
@@ -929,182 +996,3 @@ exeExt = ".exe"
|
|||||||
exeExt = ""
|
exeExt = ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
-- | The file extension for executables.
|
|
||||||
exeExt' :: ByteString
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
exeExt' = ".exe"
|
|
||||||
#else
|
|
||||||
exeExt' = ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | Enables ANSI support on windows, does nothing on unix.
|
|
||||||
--
|
|
||||||
-- Returns 'Left str' on errors and 'Right bool' on success, where
|
|
||||||
-- 'bool' markes whether ansi support was already enabled.
|
|
||||||
--
|
|
||||||
-- This function never crashes.
|
|
||||||
--
|
|
||||||
-- Rip-off of https://docs.rs/ansi_term/0.12.1/x86_64-pc-windows-msvc/src/ansi_term/windows.rs.html#10-61
|
|
||||||
enableAnsiSupport :: IO (Either String Bool)
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
enableAnsiSupport = handleIO (pure . Left . displayException) $ do
|
|
||||||
-- ref: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
|
|
||||||
-- Using `CreateFileW("CONOUT$", ...)` to retrieve the console handle works correctly even if STDOUT and/or STDERR are redirected
|
|
||||||
h <- createFile "CONOUT$" (gENERIC_WRITE .|. gENERIC_READ)
|
|
||||||
fILE_SHARE_WRITE Nothing oPEN_EXISTING 0 Nothing
|
|
||||||
when (h == iNVALID_HANDLE_VALUE ) $ fail "invalid handle value"
|
|
||||||
|
|
||||||
-- ref: https://docs.microsoft.com/en-us/windows/console/getconsolemode
|
|
||||||
m <- getConsoleMode h
|
|
||||||
|
|
||||||
-- VT processing not already enabled?
|
|
||||||
if ((m .&. eNABLE_VIRTUAL_TERMINAL_PROCESSING) == 0)
|
|
||||||
-- https://docs.microsoft.com/en-us/windows/console/setconsolemode
|
|
||||||
then setConsoleMode h (m .|. eNABLE_VIRTUAL_TERMINAL_PROCESSING)
|
|
||||||
>> pure (Right False)
|
|
||||||
else pure (Right True)
|
|
||||||
#else
|
|
||||||
enableAnsiSupport = pure (Right True)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | On unix, we can use symlinks, so we just get the
|
|
||||||
-- symbolic link target.
|
|
||||||
--
|
|
||||||
-- On windows, we have to emulate symlinks via shims,
|
|
||||||
-- see 'createLink'.
|
|
||||||
getLinkTarget :: FilePath -> IO FilePath
|
|
||||||
getLinkTarget fp = do
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
content <- readFile (dropExtension fp <.> "shim")
|
|
||||||
[p] <- pure . filter ("path = " `isPrefixOf`) . lines $ content
|
|
||||||
pure $ stripNewline $ dropPrefix "path = " p
|
|
||||||
#else
|
|
||||||
getSymbolicLinkTarget fp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | Checks whether the path is a link.
|
|
||||||
pathIsLink :: FilePath -> IO Bool
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
pathIsLink fp = doesPathExist (dropExtension fp <.> "shim")
|
|
||||||
#else
|
|
||||||
pathIsLink = pathIsSymbolicLink
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
rmLink :: FilePath -> IO ()
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
rmLink fp = do
|
|
||||||
hideError doesNotExistErrorType . liftIO . rmFile $ fp
|
|
||||||
hideError doesNotExistErrorType . liftIO . rmFile $ (dropExtension fp <.> "shim")
|
|
||||||
#else
|
|
||||||
rmLink = hideError doesNotExistErrorType . liftIO . rmFile
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | Creates a symbolic link on unix and a fake symlink on windows for
|
|
||||||
-- executables, which:
|
|
||||||
-- 1. is a shim exe
|
|
||||||
-- 2. has a corresponding .shim file in the same directory that
|
|
||||||
-- contains the target
|
|
||||||
--
|
|
||||||
-- This overwrites previously existing files.
|
|
||||||
--
|
|
||||||
-- On windows, this requires that 'ensureGlobalTools' was run beforehand.
|
|
||||||
createLink :: ( MonadMask m
|
|
||||||
, MonadThrow m
|
|
||||||
, MonadLogger m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, MonadUnliftIO m
|
|
||||||
, MonadFail m
|
|
||||||
)
|
|
||||||
=> FilePath -- ^ path to the target executable
|
|
||||||
-> FilePath -- ^ path to be created
|
|
||||||
-> m ()
|
|
||||||
createLink link exe = do
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
dirs <- getDirs
|
|
||||||
let shimGen = cacheDir dirs </> "gs.exe"
|
|
||||||
|
|
||||||
let shim = dropExtension exe <.> "shim"
|
|
||||||
-- For hardlinks, link needs to be absolute.
|
|
||||||
-- If link is relative, it's relative to the target exe.
|
|
||||||
-- Note that (</>) drops lhs when rhs is absolute.
|
|
||||||
fullLink = takeDirectory exe </> link
|
|
||||||
shimContents = "path = " <> fullLink
|
|
||||||
|
|
||||||
$(logDebug) [i|rm -f #{exe}|]
|
|
||||||
liftIO $ rmLink exe
|
|
||||||
|
|
||||||
$(logDebug) [i|ln -s #{fullLink} #{exe}|]
|
|
||||||
liftIO $ copyFile shimGen exe
|
|
||||||
liftIO $ writeFile shim shimContents
|
|
||||||
#else
|
|
||||||
$(logDebug) [i|rm -f #{exe}|]
|
|
||||||
liftIO $ hideError doesNotExistErrorType $ rmFile exe
|
|
||||||
|
|
||||||
$(logDebug) [i|ln -s #{link} #{exe}|]
|
|
||||||
liftIO $ createFileLink link exe
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
ensureGlobalTools :: ( MonadMask m
|
|
||||||
, MonadThrow m
|
|
||||||
, MonadLogger m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, HasGHCupInfo env
|
|
||||||
, MonadUnliftIO m
|
|
||||||
, MonadFail m
|
|
||||||
)
|
|
||||||
=> Excepts '[DigestError , DownloadFailed, NoDownload] m ()
|
|
||||||
ensureGlobalTools = do
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
(GHCupInfo _ _ gTools) <- lift getGHCupInfo
|
|
||||||
settings <- lift getSettings
|
|
||||||
dirs <- lift getDirs
|
|
||||||
shimDownload <- liftE $ lE @_ @'[NoDownload]
|
|
||||||
$ maybe (Left NoDownload) Right $ Map.lookup ShimGen gTools
|
|
||||||
let dl = downloadCached' shimDownload (Just "gs.exe") Nothing
|
|
||||||
void $ (\(DigestError _ _) -> do
|
|
||||||
lift $ $(logWarn) [i|Digest doesn't match, redownloading gs.exe...|]
|
|
||||||
lift $ $(logDebug) [i|rm -f #{shimDownload}|]
|
|
||||||
liftIO $ hideError doesNotExistErrorType $ rmFile (cacheDir dirs </> "gs.exe")
|
|
||||||
liftE @'[DigestError , DownloadFailed] $ dl
|
|
||||||
) `catchE` (liftE @'[DigestError , DownloadFailed] dl)
|
|
||||||
pure ()
|
|
||||||
#else
|
|
||||||
pure ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | Ensure ghcup directory structure exists.
|
|
||||||
ensureDirectories :: Dirs -> IO ()
|
|
||||||
ensureDirectories (Dirs baseDir binDir cacheDir logsDir confDir tmpDir) = do
|
|
||||||
createDirRecursive' baseDir
|
|
||||||
createDirRecursive' (baseDir </> "ghc")
|
|
||||||
createDirRecursive' binDir
|
|
||||||
createDirRecursive' cacheDir
|
|
||||||
createDirRecursive' logsDir
|
|
||||||
createDirRecursive' confDir
|
|
||||||
createDirRecursive' tmpDir
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
module GHCup.Utils where
|
|
||||||
|
|
||||||
getLinkTarget :: FilePath -> IO FilePath
|
|
||||||
pathIsLink :: FilePath -> IO Bool
|
|
||||||
@@ -16,8 +16,7 @@ Stability : experimental
|
|||||||
Portability : portable
|
Portability : portable
|
||||||
-}
|
-}
|
||||||
module GHCup.Utils.Dirs
|
module GHCup.Utils.Dirs
|
||||||
( getAllDirs
|
( getDirs
|
||||||
, ghcupBaseDir
|
|
||||||
, ghcupConfigFile
|
, ghcupConfigFile
|
||||||
, ghcupCacheDir
|
, ghcupCacheDir
|
||||||
, ghcupGHCBaseDir
|
, ghcupGHCBaseDir
|
||||||
@@ -26,10 +25,6 @@ module GHCup.Utils.Dirs
|
|||||||
, parseGHCupGHCDir
|
, parseGHCupGHCDir
|
||||||
, relativeSymlink
|
, relativeSymlink
|
||||||
, withGHCupTmpDir
|
, withGHCupTmpDir
|
||||||
, getConfigFilePath
|
|
||||||
#if !defined(IS_WINDOWS)
|
|
||||||
, useXDG
|
|
||||||
#endif
|
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@@ -37,7 +32,6 @@ 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
|
||||||
|
|
||||||
@@ -53,9 +47,7 @@ import Data.String.Interpolate
|
|||||||
import GHC.IO.Exception ( IOErrorType(NoSuchThing) )
|
import GHC.IO.Exception ( IOErrorType(NoSuchThing) )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Optics
|
import Optics
|
||||||
#if !defined(IS_WINDOWS)
|
import System.Directory
|
||||||
import System.Directory
|
|
||||||
#endif
|
|
||||||
import System.DiskSpace
|
import System.DiskSpace
|
||||||
import System.Environment
|
import System.Environment
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
@@ -80,10 +72,6 @@ import Control.Concurrent (threadDelay)
|
|||||||
-- then uses 'XDG_DATA_HOME/ghcup' as per xdg spec.
|
-- then uses 'XDG_DATA_HOME/ghcup' as per xdg spec.
|
||||||
ghcupBaseDir :: IO FilePath
|
ghcupBaseDir :: IO FilePath
|
||||||
ghcupBaseDir = do
|
ghcupBaseDir = do
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
bdir <- fromMaybe "C:\\" <$> lookupEnv "GHCUP_INSTALL_BASE_PREFIX"
|
|
||||||
pure (bdir </> "ghcup")
|
|
||||||
#else
|
|
||||||
xdg <- useXDG
|
xdg <- useXDG
|
||||||
if xdg
|
if xdg
|
||||||
then do
|
then do
|
||||||
@@ -98,7 +86,6 @@ ghcupBaseDir = do
|
|||||||
Just r -> pure r
|
Just r -> pure r
|
||||||
Nothing -> liftIO getHomeDirectory
|
Nothing -> liftIO getHomeDirectory
|
||||||
pure (bdir </> ".ghcup")
|
pure (bdir </> ".ghcup")
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | ~/.ghcup by default
|
-- | ~/.ghcup by default
|
||||||
@@ -107,9 +94,6 @@ ghcupBaseDir = do
|
|||||||
-- then uses 'XDG_CONFIG_HOME/ghcup' as per xdg spec.
|
-- then uses 'XDG_CONFIG_HOME/ghcup' as per xdg spec.
|
||||||
ghcupConfigDir :: IO FilePath
|
ghcupConfigDir :: IO FilePath
|
||||||
ghcupConfigDir = do
|
ghcupConfigDir = do
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
ghcupBaseDir
|
|
||||||
#else
|
|
||||||
xdg <- useXDG
|
xdg <- useXDG
|
||||||
if xdg
|
if xdg
|
||||||
then do
|
then do
|
||||||
@@ -124,7 +108,6 @@ ghcupConfigDir = do
|
|||||||
Just r -> pure r
|
Just r -> pure r
|
||||||
Nothing -> liftIO getHomeDirectory
|
Nothing -> liftIO getHomeDirectory
|
||||||
pure (bdir </> ".ghcup")
|
pure (bdir </> ".ghcup")
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | If 'GHCUP_USE_XDG_DIRS' is set (to anything),
|
-- | If 'GHCUP_USE_XDG_DIRS' is set (to anything),
|
||||||
@@ -132,9 +115,6 @@ ghcupConfigDir = do
|
|||||||
-- (which, sadly is not strictly xdg spec).
|
-- (which, sadly is not strictly xdg spec).
|
||||||
ghcupBinDir :: IO FilePath
|
ghcupBinDir :: IO FilePath
|
||||||
ghcupBinDir = do
|
ghcupBinDir = do
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
ghcupBaseDir <&> (</> "bin")
|
|
||||||
#else
|
|
||||||
xdg <- useXDG
|
xdg <- useXDG
|
||||||
if xdg
|
if xdg
|
||||||
then do
|
then do
|
||||||
@@ -144,7 +124,6 @@ ghcupBinDir = do
|
|||||||
home <- liftIO getHomeDirectory
|
home <- liftIO getHomeDirectory
|
||||||
pure (home </> ".local" </> "bin")
|
pure (home </> ".local" </> "bin")
|
||||||
else ghcupBaseDir <&> (</> "bin")
|
else ghcupBaseDir <&> (</> "bin")
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | Defaults to '~/.ghcup/cache'.
|
-- | Defaults to '~/.ghcup/cache'.
|
||||||
@@ -153,9 +132,6 @@ ghcupBinDir = do
|
|||||||
-- then uses 'XDG_CACHE_HOME/ghcup' as per xdg spec.
|
-- then uses 'XDG_CACHE_HOME/ghcup' as per xdg spec.
|
||||||
ghcupCacheDir :: IO FilePath
|
ghcupCacheDir :: IO FilePath
|
||||||
ghcupCacheDir = do
|
ghcupCacheDir = do
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
ghcupBaseDir <&> (</> "cache")
|
|
||||||
#else
|
|
||||||
xdg <- useXDG
|
xdg <- useXDG
|
||||||
if xdg
|
if xdg
|
||||||
then do
|
then do
|
||||||
@@ -166,7 +142,6 @@ ghcupCacheDir = do
|
|||||||
pure (home </> ".cache")
|
pure (home </> ".cache")
|
||||||
pure (bdir </> "ghcup")
|
pure (bdir </> "ghcup")
|
||||||
else ghcupBaseDir <&> (</> "cache")
|
else ghcupBaseDir <&> (</> "cache")
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | Defaults to '~/.ghcup/logs'.
|
-- | Defaults to '~/.ghcup/logs'.
|
||||||
@@ -175,9 +150,6 @@ ghcupCacheDir = do
|
|||||||
-- then uses 'XDG_CACHE_HOME/ghcup/logs' as per xdg spec.
|
-- then uses 'XDG_CACHE_HOME/ghcup/logs' as per xdg spec.
|
||||||
ghcupLogsDir :: IO FilePath
|
ghcupLogsDir :: IO FilePath
|
||||||
ghcupLogsDir = do
|
ghcupLogsDir = do
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
ghcupBaseDir <&> (</> "logs")
|
|
||||||
#else
|
|
||||||
xdg <- useXDG
|
xdg <- useXDG
|
||||||
if xdg
|
if xdg
|
||||||
then do
|
then do
|
||||||
@@ -188,26 +160,15 @@ ghcupLogsDir = do
|
|||||||
pure (home </> ".cache")
|
pure (home </> ".cache")
|
||||||
pure (bdir </> "ghcup" </> "logs")
|
pure (bdir </> "ghcup" </> "logs")
|
||||||
else ghcupBaseDir <&> (</> "logs")
|
else ghcupBaseDir <&> (</> "logs")
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- | Defaults to '~/.ghcup/tmp.
|
getDirs :: IO Dirs
|
||||||
--
|
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 { .. }
|
||||||
|
|
||||||
|
|
||||||
@@ -216,16 +177,13 @@ getAllDirs = do
|
|||||||
--[ GHCup files ]--
|
--[ GHCup files ]--
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
getConfigFilePath :: (MonadIO m) => m FilePath
|
|
||||||
getConfigFilePath = do
|
|
||||||
confDir <- liftIO ghcupConfigDir
|
|
||||||
pure $ confDir </> "config.yaml"
|
|
||||||
|
|
||||||
ghcupConfigFile :: (MonadIO m)
|
ghcupConfigFile :: (MonadIO m)
|
||||||
=> Excepts '[JSONError] m UserSettings
|
=> Excepts '[JSONError] m UserSettings
|
||||||
ghcupConfigFile = do
|
ghcupConfigFile = do
|
||||||
filepath <- getConfigFilePath
|
confDir <- liftIO ghcupConfigDir
|
||||||
contents <- liftIO $ handleIO' NoSuchThing (\_ -> pure Nothing) $ Just <$> BS.readFile filepath
|
let file = confDir </> "config.yaml"
|
||||||
|
contents <- liftIO $ handleIO' NoSuchThing (\_ -> pure Nothing) $ Just <$> BS.readFile file
|
||||||
case contents of
|
case contents of
|
||||||
Nothing -> pure defaultUserSettings
|
Nothing -> pure defaultUserSettings
|
||||||
Just contents' -> lE' JSONDecodeError . first show . Y.decodeEither' $ contents'
|
Just contents' -> lE' JSONDecodeError . first show . Y.decodeEither' $ contents'
|
||||||
@@ -237,9 +195,9 @@ ghcupConfigFile = do
|
|||||||
|
|
||||||
|
|
||||||
-- | ~/.ghcup/ghc by default.
|
-- | ~/.ghcup/ghc by default.
|
||||||
ghcupGHCBaseDir :: (MonadReader env m, HasDirs env) => m FilePath
|
ghcupGHCBaseDir :: (MonadReader AppState m) => m FilePath
|
||||||
ghcupGHCBaseDir = do
|
ghcupGHCBaseDir = do
|
||||||
Dirs {..} <- getDirs
|
AppState { dirs = Dirs {..} } <- ask
|
||||||
pure (baseDir </> "ghc")
|
pure (baseDir </> "ghc")
|
||||||
|
|
||||||
|
|
||||||
@@ -247,7 +205,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 env m, HasDirs env, MonadThrow m)
|
ghcupGHCDir :: (MonadReader AppState m, MonadThrow m)
|
||||||
=> GHCTargetVersion
|
=> GHCTargetVersion
|
||||||
-> m FilePath
|
-> m FilePath
|
||||||
ghcupGHCDir ver = do
|
ghcupGHCDir ver = do
|
||||||
@@ -284,7 +242,7 @@ mkGhcupTmpDir = do
|
|||||||
|
|
||||||
|
|
||||||
withGHCupTmpDir :: (MonadUnliftIO m, MonadLogger m, MonadCatch m, MonadResource m, MonadThrow m, MonadIO m) => m FilePath
|
withGHCupTmpDir :: (MonadUnliftIO m, MonadLogger m, MonadCatch m, MonadResource m, MonadThrow m, MonadIO m) => m FilePath
|
||||||
withGHCupTmpDir = snd <$> withRunInIO (\run -> run $ allocate (run mkGhcupTmpDir) rmPath)
|
withGHCupTmpDir = snd <$> withRunInIO (\run -> run $ allocate (run mkGhcupTmpDir) removeDirectoryRecursive)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -294,10 +252,8 @@ withGHCupTmpDir = snd <$> withRunInIO (\run -> run $ allocate (run mkGhcupTmpDir
|
|||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
||||||
#if !defined(IS_WINDOWS)
|
|
||||||
useXDG :: IO Bool
|
useXDG :: IO Bool
|
||||||
useXDG = isJust <$> lookupEnv "GHCUP_USE_XDG_DIRS"
|
useXDG = isJust <$> lookupEnv "GHCUP_USE_XDG_DIRS"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
relativeSymlink :: FilePath -- ^ the path in which to create the symlink
|
relativeSymlink :: FilePath -- ^ the path in which to create the symlink
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ module GHCup.Utils.File.Common where
|
|||||||
|
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Utils.Prelude
|
||||||
|
|
||||||
|
import Control.Exception
|
||||||
import Control.Monad.Extra
|
import Control.Monad.Extra
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
@@ -16,6 +17,7 @@ import GHC.IO.Exception
|
|||||||
import Optics hiding ((<|), (|>))
|
import Optics hiding ((<|), (|>))
|
||||||
import System.Directory
|
import System.Directory
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
|
import System.IO.Error
|
||||||
import Text.PrettyPrint.HughesPJClass hiding ( (<>) )
|
import Text.PrettyPrint.HughesPJClass hiding ( (<>) )
|
||||||
import Text.Regex.Posix
|
import Text.Regex.Posix
|
||||||
|
|
||||||
@@ -104,3 +106,17 @@ findFiles path regex = do
|
|||||||
contents <- listDirectory path
|
contents <- listDirectory path
|
||||||
pure $ filter (match regex) contents
|
pure $ filter (match regex) contents
|
||||||
|
|
||||||
|
|
||||||
|
isBrokenSymlink :: FilePath -> IO Bool
|
||||||
|
isBrokenSymlink fp = do
|
||||||
|
try (pathIsSymbolicLink fp) >>= \case
|
||||||
|
Right True -> do
|
||||||
|
let symDir = takeDirectory fp
|
||||||
|
tfp <- getSymbolicLinkTarget fp
|
||||||
|
not <$> doesPathExist
|
||||||
|
-- this drops 'symDir' if 'tfp' is absolute
|
||||||
|
(symDir </> tfp)
|
||||||
|
Right b -> pure b
|
||||||
|
Left e | isDoesNotExistError e -> pure False
|
||||||
|
| otherwise -> throwIO e
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ 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
|
||||||
@@ -43,7 +42,6 @@ import System.Console.Pretty hiding ( Pretty )
|
|||||||
import System.Console.Regions
|
import System.Console.Regions
|
||||||
import System.IO.Error
|
import System.IO.Error
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.Directory
|
|
||||||
import System.Posix.Directory
|
import System.Posix.Directory
|
||||||
import System.Posix.Files
|
import System.Posix.Files
|
||||||
import System.Posix.IO
|
import System.Posix.IO
|
||||||
@@ -65,21 +63,16 @@ import qualified "unix-bytestring" System.Posix.IO.ByteString
|
|||||||
|
|
||||||
-- | Execute the given command and collect the stdout, stderr and the exit code.
|
-- | Execute the given command and collect the stdout, stderr and the exit code.
|
||||||
-- The command is run in a subprocess.
|
-- The command is run in a subprocess.
|
||||||
executeOut :: MonadIO m
|
executeOut :: FilePath -- ^ command as filename, e.g. 'ls'
|
||||||
=> FilePath -- ^ command as filename, e.g. 'ls'
|
|
||||||
-> [String] -- ^ arguments to the command
|
-> [String] -- ^ arguments to the command
|
||||||
-> Maybe FilePath -- ^ chdir to this path
|
-> Maybe FilePath -- ^ chdir to this path
|
||||||
-> m CapturedProcess
|
-> IO CapturedProcess
|
||||||
executeOut path args chdir = liftIO $ captureOutStreams $ do
|
executeOut path args chdir = captureOutStreams $ do
|
||||||
maybe (pure ()) changeWorkingDirectory chdir
|
maybe (pure ()) changeWorkingDirectory chdir
|
||||||
SPP.executeFile path True args Nothing
|
SPP.executeFile path True args Nothing
|
||||||
|
|
||||||
|
|
||||||
execLogged :: ( MonadReader env m
|
execLogged :: (MonadReader AppState m, MonadIO m, MonadThrow 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
|
||||||
@@ -87,8 +80,7 @@ execLogged :: ( MonadReader env 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
|
||||||
Settings {..} <- getSettings
|
AppState { settings = Settings {..}, dirs = Dirs {..} } <- ask
|
||||||
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
|
||||||
@@ -324,13 +316,12 @@ createRegularFileFd fm dest =
|
|||||||
|
|
||||||
|
|
||||||
-- | Thin wrapper around `executeFile`.
|
-- | Thin wrapper around `executeFile`.
|
||||||
exec :: MonadIO m
|
exec :: String -- ^ thing to execute
|
||||||
=> String -- ^ 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
|
||||||
-> Maybe [(String, String)] -- ^ optional environment
|
-> Maybe [(String, String)] -- ^ optional environment
|
||||||
-> m (Either ProcessError ())
|
-> IO (Either ProcessError ())
|
||||||
exec exe args chdir env = liftIO $ do
|
exec exe args chdir env = do
|
||||||
pid <- SPP.forkProcess $ do
|
pid <- SPP.forkProcess $ do
|
||||||
maybe (pure ()) changeWorkingDirectory chdir
|
maybe (pure ()) changeWorkingDirectory chdir
|
||||||
SPP.executeFile exe (not ("./" `isPrefixOf` exe)) args env
|
SPP.executeFile exe (not ("./" `isPrefixOf` exe)) args env
|
||||||
@@ -375,18 +366,3 @@ newFilePerms =
|
|||||||
`unionFileModes` groupReadMode
|
`unionFileModes` groupReadMode
|
||||||
`unionFileModes` otherWriteMode
|
`unionFileModes` otherWriteMode
|
||||||
`unionFileModes` otherReadMode
|
`unionFileModes` otherReadMode
|
||||||
|
|
||||||
|
|
||||||
-- | Checks whether the binary is a broken link.
|
|
||||||
isBrokenSymlink :: FilePath -> IO Bool
|
|
||||||
isBrokenSymlink fp = do
|
|
||||||
try (pathIsSymbolicLink fp) >>= \case
|
|
||||||
Right True -> do
|
|
||||||
let symDir = takeDirectory fp
|
|
||||||
tfp <- getSymbolicLinkTarget fp
|
|
||||||
not <$> doesPathExist
|
|
||||||
-- this drops 'symDir' if 'tfp' is absolute
|
|
||||||
(symDir </> tfp)
|
|
||||||
Right b -> pure b
|
|
||||||
Left e | isDoesNotExistError e -> pure False
|
|
||||||
| otherwise -> throwIO e
|
|
||||||
|
|||||||
@@ -15,23 +15,18 @@ Some of these functions use sophisticated logging.
|
|||||||
-}
|
-}
|
||||||
module GHCup.Utils.File.Windows where
|
module GHCup.Utils.File.Windows where
|
||||||
|
|
||||||
import {-# SOURCE #-} GHCup.Utils ( getLinkTarget, pathIsLink )
|
|
||||||
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
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Data.List
|
|
||||||
import Foreign.C.Error
|
import Foreign.C.Error
|
||||||
import GHC.IO.Exception
|
import GHC.IO.Exception
|
||||||
import GHC.IO.Handle
|
import GHC.IO.Handle
|
||||||
import System.Directory
|
import System.Directory
|
||||||
import System.Environment
|
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.IO
|
import System.IO
|
||||||
import System.Process
|
import System.Process
|
||||||
@@ -39,7 +34,6 @@ import System.Process
|
|||||||
import qualified Control.Exception as EX
|
import qualified Control.Exception as EX
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.Map.Strict as Map
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -69,7 +63,7 @@ readCreateProcessWithExitCodeBS cp input = do
|
|||||||
std_out = CreatePipe,
|
std_out = CreatePipe,
|
||||||
std_err = CreatePipe
|
std_err = CreatePipe
|
||||||
}
|
}
|
||||||
withCreateProcess_ "readCreateProcessWithExitCodeBS" cp_opts $
|
withCreateProcess_ "readCreateProcessWithExitCode" cp_opts $
|
||||||
\mb_inh mb_outh mb_errh ph ->
|
\mb_inh mb_outh mb_errh ph ->
|
||||||
case (mb_inh, mb_outh, mb_errh) of
|
case (mb_inh, mb_outh, mb_errh) of
|
||||||
(Just inh, Just outh, Just errh) -> do
|
(Just inh, Just outh, Just errh) -> do
|
||||||
@@ -136,22 +130,16 @@ withForkWait async' body = do
|
|||||||
|
|
||||||
-- | Execute the given command and collect the stdout, stderr and the exit code.
|
-- | Execute the given command and collect the stdout, stderr and the exit code.
|
||||||
-- The command is run in a subprocess.
|
-- The command is run in a subprocess.
|
||||||
executeOut :: MonadIO m
|
executeOut :: FilePath -- ^ command as filename, e.g. 'ls'
|
||||||
=> FilePath -- ^ command as filename, e.g. 'ls'
|
|
||||||
-> [String] -- ^ arguments to the command
|
-> [String] -- ^ arguments to the command
|
||||||
-> Maybe FilePath -- ^ chdir to this path
|
-> Maybe FilePath -- ^ chdir to this path
|
||||||
-> m CapturedProcess
|
-> IO CapturedProcess
|
||||||
executeOut path args chdir = do
|
executeOut path args chdir = do
|
||||||
cp <- createProcessWithMingwPath ((proc path args){ cwd = chdir })
|
(exit, out, err) <- readCreateProcessWithExitCodeBS (proc path args){ cwd = chdir } ""
|
||||||
(exit, out, err) <- liftIO $ readCreateProcessWithExitCodeBS cp ""
|
|
||||||
pure $ CapturedProcess exit out err
|
pure $ CapturedProcess exit out err
|
||||||
|
|
||||||
|
|
||||||
execLogged :: ( MonadReader env m
|
execLogged :: (MonadReader AppState m, MonadIO m, MonadThrow 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
|
||||||
@@ -159,19 +147,18 @@ execLogged :: ( MonadReader env 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
|
||||||
Dirs {..} <- getDirs
|
AppState { dirs = Dirs {..} } <- ask
|
||||||
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)
|
|
||||||
{ cwd = chdir
|
|
||||||
, env = env
|
|
||||||
, std_in = CreatePipe
|
|
||||||
, std_out = CreatePipe
|
|
||||||
, std_err = CreatePipe
|
|
||||||
})
|
|
||||||
fmap (toProcessError exe args)
|
fmap (toProcessError exe args)
|
||||||
$ liftIO
|
$ liftIO
|
||||||
$ withCreateProcess cp
|
$ withCreateProcess
|
||||||
|
(proc exe args){ cwd = chdir
|
||||||
|
, env = env
|
||||||
|
, std_in = CreatePipe
|
||||||
|
, std_out = CreatePipe
|
||||||
|
, std_err = CreatePipe
|
||||||
|
}
|
||||||
$ \_ mout merr ph ->
|
$ \_ mout merr ph ->
|
||||||
case (mout, merr) of
|
case (mout, merr) of
|
||||||
(Just cStdout, Just cStderr) -> do
|
(Just cStdout, Just cStderr) -> do
|
||||||
@@ -197,15 +184,15 @@ execLogged exe args chdir lfile env = do
|
|||||||
|
|
||||||
|
|
||||||
-- | Thin wrapper around `executeFile`.
|
-- | Thin wrapper around `executeFile`.
|
||||||
exec :: MonadIO m
|
exec :: FilePath -- ^ thing to execute
|
||||||
=> FilePath -- ^ thing to execute
|
|
||||||
-> [FilePath] -- ^ args for the thing
|
-> [FilePath] -- ^ args for the thing
|
||||||
-> Maybe FilePath -- ^ optionally chdir into this
|
-> Maybe FilePath -- ^ optionally chdir into this
|
||||||
-> Maybe [(String, String)] -- ^ optional environment
|
-> Maybe [(String, String)] -- ^ optional environment
|
||||||
-> m (Either ProcessError ())
|
-> IO (Either ProcessError ())
|
||||||
exec exe args chdir env = do
|
exec exe args chdir env = do
|
||||||
cp <- createProcessWithMingwPath ((proc exe args) { cwd = chdir, env = env })
|
exit_code <- withCreateProcess
|
||||||
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
|
(proc exe args) { cwd = chdir, env = env } $ \_ _ _ p ->
|
||||||
|
waitForProcess p
|
||||||
pure $ toProcessError exe args exit_code
|
pure $ toProcessError exe args exit_code
|
||||||
|
|
||||||
|
|
||||||
@@ -213,40 +200,3 @@ chmod_755 :: MonadIO m => FilePath -> m ()
|
|||||||
chmod_755 fp =
|
chmod_755 fp =
|
||||||
let perm = setOwnerWritable True emptyPermissions
|
let perm = setOwnerWritable True emptyPermissions
|
||||||
in liftIO $ setPermissions fp perm
|
in liftIO $ setPermissions fp perm
|
||||||
|
|
||||||
|
|
||||||
createProcessWithMingwPath :: MonadIO m
|
|
||||||
=> CreateProcess
|
|
||||||
-> m CreateProcess
|
|
||||||
createProcessWithMingwPath cp = do
|
|
||||||
msys2Dir <- liftIO ghcupMsys2Dir
|
|
||||||
cEnv <- Map.fromList <$> maybe (liftIO getEnvironment) pure (env cp)
|
|
||||||
let mingWPaths = [msys2Dir </> "usr" </> "bin"
|
|
||||||
,msys2Dir </> "mingw64" </> "bin"]
|
|
||||||
paths = ["PATH", "Path"]
|
|
||||||
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
|
||||||
newPath = intercalate [searchPathSeparator] (mingWPaths ++ curPaths)
|
|
||||||
envWithoutPath = foldr (\x y -> Map.delete x y) cEnv paths
|
|
||||||
envWithNewPath = Map.insert "Path" newPath envWithoutPath
|
|
||||||
liftIO $ setEnv "Path" newPath
|
|
||||||
pure $ cp { env = Just $ Map.toList envWithNewPath }
|
|
||||||
|
|
||||||
ghcupMsys2Dir :: IO FilePath
|
|
||||||
ghcupMsys2Dir =
|
|
||||||
lookupEnv "GHCUP_MSYS2" >>= \case
|
|
||||||
Just fp -> pure fp
|
|
||||||
Nothing -> do
|
|
||||||
baseDir <- liftIO ghcupBaseDir
|
|
||||||
pure (baseDir </> "msys64")
|
|
||||||
|
|
||||||
-- | Checks whether the binary is a broken link.
|
|
||||||
isBrokenSymlink :: FilePath -> IO Bool
|
|
||||||
isBrokenSymlink fp = do
|
|
||||||
b <- pathIsLink fp
|
|
||||||
if b
|
|
||||||
then do
|
|
||||||
tfp <- getLinkTarget fp
|
|
||||||
not <$> doesPathExist
|
|
||||||
-- this drops 'symDir' if 'tfp' is absolute
|
|
||||||
(takeDirectory fp </> tfp)
|
|
||||||
else pure False
|
|
||||||
|
|||||||
@@ -14,15 +14,17 @@ Here we define our main logger.
|
|||||||
-}
|
-}
|
||||||
module GHCup.Utils.Logger where
|
module GHCup.Utils.Logger where
|
||||||
|
|
||||||
|
import GHCup.Types
|
||||||
import GHCup.Utils.File
|
import GHCup.Utils.File
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Utils.String.QQ
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.IO.Class
|
import Control.Monad.IO.Class
|
||||||
|
import Control.Monad.Reader
|
||||||
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.Directory hiding ( findFiles )
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.IO.Error
|
import System.IO.Error
|
||||||
import Text.Regex.Posix
|
import Text.Regex.Posix
|
||||||
@@ -44,33 +46,20 @@ 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' "[ Debug ]")
|
LevelDebug -> toLogStr (style Bold $ color Blue "[ Debug ]")
|
||||||
LevelInfo -> toLogStr (style' "[ Info ]")
|
LevelInfo -> toLogStr (style Bold $ color Green "[ Info ]")
|
||||||
LevelWarn -> toLogStr (style' "[ Warn ]")
|
LevelWarn -> toLogStr (style Bold $ color Yellow "[ Warn ]")
|
||||||
LevelError -> toLogStr (style' "[ Error ]")
|
LevelError -> toLogStr (style Bold $ color Red "[ Error ]")
|
||||||
LevelOther t -> toLogStr "[ " <> toLogStr t <> toLogStr " ]"
|
LevelOther t -> toLogStr "[ " <> toLogStr t <> toLogStr " ]"
|
||||||
let strs = fmap toLogStr . B.split (fromIntegral $ ord '\n') . fromLogStr $ str'
|
let out = fromLogStr (l <> toLogStr " " <> str' <> toLogStr "\n")
|
||||||
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:"
|
||||||
@@ -79,17 +68,19 @@ myLoggerT LoggerConfig {..} loggingt = runLoggingT loggingt mylogger
|
|||||||
rawOutter outr
|
rawOutter outr
|
||||||
|
|
||||||
|
|
||||||
initGHCupFileLogging :: (MonadIO m) => FilePath -> m FilePath
|
initGHCupFileLogging :: (MonadIO m, MonadReader AppState m) => m FilePath
|
||||||
initGHCupFileLogging logsDir = do
|
initGHCupFileLogging = do
|
||||||
|
AppState {dirs = Dirs {..}} <- ask
|
||||||
let logfile = logsDir </> "ghcup.log"
|
let logfile = logsDir </> "ghcup.log"
|
||||||
liftIO $ do
|
liftIO $ do
|
||||||
|
createDirectoryIfMissing True logsDir
|
||||||
logFiles <- findFiles
|
logFiles <- findFiles
|
||||||
logsDir
|
logsDir
|
||||||
(makeRegexOpts compExtended
|
(makeRegexOpts compExtended
|
||||||
execBlank
|
execBlank
|
||||||
([s|^.*\.log$|] :: B.ByteString)
|
([s|^.*\.log$|] :: B.ByteString)
|
||||||
)
|
)
|
||||||
forM_ logFiles $ hideError doesNotExistErrorType . rmFile . (logsDir </>)
|
forM_ logFiles $ hideError doesNotExistErrorType . removeFile . (logsDir </>)
|
||||||
|
|
||||||
writeFile logfile ""
|
writeFile logfile ""
|
||||||
pure logfile
|
pure logfile
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
@@ -26,8 +25,6 @@ import Control.Monad.IO.Class
|
|||||||
import Control.Monad.Trans.Class ( lift )
|
import Control.Monad.Trans.Class ( lift )
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.List ( nub )
|
|
||||||
import Data.Foldable
|
|
||||||
import Data.String
|
import Data.String
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
@@ -35,15 +32,6 @@ import Data.Word8
|
|||||||
import Haskus.Utils.Types.List
|
import Haskus.Utils.Types.List
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import System.IO.Error
|
import System.IO.Error
|
||||||
import System.IO.Unsafe
|
|
||||||
import System.Directory
|
|
||||||
import System.FilePath
|
|
||||||
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
import Control.Retry
|
|
||||||
import GHC.IO.Exception
|
|
||||||
#endif
|
|
||||||
|
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Data.Strict.Maybe as S
|
import qualified Data.Strict.Maybe as S
|
||||||
@@ -190,14 +178,14 @@ hideError :: (MonadIO m, MonadCatch m) => IOErrorType -> m () -> m ()
|
|||||||
hideError err = handleIO (\e -> if err == ioeGetErrorType e then pure () else liftIO . ioError $ e)
|
hideError err = handleIO (\e -> if err == ioeGetErrorType e then pure () else liftIO . ioError $ e)
|
||||||
|
|
||||||
|
|
||||||
hideErrorDef :: (MonadIO m, MonadCatch m) => [IOErrorType] -> a -> m a -> m a
|
hideErrorDef :: [IOErrorType] -> a -> IO a -> IO a
|
||||||
hideErrorDef errs def =
|
hideErrorDef errs def =
|
||||||
handleIO (\e -> if ioeGetErrorType e `elem` errs then pure def else liftIO $ ioError e)
|
handleIO (\e -> if ioeGetErrorType e `elem` errs then pure def else ioError e)
|
||||||
|
|
||||||
|
|
||||||
hideErrorDefM :: (MonadIO m, MonadCatch m) => [IOErrorType] -> m a -> m a -> m a
|
hideErrorDefM :: [IOErrorType] -> IO a -> IO a -> IO a
|
||||||
hideErrorDefM errs def =
|
hideErrorDefM errs def =
|
||||||
handleIO (\e -> if ioeGetErrorType e `elem` errs then def else liftIO $ ioError e)
|
handleIO (\e -> if ioeGetErrorType e `elem` errs then def else ioError e)
|
||||||
|
|
||||||
|
|
||||||
-- TODO: does this work?
|
-- TODO: does this work?
|
||||||
@@ -288,140 +276,3 @@ escapeVerRex = B.pack . go . B.unpack . verToBS
|
|||||||
go (x : xs) | x == _period = [_backslash, _period] ++ go xs
|
go (x : xs) | x == _period = [_backslash, _period] ++ go xs
|
||||||
| otherwise = x : go xs
|
| otherwise = x : go xs
|
||||||
|
|
||||||
-- | More permissive version of 'createDirRecursive'. This doesn't
|
|
||||||
-- error when the destination is a symlink to a directory.
|
|
||||||
createDirRecursive' :: FilePath -> IO ()
|
|
||||||
createDirRecursive' p =
|
|
||||||
handleIO (\e -> if isAlreadyExistsError e then isSymlinkDir e else throwIO e)
|
|
||||||
. createDirectoryIfMissing True
|
|
||||||
$ p
|
|
||||||
|
|
||||||
where
|
|
||||||
isSymlinkDir e = do
|
|
||||||
ft <- pathIsSymbolicLink p
|
|
||||||
case ft of
|
|
||||||
True -> do
|
|
||||||
rp <- canonicalizePath p
|
|
||||||
rft <- doesDirectoryExist rp
|
|
||||||
case rft of
|
|
||||||
True -> pure ()
|
|
||||||
_ -> throwIO e
|
|
||||||
_ -> throwIO e
|
|
||||||
|
|
||||||
|
|
||||||
-- | Recursively copy the contents of one directory to another path.
|
|
||||||
--
|
|
||||||
-- This is a rip-off of Cabal library.
|
|
||||||
copyDirectoryRecursive :: FilePath -> FilePath -> IO ()
|
|
||||||
copyDirectoryRecursive srcDir destDir = do
|
|
||||||
srcFiles <- getDirectoryContentsRecursive srcDir
|
|
||||||
copyFilesWith copyFile destDir [ (srcDir, f)
|
|
||||||
| f <- srcFiles ]
|
|
||||||
where
|
|
||||||
-- | Common implementation of 'copyFiles', 'installOrdinaryFiles',
|
|
||||||
-- 'installExecutableFiles' and 'installMaybeExecutableFiles'.
|
|
||||||
copyFilesWith :: (FilePath -> FilePath -> IO ())
|
|
||||||
-> FilePath -> [(FilePath, FilePath)] -> IO ()
|
|
||||||
copyFilesWith doCopy targetDir srcFiles = do
|
|
||||||
|
|
||||||
-- Create parent directories for everything
|
|
||||||
let dirs = map (targetDir </>) . nub . map (takeDirectory . snd) $ srcFiles
|
|
||||||
traverse_ (createDirectoryIfMissing True) dirs
|
|
||||||
|
|
||||||
-- Copy all the files
|
|
||||||
sequence_ [ let src = srcBase </> srcFile
|
|
||||||
dest = targetDir </> srcFile
|
|
||||||
in doCopy src dest
|
|
||||||
| (srcBase, srcFile) <- srcFiles ]
|
|
||||||
|
|
||||||
|
|
||||||
-- | List all the files in a directory and all subdirectories.
|
|
||||||
--
|
|
||||||
-- The order places files in sub-directories after all the files in their
|
|
||||||
-- parent directories. The list is generated lazily so is not well defined if
|
|
||||||
-- the source directory structure changes before the list is used.
|
|
||||||
--
|
|
||||||
getDirectoryContentsRecursive :: FilePath -> IO [FilePath]
|
|
||||||
getDirectoryContentsRecursive topdir = recurseDirectories [""]
|
|
||||||
where
|
|
||||||
recurseDirectories :: [FilePath] -> IO [FilePath]
|
|
||||||
recurseDirectories [] = return []
|
|
||||||
recurseDirectories (dir:dirs) = unsafeInterleaveIO $ do
|
|
||||||
(files, dirs') <- collect [] [] =<< getDirectoryContents (topdir </> dir)
|
|
||||||
files' <- recurseDirectories (dirs' ++ dirs)
|
|
||||||
return (files ++ files')
|
|
||||||
|
|
||||||
where
|
|
||||||
collect files dirs' [] = return (reverse files
|
|
||||||
,reverse dirs')
|
|
||||||
collect files dirs' (entry:entries) | ignore entry
|
|
||||||
= collect files dirs' entries
|
|
||||||
collect files dirs' (entry:entries) = do
|
|
||||||
let dirEntry = dir </> entry
|
|
||||||
isDirectory <- doesDirectoryExist (topdir </> dirEntry)
|
|
||||||
if isDirectory
|
|
||||||
then collect files (dirEntry:dirs') entries
|
|
||||||
else collect (dirEntry:files) dirs' entries
|
|
||||||
|
|
||||||
ignore ['.'] = True
|
|
||||||
ignore ['.', '.'] = True
|
|
||||||
ignore _ = False
|
|
||||||
|
|
||||||
-- https://github.com/haskell/directory/issues/110
|
|
||||||
-- https://github.com/haskell/directory/issues/96
|
|
||||||
-- https://www.sqlite.org/src/info/89f1848d7f
|
|
||||||
rmPath :: (MonadIO m, MonadMask m)
|
|
||||||
=> FilePath
|
|
||||||
-> m ()
|
|
||||||
rmPath fp =
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
recovering (fullJitterBackoff 25000 <> limitRetries 10)
|
|
||||||
[\_ -> Handler (\e -> pure $ isPermissionError e)
|
|
||||||
,\_ -> Handler (\e -> pure (ioeGetErrorType e == UnsatisfiedConstraints))
|
|
||||||
,\_ -> Handler (\e -> pure (ioeGetErrorType e == InappropriateType))
|
|
||||||
]
|
|
||||||
(\_ -> liftIO $ removePathForcibly fp)
|
|
||||||
#else
|
|
||||||
liftIO $ removeDirectoryRecursive fp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- https://www.sqlite.org/src/info/89f1848d7f
|
|
||||||
-- https://github.com/haskell/directory/issues/96
|
|
||||||
rmFile :: (MonadIO m, MonadMask m)
|
|
||||||
=> FilePath
|
|
||||||
-> m ()
|
|
||||||
rmFile fp =
|
|
||||||
#if defined(IS_WINDOWS)
|
|
||||||
recovering (fullJitterBackoff 25000 <> limitRetries 10)
|
|
||||||
[\_ -> Handler (\e -> pure $ isPermissionError e)
|
|
||||||
,\_ -> Handler (\e -> pure (ioeGetErrorType e == UnsatisfiedConstraints))
|
|
||||||
]
|
|
||||||
(\_ -> liftIO $ removeFile fp)
|
|
||||||
#else
|
|
||||||
liftIO $ removeFile fp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
-- Gathering monoidal values
|
|
||||||
traverseFold :: (Foldable t, Applicative m, Monoid b) => (a -> m b) -> t a -> m b
|
|
||||||
traverseFold f = foldl (\mb a -> (<>) <$> mb <*> f a) (pure mempty)
|
|
||||||
|
|
||||||
-- | Gathering monoidal values
|
|
||||||
forFold :: (Foldable t, Applicative m, Monoid b) => t a -> (a -> m b) -> m b
|
|
||||||
forFold = \t -> (`traverseFold` t)
|
|
||||||
|
|
||||||
|
|
||||||
-- | Strip @\\r@ and @\\n@ from 'ByteString's
|
|
||||||
stripNewline :: String -> String
|
|
||||||
stripNewline s
|
|
||||||
| null s = []
|
|
||||||
| head s `elem` "\n\r" = stripNewline (tail s)
|
|
||||||
| otherwise = head s : stripNewline (tail s)
|
|
||||||
|
|
||||||
|
|
||||||
isNewLine :: Word8 -> Bool
|
|
||||||
isNewLine w
|
|
||||||
| w == _lf = True
|
|
||||||
| w == _cr = True
|
|
||||||
| otherwise = False
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import qualified Data.Text as T
|
|||||||
|
|
||||||
-- | This reflects the API version of the YAML.
|
-- | This reflects the API version of the YAML.
|
||||||
ghcupURL :: URI
|
ghcupURL :: URI
|
||||||
ghcupURL = [uri|https://www.haskell.org/ghcup/data/ghcup-0.0.5.yaml|]
|
ghcupURL = [uri|https://www.haskell.org/ghcup/data/ghcup-0.0.4.yaml|]
|
||||||
|
|
||||||
-- | The current ghcup version.
|
-- | The current ghcup version.
|
||||||
ghcUpVer :: PVP
|
ghcUpVer :: PVP
|
||||||
|
|||||||
27
refreeze.sh
27
refreeze.sh
@@ -1,27 +0,0 @@
|
|||||||
#!/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
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
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.
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
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/>
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
# `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`
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
@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
|
|
||||||
)
|
|
||||||
@@ -1,256 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
14
stack.yaml
14
stack.yaml
@@ -1,4 +1,4 @@
|
|||||||
resolver: lts-18.2
|
resolver: lts-17.11
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- .
|
- .
|
||||||
@@ -12,7 +12,6 @@ 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
|
||||||
@@ -21,28 +20,23 @@ 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
|
- lzma-static-5.2.5.2@sha256:ac38dcad9ab423342a72ba48415bd75f62234e9c9e11831495b75603b5a060f6,7184
|
||||||
- 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
|
|
||||||
- os-release-1.0.1@sha256:1281c62081f438fc3f0874d3bae6a4887d5964ac25261ba06e29d368ab173467,2716
|
- os-release-1.0.1@sha256:1281c62081f438fc3f0874d3bae6a4887d5964ac25261ba06e29d368ab173467,2716
|
||||||
- optics-0.4@sha256:9fb69bf0195b8d8f1f8cd0098000946868b8a3c3ffb51e5b64f79fc600c3eb4c,6568
|
- primitive-0.7.0.1@sha256:a381571c36edc7dca28b77fe8159b43c14c640087ec5946adacf949feec64231,3433
|
||||||
- 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
|
||||||
- streamly-posix-0.1.0.1@sha256:5d89b806281035d34020387ed99dde1ddab282c7ed66df3b7cd010b38fd3517b,2138
|
- streamly-posix-0.1.0.1@sha256:5d89b806281035d34020387ed99dde1ddab282c7ed66df3b7cd010b38fd3517b,2138
|
||||||
- strict-base-0.4.0.0@sha256:2ff4e43cb95eedf2995558d7fc34d19362846413dd39e6aa6a5b3ea8228fef9f,1248
|
- strict-base-0.4.0.0@sha256:2ff4e43cb95eedf2995558d7fc34d19362846413dd39e6aa6a5b3ea8228fef9f,1248
|
||||||
- xor-0.0.1.0@sha256:f8362b4a68562b9afbcd727ff64c1a303970df3a032e0033d2f4c094c3501df3,2243
|
- xor-0.0.1.0@sha256:f8362b4a68562b9afbcd727ff64c1a303970df3a032e0033d2f4c094c3501df3,2243
|
||||||
- zip-1.7.1@sha256:0ce03d0fbffba47c1ab6fbb9166f8ba5373d828d78587df21b7e9d7bb150f929,3918
|
|
||||||
|
|
||||||
flags:
|
flags:
|
||||||
http-io-streams:
|
http-io-streams:
|
||||||
|
|||||||
@@ -171,10 +171,6 @@ instance Arbitrary Tool where
|
|||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
instance Arbitrary GlobalTool where
|
|
||||||
arbitrary = genericArbitrary
|
|
||||||
shrink = genericShrink
|
|
||||||
|
|
||||||
instance Arbitrary GHCupInfo where
|
instance Arbitrary GHCupInfo where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|||||||
@@ -132,17 +132,13 @@ hr {
|
|||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.code {
|
#platform-instructions-linux > div > pre,
|
||||||
font-family: 'Lucida Console', monospace;
|
#platform-instructions-mac > div > pre,
|
||||||
}
|
#platform-instructions-freebsd > div > pre,
|
||||||
|
#platform-instructions-win32 > div > pre,
|
||||||
#platform-instructions-linux div > pre,
|
#platform-instructions-win64 > div > pre,
|
||||||
#platform-instructions-mac div > pre,
|
#platform-instructions-default > div > div > pre,
|
||||||
#platform-instructions-freebsd div > pre,
|
#platform-instructions-unknown > div > div > pre {
|
||||||
#platform-instructions-win32 div > pre,
|
|
||||||
#platform-instructions-win64 div > pre,
|
|
||||||
#platform-instructions-default div > div > pre,
|
|
||||||
#platform-instructions-unknown div > div > pre {
|
|
||||||
background-color: #515151;
|
background-color: #515151;
|
||||||
color: white;
|
color: white;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
|||||||
@@ -158,8 +158,8 @@ function copyToClipboard() {
|
|||||||
document.body.removeChild(el);
|
document.body.removeChild(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyToClipboardPowershell() {
|
function copyToClipboardSilicon() {
|
||||||
const text = document.getElementById("ghcup-command-powershell").innerText;
|
const text = document.getElementById("ghcup-command-silicon").innerText;
|
||||||
const el = document.createElement('textarea');
|
const el = document.createElement('textarea');
|
||||||
el.value = text;
|
el.value = text;
|
||||||
document.body.appendChild(el);
|
document.body.appendChild(el);
|
||||||
|
|||||||
104
www/index.html
104
www/index.html
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<body id="idx">
|
<body id="idx">
|
||||||
|
|
||||||
|
<script id='html-content' type="text/html">
|
||||||
<a id="platform-button" style="display: none;" href="#">
|
<a id="platform-button" style="display: none;" href="#">
|
||||||
click or press "n" to cycle platforms
|
click or press "n" to cycle platforms
|
||||||
</a>
|
</a>
|
||||||
@@ -31,7 +32,10 @@
|
|||||||
|
|
||||||
<div id="platform-instructions-mac" class="instructions" style="display: none;">
|
<div id="platform-instructions-mac" class="instructions" style="display: none;">
|
||||||
<p>Run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
<p>Run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
|
<p>On Intel:</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command' id="ghcup-command-normal">curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command' id="ghcup-command-normal">curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
|
<p>On Apple Silicon:</p>
|
||||||
|
<div class="command-button"><pre><span class='ghcup-command' id="ghcup-command-silicon">curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | arch -x86_64 /bin/bash</span></pre><button class="tooltip" onclick="copyToClipboardSilicon()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.<br/>You appear to be running macOS. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.<br/>You appear to be running macOS. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -43,41 +47,24 @@
|
|||||||
|
|
||||||
<div id="platform-instructions-win32" class="instructions">
|
<div id="platform-instructions-win32" class="instructions">
|
||||||
<p>
|
<p>
|
||||||
To install Haskell,<br/>run the following in a powershell session (as a non-admin user).
|
To install Haskell, follow the instructions on
|
||||||
<div>
|
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
||||||
<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>
|
<p>If you're a Windows Subsystem for Linux user run the following in your terminal, then follow the onscreen instructions to install Haskell.
|
||||||
</div>
|
|
||||||
<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>
|
|
||||||
<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>
|
||||||
<div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button>
|
|
||||||
</div>
|
|
||||||
<p class="other-help">WSL1 does not work with ghcup, follow <a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10">the instructions here</a> to upgrade to WSL2 if needed.</p>
|
|
||||||
</div>
|
|
||||||
</p>
|
</p>
|
||||||
<hr/>
|
<p class="other-help">You appear to be running Windows 32-bit. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
||||||
<p class="other-help">You appear to be running Windows 32-bit. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="platform-instructions-win64" class="instructions" style="display: none;">
|
<div id="platform-instructions-win64" class="instructions" style="display: none;">
|
||||||
<p>
|
<p>
|
||||||
To install Haskell,<br/>run the following in a powershell session (as a non-admin user).
|
To install Haskell, follow the instructions on
|
||||||
<div>
|
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
||||||
<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>
|
|
||||||
<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>
|
|
||||||
</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 for Linux user run the following in your terminal, then follow the onscreen instructions to install Haskell.
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button>
|
<p class="other-help">You appear to be running Windows 64-bit. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
||||||
</div>
|
|
||||||
<p class="other-help">WSL1 does not work with ghcup, follow <a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10">the instructions here</a> to upgrade to WSL2 if needed.</p>
|
|
||||||
</div>
|
|
||||||
<p class="other-help">You appear to be running Windows 64-bit. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="platform-instructions-unknown" class="instructions" style="display: none;">
|
<div id="platform-instructions-unknown" class="instructions" style="display: none;">
|
||||||
@@ -99,7 +86,7 @@
|
|||||||
|
|
||||||
<!-- duplicate the default cross-platform instructions -->
|
<!-- duplicate the default cross-platform instructions -->
|
||||||
<div>
|
<div>
|
||||||
<p>If you are running Linux, macOS, FreeBSD or Windows Subsystem 2 for Linux, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
<p>If you are running Linux, macOS, FreeBSD or Windows Subsystem for Linux, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -108,8 +95,8 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
If you are running Windows,<br/>run the following in a powershell session (as a non-admin user).
|
If you are running Windows,<br/>follow the instructions on
|
||||||
<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>
|
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -117,9 +104,11 @@
|
|||||||
|
|
||||||
<div id="platform-instructions-default" class="instructions">
|
<div id="platform-instructions-default" class="instructions">
|
||||||
<div>
|
<div>
|
||||||
<p>To install Haskell, if you are running Linux, macOS, FreeBSD or Windows Subsystem 2 for Linux, run the following
|
<p>To install Haskell, if you are running Linux, macOS (on Intel), FreeBSD or Windows Subsystem for Linux, run the following
|
||||||
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
|
<p>For macOS on Apple Silicon, run this instead:</p>
|
||||||
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | arch -x86_64 /bin/bash</span></pre><button class="tooltip" onclick="copyToClipboardSilicon()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -127,15 +116,15 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
If you are running Windows,<br/>run the following in a powershell session (as a non-admin user).
|
If you are running Windows,<br/>follow the instructions on
|
||||||
<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>
|
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Need help? Ask on <a href="https://kiwiirc.com/nextclient/irc.libera.chat/#haskell-ghcup">#haskell-ghcup</a>, <a href="https://kiwiirc.com/nextclient/irc.libera.chat/#haskell">#haskell</a> or <a href="https://gitlab.haskell.org/haskell/ghcup-hs/issues">report a bug</a>.
|
Need help? <a href="http://webchat.freenode.net/?randomnick=1&channels=%23haskell&uio=d4">Ask on #haskell</a> or <a href="https://gitlab.haskell.org/haskell/ghcup-hs/issues">report a bug</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p id="about">
|
<p id="about">
|
||||||
@@ -148,7 +137,54 @@
|
|||||||
·
|
·
|
||||||
<a href="https://github.com/rust-lang/rustup.rs/tree/master/www">web design from rustup</a>
|
<a href="https://github.com/rust-lang/rustup.rs/tree/master/www">web design from rustup</a>
|
||||||
</p>
|
</p>
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
document.write(document.getElementById("html-content").innerHTML);
|
||||||
|
</script>
|
||||||
<script type="text/javascript" src="ghcup.js"></script>
|
<script type="text/javascript" src="ghcup.js"></script>
|
||||||
|
|
||||||
|
<noscript>
|
||||||
|
<p id="pitch">
|
||||||
|
<em>ghcup</em> is an installer for<br/>
|
||||||
|
the general purpose language <a href="https://www.haskell.org/">Haskell</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div id="platform-instructions-default" class="instructions">
|
||||||
|
<div>
|
||||||
|
<p>To install Haskell, if you are running Linux, macOS (on Intel), FreeBSD or Windows Subsystem for Linux, run the following
|
||||||
|
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
|
<pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre>
|
||||||
|
<p>For macOS on Apple Silicon, run this instead:</p>
|
||||||
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | arch -x86_64 /bin/bash</span></pre><button class="tooltip" onclick="copyToClipboardSilicon()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
|
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
If you are running Windows,<br/>follow the instructions on
|
||||||
|
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Need help? <a href="http://webchat.freenode.net/?randomnick=1&channels=%23haskell&uio=d4">Ask on #haskell</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="about">
|
||||||
|
<img src="haskell-logo.svg" alt="" />
|
||||||
|
ghcup is a haskell.org hosted project.
|
||||||
|
<br/>
|
||||||
|
<a href="https://www.haskell.org/downloads/">other installation options</a>
|
||||||
|
·
|
||||||
|
<a href="https://gitlab.haskell.org/haskell/ghcup-hs">about ghcup</a>
|
||||||
|
·
|
||||||
|
<a href="https://github.com/rust-lang/rustup.rs/tree/master/www">web design from rustup</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</noscript>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user