Compare commits
35 Commits
advance-in
...
screen-rea
| Author | SHA1 | Date | |
|---|---|---|---|
| 1793fa43cf | |||
|
|
b375398416 | ||
|
|
04b29b0b98 | ||
|
|
255f7c8eac | ||
|
|
80a6c67cf3 | ||
|
|
cee4a0d610 | ||
|
|
9c4e64baf1 | ||
|
|
0b6e9289fc | ||
|
|
cd8d13ff2b | ||
|
|
40f94fa016 | ||
|
|
32c2cd2efa | ||
|
|
7b18cc9081 | ||
|
|
3f80d41dd7 | ||
|
|
6485e230cd | ||
|
|
3a8c32ae87 | ||
|
|
5ebb800646 | ||
|
|
f157cf809e | ||
| 456200e747 | |||
| 09e199a176 | |||
| 2ecc61ad92 | |||
| dd8b23ff86 | |||
| d78e7af80c | |||
| cf8ed4211b | |||
| 39931d98b9 | |||
| ac18c044e1 | |||
| e5c941b4d7 | |||
| 065b307d60 | |||
| 5eaae9916d | |||
| 5d0a7b71a2 | |||
| b4600b8183 | |||
| f465243fc6 | |||
| e4b0e8debf | |||
| d9d13dda5f | |||
| aef10a699e | |||
| b413ade4db |
26
.github/workflows/release.yaml
vendored
26
.github/workflows/release.yaml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
ARCH: 64
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
@@ -94,11 +94,11 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
include:
|
||||
- os: [self-hosted, Linux, ARM64]
|
||||
- os: [self-hosted, Linux, ARM64, maerwald]
|
||||
ARTIFACT: "armv7-linux-ghcup"
|
||||
GHC_VER: 9.2.8
|
||||
ARCH: ARM
|
||||
- os: [self-hosted, Linux, ARM64]
|
||||
- os: [self-hosted, Linux, ARM64, maerwald]
|
||||
ARTIFACT: "aarch64-linux-ghcup"
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: ARM64
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
@@ -177,7 +177,7 @@ jobs:
|
||||
ARCH: 64
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
@@ -258,7 +258,7 @@ jobs:
|
||||
RUNNER_OS: FreeBSD
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
@@ -305,7 +305,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
@@ -365,12 +365,12 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: [self-hosted, Linux, ARM64]
|
||||
- os: [self-hosted, Linux, ARM64, maerwald]
|
||||
ARTIFACT: "armv7-linux-ghcup"
|
||||
GHC_VER: 9.2.8
|
||||
ARCH: ARM
|
||||
DISTRO: Ubuntu
|
||||
- os: [self-hosted, Linux, ARM64]
|
||||
- os: [self-hosted, Linux, ARM64, maerwald]
|
||||
ARTIFACT: "aarch64-linux-ghcup"
|
||||
GHC_VER: 9.4.8
|
||||
ARCH: ARM64
|
||||
@@ -378,7 +378,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
@@ -446,7 +446,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
@@ -508,7 +508,7 @@ jobs:
|
||||
RUNNER_OS: FreeBSD
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
@@ -545,7 +545,7 @@ jobs:
|
||||
S3_HOST: ${{ secrets.S3_HOST }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
# Revision history for ghcup
|
||||
|
||||
## 0.1.22.0 -- ????-??-??
|
||||
## 0.1.22.0 -- 2024-03-13
|
||||
|
||||
### New features
|
||||
|
||||
* A help screen/tutorial in the TUI by @lsmor (Luis Morillo)
|
||||
* Beef up `--overwrite-version`, fixes [#998](https://github.com/haskell/ghcup-hs/issues/998)
|
||||
* e.g. `ghcup compile hls -g master --overwrite-version='%v-%h' --ghc 9.4.8` will produce a binary called `haskell-language-server-wrapper-<version-from-cabal-file>-<short-git-commit-hash>`... refer to `ghcup compile hls --help` for more information
|
||||
* Allow to set ghcup msys2 environment wrt [#982](https://github.com/haskell/ghcup-hs/issues/982)
|
||||
* Add mechanism to warn on new metadata versions, fixes [#860](https://github.com/haskell/ghcup-hs/issues/860)
|
||||
* Add pre-install message support via ghcup metadata, wrt [#1016](https://github.com/haskell/ghcup-hs/issues/1016)
|
||||
* Allow to remove all unset versions, fixes [#1019](https://github.com/haskell/ghcup-hs/issues/1019)
|
||||
* e.g.: `ghcup gc --unset`
|
||||
|
||||
### Improvements and bug fixes
|
||||
|
||||
* Fix potential [HSEC-2024-0002](https://haskell.github.io/security-advisories/advisory/HSEC-2024-0002.html)
|
||||
* Fix TUI crash in windows terminal 1.19 [#1013](https://github.com/haskell/ghcup-hs/issues/1013)
|
||||
* Clean up on git clone errors, fixes [#1004](https://github.com/haskell/ghcup-hs/issues/1004)
|
||||
* Error out on empty UserSettings wrt [#922](https://github.com/haskell/ghcup-hs/issues/922)
|
||||
* Fix failure mode when metadata is garbage, fixes [#921](https://github.com/haskell/ghcup-hs/issues/921)
|
||||
|
||||
@@ -10,12 +10,18 @@ else
|
||||
flags: +tui +tar
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
any.aeson >= 2.0.1.0,
|
||||
bzlib-conduit >= 0.3.0.3,
|
||||
bz2 >= 1.0.1.1,
|
||||
bzlib >= 0.5.2.0
|
||||
|
||||
if os(mingw32)
|
||||
constraints: vty-windows >=0.2.0.2
|
||||
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/tar.git
|
||||
|
||||
@@ -14,7 +14,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
aeson +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.10,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.5.0.0,
|
||||
any.alex ==3.5.1.0,
|
||||
any.ansi-terminal ==1.0.2,
|
||||
ansi-terminal -example,
|
||||
any.ansi-terminal-types ==0.11.5,
|
||||
@@ -44,8 +44,9 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.brick ==2.1.1,
|
||||
brick -demos,
|
||||
any.bytestring ==0.11.5.3,
|
||||
any.bz2 ==1.0.1.0,
|
||||
any.bz2 ==1.0.1.1,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.bzip2-clib ==1.0.8,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-install-parsers ==0.6.1.1,
|
||||
@@ -241,7 +242,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||
any.vector-binary-instances ==0.2.5.2,
|
||||
any.vector-stream ==0.1.0.1,
|
||||
any.versions ==6.0.5,
|
||||
any.versions ==6.0.6,
|
||||
any.vty ==6.2,
|
||||
any.vty-crossplatform ==0.4.0.0,
|
||||
vty-crossplatform -demos,
|
||||
@@ -255,4 +256,4 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.zlib ==0.6.3.0,
|
||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||
any.zlib-bindings ==0.1.1.5
|
||||
index-state: hackage.haskell.org 2024-02-18T14:07:35Z
|
||||
index-state: hackage.haskell.org 2024-03-10T10:13:56Z
|
||||
|
||||
@@ -10,12 +10,18 @@ else
|
||||
flags: +tui +tar
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
any.aeson >= 2.0.1.0,
|
||||
bzlib-conduit >= 0.3.0.3,
|
||||
bz2 >= 1.0.1.1,
|
||||
bzlib >= 0.5.2.0
|
||||
|
||||
if os(mingw32)
|
||||
constraints: vty-windows >=0.2.0.2
|
||||
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/tar.git
|
||||
|
||||
@@ -14,7 +14,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
aeson +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.10,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.5.0.0,
|
||||
any.alex ==3.5.1.0,
|
||||
any.ansi-terminal ==1.0.2,
|
||||
ansi-terminal -example,
|
||||
any.ansi-terminal-types ==0.11.5,
|
||||
@@ -47,9 +47,10 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.brick ==2.1.1,
|
||||
brick -demos,
|
||||
any.bytestring ==0.11.5.3,
|
||||
any.bz2 ==1.0.1.0,
|
||||
any.bz2 ==1.0.1.1,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.bzlib-conduit ==0.3.0.2,
|
||||
any.bzip2-clib ==1.0.8,
|
||||
any.bzlib-conduit ==0.3.0.3,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-install-parsers ==0.6.1.1,
|
||||
@@ -140,7 +141,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.microlens-mtl ==0.2.0.3,
|
||||
any.microlens-th ==0.4.3.14,
|
||||
any.monad-control ==1.0.3.1,
|
||||
any.mono-traversable ==1.0.15.3,
|
||||
any.mono-traversable ==1.0.17.0,
|
||||
any.mtl ==2.2.2,
|
||||
any.mtl-compat ==0.2.2,
|
||||
mtl-compat -two-point-one -two-point-two,
|
||||
@@ -250,7 +251,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
|
||||
any.vector-binary-instances ==0.2.5.2,
|
||||
any.vector-stream ==0.1.0.1,
|
||||
any.versions ==6.0.5,
|
||||
any.versions ==6.0.6,
|
||||
any.vty ==6.2,
|
||||
any.vty-crossplatform ==0.4.0.0,
|
||||
vty-crossplatform -demos,
|
||||
@@ -268,4 +269,4 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.zlib-bindings ==0.1.1.5,
|
||||
any.zstd ==0.1.3.0,
|
||||
zstd +standalone
|
||||
index-state: hackage.haskell.org 2024-02-18T14:07:35Z
|
||||
index-state: hackage.haskell.org 2024-03-10T10:13:56Z
|
||||
|
||||
@@ -10,12 +10,18 @@ else
|
||||
flags: +tui +tar
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
any.aeson >= 2.0.1.0,
|
||||
bzlib-conduit >= 0.3.0.3,
|
||||
bz2 >= 1.0.1.1,
|
||||
bzlib >= 0.5.2.0
|
||||
|
||||
if os(mingw32)
|
||||
constraints: vty-windows >=0.2.0.2
|
||||
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/tar.git
|
||||
|
||||
@@ -14,7 +14,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
aeson +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.10,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.5.0.0,
|
||||
any.alex ==3.5.1.0,
|
||||
any.ansi-terminal ==1.0.2,
|
||||
ansi-terminal -example,
|
||||
any.ansi-terminal-types ==0.11.5,
|
||||
@@ -47,9 +47,10 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.brick ==2.1.1,
|
||||
brick -demos,
|
||||
any.bytestring ==0.11.4.0,
|
||||
any.bz2 ==1.0.1.0,
|
||||
any.bz2 ==1.0.1.1,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.bzlib-conduit ==0.3.0.2,
|
||||
any.bzip2-clib ==1.0.8,
|
||||
any.bzlib-conduit ==0.3.0.3,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-install-parsers ==0.6.1.1,
|
||||
@@ -140,7 +141,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.microlens-mtl ==0.2.0.3,
|
||||
any.microlens-th ==0.4.3.14,
|
||||
any.monad-control ==1.0.3.1,
|
||||
any.mono-traversable ==1.0.15.3,
|
||||
any.mono-traversable ==1.0.17.0,
|
||||
any.mtl ==2.2.2,
|
||||
any.mtl-compat ==0.2.2,
|
||||
mtl-compat -two-point-one -two-point-two,
|
||||
@@ -249,7 +250,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
|
||||
any.vector-binary-instances ==0.2.5.2,
|
||||
any.vector-stream ==0.1.0.1,
|
||||
any.versions ==6.0.5,
|
||||
any.versions ==6.0.6,
|
||||
any.vty ==6.2,
|
||||
any.vty-crossplatform ==0.4.0.0,
|
||||
vty-crossplatform -demos,
|
||||
@@ -267,4 +268,4 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.zlib-bindings ==0.1.1.5,
|
||||
any.zstd ==0.1.3.0,
|
||||
zstd +standalone
|
||||
index-state: hackage.haskell.org 2024-02-18T14:07:35Z
|
||||
index-state: hackage.haskell.org 2024-03-10T10:13:56Z
|
||||
|
||||
@@ -10,12 +10,18 @@ else
|
||||
flags: +tui +tar
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
any.aeson >= 2.0.1.0,
|
||||
bzlib-conduit >= 0.3.0.3,
|
||||
bz2 >= 1.0.1.1,
|
||||
bzlib >= 0.5.2.0
|
||||
|
||||
if os(mingw32)
|
||||
constraints: vty-windows >=0.2.0.2
|
||||
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/tar.git
|
||||
|
||||
@@ -14,7 +14,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
aeson +ordered-keymap,
|
||||
any.aeson-pretty ==0.8.10,
|
||||
aeson-pretty +lib-only,
|
||||
any.alex ==3.5.0.0,
|
||||
any.alex ==3.5.1.0,
|
||||
any.ansi-terminal ==1.0.2,
|
||||
ansi-terminal -example,
|
||||
any.ansi-terminal-types ==0.11.5,
|
||||
@@ -47,9 +47,10 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.brick ==2.1.1,
|
||||
brick -demos,
|
||||
any.bytestring ==0.11.5.3,
|
||||
any.bz2 ==1.0.1.0,
|
||||
any.bz2 ==1.0.1.1,
|
||||
bz2 -cross +with-bzlib,
|
||||
any.bzlib-conduit ==0.3.0.2,
|
||||
any.bzip2-clib ==1.0.8,
|
||||
any.bzlib-conduit ==0.3.0.3,
|
||||
any.c2hs ==0.28.8,
|
||||
c2hs +base3 -regression,
|
||||
any.cabal-install-parsers ==0.6.1.1,
|
||||
@@ -139,7 +140,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.microlens-mtl ==0.2.0.3,
|
||||
any.microlens-th ==0.4.3.14,
|
||||
any.monad-control ==1.0.3.1,
|
||||
any.mono-traversable ==1.0.15.3,
|
||||
any.mono-traversable ==1.0.17.0,
|
||||
any.mtl ==2.2.2,
|
||||
any.mtl-compat ==0.2.2,
|
||||
mtl-compat -two-point-one -two-point-two,
|
||||
@@ -248,7 +249,7 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
vector-algorithms +bench +boundschecks -internalchecks -llvm +properties -unsafechecks,
|
||||
any.vector-binary-instances ==0.2.5.2,
|
||||
any.vector-stream ==0.1.0.1,
|
||||
any.versions ==6.0.5,
|
||||
any.versions ==6.0.6,
|
||||
any.vty ==6.2,
|
||||
any.vty-crossplatform ==0.4.0.0,
|
||||
vty-crossplatform -demos,
|
||||
@@ -266,4 +267,4 @@ constraints: any.Cabal ==3.10.2.1,
|
||||
any.zlib-bindings ==0.1.1.5,
|
||||
any.zstd ==0.1.3.0,
|
||||
zstd +standalone
|
||||
index-state: hackage.haskell.org 2024-02-18T14:07:35Z
|
||||
index-state: hackage.haskell.org 2024-03-10T10:13:56Z
|
||||
|
||||
@@ -10,12 +10,18 @@ else
|
||||
flags: +tui +tar
|
||||
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0
|
||||
any.aeson >= 2.0.1.0,
|
||||
bzlib-conduit >= 0.3.0.3,
|
||||
bz2 >= 1.0.1.1,
|
||||
bzlib >= 0.5.2.0
|
||||
|
||||
if os(mingw32)
|
||||
constraints: vty-windows >=0.2.0.2
|
||||
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/haskell/tar.git
|
||||
|
||||
@@ -18,7 +18,7 @@ elif os(mingw32)
|
||||
constraints: zlib +bundled-c-zlib,
|
||||
lzma +static,
|
||||
text -simdutf,
|
||||
vty-windows >=0.1.0.3
|
||||
vty-windows >=0.2.0.2
|
||||
if impl(ghc >= 9.4)
|
||||
constraints: language-c >= 0.9.3
|
||||
elif os(freebsd)
|
||||
@@ -30,12 +30,18 @@ elif os(freebsd)
|
||||
constraints: http-io-streams -brotli,
|
||||
any.aeson >= 2.0.1.0,
|
||||
any.hsc2hs ==0.68.8,
|
||||
bzlib-conduit >= 0.3.0.3,
|
||||
bz2 >= 1.0.1.1,
|
||||
bzlib >= 0.5.2.0,
|
||||
directory >= 1.3.8.3,
|
||||
filepath == 1.4.101.0 || == 1.4.300.1 || >= 1.5.2.0
|
||||
|
||||
package libarchive
|
||||
flags: -system-libarchive
|
||||
|
||||
package libyaml-streamly
|
||||
flags: -system-libyaml
|
||||
|
||||
package aeson-pretty
|
||||
flags: +lib-only
|
||||
|
||||
|
||||
@@ -561,6 +561,8 @@ export SKIP_GHC=yes
|
||||
source ~/.ghc-wasm/env
|
||||
```
|
||||
|
||||
**Note that some wasm bindists don't work with the master branch of ghc-wasm-meta. GHCup will warn you about such cases prior to installation and point you to the right commit.**
|
||||
|
||||
To install, we need to invoke ghcup like so also passing the `--host=<host>` flag (adjust as needed):
|
||||
|
||||
```sh
|
||||
|
||||
@@ -175,6 +175,7 @@ library
|
||||
, base16-bytestring >=0.1.1.6 && <1.1
|
||||
, binary ^>=0.8.6.0
|
||||
, bytestring >=0.10 && <0.12
|
||||
, bz2 ^>=1.0.1.1
|
||||
, Cabal ^>=3.0.0.0 || ^>=3.2.0.0 || ^>=3.4.0.0 || ^>=3.6.0.0 || ^>=3.8.0.0 || ^>= 3.10.0.0
|
||||
, case-insensitive ^>=1.2.1.0
|
||||
, casing ^>=0.1.4.1
|
||||
@@ -244,7 +245,6 @@ library
|
||||
-- GHCup.OptParse.Run uses this
|
||||
exposed-modules: GHCup.Prelude.Process.Windows
|
||||
build-depends:
|
||||
, bzlib
|
||||
, process ^>=1.6.11.0
|
||||
, Win32 >=2.10
|
||||
|
||||
@@ -261,7 +261,6 @@ library
|
||||
install-includes: dirutils.h
|
||||
c-sources: cbits/dirutils.c
|
||||
build-depends:
|
||||
, bz2 >=0.5.0.5 && <1.1
|
||||
, terminal-size ^>=0.3.3
|
||||
, unix ^>=2.7 || ^>=2.8
|
||||
, unix-bytestring ^>=0.3.7.3
|
||||
@@ -335,6 +334,7 @@ library ghcup-tui
|
||||
GHCup.Brick.Widgets.Menus.Context
|
||||
GHCup.Brick.Widgets.Menus.AdvanceInstall
|
||||
GHCup.Brick.Widgets.Menus.CompileGHC
|
||||
GHCup.Brick.Widgets.Menus.CompileHLS
|
||||
GHCup.Brick.Actions
|
||||
GHCup.Brick.App
|
||||
GHCup.Brick.BrickState
|
||||
|
||||
@@ -529,9 +529,14 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
HLS.SourceDist targetVer -> do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let vi = getVersionInfo (mkTVer targetVer) HLS dls
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||
lift $ logInfo msg
|
||||
lift $ logInfo
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||
_ -> pure ()
|
||||
@@ -578,9 +583,14 @@ compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||
GHC.SourceDist targetVer -> do
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
let vi = getVersionInfo (mkTVer targetVer) GHC dls
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||
lift $ logInfo msg
|
||||
lift $ logInfo
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||
_ -> pure ()
|
||||
|
||||
@@ -47,6 +47,7 @@ data GCOptions = GCOptions
|
||||
, gcHLSNoGHC :: Bool
|
||||
, gcCache :: Bool
|
||||
, gcTmp :: Bool
|
||||
, gcUnset :: Bool
|
||||
} deriving (Eq, Show)
|
||||
|
||||
|
||||
@@ -77,6 +78,9 @@ gcP =
|
||||
<*>
|
||||
switch
|
||||
(short 't' <> long "tmpdirs" <> help "Remove tmpdir leftovers")
|
||||
<*>
|
||||
switch
|
||||
(short 'u' <> long "unset" <> help "Remove all tool versions that are not 'set'")
|
||||
|
||||
|
||||
|
||||
@@ -134,6 +138,7 @@ gc GCOptions{..} runAppState runLogger = runGC runAppState (do
|
||||
liftE $ when gcHLSNoGHC rmHLSNoGHC
|
||||
lift $ when gcCache rmCache
|
||||
lift $ when gcTmp rmTmp
|
||||
liftE $ when gcUnset rmUnsetTools
|
||||
) >>= \case
|
||||
VRight _ -> do
|
||||
pure ExitSuccess
|
||||
|
||||
@@ -24,6 +24,7 @@ import GHCup.Prelude
|
||||
import GHCup.Prelude.Logger
|
||||
import GHCup.Prelude.String.QQ
|
||||
|
||||
import Control.Concurrent (threadDelay)
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
#endif
|
||||
@@ -327,6 +328,11 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
(case instBindist of
|
||||
Nothing -> runInstGHC s' $ do
|
||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
liftE $ runBothE' (installGHCBin
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
@@ -338,6 +344,11 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
Just uri -> do
|
||||
runInstGHC s'{ settings = settings {noVerify = True}} $ do
|
||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
liftE $ runBothE' (installGHCBindist
|
||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing Nothing)
|
||||
v
|
||||
@@ -399,6 +410,11 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
(case instBindist of
|
||||
Nothing -> runInstTool s' $ do
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Cabal
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
liftE $ runBothE' (installCabalBin
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
@@ -408,6 +424,11 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
Just uri -> do
|
||||
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Cabal
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
liftE $ runBothE' (installCabalBindist
|
||||
(DownloadInfo uri Nothing "" Nothing Nothing)
|
||||
v
|
||||
@@ -448,6 +469,11 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
(case instBindist of
|
||||
Nothing -> runInstTool s' $ do
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer HLS
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
liftE $ runBothE' (installHLSBin
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
@@ -457,6 +483,11 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
Just uri -> do
|
||||
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer HLS
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
-- TODO: support legacy
|
||||
liftE $ runBothE' (installHLSBindist
|
||||
(DownloadInfo uri (if isWindows then Nothing else Just (RegexDir "haskell-language-server-*")) "" Nothing Nothing)
|
||||
@@ -498,6 +529,11 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
(case instBindist of
|
||||
Nothing -> runInstTool s' $ do
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Stack
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
liftE $ runBothE' (installStackBin
|
||||
v
|
||||
(maybe GHCupInternal IsolateDir isolateDir)
|
||||
@@ -507,6 +543,11 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
||||
Just uri -> do
|
||||
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Stack
|
||||
forM_ (_viPreInstall =<< vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
liftE $ runBothE' (installStackBindist
|
||||
(DownloadInfo uri Nothing "" Nothing Nothing)
|
||||
v
|
||||
|
||||
@@ -17,6 +17,7 @@ import GHCup.Types
|
||||
import GHCup.Prelude.File
|
||||
import GHCup.Prelude.Logger
|
||||
|
||||
import Control.Concurrent (threadDelay)
|
||||
#if !MIN_VERSION_base(4,13,0)
|
||||
import Control.Monad.Fail ( MonadFail )
|
||||
#endif
|
||||
@@ -135,8 +136,15 @@ upgrade uOpts force' fatal Dirs{..} runAppState runLogger = do
|
||||
UpgradeGHCupDir -> pure (Just (binDir </> "ghcup" <> exeExt))
|
||||
|
||||
runUpgrade runAppState (do
|
||||
v' <- liftE $ upgradeGHCup target force' fatal
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
Just (tver, vi) <- pure $ getLatest dls GHCup
|
||||
let latestVer = _tvVersion tver
|
||||
forM_ (_viPreInstall vi) $ \msg -> do
|
||||
lift $ logWarn msg
|
||||
lift $ logWarn
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- give the user a sec to intervene
|
||||
v' <- liftE $ upgradeGHCup' target force' fatal latestVer
|
||||
pure (v', dls)
|
||||
) >>= \case
|
||||
VRight (v', dls) -> do
|
||||
|
||||
@@ -75,10 +75,15 @@ import Optics.Operators ((.~),(%~))
|
||||
import Optics.Getter (view)
|
||||
import Optics.Optic ((%))
|
||||
import Optics ((^.), to)
|
||||
import qualified GHCup.Brick.Widgets.Menus.CompileHLS as CompileHLS
|
||||
import Control.Concurrent (threadDelay)
|
||||
import qualified GHCup.GHC as GHC
|
||||
import qualified GHCup.OptParse.Common as OptParse
|
||||
import qualified GHCup.HLS as HLS
|
||||
|
||||
|
||||
|
||||
{- Core Logic.
|
||||
{- Core Logic.
|
||||
|
||||
This module defines the IO actions we can execute within the Brick App:
|
||||
- Install
|
||||
@@ -111,7 +116,7 @@ constructList appD settings =
|
||||
selectBy :: Tool -> (ListResult -> Bool) -> BrickInternalState -> BrickInternalState
|
||||
selectBy tool predicate internal_state =
|
||||
let new_focus = F.focusSetCurrent (Singular tool) (view sectionListFocusRingL internal_state)
|
||||
tool_lens = sectionL (Singular tool)
|
||||
tool_lens = sectionL (Singular tool)
|
||||
in internal_state
|
||||
& sectionListFocusRingL .~ new_focus
|
||||
& tool_lens %~ L.listMoveTo 0 -- We move to 0 first
|
||||
@@ -179,7 +184,7 @@ installWithOptions :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFai
|
||||
-> m (Either String ())
|
||||
installWithOptions opts (_, ListResult {..}) = do
|
||||
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
||||
let
|
||||
let
|
||||
misolated = opts ^. AdvanceInstall.isolateDirL
|
||||
shouldIsolate = maybe GHCupInternal IsolateDir (opts ^. AdvanceInstall.isolateDirL)
|
||||
shouldForce = opts ^. AdvanceInstall.forceInstallL
|
||||
@@ -228,15 +233,15 @@ installWithOptions opts (_, ListResult {..}) = do
|
||||
case opts ^. AdvanceInstall.instBindistL of
|
||||
Nothing -> do
|
||||
liftE $
|
||||
runBothE'
|
||||
runBothE'
|
||||
(installGHCBin v shouldIsolate shouldForce extraArgs)
|
||||
(when (shouldSet && isNothing misolated) (liftE $ void $ setGHC v SetGHCOnly Nothing))
|
||||
pure (vi, dirs, ce)
|
||||
pure (vi, dirs, ce)
|
||||
Just uri -> do
|
||||
liftE $
|
||||
runBothE'
|
||||
runBothE'
|
||||
(installGHCBindist
|
||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing Nothing)
|
||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing Nothing)
|
||||
v
|
||||
shouldIsolate
|
||||
shouldForce
|
||||
@@ -248,14 +253,14 @@ installWithOptions opts (_, ListResult {..}) = do
|
||||
let vi = getVersionInfo v Cabal dls
|
||||
case opts ^. AdvanceInstall.instBindistL of
|
||||
Nothing -> do
|
||||
liftE $
|
||||
runBothE'
|
||||
liftE $
|
||||
runBothE'
|
||||
(installCabalBin lVer shouldIsolate shouldForce)
|
||||
(when (shouldSet && isNothing misolated) (liftE $ void $ setCabal lVer))
|
||||
pure (vi, dirs, ce)
|
||||
Just uri -> do
|
||||
liftE $
|
||||
runBothE'
|
||||
liftE $
|
||||
runBothE'
|
||||
(installCabalBindist (DownloadInfo uri Nothing "" Nothing Nothing) lVer shouldIsolate shouldForce)
|
||||
(when (shouldSet && isNothing misolated) (liftE $ void $ setCabal lVer))
|
||||
pure (vi, dirs, ce)
|
||||
@@ -263,19 +268,19 @@ installWithOptions opts (_, ListResult {..}) = do
|
||||
GHCup -> do
|
||||
let vi = snd <$> getLatest dls GHCup
|
||||
liftE $ upgradeGHCup Nothing False False $> (vi, dirs, ce)
|
||||
HLS -> do
|
||||
HLS -> do
|
||||
let vi = getVersionInfo v HLS dls
|
||||
case opts ^. AdvanceInstall.instBindistL of
|
||||
Nothing -> do
|
||||
liftE $
|
||||
runBothE'
|
||||
liftE $
|
||||
runBothE'
|
||||
(installHLSBin lVer shouldIsolate shouldForce)
|
||||
(when (shouldSet && isNothing misolated) (liftE $ void $ setHLS lVer SetHLSOnly Nothing))
|
||||
pure (vi, dirs, ce)
|
||||
pure (vi, dirs, ce)
|
||||
Just uri -> do
|
||||
liftE $
|
||||
runBothE'
|
||||
(installHLSBindist
|
||||
liftE $
|
||||
runBothE'
|
||||
(installHLSBindist
|
||||
(DownloadInfo uri (if isWindows then Nothing else Just (RegexDir "haskell-language-server-*")) "" Nothing Nothing)
|
||||
lVer
|
||||
shouldIsolate
|
||||
@@ -288,13 +293,13 @@ installWithOptions opts (_, ListResult {..}) = do
|
||||
case opts ^. AdvanceInstall.instBindistL of
|
||||
Nothing -> do
|
||||
liftE $
|
||||
runBothE'
|
||||
runBothE'
|
||||
(installStackBin lVer shouldIsolate shouldForce)
|
||||
(when (shouldSet && isNothing misolated) (liftE $ void $ setStack lVer))
|
||||
pure (vi, dirs, ce)
|
||||
Just uri -> do
|
||||
liftE $
|
||||
runBothE'
|
||||
runBothE'
|
||||
(installStackBindist (DownloadInfo uri Nothing "" Nothing Nothing) lVer shouldIsolate shouldForce)
|
||||
(when (shouldSet && isNothing misolated) (liftE $ void $ setStack lVer))
|
||||
pure (vi, dirs, ce)
|
||||
@@ -325,7 +330,7 @@ installWithOptions opts (_, ListResult {..}) = do
|
||||
VLeft e -> pure $ Left $ prettyHFError e <> "\n"
|
||||
<> "Also check the logs in ~/.ghcup/logs"
|
||||
|
||||
install' :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m, MonadMask m, MonadUnliftIO m, Alternative m)
|
||||
install' :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m, MonadMask m, MonadUnliftIO m, Alternative m)
|
||||
=> (Int, ListResult) -> m (Either String ())
|
||||
install' = installWithOptions (AdvanceInstall.InstallOptions Nothing False Nothing False [])
|
||||
|
||||
@@ -456,6 +461,175 @@ changelog' (_, ListResult {..}) = do
|
||||
Right _ -> pure $ Right ()
|
||||
Left e -> pure $ Left $ prettyHFError e
|
||||
|
||||
compileGHC :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m, MonadMask m, MonadUnliftIO m, Alternative m)
|
||||
=> CompileGHC.CompileGHCOptions -> (Int, ListResult) -> m (Either String ())
|
||||
compileGHC compopts (_, lr@ListResult{lTool = GHC, ..}) = do
|
||||
appstate <- ask
|
||||
let run =
|
||||
runResourceT
|
||||
. runE @'[ AlreadyInstalled
|
||||
, BuildFailed
|
||||
, DigestError
|
||||
, ContentLengthError
|
||||
, GPGError
|
||||
, DownloadFailed
|
||||
, GHCupSetError
|
||||
, NoDownload
|
||||
, NotFoundInPATH
|
||||
, PatchFailed
|
||||
, UnknownArchive
|
||||
, TarDirDoesNotExist
|
||||
, NotInstalled
|
||||
, DirNotEmpty
|
||||
, ArchiveResult
|
||||
, FileDoesNotExistError
|
||||
, HadrianNotFound
|
||||
, InvalidBuildConfig
|
||||
, ProcessError
|
||||
, CopyError
|
||||
, BuildFailed
|
||||
, UninstallFailed
|
||||
, MergeFileTreeError
|
||||
]
|
||||
compileResult <- run (do
|
||||
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
||||
let vi = getVersionInfo (mkTVer lVer) GHC dls
|
||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||
logInfo msg
|
||||
logInfo
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||
|
||||
targetVer <- liftE $ GHCup.compileGHC
|
||||
(GHC.SourceDist lVer)
|
||||
(compopts ^. CompileGHC.crossTarget)
|
||||
(compopts ^. CompileGHC.overwriteVer)
|
||||
(compopts ^. CompileGHC.bootstrapGhc)
|
||||
(compopts ^. CompileGHC.jobs)
|
||||
(compopts ^. CompileGHC.buildConfig)
|
||||
(compopts ^. CompileGHC.patches)
|
||||
(compopts ^. CompileGHC.addConfArgs)
|
||||
(compopts ^. CompileGHC.buildFlavour)
|
||||
(compopts ^. CompileGHC.buildSystem)
|
||||
(maybe GHCupInternal IsolateDir $ compopts ^. CompileGHC.isolateDir)
|
||||
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls2 }} <- ask
|
||||
let vi2 = getVersionInfo targetVer GHC dls2
|
||||
when
|
||||
(compopts ^. CompileGHC.setCompile)
|
||||
(liftE . void $ GHCup.setGHC targetVer SetGHCOnly Nothing)
|
||||
pure (vi2, targetVer)
|
||||
)
|
||||
case compileResult of
|
||||
VRight (vi, tv) -> do
|
||||
logInfo "GHC successfully compiled and installed"
|
||||
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo msg
|
||||
liftIO $ putStr (T.unpack $ tVerToText tv)
|
||||
pure $ Right ()
|
||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
||||
logWarn $
|
||||
"GHC ver " <> prettyVer v <> " already installed, remove it first to reinstall"
|
||||
pure $ Right ()
|
||||
VLeft (V (DirNotEmpty fp)) -> do
|
||||
logError $
|
||||
"Install directory " <> T.pack fp <> " is not empty."
|
||||
pure $ Right ()
|
||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||
case keepDirs (appstate & settings) of
|
||||
Never -> logError $ T.pack $ prettyHFError err
|
||||
_ -> logError $ T.pack (prettyHFError err) <> "\n"
|
||||
<> "Check the logs at " <> T.pack (fromGHCupPath $ appstate & dirs & logsDir)
|
||||
<> " and the build directory "
|
||||
<> T.pack tmpdir <> " for more clues." <> "\n"
|
||||
<> "Make sure to clean up " <> T.pack tmpdir <> " afterwards."
|
||||
pure $ Right ()
|
||||
VLeft e -> do
|
||||
logError $ T.pack $ prettyHFError e
|
||||
pure $ Right ()
|
||||
-- This is the case when the tool is not GHC... which should be impossible but,
|
||||
-- it exhaustes pattern matches
|
||||
compileGHC _ (_, ListResult{lTool = _}) = pure (Right ())
|
||||
|
||||
|
||||
compileHLS :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m, MonadMask m, MonadUnliftIO m, Alternative m)
|
||||
=> CompileHLS.CompileHLSOptions -> (Int, ListResult) -> m (Either String ())
|
||||
compileHLS compopts (_, lr@ListResult{lTool = HLS, ..}) = do
|
||||
appstate <- ask
|
||||
let run =
|
||||
runResourceT
|
||||
. runE @'[ AlreadyInstalled
|
||||
, BuildFailed
|
||||
, DigestError
|
||||
, ContentLengthError
|
||||
, GPGError
|
||||
, DownloadFailed
|
||||
, GHCupSetError
|
||||
, NoDownload
|
||||
, NotFoundInPATH
|
||||
, PatchFailed
|
||||
, UnknownArchive
|
||||
, TarDirDoesNotExist
|
||||
, TagNotFound
|
||||
, DayNotFound
|
||||
, NextVerNotFound
|
||||
, NoToolVersionSet
|
||||
, NotInstalled
|
||||
, DirNotEmpty
|
||||
, ArchiveResult
|
||||
, UninstallFailed
|
||||
, MergeFileTreeError
|
||||
]
|
||||
compileResult <- run (do
|
||||
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
||||
let vi = getVersionInfo (mkTVer lVer) GHC dls
|
||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||
logInfo msg
|
||||
logInfo
|
||||
"...waiting for 5 seconds, you can still abort..."
|
||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||
|
||||
ghcs <-
|
||||
liftE $ forM (compopts ^. CompileHLS.targetGHCs)
|
||||
(\ghc -> fmap (_tvVersion . fst) . OptParse.fromVersion (Just ghc) $ GHC)
|
||||
targetVer <- liftE $ GHCup.compileHLS
|
||||
(HLS.SourceDist lVer)
|
||||
ghcs
|
||||
(compopts ^. CompileHLS.jobs)
|
||||
(compopts ^. CompileHLS.overwriteVer)
|
||||
(maybe GHCupInternal IsolateDir $ compopts ^. CompileHLS.isolateDir)
|
||||
(compopts ^. CompileHLS.cabalProject)
|
||||
(compopts ^. CompileHLS.cabalProjectLocal)
|
||||
(compopts ^. CompileHLS.updateCabal)
|
||||
(compopts ^. CompileHLS.patches)
|
||||
(compopts ^. CompileHLS.cabalArgs)
|
||||
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls2 }} <- ask
|
||||
let vi2 = getVersionInfo (mkTVer targetVer) GHC dls2
|
||||
when
|
||||
(compopts ^. CompileHLS.setCompile)
|
||||
(liftE . void $ GHCup.setHLS targetVer SetHLSOnly Nothing)
|
||||
pure (vi2, targetVer)
|
||||
)
|
||||
case compileResult of
|
||||
VRight (vi, tv) -> do
|
||||
logInfo "HLS successfully compiled and installed"
|
||||
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo msg
|
||||
liftIO $ putStr (T.unpack $ prettyVer tv)
|
||||
pure $ Right ()
|
||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||
case keepDirs (appstate & settings) of
|
||||
Never -> logError $ T.pack $ prettyHFError err
|
||||
_ -> logError $ T.pack (prettyHFError err) <> "\n"
|
||||
<> "Check the logs at " <> T.pack (fromGHCupPath $ appstate & dirs & logsDir)
|
||||
<> " and the build directory "
|
||||
<> T.pack tmpdir <> " for more clues." <> "\n"
|
||||
<> "Make sure to clean up " <> T.pack tmpdir <> " afterwards."
|
||||
pure $ Right ()
|
||||
VLeft e -> do
|
||||
logError $ T.pack $ prettyHFError e
|
||||
pure $ Right ()
|
||||
-- This is the case when the tool is not HLS... which should be impossible but,
|
||||
-- it exhaustes pattern matches
|
||||
compileHLS _ (_, ListResult{lTool = _}) = pure (Right ())
|
||||
|
||||
|
||||
settings' :: IORef AppState
|
||||
{-# NOINLINE settings' #-}
|
||||
@@ -501,7 +675,7 @@ getAppData mgi = runExceptT $ do
|
||||
lV <- listVersions Nothing [] False True (Nothing, Nothing)
|
||||
pure $ BrickData (reverse lV)
|
||||
|
||||
--
|
||||
--
|
||||
|
||||
keyHandlers :: KeyBindings
|
||||
-> [ ( KeyCombination
|
||||
@@ -526,23 +700,25 @@ keyHandlers KeyBindings {..} =
|
||||
, (KeyCombination Vty.KEnter [], const "advance options", createMenuforTool )
|
||||
]
|
||||
where
|
||||
createMenuforTool = do
|
||||
createMenuforTool = do
|
||||
e <- use (appState % to sectionListSelectedElement)
|
||||
let exitKey = KeyCombination (Vty.KChar 'c') [Vty.MCtrl]
|
||||
case e of
|
||||
Nothing -> pure ()
|
||||
Just (_, r) -> do
|
||||
-- Create new menus
|
||||
contextMenu .= ContextMenu.create r bQuit
|
||||
advanceInstallMenu .= AdvanceInstall.create bQuit
|
||||
compileGHCMenu .= CompileGHC.create bQuit
|
||||
contextMenu .= ContextMenu.create r exitKey
|
||||
advanceInstallMenu .= AdvanceInstall.create exitKey
|
||||
compileGHCMenu .= CompileGHC.create exitKey
|
||||
compileHLSMenu .= CompileHLS.create exitKey
|
||||
-- Set mode to context
|
||||
mode .= ContextPanel
|
||||
pure ()
|
||||
|
||||
--hideShowHandler' :: (BrickSettings -> Bool) -> (BrickSettings -> Bool) -> m ()
|
||||
hideShowHandler' f = do
|
||||
hideShowHandler' f = do
|
||||
app_settings <- use appSettings
|
||||
let
|
||||
let
|
||||
vers = f app_settings
|
||||
newAppSettings = app_settings & Common.showAllVersions .~ vers
|
||||
ad <- use appData
|
||||
|
||||
@@ -25,7 +25,7 @@ module GHCup.Brick.App where
|
||||
|
||||
import qualified GHCup.Brick.Actions as Actions
|
||||
import qualified GHCup.Brick.Attributes as Attributes
|
||||
import GHCup.Brick.BrickState (BrickState (..), advanceInstallMenu, appKeys, appSettings, appState, contextMenu, mode, compileGHCMenu)
|
||||
import GHCup.Brick.BrickState (BrickState (..), advanceInstallMenu, appKeys, appSettings, appState, contextMenu, mode, compileGHCMenu, compileHLSMenu)
|
||||
import GHCup.Brick.Common (Mode (..), Name (..))
|
||||
import qualified GHCup.Brick.Common as Common
|
||||
import qualified GHCup.Brick.Widgets.KeyInfo as KeyInfo
|
||||
@@ -65,6 +65,8 @@ import Optics.Optic ((%))
|
||||
import Optics.State (use)
|
||||
import Optics.State.Operators ((.=))
|
||||
import qualified GHCup.Brick.Widgets.Menus.CompileGHC as CompileGHC
|
||||
import qualified GHCup.Brick.Widgets.Menus.CompileHLS as CompileHLS
|
||||
import Control.Monad (when)
|
||||
|
||||
app :: AttrMap -> AttrMap -> App BrickState () Name
|
||||
app attrs dimAttrs =
|
||||
@@ -77,12 +79,12 @@ app attrs dimAttrs =
|
||||
|
||||
drawUI :: AttrMap -> BrickState -> [Widget Name]
|
||||
drawUI dimAttrs st =
|
||||
let
|
||||
let
|
||||
footer = Brick.withAttr Attributes.helpAttr
|
||||
. Brick.txtWrap
|
||||
. T.pack
|
||||
. foldr1 (\x y -> x <> " " <> y)
|
||||
. fmap (\(KeyCombination key mods, pretty_setting, _)
|
||||
. fmap (\(KeyCombination key mods, pretty_setting, _)
|
||||
-> intercalate "+" (Common.showKey key : (Common.showMod <$> mods)) <> ":" <> pretty_setting (st ^. appSettings)
|
||||
)
|
||||
$ Actions.keyHandlers (st ^. appKeys)
|
||||
@@ -94,13 +96,13 @@ drawUI dimAttrs st =
|
||||
ContextPanel -> [ContextMenu.draw (st ^. contextMenu), navg]
|
||||
AdvanceInstallPanel -> [AdvanceInstall.draw (st ^. advanceInstallMenu), navg]
|
||||
CompileGHCPanel -> [CompileGHC.draw (st ^. compileGHCMenu), navg]
|
||||
CompileHLSPanel -> [CompileHLS.draw (st ^. compileHLSMenu), navg]
|
||||
|
||||
|
||||
-- | On q, go back to navigation.
|
||||
-- | On q, go back to navigation.
|
||||
-- On Enter, to go to tutorial
|
||||
keyInfoHandler :: BrickEvent Name e -> EventM Name BrickState ()
|
||||
keyInfoHandler ev = case ev of
|
||||
VtyEvent (Vty.EvKey (Vty.KChar 'q') _ ) -> mode .= Navigation
|
||||
VtyEvent (Vty.EvKey (Vty.KChar 'c') [Vty.MCtrl]) -> mode .= Navigation
|
||||
VtyEvent (Vty.EvKey Vty.KEnter _ ) -> mode .= Tutorial
|
||||
_ -> pure ()
|
||||
|
||||
@@ -108,50 +110,41 @@ keyInfoHandler ev = case ev of
|
||||
tutorialHandler :: BrickEvent Name e -> EventM Name BrickState ()
|
||||
tutorialHandler ev =
|
||||
case ev of
|
||||
VtyEvent (Vty.EvKey (Vty.KChar 'q') _ ) -> mode .= Navigation
|
||||
VtyEvent (Vty.EvKey (Vty.KChar 'c') [Vty.MCtrl]) -> mode .= Navigation
|
||||
_ -> pure ()
|
||||
|
||||
-- | Tab/Arrows to navigate.
|
||||
-- | Tab/Arrows to navigate.
|
||||
navigationHandler :: BrickEvent Name e -> EventM Name BrickState ()
|
||||
navigationHandler ev = do
|
||||
AppState { keyBindings = kb } <- liftIO $ readIORef Actions.settings'
|
||||
case ev of
|
||||
inner_event@(VtyEvent (Vty.EvKey key _)) ->
|
||||
case find (\(key', _, _) -> key' == KeyCombination key []) (Actions.keyHandlers kb) of
|
||||
inner_event@(VtyEvent (Vty.EvKey key mods)) ->
|
||||
case find (\(key', _, _) -> key' == KeyCombination key mods) (Actions.keyHandlers kb) of
|
||||
Just (_, _, handler) -> handler
|
||||
Nothing -> void $ Common.zoom appState $ Navigation.handler inner_event
|
||||
inner_event -> Common.zoom appState $ Navigation.handler inner_event
|
||||
|
||||
contextMenuHandler :: BrickEvent Name e -> EventM Name BrickState ()
|
||||
contextMenuHandler ev = do
|
||||
ctx <- use contextMenu
|
||||
ctx <- use contextMenu
|
||||
let focusedElement = ctx ^. Menu.menuFocusRingL % to F.focusGetCurrent
|
||||
buttons = ctx ^. Menu.menuButtonsL
|
||||
(KeyCombination exitKey mods) = ctx ^. Menu.menuExitKeyL
|
||||
case (ev, focusedElement) of
|
||||
(_ , Nothing) -> pure ()
|
||||
(VtyEvent (Vty.EvKey k m), Just n)
|
||||
| k == exitKey
|
||||
&& m == mods
|
||||
&& n `elem` [Menu.fieldName button | button <- buttons]
|
||||
-> mode .= Navigation
|
||||
(VtyEvent (Vty.EvKey k m), Just n) | k == exitKey && m == mods -> mode .= Navigation
|
||||
(VtyEvent (Vty.EvKey Vty.KEnter []), Just (Common.MenuElement Common.AdvanceInstallButton) ) -> mode .= Common.AdvanceInstallPanel
|
||||
(VtyEvent (Vty.EvKey Vty.KEnter []), Just (Common.MenuElement Common.CompilieButton) ) -> mode .= Common.CompileGHCPanel
|
||||
(VtyEvent (Vty.EvKey Vty.KEnter []), Just (Common.MenuElement Common.CompileGHCButton) ) -> mode .= Common.CompileGHCPanel
|
||||
(VtyEvent (Vty.EvKey Vty.KEnter []), Just (Common.MenuElement Common.CompileHLSButton) ) -> mode .= Common.CompileHLSPanel
|
||||
_ -> Common.zoom contextMenu $ ContextMenu.handler ev
|
||||
--
|
||||
--
|
||||
advanceInstallHandler :: BrickEvent Name e -> EventM Name BrickState ()
|
||||
advanceInstallHandler ev = do
|
||||
ctx <- use advanceInstallMenu
|
||||
ctx <- use advanceInstallMenu
|
||||
let focusedElement = ctx ^. Menu.menuFocusRingL % to F.focusGetCurrent
|
||||
buttons = ctx ^. Menu.menuButtonsL
|
||||
(KeyCombination exitKey mods) = ctx ^. Menu.menuExitKeyL
|
||||
case (ev, focusedElement) of
|
||||
(_ , Nothing) -> pure ()
|
||||
(VtyEvent (Vty.EvKey k m), Just n)
|
||||
| k == exitKey
|
||||
&& m == mods
|
||||
&& n `elem` [Menu.fieldName button | button <- buttons]
|
||||
-> mode .= ContextPanel
|
||||
(VtyEvent (Vty.EvKey k m), Just n) | k == exitKey && m == mods -> mode .= ContextPanel
|
||||
(VtyEvent (Vty.EvKey Vty.KEnter []), Just (MenuElement Common.OkButton)) -> do
|
||||
let iopts = ctx ^. Menu.menuStateL
|
||||
Actions.withIOAction $ Actions.installWithOptions iopts
|
||||
@@ -159,19 +152,33 @@ advanceInstallHandler ev = do
|
||||
|
||||
compileGHCHandler :: BrickEvent Name e -> EventM Name BrickState ()
|
||||
compileGHCHandler ev = do
|
||||
ctx <- use compileGHCMenu
|
||||
ctx <- use compileGHCMenu
|
||||
let focusedElement = ctx ^. Menu.menuFocusRingL % to F.focusGetCurrent
|
||||
buttons = ctx ^. Menu.menuButtonsL
|
||||
(KeyCombination exitKey mods) = ctx ^. Menu.menuExitKeyL
|
||||
case (ev, focusedElement) of
|
||||
(_ , Nothing) -> pure ()
|
||||
(VtyEvent (Vty.EvKey k m), Just n)
|
||||
| k == exitKey
|
||||
&& m == mods
|
||||
&& n `elem` [Menu.fieldName button | button <- buttons]
|
||||
-> mode .= ContextPanel
|
||||
(VtyEvent (Vty.EvKey k m), Just n) | k == exitKey && m == mods -> mode .= ContextPanel
|
||||
(VtyEvent (Vty.EvKey Vty.KEnter []), Just (MenuElement Common.OkButton)) -> do
|
||||
let iopts = ctx ^. Menu.menuStateL
|
||||
when (Menu.isValidMenu ctx)
|
||||
(Actions.withIOAction $ Actions.compileGHC iopts)
|
||||
_ -> Common.zoom compileGHCMenu $ CompileGHC.handler ev
|
||||
|
||||
|
||||
compileHLSHandler :: BrickEvent Name e -> EventM Name BrickState ()
|
||||
compileHLSHandler ev = do
|
||||
ctx <- use compileHLSMenu
|
||||
let focusedElement = ctx ^. Menu.menuFocusRingL % to F.focusGetCurrent
|
||||
(KeyCombination exitKey mods) = ctx ^. Menu.menuExitKeyL
|
||||
case (ev, focusedElement) of
|
||||
(_ , Nothing) -> pure ()
|
||||
(VtyEvent (Vty.EvKey k m), Just n) | k == exitKey && m == mods -> mode .= ContextPanel
|
||||
(VtyEvent (Vty.EvKey Vty.KEnter []), Just (MenuElement Common.OkButton)) -> do
|
||||
let iopts = ctx ^. Menu.menuStateL
|
||||
when (Menu.isValidMenu ctx)
|
||||
(Actions.withIOAction $ Actions.compileHLS iopts)
|
||||
_ -> Common.zoom compileHLSMenu $ CompileHLS.handler ev
|
||||
|
||||
eventHandler :: BrickEvent Name e -> EventM Name BrickState ()
|
||||
eventHandler ev = do
|
||||
m <- use mode
|
||||
@@ -182,3 +189,4 @@ eventHandler ev = do
|
||||
ContextPanel -> contextMenuHandler ev
|
||||
AdvanceInstallPanel -> advanceInstallHandler ev
|
||||
CompileGHCPanel -> compileGHCHandler ev
|
||||
CompileHLSPanel -> compileHLSHandler ev
|
||||
|
||||
@@ -46,10 +46,8 @@ defaultAttributes no_color = Brick.attrMap
|
||||
where
|
||||
withForeColor | no_color = const
|
||||
| otherwise = Vty.withForeColor
|
||||
|
||||
withBackColor | no_color = \attr _ -> attr `Vty.withStyle` Vty.reverseVideo
|
||||
| otherwise = Vty.withBackColor
|
||||
|
||||
withStyle = Vty.withStyle
|
||||
|
||||
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
|
||||
{-
|
||||
This module contains the BrickState. One could be tempted to include this data structure in GHCup.Brick.Common,
|
||||
This module contains the BrickState. One could be tempted to include this data structure in GHCup.Brick.Common,
|
||||
but it is better to make a separated module in order to avoid cyclic dependencies.
|
||||
|
||||
This happens because the BrickState is sort of a container for all widgets,
|
||||
This happens because the BrickState is sort of a container for all widgets,
|
||||
but widgets depends on common functionality, hence:
|
||||
|
||||
BrickState `depends on` Widgets.XYZ `depends on` Common
|
||||
BrickState `depends on` Widgets.XYZ `depends on` Common
|
||||
|
||||
The linear relation above breaks if BrickState is defined in Common.
|
||||
The linear relation above breaks if BrickState is defined in Common.
|
||||
|
||||
-}
|
||||
|
||||
@@ -35,6 +35,7 @@ import GHCup.Brick.Widgets.Menus.Context (ContextMenu)
|
||||
import GHCup.Brick.Widgets.Menus.AdvanceInstall (AdvanceInstallMenu)
|
||||
import GHCup.Brick.Widgets.Menus.CompileGHC (CompileGHCMenu)
|
||||
import Optics.TH (makeLenses)
|
||||
import GHCup.Brick.Widgets.Menus.CompileHLS (CompileHLSMenu)
|
||||
|
||||
|
||||
data BrickState = BrickState
|
||||
@@ -44,6 +45,7 @@ data BrickState = BrickState
|
||||
, _contextMenu :: ContextMenu
|
||||
, _advanceInstallMenu :: AdvanceInstallMenu
|
||||
, _compileGHCMenu :: CompileGHCMenu
|
||||
, _compileHLSMenu :: CompileHLSMenu
|
||||
, _appKeys :: KeyBindings
|
||||
, _mode :: Mode
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ module GHCup.Brick.Common (
|
||||
, TargetGhcEditBox, BootstrapGhcEditBox, JobsEditBox, BuildConfigEditBox
|
||||
, PatchesEditBox, CrossTargetEditBox, AddConfArgsEditBox, OvewrwiteVerEditBox
|
||||
, BuildFlavourEditBox, BuildSystemEditBox, OkButton, AdvanceInstallButton
|
||||
, CompilieButton
|
||||
, CompileGHCButton, CompileHLSButton, CabalProjectEditBox
|
||||
, CabalProjectLocalEditBox, UpdateCabalCheckBox
|
||||
) ) where
|
||||
|
||||
import GHCup.List ( ListResult )
|
||||
@@ -75,8 +76,10 @@ pattern OkButton :: ResourceId
|
||||
pattern OkButton = ResourceId 0
|
||||
pattern AdvanceInstallButton :: ResourceId
|
||||
pattern AdvanceInstallButton = ResourceId 100
|
||||
pattern CompilieButton :: ResourceId
|
||||
pattern CompilieButton = ResourceId 101
|
||||
pattern CompileGHCButton :: ResourceId
|
||||
pattern CompileGHCButton = ResourceId 101
|
||||
pattern CompileHLSButton :: ResourceId
|
||||
pattern CompileHLSButton = ResourceId 102
|
||||
|
||||
pattern UrlEditBox :: ResourceId
|
||||
pattern UrlEditBox = ResourceId 1
|
||||
@@ -110,7 +113,15 @@ pattern BuildFlavourEditBox = ResourceId 14
|
||||
pattern BuildSystemEditBox :: ResourceId
|
||||
pattern BuildSystemEditBox = ResourceId 15
|
||||
|
||||
-- | Name data type. Uniquely identifies each widget in the TUI.
|
||||
pattern CabalProjectEditBox :: ResourceId
|
||||
pattern CabalProjectEditBox = ResourceId 16
|
||||
pattern CabalProjectLocalEditBox :: ResourceId
|
||||
pattern CabalProjectLocalEditBox = ResourceId 17
|
||||
pattern UpdateCabalCheckBox :: ResourceId
|
||||
pattern UpdateCabalCheckBox = ResourceId 18
|
||||
|
||||
|
||||
-- | Name data type. Uniquely identifies each widget in the TUI.
|
||||
-- some constructors might end up unused, but still is a good practise
|
||||
-- to have all of them defined, just in case
|
||||
data Name = AllTools -- ^ The main list widget
|
||||
@@ -118,8 +129,8 @@ data Name = AllTools -- ^ The main list widget
|
||||
| KeyInfoBox -- ^ The text box widget with action informacion
|
||||
| TutorialBox -- ^ The tutorial widget
|
||||
| ContextBox -- ^ The resource for Context Menu
|
||||
| CompileGHCBox -- ^ The resource for CompileGHC Menu
|
||||
| AdvanceInstallBox -- ^ The resource for AdvanceInstall Menu
|
||||
| CompileGHCBox -- ^ The resource for CompileGHC Menu
|
||||
| AdvanceInstallBox -- ^ The resource for AdvanceInstall Menu
|
||||
| MenuElement ResourceId -- ^ Each element in a Menu. Resources must not be share for visible
|
||||
-- Menus, but MenuA and MenuB can share resources if they both are
|
||||
-- invisible, or just one of them is visible.
|
||||
@@ -131,8 +142,9 @@ data Mode = Navigation
|
||||
| KeyInfo
|
||||
| Tutorial
|
||||
| ContextPanel
|
||||
| AdvanceInstallPanel
|
||||
| AdvanceInstallPanel
|
||||
| CompileGHCPanel
|
||||
| CompileHLSPanel
|
||||
deriving (Eq, Show, Ord)
|
||||
|
||||
installedSign :: String
|
||||
@@ -183,7 +195,7 @@ frontwardLayer layer_name =
|
||||
. Brick.withBorderStyle Border.unicode
|
||||
. Border.borderWithLabel (Brick.txt layer_name)
|
||||
|
||||
-- I refuse to give this a type signature.
|
||||
-- I refuse to give this a type signature.
|
||||
|
||||
-- | Given a lens, zoom on it. It is needed because Brick uses microlens but GHCup uses optics.
|
||||
zoom l = Brick.zoom (toLensVL l)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
|
||||
{-
|
||||
A very simple information-only widget with no handler.
|
||||
A very simple information-only widget with no handler.
|
||||
-}
|
||||
|
||||
module GHCup.Brick.Widgets.KeyInfo where
|
||||
@@ -20,7 +20,7 @@ import qualified GHCup.Brick.Common as Common
|
||||
|
||||
import Brick
|
||||
( Padding(Max),
|
||||
Widget(..),
|
||||
Widget(..),
|
||||
(<+>),
|
||||
(<=>))
|
||||
import qualified Brick
|
||||
@@ -69,4 +69,4 @@ draw KeyBindings {..} =
|
||||
]
|
||||
]
|
||||
]
|
||||
<=> Brick.hBox [Brick.txt "Press q to return to Navigation" <+> Brick.padRight Brick.Max (Brick.txt " ") <+> Brick.txt "Press Enter to go to the Tutorial"]
|
||||
<=> Brick.hBox [Brick.txt "Press c+ctrl to return to Navigation" <+> Brick.padRight Brick.Max (Brick.txt " ") <+> Brick.txt "Press Enter to go to the Tutorial"]
|
||||
|
||||
@@ -34,9 +34,9 @@ An input (type FieldInput) consist in
|
||||
b) a validator function
|
||||
c) a handler and a renderer
|
||||
|
||||
We have to use existential types to achive a composable API since every FieldInput has a different
|
||||
internal type, and every MenuField has a different Lens. For example:
|
||||
- The menu state is a record (MyRecord {uri: URI, flag : Bool})
|
||||
We have to use existential types to achive a composable API since every FieldInput has a different
|
||||
internal type, and every MenuField has a different Lens. For example:
|
||||
- The menu state is a record (MyRecord {uri: URI, flag : Bool})
|
||||
- Then, there are two MenuField:
|
||||
- One MenuField has (Lens' MyRecord URI) and the other has (Lens' MyRecord Bool)
|
||||
- The MenuFields has FieldInputs with internal state Text and Bool, respectively
|
||||
@@ -93,7 +93,7 @@ idFormatter = const id
|
||||
|
||||
-- | An error message
|
||||
type ErrorMessage = T.Text
|
||||
data ErrorStatus = Valid | Invalid ErrorMessage
|
||||
data ErrorStatus = Valid | Invalid ErrorMessage deriving (Eq)
|
||||
|
||||
-- | A lens which does nothing. Usefull to defined no-op fields
|
||||
emptyLens :: Lens' s ()
|
||||
@@ -113,7 +113,7 @@ data FieldInput a b n =
|
||||
-> HelpMessage
|
||||
-> b
|
||||
-> (Widget n -> Widget n)
|
||||
-> Widget n -- ^ How to draw the input, with focus a help message and input.
|
||||
-> Widget n -- ^ How to draw the input, with focus a help message and input.
|
||||
-- A extension function can be applied too
|
||||
, inputHandler :: BrickEvent n () -> EventM n b () -- ^ The handler
|
||||
}
|
||||
@@ -137,6 +137,8 @@ data MenuField s n where
|
||||
, fieldName :: n
|
||||
} -> MenuField s n
|
||||
|
||||
isValidField :: MenuField s n -> Bool
|
||||
isValidField = (== Valid) . fieldStatus
|
||||
|
||||
makeLensesFor
|
||||
[ ("fieldLabel", "fieldLabelL")
|
||||
@@ -179,7 +181,7 @@ createCheckBoxInput = FieldInput False Right "" checkBoxRender checkBoxHandler
|
||||
else border . Brick.withAttr Attributes.notInstalledAttr $ Brick.str Common.notInstalledSign
|
||||
checkBoxRender focus _ help check f =
|
||||
let core = f $ drawBool check
|
||||
in if focus
|
||||
in if focus
|
||||
then core
|
||||
else core <+> (Brick.padLeft (Brick.Pad 1) . centerV . renderAsHelpMsg $ help)
|
||||
checkBoxHandler = \case
|
||||
@@ -199,18 +201,18 @@ createEditableInput :: (Ord n, Show n) => n -> (T.Text -> Either ErrorMessage a)
|
||||
createEditableInput name validator = FieldInput initEdit validateEditContent "" drawEdit Edit.handleEditorEvent
|
||||
where
|
||||
drawEdit focus errMsg help edi amp =
|
||||
let
|
||||
let
|
||||
borderBox = amp . Border.border . Brick.padRight Brick.Max
|
||||
editorRender = Edit.renderEditor (Brick.txt . T.unlines) focus edi
|
||||
isEditorEmpty = Edit.getEditContents edi == [mempty]
|
||||
in case errMsg of
|
||||
Valid | isEditorEmpty -> borderBox $ renderAsHelpMsg help
|
||||
| otherwise -> borderBox editorRender
|
||||
Invalid msg
|
||||
Invalid msg
|
||||
| focus && isEditorEmpty -> borderBox $ renderAsHelpMsg help
|
||||
| focus -> borderBox editorRender
|
||||
| otherwise -> borderBox $ renderAsErrMsg msg
|
||||
validateEditContent = validator . T.unlines . Edit.getEditContents
|
||||
validateEditContent = validator . T.init . T.unlines . Edit.getEditContents
|
||||
initEdit = Edit.editorText name (Just 1) ""
|
||||
|
||||
createEditableField :: (Eq n, Ord n, Show n) => n -> (T.Text -> Either ErrorMessage a) -> Lens' s a -> EditableField s n
|
||||
@@ -226,7 +228,9 @@ type Button = MenuField
|
||||
|
||||
createButtonInput :: FieldInput () () n
|
||||
createButtonInput = FieldInput () Right "" drawButton (const $ pure ())
|
||||
where drawButton _ _ help _ amp = amp . centerV . renderAsHelpMsg $ help
|
||||
where
|
||||
drawButton True (Invalid err) _ _ amp = amp . centerV . renderAsErrMsg $ err
|
||||
drawButton _ _ help _ amp = amp . centerV . renderAsHelpMsg $ help
|
||||
|
||||
createButtonField :: n -> Button s n
|
||||
createButtonField = MenuField emptyLens createButtonInput "" Valid
|
||||
@@ -246,14 +250,14 @@ renderAslabel t focus =
|
||||
then highlighted $ Brick.txt t
|
||||
else Brick.txt t
|
||||
|
||||
-- | Creates a left align column.
|
||||
-- | Creates a left align column.
|
||||
-- Example: |- col2 is align dispite the length of col1
|
||||
-- row1_col1 row1_col2
|
||||
-- row2_col1_large row2_col2
|
||||
leftify :: Int -> Brick.Widget n -> Brick.Widget n
|
||||
leftify i = Brick.hLimit i . Brick.padRight Brick.Max
|
||||
|
||||
-- | center a line in three rows.
|
||||
-- | center a line in three rows.
|
||||
centerV :: Widget n -> Widget n
|
||||
centerV = Brick.padTopBottom 1
|
||||
|
||||
@@ -269,8 +273,8 @@ renderAsErrMsg = Brick.withAttr Attributes.errMsgAttr . Brick.txt
|
||||
Menu widget
|
||||
***************** -}
|
||||
|
||||
-- | A menu is a list of Fields and a state. Informally we can think about s in terms of the record type returned by
|
||||
-- a form.
|
||||
-- | A menu is a list of Fields and a state. Informally we can think about s in terms of the record type returned by
|
||||
-- a form.
|
||||
data Menu s n
|
||||
= Menu
|
||||
{ menuFields :: [MenuField s n] -- ^ The datatype representing the list of entries. Precisely, any array-like data type is highly unconvinient.
|
||||
@@ -281,7 +285,6 @@ data Menu s n
|
||||
, menuName :: n -- ^ The resource Name.
|
||||
}
|
||||
|
||||
|
||||
makeLensesFor
|
||||
[ ("menuFields", "menuFieldsL"), ("menuState", "menuStateL")
|
||||
, ("menuButtons", "menuButtonsL"), ("menuFocusRing", "menuFocusRingL")
|
||||
@@ -289,6 +292,9 @@ makeLensesFor
|
||||
]
|
||||
''Menu
|
||||
|
||||
isValidMenu :: Menu s n -> Bool
|
||||
isValidMenu = all isValidField . menuFields
|
||||
|
||||
createMenu :: n -> s -> KeyCombination -> [Button s n] -> [MenuField s n] -> Menu s n
|
||||
createMenu n initial exitK buttons fields = Menu fields initial buttons ring exitK n
|
||||
where ring = F.focusRing $ [field & fieldName | field <- fields] ++ [button & fieldName | button <- buttons]
|
||||
@@ -305,11 +311,15 @@ handlerMenu ev =
|
||||
fields <- use menuFieldsL
|
||||
case focused of
|
||||
Nothing -> pure ()
|
||||
Just n -> do
|
||||
Just n -> do
|
||||
updated_fields <- updateFields n (VtyEvent e) fields
|
||||
if all isValidField updated_fields
|
||||
then menuButtonsL %= fmap (fieldStatusL .~ Valid)
|
||||
else menuButtonsL %= fmap (fieldStatusL .~ Invalid "Some fields are invalid")
|
||||
menuFieldsL .= updated_fields
|
||||
_ -> pure ()
|
||||
where
|
||||
-- runs the Event with the inner handler of MenuField.
|
||||
updateFields :: n -> BrickEvent n () -> [MenuField s n] -> EventM n (Menu s n) [MenuField s n]
|
||||
updateFields n e [] = pure []
|
||||
updateFields n e (x@(MenuField {fieldInput = i@(FieldInput {..}) , ..}):xs) =
|
||||
@@ -324,7 +334,7 @@ handlerMenu ev =
|
||||
|
||||
|
||||
drawMenu :: (Eq n, Ord n, Show n, Brick.Named (MenuField s n) n) => Menu s n -> Widget n
|
||||
drawMenu menu =
|
||||
drawMenu menu =
|
||||
Brick.vBox
|
||||
[ Brick.vBox buttonWidgets
|
||||
, Common.separator
|
||||
@@ -332,8 +342,8 @@ drawMenu menu =
|
||||
$ Brick.viewport (menu ^. menuNameL) Brick.Vertical
|
||||
$ Brick.vBox fieldWidgets
|
||||
, Brick.txt " "
|
||||
, Brick.padRight Brick.Max $
|
||||
Brick.txt "Press "
|
||||
, Brick.padRight Brick.Max $
|
||||
Brick.txt "Press "
|
||||
<+> Common.keyToWidget (menu ^. menuExitKeyL)
|
||||
<+> Brick.txt " to go back"
|
||||
]
|
||||
@@ -344,7 +354,7 @@ drawMenu menu =
|
||||
|
||||
maxWidth = foldl' max 5 (fmap Brick.textWidth allLabels)
|
||||
|
||||
-- A list of functions which draw a highlighted label with right padding at the left of a widget.
|
||||
-- A list of functions which draw a highlighted label with right padding at the left of a widget.
|
||||
amplifiers =
|
||||
let labelsWidgets = fmap renderAslabel fieldLabels
|
||||
in fmap (\f b -> ((centerV . leftify (maxWidth + 10) $ f b) <+>) ) labelsWidgets
|
||||
|
||||
@@ -46,6 +46,8 @@ import Data.Bifunctor (Bifunctor(..))
|
||||
import Data.Function ((&))
|
||||
import Optics ((.~))
|
||||
import Data.Char (isSpace)
|
||||
import System.FilePath (isValid, isAbsolute, normalise)
|
||||
import GHCup.Prelude (stripNewlineEnd)
|
||||
|
||||
data InstallOptions = InstallOptions
|
||||
{ instBindist :: Maybe URI
|
||||
@@ -72,23 +74,28 @@ create k = Menu.createMenu AdvanceInstallBox initialState k [ok] fields
|
||||
initialState = InstallOptions Nothing False Nothing False []
|
||||
-- Brick's internal editor representation is [mempty].
|
||||
emptyEditor i = T.null i || (i == "\n")
|
||||
|
||||
|
||||
uriValidator :: T.Text -> Either Menu.ErrorMessage (Maybe URI)
|
||||
uriValidator i =
|
||||
uriValidator i =
|
||||
case not $ emptyEditor i of
|
||||
True -> bimap (T.pack . show) Just . parseURI . UTF8.fromString . T.unpack $ i
|
||||
False -> Right Nothing
|
||||
|
||||
filepathValidator :: T.Text -> Either Menu.ErrorMessage (Maybe FilePath)
|
||||
filepathValidator i =
|
||||
filepathValidator i =
|
||||
case not $ emptyEditor i of
|
||||
True -> Right . Just . T.unpack $ i
|
||||
True -> absolutePathParser (T.unpack i)
|
||||
False -> Right Nothing
|
||||
|
||||
absolutePathParser :: FilePath -> Either Menu.ErrorMessage (Maybe FilePath)
|
||||
absolutePathParser f = case isValid f && isAbsolute f of
|
||||
True -> Right . Just . stripNewlineEnd . normalise $ f
|
||||
False -> Left "Please enter a valid absolute filepath."
|
||||
|
||||
additionalValidator :: T.Text -> Either Menu.ErrorMessage [T.Text]
|
||||
additionalValidator = Right . T.split isSpace
|
||||
|
||||
fields =
|
||||
fields =
|
||||
[ Menu.createEditableField (Common.MenuElement Common.UrlEditBox) uriValidator instBindistL
|
||||
& Menu.fieldLabelL .~ "url"
|
||||
& Menu.fieldHelpMsgL .~ "Install the specified version from this bindist"
|
||||
@@ -105,7 +112,7 @@ create k = Menu.createMenu AdvanceInstallBox initialState k [ok] fields
|
||||
& Menu.fieldLabelL .~ "CONFIGURE_ARGS"
|
||||
& Menu.fieldHelpMsgL .~ "Additional arguments to bindist configure, prefix with '-- ' (longopts)"
|
||||
]
|
||||
|
||||
|
||||
ok = Menu.createButtonField (Common.MenuElement Common.OkButton)
|
||||
& Menu.fieldLabelL .~ "Advance Install"
|
||||
& Menu.fieldHelpMsgL .~ "Install with options below"
|
||||
|
||||
@@ -14,7 +14,24 @@
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
|
||||
|
||||
module GHCup.Brick.Widgets.Menus.CompileGHC (CompileGHCOptions, CompileGHCMenu, create, handler, draw) where
|
||||
module GHCup.Brick.Widgets.Menus.CompileGHC (
|
||||
CompileGHCOptions,
|
||||
CompileGHCMenu,
|
||||
create,
|
||||
handler,
|
||||
draw,
|
||||
bootstrapGhc,
|
||||
jobs,
|
||||
buildConfig,
|
||||
patches,
|
||||
crossTarget,
|
||||
addConfArgs,
|
||||
setCompile,
|
||||
overwriteVer,
|
||||
buildFlavour,
|
||||
buildSystem,
|
||||
isolateDir,
|
||||
) where
|
||||
|
||||
import GHCup.Brick.Widgets.Menu (Menu)
|
||||
import qualified GHCup.Brick.Widgets.Menu as Menu
|
||||
@@ -26,7 +43,8 @@ import Brick
|
||||
import Prelude hiding ( appendFile )
|
||||
import Optics.TH (makeLenses)
|
||||
import qualified GHCup.Brick.Common as Common
|
||||
import GHCup.Types (KeyCombination, BuildSystem (Hadrian))
|
||||
import GHCup.Types
|
||||
( KeyCombination, BuildSystem(..), VersionPattern )
|
||||
import URI.ByteString (URI)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.ByteString.UTF8 as UTF8
|
||||
@@ -36,9 +54,11 @@ import Data.Function ((&))
|
||||
import Optics ((.~))
|
||||
import Data.Char (isSpace)
|
||||
import Data.Versions (Version, version)
|
||||
import System.FilePath (isPathSeparator)
|
||||
import System.FilePath (isPathSeparator, isValid, isAbsolute, normalise)
|
||||
import Control.Applicative (Alternative((<|>)))
|
||||
import Text.Read (readEither)
|
||||
import GHCup.Prelude (stripNewlineEnd)
|
||||
import qualified GHCup.OptParse.Common as OptParse
|
||||
|
||||
data CompileGHCOptions = CompileGHCOptions
|
||||
{ _bootstrapGhc :: Either Version FilePath
|
||||
@@ -48,7 +68,7 @@ data CompileGHCOptions = CompileGHCOptions
|
||||
, _crossTarget :: Maybe T.Text
|
||||
, _addConfArgs :: [T.Text]
|
||||
, _setCompile :: Bool
|
||||
, _ovewrwiteVer :: Maybe Version
|
||||
, _overwriteVer :: Maybe [VersionPattern]
|
||||
, _buildFlavour :: Maybe String
|
||||
, _buildSystem :: Maybe BuildSystem
|
||||
, _isolateDir :: Maybe FilePath
|
||||
@@ -61,8 +81,8 @@ type CompileGHCMenu = Menu CompileGHCOptions Name
|
||||
create :: KeyCombination -> CompileGHCMenu
|
||||
create k = Menu.createMenu CompileGHCBox initialState k buttons fields
|
||||
where
|
||||
initialState =
|
||||
CompileGHCOptions
|
||||
initialState =
|
||||
CompileGHCOptions
|
||||
(Right "")
|
||||
Nothing
|
||||
Nothing
|
||||
@@ -82,51 +102,60 @@ create k = Menu.createMenu CompileGHCBox initialState k buttons fields
|
||||
bootstrapV :: T.Text -> Either Menu.ErrorMessage (Either Version FilePath)
|
||||
bootstrapV i =
|
||||
case not $ emptyEditor i of
|
||||
True ->
|
||||
let readVersion = bimap (const "Not a valid version") Left (version (T.init i)) -- Brick adds \n at the end, hence T.init
|
||||
readPath
|
||||
= if isPathSeparator (T.head i)
|
||||
then pure $ Right (T.unpack i)
|
||||
else Left "Not an absolute Path"
|
||||
in if T.any isPathSeparator i
|
||||
True ->
|
||||
let readVersion = bimap (const "Not a valid version") Left (version i)
|
||||
readPath = do
|
||||
mfilepath <- filepathV i
|
||||
case mfilepath of
|
||||
Nothing -> Left "Invalid Empty value"
|
||||
Just f -> Right (Right f)
|
||||
in if T.any isPathSeparator i
|
||||
then readPath
|
||||
else readVersion
|
||||
False -> Left "Invalid Empty value"
|
||||
|
||||
versionV :: T.Text -> Either Menu.ErrorMessage (Maybe Version)
|
||||
versionV = bimap (const "Not a valid version") Just . version . T.init -- Brick adds \n at the end, hence T.init
|
||||
versionV :: T.Text -> Either Menu.ErrorMessage (Maybe [VersionPattern])
|
||||
versionV = whenEmpty Nothing (bimap T.pack Just . OptParse.overWriteVersionParser . T.unpack)
|
||||
|
||||
jobsV :: T.Text -> Either Menu.ErrorMessage (Maybe Int)
|
||||
jobsV =
|
||||
jobsV =
|
||||
let parseInt = bimap (const "Invalid value. Must be an integer") Just . readEither @Int . T.unpack
|
||||
in whenEmpty Nothing parseInt
|
||||
in whenEmpty Nothing parseInt
|
||||
|
||||
patchesV :: T.Text -> Either Menu.ErrorMessage (Maybe (Either FilePath [URI]))
|
||||
patchesV = whenEmpty Nothing readPatches
|
||||
where
|
||||
where
|
||||
readUri :: T.Text -> Either String URI
|
||||
readUri = first show . parseURI . UTF8.fromString . T.unpack
|
||||
readPatches j =
|
||||
let
|
||||
readUri = first show . parseURI . UTF8.fromString . T.unpack
|
||||
readPatches j =
|
||||
let
|
||||
x = (bimap T.unpack (fmap Left) $ filepathV j)
|
||||
y = second (Just . Right) $ traverse readUri (T.split isSpace j)
|
||||
in first T.pack $ x <|> y
|
||||
|
||||
filepathV :: T.Text -> Either Menu.ErrorMessage (Maybe FilePath)
|
||||
filepathV = whenEmpty Nothing (Right . Just . T.unpack)
|
||||
filepathV i =
|
||||
case not $ emptyEditor i of
|
||||
True -> absolutePathParser (T.unpack i)
|
||||
False -> Right Nothing
|
||||
|
||||
absolutePathParser :: FilePath -> Either Menu.ErrorMessage (Maybe FilePath)
|
||||
absolutePathParser f = case isValid f && isAbsolute f of
|
||||
True -> Right . Just . stripNewlineEnd . normalise $ f
|
||||
False -> Left "Please enter a valid absolute filepath."
|
||||
|
||||
additionalValidator :: T.Text -> Either Menu.ErrorMessage [T.Text]
|
||||
additionalValidator = Right . T.split isSpace
|
||||
|
||||
systemV :: T.Text -> Either Menu.ErrorMessage (Maybe BuildSystem)
|
||||
systemV = whenEmpty Nothing readSys
|
||||
where
|
||||
where
|
||||
readSys i
|
||||
| T.toLower i == "hadrian" = Right $ Just Hadrian
|
||||
| T.toLower i == "make" = Right $ Just Hadrian
|
||||
| T.toLower i == "make" = Right $ Just Make
|
||||
| otherwise = Left "Not a valid Build System"
|
||||
|
||||
fields =
|
||||
fields =
|
||||
[ Menu.createEditableField (Common.MenuElement Common.BootstrapGhcEditBox) bootstrapV bootstrapGhc
|
||||
& Menu.fieldLabelL .~ "bootstrap-ghc"
|
||||
& Menu.fieldHelpMsgL .~ "The GHC version (or full path) to bootstrap with (must be installed)"
|
||||
@@ -149,14 +178,14 @@ create k = Menu.createMenu CompileGHCBox initialState k buttons fields
|
||||
, Menu.createCheckBoxField (Common.MenuElement Common.SetCheckBox) setCompile
|
||||
& Menu.fieldLabelL .~ "set"
|
||||
& Menu.fieldHelpMsgL .~ "Set as active version after install"
|
||||
, Menu.createEditableField (Common.MenuElement Common.OvewrwiteVerEditBox) versionV ovewrwiteVer
|
||||
, Menu.createEditableField (Common.MenuElement Common.OvewrwiteVerEditBox) versionV overwriteVer
|
||||
& Menu.fieldLabelL .~ "overwrite-version"
|
||||
& Menu.fieldHelpMsgL .~ "Allows to overwrite the finally installed VERSION with a different one"
|
||||
, Menu.createEditableField (Common.MenuElement Common.BuildFlavourEditBox) (Right . Just . T.unpack) buildFlavour
|
||||
& Menu.fieldLabelL .~ "flavour"
|
||||
& Menu.fieldHelpMsgL .~ "Set the compile build flavour (this value depends on the build system type: 'make' vs 'hadrian')"
|
||||
, Menu.createEditableField (Common.MenuElement Common.BuildSystemEditBox) systemV buildSystem
|
||||
& Menu.fieldLabelL .~ "build system"
|
||||
& Menu.fieldHelpMsgL .~ "either 'make' or 'hadrian'"
|
||||
, Menu.createEditableField (Common.MenuElement Common.BuildFlavourEditBox) (Right . Just . T.unpack) buildFlavour
|
||||
& Menu.fieldLabelL .~ "flavour"
|
||||
& Menu.fieldHelpMsgL .~ "Set the compile build flavour (this value depends on the build system type: 'make' vs 'hadrian')"
|
||||
, Menu.createEditableField (Common.MenuElement Common.IsolateEditBox) filepathV isolateDir
|
||||
& Menu.fieldLabelL .~ "isolated"
|
||||
@@ -167,6 +196,7 @@ create k = Menu.createMenu CompileGHCBox initialState k buttons fields
|
||||
Menu.createButtonField (Common.MenuElement Common.OkButton)
|
||||
& Menu.fieldLabelL .~ "Compile"
|
||||
& Menu.fieldHelpMsgL .~ "Compile GHC from source with options below"
|
||||
& Menu.fieldStatusL .~ Menu.Invalid "bootstrap GHC is mandatory"
|
||||
]
|
||||
|
||||
handler :: BrickEvent Name e -> EventM Name CompileGHCMenu ()
|
||||
|
||||
191
lib-tui/GHCup/Brick/Widgets/Menus/CompileHLS.hs
Normal file
191
lib-tui/GHCup/Brick/Widgets/Menus/CompileHLS.hs
Normal file
@@ -0,0 +1,191 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
{-# LANGUAGE ViewPatterns #-}
|
||||
{-# OPTIONS_GHC -Wno-unused-record-wildcards #-}
|
||||
{-# OPTIONS_GHC -Wno-unused-matches #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE BangPatterns #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
|
||||
|
||||
module GHCup.Brick.Widgets.Menus.CompileHLS (
|
||||
CompileHLSOptions,
|
||||
CompileHLSMenu,
|
||||
create,
|
||||
handler,
|
||||
draw,
|
||||
jobs,
|
||||
setCompile,
|
||||
updateCabal,
|
||||
overwriteVer,
|
||||
isolateDir,
|
||||
cabalProject,
|
||||
cabalProjectLocal,
|
||||
patches,
|
||||
targetGHCs,
|
||||
cabalArgs,
|
||||
)
|
||||
where
|
||||
|
||||
import GHCup.Brick.Widgets.Menu (Menu)
|
||||
import qualified GHCup.Brick.Widgets.Menu as Menu
|
||||
import GHCup.Brick.Common(Name(..))
|
||||
import Brick
|
||||
( BrickEvent(..),
|
||||
EventM,
|
||||
Widget(..))
|
||||
import Prelude hiding ( appendFile )
|
||||
import Optics.TH (makeLenses)
|
||||
import qualified GHCup.Brick.Common as Common
|
||||
import GHCup.Types (KeyCombination, VersionPattern, ToolVersion)
|
||||
import URI.ByteString (URI)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.ByteString.UTF8 as UTF8
|
||||
import GHCup.Utils (parseURI)
|
||||
import Data.Bifunctor (Bifunctor(..))
|
||||
import Data.Function ((&))
|
||||
import Optics ((.~))
|
||||
import Data.Char (isSpace)
|
||||
import System.FilePath (isValid, isAbsolute, normalise)
|
||||
import Control.Applicative (Alternative((<|>)))
|
||||
import Text.Read (readEither)
|
||||
import GHCup.Prelude (stripNewlineEnd)
|
||||
import qualified GHCup.OptParse.Common as OptParse
|
||||
|
||||
data CompileHLSOptions = CompileHLSOptions
|
||||
{ _jobs :: Maybe Int
|
||||
, _setCompile :: Bool
|
||||
, _updateCabal :: Bool
|
||||
, _overwriteVer :: Maybe [VersionPattern]
|
||||
, _isolateDir :: Maybe FilePath
|
||||
, _cabalProject :: Maybe (Either FilePath URI)
|
||||
, _cabalProjectLocal :: Maybe URI
|
||||
, _patches :: Maybe (Either FilePath [URI])
|
||||
, _targetGHCs :: [ToolVersion]
|
||||
, _cabalArgs :: [T.Text]
|
||||
} deriving (Eq, Show)
|
||||
|
||||
makeLenses ''CompileHLSOptions
|
||||
|
||||
type CompileHLSMenu = Menu CompileHLSOptions Name
|
||||
|
||||
create :: KeyCombination -> CompileHLSMenu
|
||||
create k = Menu.createMenu CompileGHCBox initialState k buttons fields
|
||||
where
|
||||
initialState =
|
||||
CompileHLSOptions
|
||||
Nothing
|
||||
False
|
||||
False
|
||||
Nothing
|
||||
Nothing
|
||||
Nothing
|
||||
Nothing
|
||||
Nothing
|
||||
[]
|
||||
[]
|
||||
-- Brick's internal editor representation is [mempty].
|
||||
emptyEditor i = T.null i || (i == "\n")
|
||||
whenEmpty :: a -> (T.Text -> Either Menu.ErrorMessage a) -> T.Text -> Either Menu.ErrorMessage a
|
||||
whenEmpty emptyval f i = if not (emptyEditor i) then f i else Right emptyval
|
||||
|
||||
cabalProjectV :: T.Text -> Either Menu.ErrorMessage (Maybe (Either FilePath URI))
|
||||
cabalProjectV i =
|
||||
case not $ emptyEditor i of
|
||||
True ->
|
||||
let readPath = Right . Left . stripNewlineEnd . T.unpack $ i
|
||||
in bimap T.pack Just $ second Right (readUri i) <|> readPath
|
||||
False -> Right Nothing
|
||||
|
||||
{- There is an unwanted dependency to ghcup-opt... Alternatives are
|
||||
- copy-paste a bunch of code
|
||||
- define a new common library
|
||||
-}
|
||||
ghcVersionTagEither :: T.Text -> Either Menu.ErrorMessage [ToolVersion]
|
||||
ghcVersionTagEither = first T.pack . traverse (OptParse.ghcVersionTagEither . T.unpack) . T.split isSpace
|
||||
|
||||
overWriteVersionParser :: T.Text -> Either Menu.ErrorMessage (Maybe [VersionPattern])
|
||||
overWriteVersionParser = bimap T.pack Just . OptParse.overWriteVersionParser . T.unpack
|
||||
|
||||
jobsV :: T.Text -> Either Menu.ErrorMessage (Maybe Int)
|
||||
jobsV =
|
||||
let parseInt = bimap (const "Invalid value. Must be an integer") Just . readEither @Int . T.unpack
|
||||
in whenEmpty Nothing parseInt
|
||||
|
||||
readUri :: T.Text -> Either String URI
|
||||
readUri = first show . parseURI . UTF8.fromString . T.unpack
|
||||
|
||||
patchesV :: T.Text -> Either Menu.ErrorMessage (Maybe (Either FilePath [URI]))
|
||||
patchesV = whenEmpty Nothing readPatches
|
||||
where
|
||||
readPatches j =
|
||||
let
|
||||
x = (bimap T.unpack (fmap Left) $ filepathV j)
|
||||
y = second (Just . Right) $ traverse readUri (T.split isSpace j)
|
||||
in first T.pack $ x <|> y
|
||||
|
||||
filepathV :: T.Text -> Either Menu.ErrorMessage (Maybe FilePath)
|
||||
filepathV i =
|
||||
case not $ emptyEditor i of
|
||||
True -> absolutePathParser (T.unpack i)
|
||||
False -> Right Nothing
|
||||
|
||||
absolutePathParser :: FilePath -> Either Menu.ErrorMessage (Maybe FilePath)
|
||||
absolutePathParser f = case isValid f && isAbsolute f of
|
||||
True -> Right . Just . stripNewlineEnd . normalise $ f
|
||||
False -> Left "Please enter a valid absolute filepath."
|
||||
|
||||
additionalValidator :: T.Text -> Either Menu.ErrorMessage [T.Text]
|
||||
additionalValidator = Right . T.split isSpace
|
||||
|
||||
fields =
|
||||
[ Menu.createEditableField (Common.MenuElement Common.CabalProjectEditBox) cabalProjectV cabalProject
|
||||
& Menu.fieldLabelL .~ "cabal project"
|
||||
& Menu.fieldHelpMsgL .~ "If relative filepath, specifies the path to cabal.project inside the unpacked HLS tarball/checkout. Otherwise expects a full URI with https/http/file scheme."
|
||||
, Menu.createEditableField (Common.MenuElement Common.CabalProjectLocalEditBox) (bimap T.pack Just . readUri) cabalProjectLocal
|
||||
& Menu.fieldLabelL .~ "cabal project local"
|
||||
& Menu.fieldHelpMsgL .~ "URI (https/http/file) to a cabal.project.local to be used for the build. Will be copied over."
|
||||
, Menu.createCheckBoxField (Common.MenuElement Common.UpdateCabalCheckBox) updateCabal
|
||||
& Menu.fieldLabelL .~ "cabal update"
|
||||
& Menu.fieldHelpMsgL .~ "Run 'cabal update' before the build"
|
||||
, Menu.createEditableField (Common.MenuElement Common.JobsEditBox) jobsV jobs
|
||||
& Menu.fieldLabelL .~ "jobs"
|
||||
& Menu.fieldHelpMsgL .~ "How many jobs to use for make"
|
||||
, Menu.createEditableField (Common.MenuElement Common.TargetGhcEditBox) ghcVersionTagEither targetGHCs
|
||||
& Menu.fieldLabelL .~ "target GHC"
|
||||
& Menu.fieldHelpMsgL .~ "For which GHC version to compile for (can be specified multiple times)"
|
||||
, Menu.createEditableField (Common.MenuElement Common.PatchesEditBox) patchesV patches
|
||||
& Menu.fieldLabelL .~ "patches"
|
||||
& Menu.fieldHelpMsgL .~ "Either a URI to a patch (https/http/file) or Absolute path to patch directory"
|
||||
, Menu.createCheckBoxField (Common.MenuElement Common.SetCheckBox) setCompile
|
||||
& Menu.fieldLabelL .~ "set"
|
||||
& Menu.fieldHelpMsgL .~ "Set as active version after install"
|
||||
, Menu.createEditableField (Common.MenuElement Common.AdditionalEditBox) additionalValidator cabalArgs
|
||||
& Menu.fieldLabelL .~ "CONFIGURE_ARGS"
|
||||
& Menu.fieldHelpMsgL .~ "Additional arguments to cabal install, prefix with '-- ' (longopts)"
|
||||
, Menu.createEditableField (Common.MenuElement Common.IsolateEditBox) filepathV isolateDir
|
||||
& Menu.fieldLabelL .~ "isolated"
|
||||
& Menu.fieldHelpMsgL .~ "install in an isolated absolute directory instead of the default one"
|
||||
, Menu.createEditableField (Common.MenuElement Common.OvewrwiteVerEditBox) overWriteVersionParser overwriteVer
|
||||
& Menu.fieldLabelL .~ "overwrite version"
|
||||
& Menu.fieldHelpMsgL .~ "Allows to overwrite the finally installed VERSION with a different one"
|
||||
]
|
||||
|
||||
buttons = [
|
||||
Menu.createButtonField (Common.MenuElement Common.OkButton)
|
||||
& Menu.fieldLabelL .~ "Compile"
|
||||
& Menu.fieldHelpMsgL .~ "Compile HLS from source with options below"
|
||||
]
|
||||
|
||||
handler :: BrickEvent Name e -> EventM Name CompileHLSMenu ()
|
||||
handler = Menu.handlerMenu
|
||||
|
||||
|
||||
draw :: CompileHLSMenu -> Widget Name
|
||||
draw = Common.frontwardLayer "Compile HLS" . Menu.drawMenu
|
||||
@@ -35,25 +35,29 @@ create lr exit_key = Menu.createMenu Common.ContextBox lr exit_key buttons []
|
||||
Menu.createButtonField (MenuElement Common.AdvanceInstallButton)
|
||||
& Menu.fieldLabelL .~ "Install"
|
||||
& Menu.fieldHelpMsgL .~ "Advance Installation Settings"
|
||||
compileButton =
|
||||
Menu.createButtonField (MenuElement Common.CompilieButton)
|
||||
compileGhcButton =
|
||||
Menu.createButtonField (MenuElement Common.CompileGHCButton)
|
||||
& Menu.fieldLabelL .~ "Compile"
|
||||
& Menu.fieldHelpMsgL .~ "Compile tool from source"
|
||||
& Menu.fieldHelpMsgL .~ "Compile GHC from source"
|
||||
compileHLSButton =
|
||||
Menu.createButtonField (MenuElement Common.CompileHLSButton)
|
||||
& Menu.fieldLabelL .~ "Compile"
|
||||
& Menu.fieldHelpMsgL .~ "Compile HLS from source"
|
||||
buttons =
|
||||
case lTool lr of
|
||||
GHC -> [advInstallButton, compileButton]
|
||||
HLS -> [advInstallButton, compileButton]
|
||||
GHC -> [advInstallButton, compileGhcButton]
|
||||
HLS -> [advInstallButton, compileHLSButton]
|
||||
_ -> [advInstallButton]
|
||||
|
||||
draw :: ContextMenu -> Widget Name
|
||||
draw menu =
|
||||
draw menu =
|
||||
Common.frontwardLayer
|
||||
("Context Menu for " <> tool_str <> " " <> prettyVer (lVer $ menu ^. Menu.menuStateL))
|
||||
$ Brick.vBox
|
||||
[ Brick.vBox buttonWidgets
|
||||
, Brick.txt " "
|
||||
, Brick.padRight Brick.Max $
|
||||
Brick.txt "Press "
|
||||
, Brick.padRight Brick.Max $
|
||||
Brick.txt "Press "
|
||||
<+> Common.keyToWidget (menu ^. Menu.menuExitKeyL)
|
||||
<+> Brick.txt " to go back"
|
||||
]
|
||||
|
||||
@@ -36,6 +36,8 @@ import Brick
|
||||
(<+>),
|
||||
(<=>))
|
||||
import qualified Brick
|
||||
import Brick.Widgets.Core ( putCursor )
|
||||
import Brick.Types ( Location(..) )
|
||||
import Brick.Widgets.Border ( hBorder, borderWithLabel)
|
||||
import Brick.Widgets.Border.Style ( unicode )
|
||||
import Brick.Widgets.Center ( center )
|
||||
@@ -54,7 +56,7 @@ type BrickInternalState = SectionList.SectionList Common.Name ListResult
|
||||
-- | How to create a navigation widget
|
||||
create :: Common.Name -- The name of the section list
|
||||
-> [(Common.Name, Vector ListResult)] -- a list of tuples (section name, collection of elements)
|
||||
-> Int -- The height of each item in a list. Commonly 1
|
||||
-> Int -- The height of each item in a list. Commonly 1
|
||||
-> BrickInternalState
|
||||
create = SectionList.sectionList
|
||||
|
||||
@@ -100,7 +102,8 @@ draw dimAttrs section_list
|
||||
| elem Latest lTag' && not lInstalled =
|
||||
Brick.withAttr Attributes.hoorayAttr
|
||||
| otherwise = id
|
||||
in hooray $ dim
|
||||
active = if b then putCursor Common.AllTools (Location (0,0)) else id
|
||||
in hooray $ active $ dim
|
||||
( marks
|
||||
<+> Brick.padLeft (Pad 2)
|
||||
( minHSize 6
|
||||
@@ -145,4 +148,4 @@ draw dimAttrs section_list
|
||||
Nothing -> mempty
|
||||
Just d -> [Brick.withAttr Attributes.dayAttr $ Brick.str (show d)])
|
||||
|
||||
minHSize s' = Brick.hLimit s' . Brick.vLimit 1 . (<+> Brick.fill ' ')
|
||||
minHSize s' = Brick.hLimit s' . Brick.vLimit 1 . (<+> Brick.fill ' ')
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
{- A general system for lists with sections
|
||||
|
||||
Consider this code as private. GenericSectionList should not be used directly as the FocusRing should be align with the Vector containing
|
||||
the elements, otherwise you'd be focusing on a non-existent widget with unknown result (In theory the code is safe unless you have an empty section list).
|
||||
Consider this code as private. GenericSectionList should not be used directly as the FocusRing should be align with the Vector containing
|
||||
the elements, otherwise you'd be focusing on a non-existent widget with unknown result (In theory the code is safe unless you have an empty section list).
|
||||
|
||||
- To build a SectionList use the safe constructor sectionList
|
||||
- To access sections use the lens provider sectionL and the name of the section you'd like to access
|
||||
@@ -33,7 +33,7 @@ import Brick
|
||||
( BrickEvent(VtyEvent, MouseDown),
|
||||
EventM,
|
||||
Size(..),
|
||||
Widget(..),
|
||||
Widget(..),
|
||||
ViewportType (Vertical),
|
||||
(<=>))
|
||||
import qualified Brick
|
||||
@@ -68,8 +68,8 @@ makeLensesFor [("sectionListFocusRing", "sectionListFocusRingL"), ("sectionListE
|
||||
type SectionList n e = GenericSectionList n V.Vector e
|
||||
|
||||
|
||||
-- | Build a SectionList from nonempty list. If empty we could not defined sectionL lenses.
|
||||
sectionList :: Foldable t
|
||||
-- | Build a SectionList from nonempty list. If empty we could not defined sectionL lenses.
|
||||
sectionList :: Foldable t
|
||||
=> n -- The name of the section list
|
||||
-> [(n, t e)] -- a list of tuples (section name, collection of elements)
|
||||
-> Int
|
||||
@@ -81,14 +81,14 @@ sectionList name elements height
|
||||
, sectionListName = name
|
||||
}
|
||||
-- | This lens constructor, takes a name and looks if a section has such a name.
|
||||
-- Used to dispatch events to sections. It is a partial function only meant to
|
||||
-- Used to dispatch events to sections. It is a partial function only meant to
|
||||
-- be used with the FocusRing inside GenericSectionList
|
||||
sectionL :: Eq n => n -> Lens' (GenericSectionList n t e) (L.GenericList n t e)
|
||||
sectionL section_name = lens g s
|
||||
where is_section_name = (== section_name) . L.listName
|
||||
g section_list =
|
||||
let elms = section_list ^. sectionListElementsL
|
||||
zeroth = elms V.! 0 -- TODO: This crashes for empty vectors.
|
||||
zeroth = elms V.! 0 -- TODO: This crashes for empty vectors.
|
||||
in fromMaybe zeroth (V.find is_section_name elms)
|
||||
s gl@(GenericSectionList _ elms _) list =
|
||||
case V.findIndex is_section_name elms of
|
||||
@@ -97,16 +97,16 @@ sectionL section_name = lens g s
|
||||
in gl & sectionListElementsL .~ new_elms
|
||||
|
||||
moveDown :: (L.Splittable t, Ord n, Foldable t) => EventM n (GenericSectionList n t e) ()
|
||||
moveDown = do
|
||||
moveDown = do
|
||||
ring <- use sectionListFocusRingL
|
||||
case F.focusGetCurrent ring of
|
||||
case F.focusGetCurrent ring of
|
||||
Nothing -> pure ()
|
||||
Just l -> do -- If it is the last element, move to the first element of the next focus; else, just handle regular list event.
|
||||
current_list <- use (sectionL l)
|
||||
let current_idx = L.listSelected current_list
|
||||
list_length = current_list & length
|
||||
if current_idx == Just (list_length - 1)
|
||||
then do
|
||||
then do
|
||||
new_focus <- sectionListFocusRingL <%= F.focusNext
|
||||
case F.focusGetCurrent new_focus of
|
||||
Nothing -> pure () -- |- Optic.Zoom.zoom doesn't typecheck but Lens.Micro.Mtl.zoom does. It is re-exported by Brick
|
||||
@@ -122,10 +122,10 @@ moveUp = do
|
||||
current_list <- use (sectionL l)
|
||||
let current_idx = L.listSelected current_list
|
||||
if current_idx == Just 0
|
||||
then do
|
||||
then do
|
||||
new_focus <- sectionListFocusRingL <%= F.focusPrev
|
||||
case F.focusGetCurrent new_focus of
|
||||
Nothing -> pure ()
|
||||
Nothing -> pure ()
|
||||
Just new_l -> Common.zoom (sectionL new_l) (Brick.modify L.listMoveToEnd)
|
||||
else Common.zoom (sectionL l) $ Brick.modify L.listMoveUp
|
||||
|
||||
@@ -188,6 +188,6 @@ renderSectionList renderElem sectionFocus ge@(GenericSectionList focus elms slNa
|
||||
-- | Equivalent to listSelectedElement
|
||||
sectionListSelectedElement :: (Eq n, L.Splittable t, Traversable t, Semigroup (t e)) => GenericSectionList n t e -> Maybe (Int, e)
|
||||
sectionListSelectedElement generic_section_list = do
|
||||
current_focus <- generic_section_list ^. sectionListFocusRingL & F.focusGetCurrent
|
||||
current_focus <- generic_section_list ^. sectionListFocusRingL & F.focusGetCurrent
|
||||
let current_section = generic_section_list ^. sectionL current_focus
|
||||
L.listSelectedElement current_section
|
||||
L.listSelectedElement current_section
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
|
||||
{-
|
||||
A very simple information-only widget with no handler.
|
||||
A very simple information-only widget with no handler.
|
||||
-}
|
||||
|
||||
module GHCup.Brick.Widgets.Tutorial (draw) where
|
||||
@@ -74,4 +74,4 @@ draw =
|
||||
]
|
||||
, Brick.txt " "
|
||||
])
|
||||
<=> Brick.padRight Brick.Max (Brick.txt "Press q to exit the tutorial")
|
||||
<=> Brick.padRight Brick.Max (Brick.txt "Press c+ctrl to exit the tutorial")
|
||||
|
||||
@@ -17,7 +17,7 @@ module GHCup.BrickMain where
|
||||
|
||||
import GHCup.Types
|
||||
( Settings(noColor),
|
||||
AppState(ghcupInfo, settings, keyBindings, loggerConfig), KeyBindings (..) )
|
||||
AppState(ghcupInfo, settings, keyBindings, loggerConfig), KeyBindings (..), KeyCombination (KeyCombination) )
|
||||
import GHCup.Prelude.Logger ( logError )
|
||||
import qualified GHCup.Brick.Actions as Actions
|
||||
import qualified GHCup.Brick.Common as Common
|
||||
@@ -29,6 +29,7 @@ import qualified GHCup.Brick.Widgets.SectionList as Navigation
|
||||
import qualified GHCup.Brick.Widgets.Menus.AdvanceInstall as AdvanceInstall
|
||||
import qualified GHCup.Brick.Widgets.Menus.CompileGHC as CompileGHC
|
||||
import qualified Brick
|
||||
import qualified Graphics.Vty as Vty
|
||||
|
||||
import Control.Monad.Reader ( ReaderT(runReaderT) )
|
||||
import Data.Functor ( ($>) )
|
||||
@@ -37,6 +38,7 @@ import Prelude hiding ( appendFile )
|
||||
import System.Exit ( ExitCode(ExitFailure), exitWith )
|
||||
|
||||
import qualified Data.Text as T
|
||||
import qualified GHCup.Brick.Widgets.Menus.CompileHLS as CompileHLS
|
||||
|
||||
|
||||
|
||||
@@ -50,14 +52,14 @@ brickMain s = do
|
||||
Right ad -> do
|
||||
let initial_list = Actions.constructList ad Common.defaultAppSettings Nothing
|
||||
current_element = Navigation.sectionListSelectedElement initial_list
|
||||
exit_key = bQuit . keyBindings $ s
|
||||
exit_key = KeyCombination (Vty.KChar 'c') [Vty.MCtrl] -- bQuit . keyBindings $ s
|
||||
case current_element of
|
||||
Nothing -> do
|
||||
flip runReaderT s $ logError "Error building app state: empty ResultList"
|
||||
flip runReaderT s $ logError "Error building app state: empty ResultList"
|
||||
exitWith $ ExitFailure 2
|
||||
Just (_, e) ->
|
||||
let initapp =
|
||||
BrickApp.app
|
||||
let initapp =
|
||||
BrickApp.app
|
||||
(Attributes.defaultAttributes $ noColor $ settings s)
|
||||
(Attributes.dimAttributes $ noColor $ settings s)
|
||||
initstate =
|
||||
@@ -65,11 +67,12 @@ brickMain s = do
|
||||
Common.defaultAppSettings
|
||||
initial_list
|
||||
(ContextMenu.create e exit_key)
|
||||
(AdvanceInstall.create (bQuit . keyBindings $ s ))
|
||||
(AdvanceInstall.create exit_key)
|
||||
(CompileGHC.create exit_key)
|
||||
(CompileHLS.create exit_key)
|
||||
(keyBindings s)
|
||||
Common.Navigation
|
||||
in Brick.defaultMain initapp initstate
|
||||
in Brick.defaultMain initapp initstate
|
||||
$> ()
|
||||
Left e -> do
|
||||
flip runReaderT s $ logError $ "Error building app state: " <> T.pack (show e)
|
||||
|
||||
64
lib/GHCup.hs
64
lib/GHCup.hs
@@ -273,7 +273,6 @@ getDebugInfo = do
|
||||
--[ GHCup upgrade etc ]--
|
||||
-------------------------
|
||||
|
||||
|
||||
-- | Upgrade ghcup and place it in @~\/.ghcup\/bin\/ghcup@,
|
||||
-- if no path is provided.
|
||||
upgradeGHCup :: ( MonadMask m
|
||||
@@ -308,11 +307,48 @@ upgradeGHCup :: ( MonadMask m
|
||||
m
|
||||
Version
|
||||
upgradeGHCup mtarget force' fatal = do
|
||||
Dirs {..} <- lift getDirs
|
||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||
|
||||
lift $ logInfo "Upgrading GHCup..."
|
||||
let latestVer = _tvVersion $ fst (fromJust (getLatest dls GHCup))
|
||||
upgradeGHCup' mtarget force' fatal latestVer
|
||||
|
||||
|
||||
-- | Upgrade ghcup and place it in @~\/.ghcup\/bin\/ghcup@,
|
||||
-- if no path is provided.
|
||||
upgradeGHCup' :: ( MonadMask m
|
||||
, MonadReader env m
|
||||
, HasDirs env
|
||||
, HasPlatformReq env
|
||||
, HasGHCupInfo env
|
||||
, HasSettings env
|
||||
, MonadCatch m
|
||||
, HasLog env
|
||||
, MonadThrow m
|
||||
, MonadFail m
|
||||
, MonadResource m
|
||||
, MonadIO m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Maybe FilePath -- ^ full file destination to write ghcup into
|
||||
-> Bool -- ^ whether to force update regardless
|
||||
-- of currently installed version
|
||||
-> Bool -- ^ whether to throw an error if ghcup is shadowed
|
||||
-> Version
|
||||
-> Excepts
|
||||
'[ CopyError
|
||||
, DigestError
|
||||
, ContentLengthError
|
||||
, GPGError
|
||||
, GPGError
|
||||
, DownloadFailed
|
||||
, NoDownload
|
||||
, NoUpdate
|
||||
, ToolShadowed
|
||||
]
|
||||
m
|
||||
Version
|
||||
upgradeGHCup' mtarget force' fatal latestVer = do
|
||||
Dirs {..} <- lift getDirs
|
||||
lift $ logInfo "Upgrading GHCup..."
|
||||
(Just ghcupPVPVer) <- pure $ pvpToVersion ghcUpVer ""
|
||||
when (not force' && (latestVer <= ghcupPVPVer)) $ throwE NoUpdate
|
||||
dli <- liftE $ getDownloadInfo GHCup latestVer
|
||||
@@ -506,6 +542,26 @@ rmOldGHC = do
|
||||
forM_ ghcs $ \ghc -> when (ghc `elem` oldGHCs) $ rmGHCVer ghc
|
||||
|
||||
|
||||
rmUnsetTools :: ( MonadReader env m
|
||||
, HasGHCupInfo env
|
||||
, HasPlatformReq env
|
||||
, HasDirs env
|
||||
, HasLog env
|
||||
, MonadIO m
|
||||
, MonadFail m
|
||||
, MonadMask m
|
||||
, MonadUnliftIO m
|
||||
)
|
||||
=> Excepts '[NotInstalled, UninstallFailed] m ()
|
||||
rmUnsetTools = do
|
||||
vers <- lift $ listVersions Nothing [ListInstalled True, ListSet False] False True (Nothing, Nothing)
|
||||
forM_ vers $ \ListResult{..} -> case lTool of
|
||||
GHC -> liftE $ rmGHCVer (GHCTargetVersion lCross lVer)
|
||||
HLS -> liftE $ rmHLSVer lVer
|
||||
Cabal -> liftE $ rmCabalVer lVer
|
||||
Stack -> liftE $ rmStackVer lVer
|
||||
GHCup -> pure ()
|
||||
|
||||
|
||||
rmProfilingLibs :: ( MonadReader env m
|
||||
, HasDirs env
|
||||
|
||||
@@ -177,7 +177,7 @@ getDownloadsF pfreq@(PlatformRequest arch plat _) = do
|
||||
where
|
||||
fromDownloadInfo :: DownloadInfo -> VersionInfo
|
||||
fromDownloadInfo dli = let aspec = M.singleton arch (M.singleton plat (M.singleton Nothing dli))
|
||||
in VersionInfo [] Nothing Nothing Nothing Nothing aspec Nothing Nothing Nothing
|
||||
in VersionInfo [] Nothing Nothing Nothing Nothing aspec Nothing Nothing Nothing Nothing
|
||||
|
||||
fromStackDownloadInfo :: MonadThrow m => Stack.GHCDownloadInfo -> m DownloadInfo
|
||||
fromStackDownloadInfo (Stack.GHCDownloadInfo { gdiDownloadInfo = Stack.DownloadInfo{..} }) = do
|
||||
|
||||
@@ -149,6 +149,7 @@ data VersionInfo = VersionInfo
|
||||
, _viTestDL :: Maybe DownloadInfo -- ^ test tarball
|
||||
, _viArch :: ArchitectureSpec -- ^ descend for binary downloads per arch
|
||||
-- informative messages
|
||||
, _viPreInstall :: Maybe Text
|
||||
, _viPostInstall :: Maybe Text
|
||||
, _viPostRemove :: Maybe Text
|
||||
, _viPreCompile :: Maybe Text
|
||||
|
||||
@@ -39,7 +39,7 @@ die() {
|
||||
|
||||
plat="$(uname -s)"
|
||||
arch=$(uname -m)
|
||||
ghver="0.1.20.0"
|
||||
ghver="0.1.22.0"
|
||||
: "${GHCUP_BASE_URL:=https://downloads.haskell.org/~ghcup}"
|
||||
|
||||
export GHCUP_SKIP_UPDATE_CHECK=yes
|
||||
|
||||
@@ -37,7 +37,7 @@ extra-deps:
|
||||
- vty-6.2@sha256:3536dc83a3fee17d9a114baf58fe47b6f080c24987266f0cd0b7b4b1fcd9cf19,3520
|
||||
- vty-crossplatform-0.4.0.0@sha256:50593f91ad16777d921138475a8d2784d538fd206addd30664c620278d6c8544,3172
|
||||
- vty-unix-0.2.0.0@sha256:2af3d0bdae3c4b7b7e567ee374efe32c7439fabdf9096465ce011a6c6736e9ae,2932
|
||||
- vty-windows-0.2.0.1@sha256:6c75230057a708168dbc420975572511ad3ec09956bf73c3b6f4be03324e8b13,2815
|
||||
- vty-windows-0.2.0.2
|
||||
- yaml-streamly-0.12.4@sha256:b5250c5dc71d668c43c42ed6f86f956d69125136ea960858527a4b2ff712d3d1,5165
|
||||
- github: hasufell/uri-bytestring
|
||||
commit: 4fb5ed14b500c192e6e7a97f6b2b1eb478806001
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@ defaultOptions =
|
||||
False
|
||||
False
|
||||
False
|
||||
False
|
||||
|
||||
gcCheckList :: [(String, GCOptions)]
|
||||
gcCheckList =
|
||||
@@ -33,7 +34,9 @@ gcCheckList =
|
||||
, ("gc --cache", defaultOptions{gcCache = True})
|
||||
, ("gc -t", defaultOptions{gcTmp = True})
|
||||
, ("gc --tmpdirs", defaultOptions{gcTmp = True})
|
||||
, ("gc -o -p -s -h -c -t", GCOptions True True True True True True)
|
||||
, ("gc -u", defaultOptions{gcUnset = True})
|
||||
, ("gc --unset", defaultOptions{gcUnset = True})
|
||||
, ("gc -o -p -s -h -c -t -u", GCOptions True True True True True True True)
|
||||
]
|
||||
|
||||
gcParseWith :: [String] -> IO GCOptions
|
||||
|
||||
Reference in New Issue
Block a user