Compare commits
38 Commits
f6725fbf5f
...
v0.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
| b3105b439c | |||
| 2b6cb5f1a8 | |||
| f4242b10e7 | |||
| ad4d185ead | |||
| b18aafe2c4 | |||
| 340196bf9d | |||
| 883226aa70 | |||
| 0d393612a7 | |||
| 5635f6cc4e | |||
| a7fd36beeb | |||
| baee1d5b85 | |||
| 68df6b8e50 | |||
| ac73090784 | |||
| faf4f3b7ca | |||
| d888d11d59 | |||
| 28a1077833 | |||
| c40b9dbc0b | |||
| 6bbd262818 | |||
| 78d36bce24 | |||
| aedfc19220 | |||
| 2f34fc7bef | |||
| de66b92631 | |||
| fee3984bf7 | |||
| b953c8fd30 | |||
| 24e4c3a19b | |||
| d2efb504b9 | |||
| df9dd0e785 | |||
| 89c9699158 | |||
| 124ddcdfeb | |||
| 5c0a0fc155 | |||
| b11b74d2b4 | |||
| 5ac8f5b651 | |||
| 9032df97cf | |||
| 14e1077ad1 | |||
| b5648bdd6b | |||
| e7cd952970 | |||
| 1455c2c175 | |||
| c106dd3f65 |
78
.gitlab-ci.yml
Normal file
78
.gitlab-ci.yml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
variables:
|
||||||
|
GIT_SSL_NO_VERIFY: "1"
|
||||||
|
|
||||||
|
# Commit of ghc/ci-images repository from which to pull Docker images
|
||||||
|
DOCKER_REV: cefaee3c742af193e0f7783f87edb0d35374515c
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# CI Step
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
.debian:
|
||||||
|
image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV"
|
||||||
|
tags:
|
||||||
|
- x86_64-linux
|
||||||
|
|
||||||
|
.darwin:
|
||||||
|
tags:
|
||||||
|
- x86_64-darwin
|
||||||
|
|
||||||
|
.test_ghcup_version:
|
||||||
|
script:
|
||||||
|
- ./.gitlab/script/ghcup_version.sh
|
||||||
|
variables:
|
||||||
|
JSON_VERSION: "0.0.1"
|
||||||
|
|
||||||
|
.test_ghcup_version:linux:
|
||||||
|
extends:
|
||||||
|
- .test_ghcup_version
|
||||||
|
- .debian
|
||||||
|
before_script:
|
||||||
|
- ./.gitlab/before_script/linux/install_deps.sh
|
||||||
|
variables:
|
||||||
|
OS: "LINUX"
|
||||||
|
|
||||||
|
.test_ghcup_version:darwin:
|
||||||
|
extends:
|
||||||
|
- .test_ghcup_version
|
||||||
|
- .darwin
|
||||||
|
before_script:
|
||||||
|
- ./.gitlab/before_script/darwin/install_deps.sh
|
||||||
|
variables:
|
||||||
|
OS: "DARWIN"
|
||||||
|
after_script:
|
||||||
|
- BUILD_DIR=$CI_PROJECT_DIR
|
||||||
|
- echo "Cleaning $BUILD_DIR"
|
||||||
|
- cd $HOME
|
||||||
|
- rm -Rf "$BUILD_DIR"/*
|
||||||
|
- exit 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
######## linux ########
|
||||||
|
|
||||||
|
test:linux:recommended:
|
||||||
|
extends: .test_ghcup_version:linux
|
||||||
|
variables:
|
||||||
|
GHC_VERSION: "recommended"
|
||||||
|
|
||||||
|
test:linux:latest:
|
||||||
|
extends: .test_ghcup_version:linux
|
||||||
|
variables:
|
||||||
|
GHC_VERSION: "latest"
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
|
|
||||||
|
######## darwin ########
|
||||||
|
|
||||||
|
test:mac:recommended:
|
||||||
|
extends: .test_ghcup_version:darwin
|
||||||
|
variables:
|
||||||
|
GHC_VERSION: "recommended"
|
||||||
|
|
||||||
|
test:mac:latest:
|
||||||
|
extends: .test_ghcup_version:darwin
|
||||||
|
variables:
|
||||||
|
GHC_VERSION: "latest"
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
14
.gitlab/before_script/darwin/install_deps.sh
Executable file
14
.gitlab/before_script/darwin/install_deps.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
. "$( cd "$(dirname "$0")" ; pwd -P )/../../ghcup_env"
|
||||||
|
|
||||||
|
curl -sSfL https://gitlab.haskell.org/haskell/ghcup/-/raw/master/ghcup > ./ghcup-legacy
|
||||||
|
chmod +x ghcup-legacy
|
||||||
|
|
||||||
|
./ghcup-legacy install ${GHC_VERSION}
|
||||||
|
./ghcup-legacy set ${GHC_VERSION}
|
||||||
|
./ghcup-legacy install-cabal
|
||||||
|
|
||||||
|
exit 0
|
||||||
16
.gitlab/before_script/linux/install_deps.sh
Executable file
16
.gitlab/before_script/linux/install_deps.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev
|
||||||
|
|
||||||
|
. "$( cd "$(dirname "$0")" ; pwd -P )/../../ghcup_env"
|
||||||
|
|
||||||
|
curl -sSfL https://gitlab.haskell.org/haskell/ghcup/-/raw/master/ghcup > ./ghcup-legacy
|
||||||
|
chmod +x ghcup-legacy
|
||||||
|
|
||||||
|
./ghcup-legacy install ${GHC_VERSION}
|
||||||
|
./ghcup-legacy set ${GHC_VERSION}
|
||||||
|
./ghcup-legacy install-cabal
|
||||||
|
|
||||||
3
.gitlab/ghcup_env
Normal file
3
.gitlab/ghcup_env
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
||||||
|
export PATH="$CI_PROJECT_DIR/.ghcup/bin:$CI_PROJECT_DIR/.local/bin:$PATH"
|
||||||
|
|
||||||
58
.gitlab/script/ghcup_version.sh
Executable file
58
.gitlab/script/ghcup_version.sh
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
. "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup_env"
|
||||||
|
|
||||||
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
|
|
||||||
|
ecabal() {
|
||||||
|
cabal --store-dir="$(pwd)"/.store "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# build
|
||||||
|
ecabal update
|
||||||
|
|
||||||
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
|
ecabal build -fcurl
|
||||||
|
else
|
||||||
|
ecabal build
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp "$(ecabal new-exec --enable-tests --verbose=0 --offline sh -- -c 'command -v ghcup')" .
|
||||||
|
cp "$(ecabal new-exec --enable-tests --verbose=0 --offline sh -- -c 'command -v ghcup-gen')" .
|
||||||
|
|
||||||
|
|
||||||
|
# testing
|
||||||
|
|
||||||
|
cp ./ghcup "$CI_PROJECT_DIR"/.local/bin/ghcup
|
||||||
|
cp ./ghcup-gen "$CI_PROJECT_DIR"/.local/bin/ghcup-gen
|
||||||
|
rm -rf "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup
|
||||||
|
|
||||||
|
ghcup-gen check -f ghcup-${JSON_VERSION}.json
|
||||||
|
|
||||||
|
ghcup numeric-version
|
||||||
|
|
||||||
|
ghcup -v -c install ${GHC_VERSION}
|
||||||
|
ghcup -v -c set ${GHC_VERSION}
|
||||||
|
ghcup -v -c install-cabal
|
||||||
|
|
||||||
|
cabal --version
|
||||||
|
|
||||||
|
ghcup -v -c debug-info
|
||||||
|
|
||||||
|
ghcup -v -c list
|
||||||
|
ghcup -v -c list -t ghc
|
||||||
|
ghcup -v -c list -t cabal
|
||||||
|
|
||||||
|
ghc --version
|
||||||
|
ghci --version
|
||||||
|
ghc-$(ghc --numeric-version) --version
|
||||||
|
ghci-$(ghc --numeric-version) --version
|
||||||
|
|
||||||
|
ghcup -v upgrade
|
||||||
|
ghcup -v upgrade -f
|
||||||
|
|
||||||
|
ghcup -v rm $(ghc --numeric-version)
|
||||||
|
|
||||||
25
.travis.yml
Normal file
25
.travis.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode10.1
|
||||||
|
language: generic
|
||||||
|
env: ARTIFACT=x86_64-apple-darwin-10.13-ghcup
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode11.3
|
||||||
|
language: generic
|
||||||
|
env: ARTIFACT=x86_64-apple-darwin-10.14-ghcup
|
||||||
|
|
||||||
|
script: ".travis/build.sh"
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
api_key:
|
||||||
|
secure: 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
|
||||||
|
|
||||||
22
.travis/build.sh
Executable file
22
.travis/build.sh
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#/bin/sh
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
## install ghc via old ghcup
|
||||||
|
|
||||||
|
mkdir -p ~/.ghcup/bin
|
||||||
|
curl https://gitlab.haskell.org/haskell/ghcup/raw/master/ghcup > ~/.ghcup/bin/ghcup
|
||||||
|
chmod +x ~/.ghcup/bin/ghcup
|
||||||
|
|
||||||
|
export PATH="$HOME/.ghcup/bin:$PATH"
|
||||||
|
|
||||||
|
ghcup install 8.8.3
|
||||||
|
ghcup install-cabal 3.2.0.0
|
||||||
|
ghcup set 8.8.3
|
||||||
|
|
||||||
|
|
||||||
|
## install ghcup
|
||||||
|
|
||||||
|
cabal update
|
||||||
|
cabal build -fcurl
|
||||||
|
cp "$(cabal new-exec --verbose=0 --offline sh -- -c 'command -v ghcup')" "./${ARTIFACT}"
|
||||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,5 +1,15 @@
|
|||||||
# Revision history for ghcup
|
# Revision history for ghcup
|
||||||
|
|
||||||
## 0.1.0.0 -- YYYY-mm-dd
|
## 0.1.2 -- 2020-04-15
|
||||||
|
|
||||||
|
* Fix bug when removing the set GHC version
|
||||||
|
* Fix use of undocumented `GHCUP_INSTALL_BASE_PREFIX` variable
|
||||||
|
* skip upgrade if ghcup is already latest version
|
||||||
|
|
||||||
|
## 0.1.1 -- 2020-04-15
|
||||||
|
|
||||||
|
* fix awful fdopendir bug on mac bug by updating hpath-posix
|
||||||
|
|
||||||
|
## 0.1.0
|
||||||
|
|
||||||
* First version. Released on an unsuspecting world.
|
* First version. Released on an unsuspecting world.
|
||||||
|
|||||||
45
HACKING.md
Normal file
45
HACKING.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# HACKING
|
||||||
|
|
||||||
|
## Design decisions
|
||||||
|
|
||||||
|
### Using [Excepts](https://hackage.haskell.org/package/haskus-utils-variant-3.0/docs/Haskus-Utils-Variant-Excepts.html) as a beefed up ExceptT
|
||||||
|
|
||||||
|
This is an open variant, similar to [plucky](https://hackage.haskell.org/package/plucky) or [oops](https://github.com/i-am-tom/oops) and allows us to combine different error types. Maybe it is too much and it's a little bit [unergonomic](https://github.com/haskus/packages/issues/32) at times. If it really hurts maintenance, it will be removed. It was more of an experiment.
|
||||||
|
|
||||||
|
### No use of filepath or directory
|
||||||
|
|
||||||
|
Filepath and directory have two fundamental problems: 1. they use String as filepath (see [AFPP](https://gitlab.haskell.org/ghc/ghc/-/wikis/proposal/abstract-file-path) as to why this is wrong) and 2. they try very hard to be cross-platform at the expense of low-level correctness. Instead, we use the [hpath](https://github.com/hasufell/hpath) libraries for file and filepath related stuff, which also gives us stronger filepath types.
|
||||||
|
|
||||||
|
### No use of haskell-TLS
|
||||||
|
|
||||||
|
I consider haskell-TLS an interesting experiment, but not a battle-tested and peer-reviewed crypto implementation. There is little to no research about what the intricacies of using haskell for low-level crypto are and how vulnerable such binaries are. Instead, we use either curl the binary (for FreeBSD and mac) or http-io-streams, which works with OpenSSL bindings.
|
||||||
|
|
||||||
|
### Optics instead of lens
|
||||||
|
|
||||||
|
They're a little safer (less Monoid weirdness with view) and have better error messages. Consider the following wit lens
|
||||||
|
|
||||||
|
```
|
||||||
|
> view (_Just . to (++ "abc")) Nothing
|
||||||
|
""
|
||||||
|
```
|
||||||
|
|
||||||
|
vs optics
|
||||||
|
|
||||||
|
```
|
||||||
|
> view (_Just % to (++ "abc")) Nothing
|
||||||
|
|
||||||
|
<interactive>:2:1: error:
|
||||||
|
• An_AffineFold cannot be used as A_Getter
|
||||||
|
• In the expression: view (_Just % to (++ "abc")) Nothing
|
||||||
|
In an equation for ‘it’: it = view (_Just % to (++ "abc")) Nothing
|
||||||
|
```
|
||||||
|
|
||||||
|
### Strict and StrictData on by default
|
||||||
|
|
||||||
|
Kazu Yamamoto [explained it in his PR](https://github.com/yesodweb/wai/pull/752#issuecomment-501531386) very well. I like to agree with him. The instances where we need non-strict behavior, we annotate it.
|
||||||
|
|
||||||
|
## Code style and formatting
|
||||||
|
|
||||||
|
1. Brittany
|
||||||
|
2. mtl-style preferred
|
||||||
|
3. no overly pointfree style
|
||||||
10
README.md
10
README.md
@@ -25,7 +25,7 @@ Follow the instructions at [https://www.haskell.org/ghcup/](https://www.haskell.
|
|||||||
|
|
||||||
### Manual install
|
### Manual install
|
||||||
|
|
||||||
Download the binary for your platform at [https://github.com/hasufell/ghcup-hs/releases](https://github.com/hasufell/ghcup-hs/releases)
|
Download the binary for your platform at [https://downloads.haskell.org/~ghcup/](https://downloads.haskell.org/~ghcup/)
|
||||||
and place it into your `PATH` anywhere.
|
and place it into your `PATH` anywhere.
|
||||||
|
|
||||||
Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) like so:
|
Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) like so:
|
||||||
@@ -45,16 +45,16 @@ Common use cases are:
|
|||||||
ghcup list
|
ghcup list
|
||||||
|
|
||||||
# install the recommended GHC version
|
# install the recommended GHC version
|
||||||
ghcup install ghc
|
ghcup install
|
||||||
|
|
||||||
# install a specific GHC version
|
# install a specific GHC version
|
||||||
ghcup install ghc -v 8.2.2
|
ghcup install 8.2.2
|
||||||
|
|
||||||
# set the currently "active" GHC version
|
# set the currently "active" GHC version
|
||||||
ghcup set -v 8.4.4
|
ghcup set 8.4.4
|
||||||
|
|
||||||
# install cabal-install
|
# install cabal-install
|
||||||
ghcup install cabal
|
ghcup install-cabal
|
||||||
|
|
||||||
# update ghcup itself
|
# update ghcup itself
|
||||||
ghcup upgrade
|
ghcup upgrade
|
||||||
|
|||||||
11
RELEASING.md
Normal file
11
RELEASING.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# RELEASING
|
||||||
|
|
||||||
|
1. update `GHCup.Version` module. `ghcupURL` must only be updated if we change the `_toolRequirements` type or the JSON representation of it. The version of the json represents the change increments. `ghcUpVer` is the current application version.
|
||||||
|
|
||||||
|
2. Add/fix downloads to `GHCupDownloads` module, then run `ghcup-gen gen` to generate the new json and validate it via `ghcup-gen check`.
|
||||||
|
|
||||||
|
3. Commit and git push with tag. Wait for tests to succeed.
|
||||||
|
|
||||||
|
4. Upload the new `ghcup-<ver>.json` to `webhost.haskell.org/ghcup/data/`.
|
||||||
|
|
||||||
|
5. Build ghcup releases for Linux (fully static), mac (with `-fcurl`) and FreeBSD (with `-fcurl`). Upload to `webhost.haskell.org/ghcup/bin/` and update symlinks.
|
||||||
21
TODO.md
21
TODO.md
@@ -2,23 +2,7 @@
|
|||||||
|
|
||||||
## Now
|
## Now
|
||||||
|
|
||||||
* travis
|
* move out GHCup.Version module, bc it's not library-ish
|
||||||
|
|
||||||
* requirements
|
|
||||||
* for ghcup (bootstrap script)
|
|
||||||
* per tool
|
|
||||||
* mac build: xattr -cr .
|
|
||||||
* static binaries
|
|
||||||
* upgrade plan from old ghcup
|
|
||||||
|
|
||||||
* bootstrap-haskell with new ghcup
|
|
||||||
* add warning to ghcup script about new binary
|
|
||||||
|
|
||||||
* make sure smart-dl is not broken
|
|
||||||
|
|
||||||
* handle SIGINT better (remove dirs)
|
|
||||||
|
|
||||||
* review symlink handling (maybe fixed set of tools?)
|
|
||||||
|
|
||||||
## Maybe
|
## Maybe
|
||||||
|
|
||||||
@@ -28,16 +12,17 @@
|
|||||||
|
|
||||||
## Later
|
## Later
|
||||||
|
|
||||||
|
* i386 support
|
||||||
* add support for RC/alpha/HEAD versions
|
* add support for RC/alpha/HEAD versions
|
||||||
|
|
||||||
## Cleanups
|
## Cleanups
|
||||||
|
|
||||||
|
* too many decodeutf8
|
||||||
* avoid alternative for IO
|
* avoid alternative for IO
|
||||||
* use plucky or oops instead of Excepts
|
* use plucky or oops instead of Excepts
|
||||||
|
|
||||||
## Questions
|
## Questions
|
||||||
|
|
||||||
* fully static musl builds for linux?
|
|
||||||
* mirror support
|
* mirror support
|
||||||
* interactive handling when distro doesn't exist and we know the tarball is incompatible?
|
* interactive handling when distro doesn't exist and we know the tarball is incompatible?
|
||||||
* ghcup-with wrapper to execute a command with a given ghc in PATH?
|
* ghcup-with wrapper to execute a command with a given ghc in PATH?
|
||||||
|
|||||||
@@ -984,11 +984,33 @@ cabal_3200_64_darwin = DownloadInfo
|
|||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
||||||
ghcup_001_64_linux :: DownloadInfo
|
ghcup_011_32_linux :: DownloadInfo
|
||||||
ghcup_001_64_linux = DownloadInfo
|
ghcup_011_32_linux = DownloadInfo
|
||||||
[uri|file:///home/maerwald/tmp/ghcup-exe|]
|
[uri|https://downloads.haskell.org/ghcup/0.1.1/i386-linux-ghcup-0.1.1|]
|
||||||
Nothing
|
Nothing
|
||||||
"558126339252788a3d44a3f910417277c7ab656f0796b68bdc58afe73296b8cd"
|
"f576f22efdcf17fa18189b65d70e596d14f2347ef549a00592ef28d529c7d5a0"
|
||||||
|
|
||||||
|
|
||||||
|
ghcup_011_64_linux :: DownloadInfo
|
||||||
|
ghcup_011_64_linux = DownloadInfo
|
||||||
|
[uri|https://downloads.haskell.org/ghcup/0.1.1/x86_64-linux-ghcup-0.1.1|]
|
||||||
|
Nothing
|
||||||
|
"2789fbab2848e4dfd77406b9a710c925b3b9680ac0f8486caca190628646486f"
|
||||||
|
|
||||||
|
|
||||||
|
ghcup_011_64_freebsd :: DownloadInfo
|
||||||
|
ghcup_011_64_freebsd = DownloadInfo
|
||||||
|
[uri|https://downloads.haskell.org/ghcup/0.1.1/x86_64-portbld-freebsd-ghcup-0.1.1|]
|
||||||
|
Nothing
|
||||||
|
"1336585b15692d6458edf4d913fd585d9963a708e2c952a71ee1ad3400ed2163"
|
||||||
|
|
||||||
|
|
||||||
|
ghcup_011_64_darwin10_13 :: DownloadInfo
|
||||||
|
ghcup_011_64_darwin10_13 = DownloadInfo
|
||||||
|
[uri|https://downloads.haskell.org/ghcup/0.1.1/x86_64-apple-darwin-ghcup-0.1.1|]
|
||||||
|
Nothing
|
||||||
|
"b9694de40134e3d17611749eba94d8e4d00a84e2a16bb2409eab1e87f810dacd"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1855,11 +1877,18 @@ ghcupDownloads = M.fromList
|
|||||||
)
|
)
|
||||||
, ( GHCup
|
, ( GHCup
|
||||||
, M.fromList
|
, M.fromList
|
||||||
[ ( [vver|0.0.1|]
|
[ ( [vver|0.1.1|]
|
||||||
, VersionInfo [Recommended, Latest] Nothing $ M.fromList
|
, VersionInfo [Recommended, Latest] Nothing $ M.fromList
|
||||||
[ ( A_64
|
[ ( A_64
|
||||||
, M.fromList
|
, M.fromList
|
||||||
[(Linux UnknownLinux, M.fromList [(Nothing, ghcup_001_64_linux)])]
|
[ (Linux UnknownLinux, M.fromList [(Nothing, ghcup_011_64_linux)])
|
||||||
|
, (Darwin, M.fromList [(Nothing, ghcup_011_64_darwin10_13)])
|
||||||
|
, (FreeBSD, M.fromList [(Nothing, ghcup_011_64_freebsd)])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
, ( A_32
|
||||||
|
, M.fromList
|
||||||
|
[(Linux UnknownLinux, M.fromList [(Nothing, ghcup_011_32_linux)])]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
{-# LANGUAGE CPP #-}
|
||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
|
{-# LANGUAGE NamedFieldPuns #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
|
||||||
|
|
||||||
module Main where
|
module Main where
|
||||||
@@ -14,7 +15,7 @@ import GHCup.Types.JSON ( )
|
|||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
import GHCupInfo
|
import GHCupInfo
|
||||||
|
|
||||||
import Data.Aeson ( eitherDecode )
|
import Data.Aeson ( eitherDecode, encode )
|
||||||
import Data.Aeson.Encode.Pretty
|
import Data.Aeson.Encode.Pretty
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Data.Semigroup ( (<>) )
|
import Data.Semigroup ( (<>) )
|
||||||
@@ -61,10 +62,13 @@ outputP = fileOutput <|> stdOutput
|
|||||||
|
|
||||||
data GenJSONOpts = GenJSONOpts
|
data GenJSONOpts = GenJSONOpts
|
||||||
{ output :: Maybe Output
|
{ output :: Maybe Output
|
||||||
|
, pretty :: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
genJSONOpts :: Parser GenJSONOpts
|
genJSONOpts :: Parser GenJSONOpts
|
||||||
genJSONOpts = GenJSONOpts <$> optional outputP
|
genJSONOpts = GenJSONOpts <$> optional outputP <*> switch
|
||||||
|
(short 'p' <> long "pretty" <> help "Make JSON output pretty (human readable)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
data Input
|
data Input
|
||||||
@@ -134,14 +138,16 @@ main = do
|
|||||||
customExecParser (prefs showHelpOnError) (info (opts <**> helper) idm)
|
customExecParser (prefs showHelpOnError) (info (opts <**> helper) idm)
|
||||||
>>= \Options {..} -> case optCommand of
|
>>= \Options {..} -> case optCommand of
|
||||||
GenJSON gopts -> do
|
GenJSON gopts -> do
|
||||||
let
|
let bs True =
|
||||||
bs = encodePretty' (defConfig { confIndent = Spaces 2 })
|
encodePretty' (defConfig { confIndent = Spaces 2 }) ghcupInfo
|
||||||
ghcupInfo
|
bs False = encode ghcupInfo
|
||||||
case gopts of
|
case gopts of
|
||||||
GenJSONOpts { output = Nothing } -> L.hPutStr stdout bs
|
GenJSONOpts { output = Nothing, pretty } ->
|
||||||
GenJSONOpts { output = Just StdOutput } -> L.hPutStr stdout bs
|
L.hPutStr stdout (bs pretty)
|
||||||
GenJSONOpts { output = Just (FileOutput file) } ->
|
GenJSONOpts { output = Just StdOutput, pretty } ->
|
||||||
L.writeFile file bs
|
L.hPutStr stdout (bs pretty)
|
||||||
|
GenJSONOpts { output = Just (FileOutput file), pretty } ->
|
||||||
|
L.writeFile file (bs pretty)
|
||||||
ValidateJSON vopts -> case vopts of
|
ValidateJSON vopts -> case vopts of
|
||||||
ValidateJSONOpts { input = Nothing } ->
|
ValidateJSONOpts { input = Nothing } ->
|
||||||
L.getContents >>= valAndExit validate
|
L.getContents >>= valAndExit validate
|
||||||
@@ -165,4 +171,3 @@ main = do
|
|||||||
Left e -> die (color Red $ show e)
|
Left e -> die (color Red $ show e)
|
||||||
myLoggerT (LoggerConfig True (B.hPut stdout) (\_ -> pure ())) (f av)
|
myLoggerT (LoggerConfig True (B.hPut stdout) (\_ -> pure ())) (f av)
|
||||||
>>= exitWith
|
>>= exitWith
|
||||||
|
|
||||||
|
|||||||
@@ -73,13 +73,14 @@ data Options = Options
|
|||||||
}
|
}
|
||||||
|
|
||||||
data Command
|
data Command
|
||||||
= Install InstallCommand
|
= Install InstallOptions
|
||||||
|
| InstallCabal InstallOptions
|
||||||
| SetGHC SetGHCOptions
|
| SetGHC SetGHCOptions
|
||||||
| List ListOptions
|
| List ListOptions
|
||||||
| Rm RmOptions
|
| Rm RmOptions
|
||||||
| DInfo
|
| DInfo
|
||||||
| Compile CompileCommand
|
| Compile CompileCommand
|
||||||
| Upgrade UpgradeOpts
|
| Upgrade UpgradeOpts Bool
|
||||||
| NumericVersion
|
| NumericVersion
|
||||||
| ToolRequirements
|
| ToolRequirements
|
||||||
|
|
||||||
@@ -87,9 +88,6 @@ data ToolVersion = ToolVersion Version
|
|||||||
| ToolTag Tag
|
| ToolTag Tag
|
||||||
|
|
||||||
|
|
||||||
data InstallCommand = InstallGHC InstallOptions
|
|
||||||
| InstallCabal InstallOptions
|
|
||||||
|
|
||||||
data InstallOptions = InstallOptions
|
data InstallOptions = InstallOptions
|
||||||
{ instVer :: Maybe ToolVersion
|
{ instVer :: Maybe ToolVersion
|
||||||
, instPlatform :: Maybe PlatformRequest
|
, instPlatform :: Maybe PlatformRequest
|
||||||
@@ -132,11 +130,11 @@ opts =
|
|||||||
Options
|
Options
|
||||||
<$> switch
|
<$> switch
|
||||||
(short 'v' <> long "verbose" <> help
|
(short 'v' <> long "verbose" <> help
|
||||||
"Whether to enable verbosity (default: False)"
|
"Enable verbosity"
|
||||||
)
|
)
|
||||||
<*> switch
|
<*> switch
|
||||||
(short 'c' <> long "cache" <> help
|
(short 'c' <> long "cache" <> help
|
||||||
"Whether to cache downloads (default: False)"
|
"Cache downloads in ~/.ghcup/cache"
|
||||||
)
|
)
|
||||||
<*> (optional
|
<*> (optional
|
||||||
(option
|
(option
|
||||||
@@ -151,7 +149,7 @@ opts =
|
|||||||
)
|
)
|
||||||
<*> switch
|
<*> switch
|
||||||
(short 'n' <> long "no-verify" <> help
|
(short 'n' <> long "no-verify" <> help
|
||||||
"Skip tarball checksum verification (default: False)"
|
"Skip tarball checksum verification"
|
||||||
)
|
)
|
||||||
<*> com
|
<*> com
|
||||||
where
|
where
|
||||||
@@ -164,11 +162,29 @@ com =
|
|||||||
subparser
|
subparser
|
||||||
( command
|
( command
|
||||||
"install"
|
"install"
|
||||||
( Install
|
((info ((Install <$> installOpts) <**> helper)
|
||||||
<$> (info (installP <**> helper)
|
(progDesc "Install or update GHC")
|
||||||
(progDesc "Install or update GHC/cabal")
|
)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
<> command
|
||||||
|
"set"
|
||||||
|
( SetGHC
|
||||||
|
<$> (info (setGHCOpts <**> helper)
|
||||||
|
(progDesc "Set currently active GHC version")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<> command
|
||||||
|
"rm"
|
||||||
|
( Rm
|
||||||
|
<$> (info (rmOpts <**> helper) (progDesc "Remove a GHC version"))
|
||||||
|
)
|
||||||
|
|
||||||
|
<> command
|
||||||
|
"install-cabal"
|
||||||
|
((info ((InstallCabal <$> installOpts) <**> helper)
|
||||||
|
(progDesc "Install or update cabal")
|
||||||
|
)
|
||||||
|
)
|
||||||
<> command
|
<> command
|
||||||
"list"
|
"list"
|
||||||
( List
|
( List
|
||||||
@@ -178,12 +194,12 @@ com =
|
|||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
"upgrade"
|
"upgrade"
|
||||||
( Upgrade
|
(info ((Upgrade <$> upgradeOptsP <*>
|
||||||
<$> (info
|
switch
|
||||||
(upgradeOptsP <**> helper)
|
(short 'f' <> long "force" <> help
|
||||||
(progDesc "Upgrade ghcup (per default in ~/.ghcup/bin/)")
|
"Force update"
|
||||||
)
|
)
|
||||||
)
|
) <**> helper) (progDesc "Upgrade ghcup"))
|
||||||
<> command
|
<> command
|
||||||
"compile"
|
"compile"
|
||||||
( Compile
|
( Compile
|
||||||
@@ -193,25 +209,6 @@ com =
|
|||||||
)
|
)
|
||||||
<> commandGroup "Main commands:"
|
<> commandGroup "Main commands:"
|
||||||
)
|
)
|
||||||
<|> subparser
|
|
||||||
( command
|
|
||||||
"set"
|
|
||||||
( SetGHC
|
|
||||||
<$> (info (setGHCOpts <**> helper)
|
|
||||||
(progDesc "Set the currently active GHC version")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<> command
|
|
||||||
"rm"
|
|
||||||
( Rm
|
|
||||||
<$> (info
|
|
||||||
(rmOpts <**> helper)
|
|
||||||
(progDesc "Remove a GHC version installed by ghcup")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<> commandGroup "GHC commands:"
|
|
||||||
<> hidden
|
|
||||||
)
|
|
||||||
<|> subparser
|
<|> subparser
|
||||||
( command
|
( command
|
||||||
"debug-info"
|
"debug-info"
|
||||||
@@ -224,34 +221,19 @@ com =
|
|||||||
<> command
|
<> command
|
||||||
"tool-requirements"
|
"tool-requirements"
|
||||||
( (\_ -> ToolRequirements)
|
( (\_ -> ToolRequirements)
|
||||||
<$> (info (helper) (progDesc "Show the requirements for ghc/cabal"))
|
<$> (info (helper)
|
||||||
|
(progDesc "Show the requirements for ghc/cabal")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
<> commandGroup "Other commands:"
|
<> commandGroup "Other commands:"
|
||||||
<> hidden
|
<> hidden
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
installP :: Parser InstallCommand
|
|
||||||
installP = subparser
|
|
||||||
( command
|
|
||||||
"ghc"
|
|
||||||
( InstallGHC
|
|
||||||
<$> (info (installOpts <**> helper) (progDesc "Install a GHC version"))
|
|
||||||
)
|
|
||||||
<> command
|
|
||||||
"cabal"
|
|
||||||
( InstallCabal
|
|
||||||
<$> (info (installOpts <**> helper)
|
|
||||||
(progDesc "Install or update a Cabal version")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
installOpts :: Parser InstallOptions
|
installOpts :: Parser InstallOptions
|
||||||
installOpts =
|
installOpts =
|
||||||
InstallOptions
|
(flip InstallOptions)
|
||||||
<$> optional toolVersionParser
|
<$> (optional
|
||||||
<*> (optional
|
|
||||||
(option
|
(option
|
||||||
(eitherReader platformParser)
|
(eitherReader platformParser)
|
||||||
( short 'p'
|
( short 'p'
|
||||||
@@ -262,10 +244,11 @@ installOpts =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
<*> optional toolVersionArgument
|
||||||
|
|
||||||
|
|
||||||
setGHCOpts :: Parser SetGHCOptions
|
setGHCOpts :: Parser SetGHCOptions
|
||||||
setGHCOpts = SetGHCOptions <$> optional toolVersionParser
|
setGHCOpts = SetGHCOptions <$> optional toolVersionArgument
|
||||||
|
|
||||||
listOpts :: Parser ListOptions
|
listOpts :: Parser ListOptions
|
||||||
listOpts =
|
listOpts =
|
||||||
@@ -289,7 +272,7 @@ listOpts =
|
|||||||
)
|
)
|
||||||
|
|
||||||
rmOpts :: Parser RmOptions
|
rmOpts :: Parser RmOptions
|
||||||
rmOpts = RmOptions <$> versionParser
|
rmOpts = RmOptions <$> versionArgument
|
||||||
|
|
||||||
|
|
||||||
compileP :: Parser CompileCommand
|
compileP :: Parser CompileCommand
|
||||||
@@ -370,13 +353,6 @@ compileOpts =
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
versionParser :: Parser Version
|
|
||||||
versionParser = option
|
|
||||||
(eitherReader (bimap (const "Not a valid version") id . version . T.pack))
|
|
||||||
(short 'v' <> long "version" <> metavar "VERSION" <> help "The target version"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
toolVersionParser :: Parser ToolVersion
|
toolVersionParser :: Parser ToolVersion
|
||||||
toolVersionParser = verP <|> toolP
|
toolVersionParser = verP <|> toolP
|
||||||
where
|
where
|
||||||
@@ -384,16 +360,44 @@ toolVersionParser = verP <|> toolP
|
|||||||
toolP =
|
toolP =
|
||||||
ToolTag
|
ToolTag
|
||||||
<$> (option
|
<$> (option
|
||||||
(eitherReader
|
(eitherReader tagEither)
|
||||||
(\s' -> case fmap toLower s' of
|
|
||||||
"recommended" -> Right Recommended
|
|
||||||
"latest" -> Right Latest
|
|
||||||
other -> Left ([i|Unknown tag #{other}|])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(short 't' <> long "tag" <> metavar "TAG" <> help "The target tag")
|
(short 't' <> long "tag" <> metavar "TAG" <> help "The target tag")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- | same as toolVersionParser, except as an argument.
|
||||||
|
toolVersionArgument :: Parser ToolVersion
|
||||||
|
toolVersionArgument =
|
||||||
|
argument (eitherReader toolVersionEither) (metavar "VERSION|TAG")
|
||||||
|
|
||||||
|
|
||||||
|
versionArgument :: Parser Version
|
||||||
|
versionArgument = argument
|
||||||
|
(eitherReader versionEither)
|
||||||
|
(metavar "VERSION")
|
||||||
|
|
||||||
|
versionParser :: Parser Version
|
||||||
|
versionParser = option
|
||||||
|
(eitherReader versionEither)
|
||||||
|
(short 'v' <> long "version" <> metavar "VERSION" <> help "The target version"
|
||||||
|
)
|
||||||
|
|
||||||
|
tagEither :: String -> Either String Tag
|
||||||
|
tagEither s' = case fmap toLower s' of
|
||||||
|
"recommended" -> Right Recommended
|
||||||
|
"latest" -> Right Latest
|
||||||
|
other -> Left ([i|Unknown tag #{other}|])
|
||||||
|
|
||||||
|
versionEither :: String -> Either String Version
|
||||||
|
versionEither s' =
|
||||||
|
-- 'version' is a bit too lax and will parse typoed tags
|
||||||
|
case readMaybe ((:[]) . head $ s') :: Maybe Int of
|
||||||
|
Just _ -> bimap (const "Not a valid version") id . version . T.pack $ s'
|
||||||
|
Nothing -> Left "Not a valid version"
|
||||||
|
|
||||||
|
toolVersionEither :: String -> Either String ToolVersion
|
||||||
|
toolVersionEither s' =
|
||||||
|
bimap id ToolTag (tagEither s') <|> bimap id ToolVersion (versionEither s')
|
||||||
|
|
||||||
|
|
||||||
toolParser :: String -> Either String Tool
|
toolParser :: String -> Either String Tool
|
||||||
toolParser s' | t == T.pack "ghc" = Right GHC
|
toolParser s' | t == T.pack "ghc" = Right GHC
|
||||||
@@ -588,11 +592,15 @@ main = do
|
|||||||
@'[ AlreadyInstalled
|
@'[ AlreadyInstalled
|
||||||
, BuildFailed
|
, BuildFailed
|
||||||
, DigestError
|
, DigestError
|
||||||
|
, DistroNotFound
|
||||||
|
, DownloadFailed
|
||||||
, GHCupSetError
|
, GHCupSetError
|
||||||
|
, NoCompatibleArch
|
||||||
|
, NoCompatiblePlatform
|
||||||
, NoDownload
|
, NoDownload
|
||||||
|
, NotFoundInPATH
|
||||||
, PatchFailed
|
, PatchFailed
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
, DownloadFailed
|
|
||||||
]
|
]
|
||||||
|
|
||||||
let runCompileCabal =
|
let runCompileCabal =
|
||||||
@@ -600,12 +608,15 @@ main = do
|
|||||||
. flip runReaderT settings
|
. flip runReaderT settings
|
||||||
. runResourceT
|
. runResourceT
|
||||||
. runE
|
. runE
|
||||||
@'[ UnknownArchive
|
@'[ BuildFailed
|
||||||
, NoDownload
|
|
||||||
, DigestError
|
, DigestError
|
||||||
, BuildFailed
|
, DistroNotFound
|
||||||
, PatchFailed
|
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
|
, NoCompatibleArch
|
||||||
|
, NoCompatiblePlatform
|
||||||
|
, NoDownload
|
||||||
|
, PatchFailed
|
||||||
|
, UnknownArchive
|
||||||
]
|
]
|
||||||
|
|
||||||
let runUpgrade =
|
let runUpgrade =
|
||||||
@@ -618,6 +629,7 @@ main = do
|
|||||||
, NoCompatiblePlatform
|
, NoCompatiblePlatform
|
||||||
, NoCompatibleArch
|
, NoCompatibleArch
|
||||||
, NoDownload
|
, NoDownload
|
||||||
|
, NoUpdate
|
||||||
, FileDoesNotExistError
|
, FileDoesNotExistError
|
||||||
, CopyError
|
, CopyError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
@@ -639,7 +651,7 @@ main = do
|
|||||||
runLogger $ checkForUpdates dls
|
runLogger $ checkForUpdates dls
|
||||||
|
|
||||||
case optCommand of
|
case optCommand of
|
||||||
Install (InstallGHC InstallOptions {..}) ->
|
Install (InstallOptions {..}) ->
|
||||||
void
|
void
|
||||||
$ (runInstTool $ do
|
$ (runInstTool $ do
|
||||||
v <- liftE $ fromVersion dls instVer GHC
|
v <- liftE $ fromVersion dls instVer GHC
|
||||||
@@ -662,7 +674,7 @@ Check the logs at ~/.ghcup/logs and the build directory #{tmpdir} for more clues
|
|||||||
$(logError) [i|#{e}|]
|
$(logError) [i|#{e}|]
|
||||||
$(logError) [i|Also check the logs in ~/.ghcup/logs|]
|
$(logError) [i|Also check the logs in ~/.ghcup/logs|]
|
||||||
exitFailure
|
exitFailure
|
||||||
Install (InstallCabal InstallOptions {..}) ->
|
InstallCabal (InstallOptions {..}) ->
|
||||||
void
|
void
|
||||||
$ (runInstTool $ do
|
$ (runInstTool $ do
|
||||||
v <- liftE $ fromVersion dls instVer Cabal
|
v <- liftE $ fromVersion dls instVer Cabal
|
||||||
@@ -762,7 +774,7 @@ Check the logs at ~/.ghcup/logs and the build directory #{tmpdir} for more clues
|
|||||||
VLeft e ->
|
VLeft e ->
|
||||||
runLogger ($(logError) [i|#{e}|]) >> exitFailure
|
runLogger ($(logError) [i|#{e}|]) >> exitFailure
|
||||||
|
|
||||||
Upgrade (uOpts) -> do
|
Upgrade (uOpts) force -> do
|
||||||
target <- case uOpts of
|
target <- case uOpts of
|
||||||
UpgradeInplace -> do
|
UpgradeInplace -> do
|
||||||
efp <- liftIO $ getExecutablePath
|
efp <- liftIO $ getExecutablePath
|
||||||
@@ -775,7 +787,7 @@ Check the logs at ~/.ghcup/logs and the build directory #{tmpdir} for more clues
|
|||||||
|
|
||||||
void
|
void
|
||||||
$ (runUpgrade $ do
|
$ (runUpgrade $ do
|
||||||
liftE $ upgradeGHCup dls target
|
liftE $ upgradeGHCup dls target force
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight v' -> do
|
VRight v' -> do
|
||||||
@@ -783,6 +795,9 @@ Check the logs at ~/.ghcup/logs and the build directory #{tmpdir} for more clues
|
|||||||
runLogger
|
runLogger
|
||||||
$ $(logInfo)
|
$ $(logInfo)
|
||||||
[i|Successfully upgraded GHCup to version #{pretty_v}|]
|
[i|Successfully upgraded GHCup to version #{pretty_v}|]
|
||||||
|
VLeft (V NoUpdate) ->
|
||||||
|
runLogger $ $(logWarn)
|
||||||
|
[i|No GHCup update available|]
|
||||||
VLeft e ->
|
VLeft e ->
|
||||||
runLogger ($(logError) [i|#{e}|]) >> exitFailure
|
runLogger ($(logError) [i|#{e}|]) >> exitFailure
|
||||||
|
|
||||||
|
|||||||
201
bootstrap-haskell
Executable file
201
bootstrap-haskell
Executable file
@@ -0,0 +1,201 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# safety subshell to avoid executing anything in case this script is not downloaded properly
|
||||||
|
(
|
||||||
|
|
||||||
|
: "${GHCUP_INSTALL_BASE_PREFIX:=$HOME}"
|
||||||
|
|
||||||
|
die() {
|
||||||
|
(>&2 printf "\\033[0;31m%s\\033[0m\\n" "$1")
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
edo()
|
||||||
|
{
|
||||||
|
"$@" || die "\"$*\" failed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
eghcup() {
|
||||||
|
if [ -z "${BOOTSTRAP_HASKELL_VERBOSE}" ] ; then
|
||||||
|
edo ghcup "$@"
|
||||||
|
else
|
||||||
|
edo ghcup --verbose "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
download_ghcup() {
|
||||||
|
_plat="$(uname -s)"
|
||||||
|
_arch=$(uname -m)
|
||||||
|
|
||||||
|
case "${_plat}" in
|
||||||
|
"linux"|"Linux")
|
||||||
|
case "${_arch}" in
|
||||||
|
x86_64|amd64)
|
||||||
|
_url=https://downloads.haskell.org/~ghcup/x86_64-linux-ghcup
|
||||||
|
;;
|
||||||
|
i*86)
|
||||||
|
_url=https://downloads.haskell.org/~ghcup/i386-linux-ghcup
|
||||||
|
;;
|
||||||
|
*) die "Unknown architecture: ${_arch}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
"FreeBSD"|"freebsd")
|
||||||
|
case "${_arch}" in
|
||||||
|
x86_64|amd64)
|
||||||
|
;;
|
||||||
|
i*86)
|
||||||
|
die "i386 currently not supported!"
|
||||||
|
;;
|
||||||
|
*) die "Unknown architecture: ${_arch}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
_url=https://downloads.haskell.org/~ghcup/x86_64-portbld-freebsd-ghcup
|
||||||
|
;;
|
||||||
|
"Darwin"|"darwin")
|
||||||
|
case "${_arch}" in
|
||||||
|
x86_64|amd64)
|
||||||
|
;;
|
||||||
|
i*86)
|
||||||
|
die "i386 currently not supported!"
|
||||||
|
;;
|
||||||
|
*) die "Unknown architecture: ${_arch}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
_url=https://downloads.haskell.org/~ghcup/x86_64-apple-darwin-ghcup ;;
|
||||||
|
*) die "Unknown platform: ${_plat}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
edo curl -Lf "${_url}" > "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/ghcup
|
||||||
|
|
||||||
|
unset _plat _arch _url
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Welcome to Haskell!"
|
||||||
|
echo
|
||||||
|
echo "This will download and install the Glasgow Haskell Compiler (GHC)"
|
||||||
|
echo "and the Cabal build tool."
|
||||||
|
echo
|
||||||
|
echo "ghcup installs only into the following directory, which can be removed anytime:"
|
||||||
|
echo " $GHCUP_INSTALL_BASE_PREFIX/.ghcup"
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Press ENTER to proceed"
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "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_INSTALL_BASE_PREFIX}"/.ghcup/bin
|
||||||
|
|
||||||
|
if command -V "ghcup" >/dev/null 2>&1 ; then
|
||||||
|
if [ -z "${BOOTSTRAP_HASKELL_NO_UPGRADE}" ] ; then
|
||||||
|
eghcup upgrade
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
download_ghcup
|
||||||
|
edo chmod +x "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/ghcup
|
||||||
|
|
||||||
|
cat <<-EOF > "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/env || die "Failed to create env file"
|
||||||
|
export PATH="\$HOME/.cabal/bin:\${GHCUP_INSTALL_BASE_PREFIX:=\$HOME}/.ghcup/bin:\$PATH"
|
||||||
|
EOF
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
edo . "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/env
|
||||||
|
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"
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "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
|
||||||
|
|
||||||
|
eghcup set
|
||||||
|
eghcup --cache install-cabal
|
||||||
|
|
||||||
|
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
|
||||||
|
echo "In order to run ghc and cabal, you need to adjust your PATH variable."
|
||||||
|
echo "You may want to source '$GHCUP_INSTALL_BASE_PREFIX/.ghcup/env' in your shell"
|
||||||
|
echo "configuration to do so (e.g. ~/.bashrc)."
|
||||||
|
|
||||||
|
case $SHELL in
|
||||||
|
*/zsh) # login shell is zsh
|
||||||
|
GHCUP_PROFILE_FILE="$HOME/.zshrc"
|
||||||
|
MY_SHELL="zsh" ;;
|
||||||
|
*/bash) # login shell is bash
|
||||||
|
if [ -f "$HOME/.bashrc" ] ; then # bashrc is not sourced by default, so assume it isn't if file does not exist
|
||||||
|
GHCUP_PROFILE_FILE="$HOME/.bashrc"
|
||||||
|
else
|
||||||
|
GHCUP_PROFILE_FILE="$HOME/.bash_profile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MY_SHELL="bash" ;;
|
||||||
|
*/sh) # login shell is sh, but might be a symlink to bash or zsh
|
||||||
|
if [ -n "${BASH}" ] ; then
|
||||||
|
if [ -f "$HOME/.bashrc" ] ; then # bashrc is not sourced by default, so assume it isn't if file does not exist
|
||||||
|
GHCUP_PROFILE_FILE="$HOME/.bashrc"
|
||||||
|
else
|
||||||
|
GHCUP_PROFILE_FILE="$HOME/.bash_profile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
MY_SHELL="bash"
|
||||||
|
elif [ -n "${ZSH_VERSION}" ] ; then
|
||||||
|
GHCUP_PROFILE_FILE="$HOME/.zshrc"
|
||||||
|
MY_SHELL="zsh"
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*) exit 0 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" ""
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "Detected ${MY_SHELL} shell on your system..."
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "If you want ghcup to automatically add the required PATH variable to \"${GHCUP_PROFILE_FILE}\""
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" "answer with YES, otherwise with NO and press ENTER."
|
||||||
|
printf "\\033[0;35m%s\\033[0m\\n" ""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -r next_answer </dev/tty
|
||||||
|
|
||||||
|
case $next_answer in
|
||||||
|
[Yy]*)
|
||||||
|
echo "[ -f \"\${GHCUP_INSTALL_BASE_PREFIX:=\$HOME}/.ghcup/env\" ] && source \"\${GHCUP_INSTALL_BASE_PREFIX:=\$HOME}/.ghcup/env\"" >> "${GHCUP_PROFILE_FILE}"
|
||||||
|
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_INSTALL_BASE_PREFIX}/.ghcup/env\" to apply them in your current terminal session."
|
||||||
|
exit 0;;
|
||||||
|
[Nn]*)
|
||||||
|
exit 0;;
|
||||||
|
*)
|
||||||
|
echo "Please type YES or NO and press enter.";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
|
||||||
|
# vim: tabstop=4 shiftwidth=4 expandtab
|
||||||
|
|
||||||
@@ -6,14 +6,11 @@ package streamly
|
|||||||
ghc-options: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
|
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 -split-sections
|
ghc-options: -O2 -fspec-constr-recursive=16 -fmax-worker-args=16
|
||||||
|
|
||||||
package tar-bytestring
|
package tar-bytestring
|
||||||
ghc-options: -O2
|
ghc-options: -O2
|
||||||
|
|
||||||
package *
|
|
||||||
ghc-options: -split-sections
|
|
||||||
|
|
||||||
constraints: http-io-streams -brotli
|
constraints: http-io-streams -brotli
|
||||||
|
|
||||||
allow-newer: base
|
allow-newer: base
|
||||||
|
|||||||
@@ -2113,14 +2113,37 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"GHCup": {
|
"GHCup": {
|
||||||
"0.0.1": {
|
"0.1.1": {
|
||||||
"viArch": {
|
"viArch": {
|
||||||
"A_64": {
|
"A_64": {
|
||||||
|
"FreeBSD": {
|
||||||
|
"unknown_versioning": {
|
||||||
|
"dlHash": "1336585b15692d6458edf4d913fd585d9963a708e2c952a71ee1ad3400ed2163",
|
||||||
|
"dlSubdir": null,
|
||||||
|
"dlUri": "https://downloads.haskell.org/ghcup/0.1.1/x86_64-portbld-freebsd-ghcup-0.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Darwin": {
|
||||||
|
"unknown_versioning": {
|
||||||
|
"dlHash": "b9694de40134e3d17611749eba94d8e4d00a84e2a16bb2409eab1e87f810dacd",
|
||||||
|
"dlSubdir": null,
|
||||||
|
"dlUri": "https://downloads.haskell.org/ghcup/0.1.1/x86_64-apple-darwin-ghcup-0.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Linux_UnknownLinux": {
|
"Linux_UnknownLinux": {
|
||||||
"unknown_versioning": {
|
"unknown_versioning": {
|
||||||
"dlHash": "558126339252788a3d44a3f910417277c7ab656f0796b68bdc58afe73296b8cd",
|
"dlHash": "2789fbab2848e4dfd77406b9a710c925b3b9680ac0f8486caca190628646486f",
|
||||||
"dlSubdir": null,
|
"dlSubdir": null,
|
||||||
"dlUri": "file:/home/maerwald/tmp/ghcup-exe"
|
"dlUri": "https://downloads.haskell.org/ghcup/0.1.1/x86_64-linux-ghcup-0.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"A_32": {
|
||||||
|
"Linux_UnknownLinux": {
|
||||||
|
"unknown_versioning": {
|
||||||
|
"dlHash": "f576f22efdcf17fa18189b65d70e596d14f2347ef549a00592ef28d529c7d5a0",
|
||||||
|
"dlSubdir": null,
|
||||||
|
"dlUri": "https://downloads.haskell.org/ghcup/0.1.1/i386-linux-ghcup-0.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
ghcup.cabal
12
ghcup.cabal
@@ -1,13 +1,13 @@
|
|||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: ghcup
|
name: ghcup
|
||||||
version: 0.1.0
|
version: 0.1.2
|
||||||
synopsis: ghc toolchain installer as an exe/library
|
synopsis: ghc toolchain installer as an exe/library
|
||||||
description:
|
description:
|
||||||
A rewrite of the shell script ghcup, for providing
|
A rewrite of the shell script ghcup, for providing
|
||||||
a more stable user experience and exposing an API.
|
a more stable user experience and exposing an API.
|
||||||
|
|
||||||
homepage: https://github.com/hasufell/ghcup-hs
|
homepage: https://gitlab.haskell.org/haskell/ghcup-hs
|
||||||
bug-reports: https://github.com/hasufell/ghcup-hs/issues
|
bug-reports: https://gitlab.haskell.org/haskell/ghcup-hs/issues
|
||||||
license: LGPL-3.0-only
|
license: LGPL-3.0-only
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
author: Julian Ospald
|
author: Julian Ospald
|
||||||
@@ -19,7 +19,7 @@ extra-source-files: CHANGELOG.md
|
|||||||
|
|
||||||
source-repository head
|
source-repository head
|
||||||
type: git
|
type: git
|
||||||
location: https://github.com/hasufell/ghcup-hs
|
location: https://gitlab.haskell.org/haskell/ghcup-hs.git
|
||||||
|
|
||||||
flag Curl
|
flag Curl
|
||||||
description: Use curl instead of http-io-streams for download
|
description: Use curl instead of http-io-streams for download
|
||||||
@@ -84,7 +84,7 @@ common hpath
|
|||||||
build-depends: hpath >=0.11
|
build-depends: hpath >=0.11
|
||||||
|
|
||||||
common hpath-directory
|
common hpath-directory
|
||||||
build-depends: hpath-directory >=0.13.2
|
build-depends: hpath-directory >=0.13.3
|
||||||
|
|
||||||
common hpath-filepath
|
common hpath-filepath
|
||||||
build-depends: hpath-filepath >=0.10.3
|
build-depends: hpath-filepath >=0.10.3
|
||||||
@@ -93,7 +93,7 @@ common hpath-io
|
|||||||
build-depends: hpath-io >=0.13.1
|
build-depends: hpath-io >=0.13.1
|
||||||
|
|
||||||
common hpath-posix
|
common hpath-posix
|
||||||
build-depends: hpath-posix >=0.11.1
|
build-depends: hpath-posix >=0.13.2
|
||||||
|
|
||||||
common http-io-streams
|
common http-io-streams
|
||||||
build-depends: http-io-streams >=0.1.2.0
|
build-depends: http-io-streams >=0.1.2.0
|
||||||
|
|||||||
60
lib/GHCup.hs
60
lib/GHCup.hs
@@ -53,6 +53,7 @@ import Prelude hiding ( abs
|
|||||||
)
|
)
|
||||||
import System.IO.Error
|
import System.IO.Error
|
||||||
import System.Posix.FilePath ( getSearchPath )
|
import System.Posix.FilePath ( getSearchPath )
|
||||||
|
import System.Posix.Files.ByteString
|
||||||
|
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
@@ -96,14 +97,16 @@ installGHCBin bDls ver mpfReq = do
|
|||||||
whenM (liftIO $ toolAlreadyInstalled GHC ver)
|
whenM (liftIO $ toolAlreadyInstalled GHC ver)
|
||||||
$ (throwE $ AlreadyInstalled GHC ver)
|
$ (throwE $ AlreadyInstalled GHC ver)
|
||||||
Settings {..} <- lift ask
|
Settings {..} <- lift ask
|
||||||
|
pfreq@(PlatformRequest {..}) <- maybe (liftE $ platformRequest) pure mpfReq
|
||||||
|
|
||||||
-- download (or use cached version)
|
-- download (or use cached version)
|
||||||
dlinfo <- liftE $ getDownloadInfo bDls GHC ver mpfReq
|
dlinfo <- lE $ getDownloadInfo GHC ver pfreq bDls
|
||||||
dl <- liftE $ downloadCached dlinfo Nothing
|
dl <- liftE $ downloadCached dlinfo Nothing
|
||||||
|
|
||||||
-- unpack
|
-- unpack
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
liftE $ unpackToDir tmpUnpack dl
|
liftE $ unpackToDir tmpUnpack dl
|
||||||
|
void $ liftIO $ darwinNotarization _rPlatform tmpUnpack
|
||||||
|
|
||||||
-- prepare paths
|
-- prepare paths
|
||||||
ghcdir <- liftIO $ ghcupGHCDir ver
|
ghcdir <- liftIO $ ghcupGHCDir ver
|
||||||
@@ -170,14 +173,16 @@ installCabalBin :: ( MonadMask m
|
|||||||
installCabalBin bDls ver mpfReq = do
|
installCabalBin bDls ver mpfReq = do
|
||||||
lift $ $(logDebug) [i|Requested to install cabal version #{ver}|]
|
lift $ $(logDebug) [i|Requested to install cabal version #{ver}|]
|
||||||
Settings {..} <- lift ask
|
Settings {..} <- lift ask
|
||||||
|
pfreq@(PlatformRequest {..}) <- maybe (liftE $ platformRequest) pure mpfReq
|
||||||
|
|
||||||
-- download (or use cached version)
|
-- download (or use cached version)
|
||||||
dlinfo <- liftE $ getDownloadInfo bDls Cabal ver mpfReq
|
dlinfo <- lE $ getDownloadInfo Cabal ver pfreq bDls
|
||||||
dl <- liftE $ downloadCached dlinfo Nothing
|
dl <- liftE $ downloadCached dlinfo Nothing
|
||||||
|
|
||||||
-- unpack
|
-- unpack
|
||||||
tmpUnpack <- lift withGHCupTmpDir
|
tmpUnpack <- lift withGHCupTmpDir
|
||||||
liftE $ unpackToDir tmpUnpack dl
|
liftE $ unpackToDir tmpUnpack dl
|
||||||
|
void $ liftIO $ darwinNotarization _rPlatform tmpUnpack
|
||||||
|
|
||||||
-- prepare paths
|
-- prepare paths
|
||||||
bindir <- liftIO ghcupBinDir
|
bindir <- liftIO ghcupBinDir
|
||||||
@@ -371,6 +376,10 @@ rmGHCVer ver = do
|
|||||||
if exists
|
if exists
|
||||||
then do
|
then do
|
||||||
-- this isn't atomic, order matters
|
-- this isn't atomic, order matters
|
||||||
|
when isSetGHC $ do
|
||||||
|
lift $ $(logInfo) [i|Removing ghc symlinks|]
|
||||||
|
liftE $ rmPlain ver
|
||||||
|
|
||||||
lift $ $(logInfo) [i|Removing directory recursively: #{d'}|]
|
lift $ $(logInfo) [i|Removing directory recursively: #{d'}|]
|
||||||
liftIO $ deleteDirRecursive dir
|
liftIO $ deleteDirRecursive dir
|
||||||
|
|
||||||
@@ -384,11 +393,6 @@ rmGHCVer ver = do
|
|||||||
(mj, mi) <- getGHCMajor ver
|
(mj, mi) <- getGHCMajor ver
|
||||||
getGHCForMajor mj mi >>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY)
|
getGHCForMajor mj mi >>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY)
|
||||||
|
|
||||||
|
|
||||||
when isSetGHC $ do
|
|
||||||
lift $ $(logInfo) [i|Removing ghc symlinks|]
|
|
||||||
liftE $ rmPlain ver
|
|
||||||
|
|
||||||
liftIO
|
liftIO
|
||||||
$ ghcupBaseDir
|
$ ghcupBaseDir
|
||||||
>>= hideError doesNotExistErrorType
|
>>= hideError doesNotExistErrorType
|
||||||
@@ -444,9 +448,13 @@ compileGHC :: ( MonadMask m
|
|||||||
'[ AlreadyInstalled
|
'[ AlreadyInstalled
|
||||||
, BuildFailed
|
, BuildFailed
|
||||||
, DigestError
|
, DigestError
|
||||||
|
, DistroNotFound
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, GHCupSetError
|
, GHCupSetError
|
||||||
|
, NoCompatibleArch
|
||||||
|
, NoCompatiblePlatform
|
||||||
, NoDownload
|
, NoDownload
|
||||||
|
, NotFoundInPATH
|
||||||
, PatchFailed
|
, PatchFailed
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
]
|
]
|
||||||
@@ -464,6 +472,8 @@ compileGHC dls tver bstrap jobs mbuildConfig patchdir = do
|
|||||||
-- unpack
|
-- unpack
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
liftE $ unpackToDir tmpUnpack dl
|
liftE $ unpackToDir tmpUnpack dl
|
||||||
|
(PlatformRequest {..}) <- liftE $ platformRequest
|
||||||
|
void $ liftIO $ darwinNotarization _rPlatform tmpUnpack
|
||||||
|
|
||||||
bghc <- case bstrap of
|
bghc <- case bstrap of
|
||||||
Right g -> pure $ Right g
|
Right g -> pure $ Right g
|
||||||
@@ -503,10 +513,10 @@ GhcWithLlvmCodeGen = YES|]
|
|||||||
-> Path Abs
|
-> Path Abs
|
||||||
-> Path Abs
|
-> Path Abs
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ NoDownload
|
'[ FileDoesNotExistError
|
||||||
, FileDoesNotExistError
|
|
||||||
, PatchFailed
|
, PatchFailed
|
||||||
, ProcessError
|
, ProcessError
|
||||||
|
, NotFoundInPATH
|
||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
@@ -524,7 +534,7 @@ GhcWithLlvmCodeGen = YES|]
|
|||||||
Right ghc' -> pure ghc'
|
Right ghc' -> pure ghc'
|
||||||
Left bver -> do
|
Left bver -> do
|
||||||
spaths <- catMaybes . fmap parseAbs <$> liftIO getSearchPath
|
spaths <- catMaybes . fmap parseAbs <$> liftIO getSearchPath
|
||||||
(liftIO $ searchPath spaths bver) !? NoDownload
|
(liftIO $ searchPath spaths bver) !? NotFoundInPATH bver
|
||||||
lEM $ liftIO $ execLogged
|
lEM $ liftIO $ execLogged
|
||||||
"./configure"
|
"./configure"
|
||||||
False
|
False
|
||||||
@@ -579,7 +589,10 @@ compileCabal :: ( MonadReader Settings m
|
|||||||
-> Excepts
|
-> Excepts
|
||||||
'[ BuildFailed
|
'[ BuildFailed
|
||||||
, DigestError
|
, DigestError
|
||||||
|
, DistroNotFound
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
|
, NoCompatibleArch
|
||||||
|
, NoCompatiblePlatform
|
||||||
, NoDownload
|
, NoDownload
|
||||||
, PatchFailed
|
, PatchFailed
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
@@ -596,6 +609,8 @@ compileCabal dls tver bghc jobs patchdir = do
|
|||||||
-- unpack
|
-- unpack
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
liftE $ unpackToDir tmpUnpack dl
|
liftE $ unpackToDir tmpUnpack dl
|
||||||
|
(PlatformRequest {..}) <- liftE $ platformRequest
|
||||||
|
void $ liftIO $ darwinNotarization _rPlatform tmpUnpack
|
||||||
|
|
||||||
let workdir = maybe id (flip (</>)) (view dlSubdir dlInfo) $ tmpUnpack
|
let workdir = maybe id (flip (</>)) (view dlSubdir dlInfo) $ tmpUnpack
|
||||||
|
|
||||||
@@ -660,6 +675,8 @@ upgradeGHCup :: ( MonadMask m
|
|||||||
)
|
)
|
||||||
=> GHCupDownloads
|
=> GHCupDownloads
|
||||||
-> Maybe (Path Abs) -- ^ full file destination to write ghcup into
|
-> Maybe (Path Abs) -- ^ full file destination to write ghcup into
|
||||||
|
-> Bool -- ^ whether to force update regardless
|
||||||
|
-- of currently installed version
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ CopyError
|
'[ CopyError
|
||||||
, DigestError
|
, DigestError
|
||||||
@@ -668,23 +685,38 @@ upgradeGHCup :: ( MonadMask m
|
|||||||
, NoCompatibleArch
|
, NoCompatibleArch
|
||||||
, NoCompatiblePlatform
|
, NoCompatiblePlatform
|
||||||
, NoDownload
|
, NoDownload
|
||||||
|
, NoUpdate
|
||||||
]
|
]
|
||||||
m
|
m
|
||||||
Version
|
Version
|
||||||
upgradeGHCup dls mtarget = do
|
upgradeGHCup dls mtarget force = do
|
||||||
lift $ $(logInfo) [i|Upgrading GHCup...|]
|
lift $ $(logInfo) [i|Upgrading GHCup...|]
|
||||||
let latestVer = fromJust $ getLatest dls GHCup
|
let latestVer = fromJust $ getLatest dls GHCup
|
||||||
dli <- liftE $ getDownloadInfo dls GHCup latestVer Nothing
|
when (not force && (latestVer < pvpToVersion ghcUpVer)) $ throwE NoUpdate
|
||||||
tmp <- lift withGHCupTmpDir
|
pfreq <- liftE platformRequest
|
||||||
|
dli <- lE $ getDownloadInfo GHCup latestVer pfreq dls
|
||||||
|
tmp <- lift withGHCupTmpDir
|
||||||
let fn = [rel|ghcup|]
|
let fn = [rel|ghcup|]
|
||||||
p <- liftE $ download dli tmp (Just fn)
|
p <- liftE $ download dli tmp (Just fn)
|
||||||
|
let fileMode' =
|
||||||
|
newFilePerms
|
||||||
|
`unionFileModes` ownerExecuteMode
|
||||||
|
`unionFileModes` groupExecuteMode
|
||||||
|
`unionFileModes` otherExecuteMode
|
||||||
case mtarget of
|
case mtarget of
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
dest <- liftIO $ ghcupBinDir
|
dest <- liftIO $ ghcupBinDir
|
||||||
|
liftIO $ hideError NoSuchThing $ deleteFile (dest </> fn)
|
||||||
handleIO (throwE . CopyError . show) $ liftIO $ copyFile p
|
handleIO (throwE . CopyError . show) $ liftIO $ copyFile p
|
||||||
(dest </> fn)
|
(dest </> fn)
|
||||||
Overwrite
|
Overwrite
|
||||||
Just fullDest -> liftIO $ copyFile p fullDest Overwrite
|
liftIO $ setFileMode (toFilePath (dest </> fn)) fileMode'
|
||||||
|
Just fullDest -> do
|
||||||
|
liftIO $ hideError NoSuchThing $ deleteFile fullDest
|
||||||
|
handleIO (throwE . CopyError . show) $ liftIO $ copyFile p
|
||||||
|
fullDest
|
||||||
|
Overwrite
|
||||||
|
liftIO $ setFileMode (toFilePath fullDest) fileMode'
|
||||||
pure latestVer
|
pure latestVer
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import GHCup.Download.IOStreams
|
|||||||
import GHCup.Download.Utils
|
import GHCup.Download.Utils
|
||||||
#endif
|
#endif
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Platform
|
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.JSON ( )
|
import GHCup.Types.JSON ( )
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
@@ -204,43 +203,13 @@ getDownloads urlSource = do
|
|||||||
setModificationTimeHiRes path mod_time
|
setModificationTimeHiRes path mod_time
|
||||||
|
|
||||||
|
|
||||||
|
getDownloadInfo :: Tool
|
||||||
getDownloadInfo :: (MonadLogger m, MonadCatch m, MonadIO m)
|
|
||||||
=> GHCupDownloads
|
|
||||||
-> Tool
|
|
||||||
-> Version
|
-> Version
|
||||||
-> Maybe PlatformRequest
|
|
||||||
-> Excepts
|
|
||||||
'[ DistroNotFound
|
|
||||||
, NoCompatiblePlatform
|
|
||||||
, NoCompatibleArch
|
|
||||||
, NoDownload
|
|
||||||
]
|
|
||||||
m
|
|
||||||
DownloadInfo
|
|
||||||
getDownloadInfo bDls t v mpfReq = do
|
|
||||||
(PlatformRequest arch' plat ver) <- case mpfReq of
|
|
||||||
Just x -> pure x
|
|
||||||
Nothing -> do
|
|
||||||
(PlatformResult rp rv) <- liftE getPlatform
|
|
||||||
ar <- lE getArchitecture
|
|
||||||
pure $ PlatformRequest ar rp rv
|
|
||||||
|
|
||||||
lE $ getDownloadInfo' t v arch' plat ver bDls
|
|
||||||
|
|
||||||
|
|
||||||
getDownloadInfo' :: Tool
|
|
||||||
-> Version
|
|
||||||
-- ^ tool version
|
-- ^ tool version
|
||||||
-> Architecture
|
-> PlatformRequest
|
||||||
-- ^ user arch
|
-> GHCupDownloads
|
||||||
-> Platform
|
-> Either NoDownload DownloadInfo
|
||||||
-- ^ user platform
|
getDownloadInfo t v (PlatformRequest a p mv) dls = maybe
|
||||||
-> Maybe Versioning
|
|
||||||
-- ^ optional version of the platform
|
|
||||||
-> GHCupDownloads
|
|
||||||
-> Either NoDownload DownloadInfo
|
|
||||||
getDownloadInfo' t v a p mv dls = maybe
|
|
||||||
(Left NoDownload)
|
(Left NoDownload)
|
||||||
Right
|
Right
|
||||||
(with_distro <|> without_distro_ver <|> without_distro)
|
(with_distro <|> without_distro_ver <|> without_distro)
|
||||||
@@ -304,7 +273,7 @@ download dli dest mfn
|
|||||||
) $ do
|
) $ do
|
||||||
#if defined(CURL)
|
#if defined(CURL)
|
||||||
liftE $ lEM @_ @'[ProcessError] $ liftIO $ exec "curl" True
|
liftE $ lEM @_ @'[ProcessError] $ liftIO $ exec "curl" True
|
||||||
["-sSfL", "-o", toFilePath destFile , serializeURIRef' $ view dlUri dli] Nothing Nothing
|
["-fL", "-o", toFilePath destFile , serializeURIRef' $ view dlUri dli] Nothing Nothing
|
||||||
#else
|
#else
|
||||||
(https, host, fullPath, port) <- liftE $ uriToQuadruple (view dlUri dli)
|
(https, host, fullPath, port) <- liftE $ uriToQuadruple (view dlUri dli)
|
||||||
liftE $ downloadToFile https host fullPath port destFile
|
liftE $ downloadToFile https host fullPath port destFile
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ data NoCompatiblePlatform = NoCompatiblePlatform String -- the platform we got
|
|||||||
data NoDownload = NoDownload
|
data NoDownload = NoDownload
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
|
-- | No update available or necessary.
|
||||||
|
data NoUpdate = NoUpdate
|
||||||
|
deriving Show
|
||||||
|
|
||||||
-- | The Architecture is unknown and unsupported.
|
-- | The Architecture is unknown and unsupported.
|
||||||
data NoCompatibleArch = NoCompatibleArch String
|
data NoCompatibleArch = NoCompatibleArch String
|
||||||
deriving Show
|
deriving Show
|
||||||
@@ -63,6 +67,10 @@ data AlreadyInstalled = AlreadyInstalled Tool Version
|
|||||||
data NotInstalled = NotInstalled Tool Version
|
data NotInstalled = NotInstalled Tool Version
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
|
-- | An executable was expected to be in PATH, but was not found.
|
||||||
|
data NotFoundInPATH = NotFoundInPATH (Path Rel)
|
||||||
|
deriving Show
|
||||||
|
|
||||||
-- | JSON decoding failed.
|
-- | JSON decoding failed.
|
||||||
data JSONError = JSONDecodeError String
|
data JSONError = JSONDecodeError String
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|||||||
@@ -46,6 +46,21 @@ import qualified Data.Text.Encoding as E
|
|||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
|
||||||
|
-- | Get the full platform request, consisting of architecture, distro, ...
|
||||||
|
platformRequest :: (MonadLogger m, MonadCatch m, MonadIO m)
|
||||||
|
=> Excepts
|
||||||
|
'[ NoCompatiblePlatform
|
||||||
|
, NoCompatibleArch
|
||||||
|
, DistroNotFound
|
||||||
|
]
|
||||||
|
m
|
||||||
|
PlatformRequest
|
||||||
|
platformRequest = do
|
||||||
|
(PlatformResult rp rv) <- liftE getPlatform
|
||||||
|
ar <- lE getArchitecture
|
||||||
|
pure $ PlatformRequest ar rp rv
|
||||||
|
|
||||||
|
|
||||||
getArchitecture :: Either NoCompatibleArch Architecture
|
getArchitecture :: Either NoCompatibleArch Architecture
|
||||||
getArchitecture = case arch of
|
getArchitecture = case arch of
|
||||||
"x86_64" -> Right A_64
|
"x86_64" -> Right A_64
|
||||||
@@ -64,16 +79,30 @@ getPlatform = do
|
|||||||
"linux" -> do
|
"linux" -> do
|
||||||
(distro, ver) <- liftE getLinuxDistro
|
(distro, ver) <- liftE getLinuxDistro
|
||||||
pure $ PlatformResult { _platform = Linux distro, _distroVersion = ver }
|
pure $ PlatformResult { _platform = Linux distro, _distroVersion = ver }
|
||||||
-- TODO: these are not verified
|
"darwin" -> do
|
||||||
"darwin" ->
|
ver <-
|
||||||
pure $ PlatformResult { _platform = Darwin, _distroVersion = Nothing }
|
( either (const Nothing) Just
|
||||||
|
. versioning
|
||||||
|
. getMajorVersion
|
||||||
|
. E.decodeUtf8
|
||||||
|
)
|
||||||
|
<$> getDarwinVersion
|
||||||
|
pure $ PlatformResult { _platform = Darwin, _distroVersion = ver }
|
||||||
"freebsd" -> do
|
"freebsd" -> do
|
||||||
ver <- getFreeBSDVersion
|
ver <-
|
||||||
|
(either (const Nothing) Just . versioning . E.decodeUtf8)
|
||||||
|
<$> getFreeBSDVersion
|
||||||
pure $ PlatformResult { _platform = FreeBSD, _distroVersion = ver }
|
pure $ PlatformResult { _platform = FreeBSD, _distroVersion = ver }
|
||||||
what -> throwE $ NoCompatiblePlatform what
|
what -> throwE $ NoCompatiblePlatform what
|
||||||
lift $ $(logDebug) [i|Identified Platform as: #{pfr}|]
|
lift $ $(logDebug) [i|Identified Platform as: #{pfr}|]
|
||||||
pure pfr
|
pure pfr
|
||||||
where getFreeBSDVersion = pure Nothing
|
where
|
||||||
|
getMajorVersion = T.intercalate "." . take 2 . T.split (== '.')
|
||||||
|
getFreeBSDVersion =
|
||||||
|
liftIO $ fmap _stdOut $ executeOut [rel|freebsd-version|] [] Nothing
|
||||||
|
getDarwinVersion = liftIO $ fmap _stdOut $ executeOut [rel|sw_vers|]
|
||||||
|
["-productVersion"]
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
|
||||||
getLinuxDistro :: (MonadCatch m, MonadIO m)
|
getLinuxDistro :: (MonadCatch m, MonadIO m)
|
||||||
|
|||||||
@@ -358,3 +358,13 @@ applyPatches pdir ddir = do
|
|||||||
Nothing
|
Nothing
|
||||||
)
|
)
|
||||||
!? PatchFailed
|
!? PatchFailed
|
||||||
|
|
||||||
|
|
||||||
|
darwinNotarization :: Platform -> Path Abs -> IO (Either ProcessError ())
|
||||||
|
darwinNotarization Darwin path = exec
|
||||||
|
"xattr"
|
||||||
|
True
|
||||||
|
["-r", "-d", "com.apple.quarantine", toFilePath path]
|
||||||
|
Nothing
|
||||||
|
Nothing
|
||||||
|
darwinNotarization _ _ = pure $ Right ()
|
||||||
|
|||||||
@@ -39,11 +39,10 @@ import qualified System.Posix.User as PU
|
|||||||
|
|
||||||
ghcupBaseDir :: IO (Path Abs)
|
ghcupBaseDir :: IO (Path Abs)
|
||||||
ghcupBaseDir = do
|
ghcupBaseDir = do
|
||||||
getEnv "GHCUP_INSTALL_BASE_PREFIX" >>= \case
|
bdir <- getEnv "GHCUP_INSTALL_BASE_PREFIX" >>= \case
|
||||||
Just r -> parseAbs r
|
Just r -> parseAbs r
|
||||||
Nothing -> do
|
Nothing -> liftIO getHomeDirectory
|
||||||
home <- liftIO getHomeDirectory
|
pure (bdir </> [rel|.ghcup|])
|
||||||
pure (home </> [rel|.ghcup|])
|
|
||||||
|
|
||||||
ghcupGHCBaseDir :: IO (Path Abs)
|
ghcupGHCBaseDir :: IO (Path Abs)
|
||||||
ghcupGHCBaseDir = ghcupBaseDir <&> (</> [rel|ghc|])
|
ghcupGHCBaseDir = ghcupBaseDir <&> (</> [rel|ghc|])
|
||||||
|
|||||||
@@ -240,3 +240,7 @@ addToCurrentEnv :: MonadIO m
|
|||||||
addToCurrentEnv adds = do
|
addToCurrentEnv adds = do
|
||||||
cEnv <- liftIO $ getEnvironment
|
cEnv <- liftIO $ getEnvironment
|
||||||
pure (adds ++ cEnv)
|
pure (adds ++ cEnv)
|
||||||
|
|
||||||
|
|
||||||
|
pvpToVersion :: PVP -> Version
|
||||||
|
pvpToVersion = either (\_ -> error "Couldn't convert PVP to Version") id . version . prettyPVP
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ ghcupURL :: URI
|
|||||||
ghcupURL = [uri|https://www.haskell.org/ghcup/data/ghcup-0.0.1.json|]
|
ghcupURL = [uri|https://www.haskell.org/ghcup/data/ghcup-0.0.1.json|]
|
||||||
|
|
||||||
ghcUpVer :: PVP
|
ghcUpVer :: PVP
|
||||||
ghcUpVer = [pver|0.1.0|]
|
ghcUpVer = [pver|0.1.2|]
|
||||||
|
|||||||
Reference in New Issue
Block a user