Compare commits
489 Commits
improve-co
...
v0.1.19.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
432962792c
|
|||
|
cb193f6069
|
|||
|
2f268b6a25
|
|||
|
580606af14
|
|||
|
faa1c3992b
|
|||
|
d17efef853
|
|||
|
179d4dd493
|
|||
|
e03c5ee4a1
|
|||
|
e57a8abd3d
|
|||
|
5fa10390a3
|
|||
|
e1e6f579d5
|
|||
|
72f8e53344
|
|||
|
9c464ec9fc
|
|||
|
1c9b296a5e
|
|||
|
|
275522584e | ||
|
|
804520c4bb | ||
|
|
9d25581f3c | ||
|
|
e798037d80 | ||
|
|
2afe5858cb | ||
|
f575dcdad6
|
|||
|
6cf9967e7c
|
|||
|
15a75d790a
|
|||
|
988672ea75
|
|||
|
6d3e8d65e1
|
|||
|
895e4b3f18
|
|||
|
20f0505120
|
|||
|
31e83cac5e
|
|||
|
|
9baba88f75 | ||
|
d3a1115b99
|
|||
|
6d46849fec
|
|||
|
53e324bfee
|
|||
|
2e39b7b603
|
|||
|
048932bf50
|
|||
|
69d325bf90
|
|||
|
3d1b8859cd
|
|||
|
db89ca9942
|
|||
|
bba009d98c
|
|||
|
9d954ea174
|
|||
|
da9c9049d2
|
|||
|
a4c00d2c56
|
|||
|
|
b30f565871 | ||
|
|
fa378a1d34 | ||
|
|
119efb1ff4 | ||
|
1fb4101b49
|
|||
|
ec8333b223
|
|||
|
54b979aa0b
|
|||
|
ba274307c0
|
|||
|
|
a623d0809d | ||
|
e00899d176
|
|||
|
a38ca1954b
|
|||
|
3f5a19c63e
|
|||
|
525e9672e8
|
|||
|
070c6e1cf1
|
|||
|
195fd00e0a
|
|||
|
733d014c19
|
|||
|
16039769d5
|
|||
|
5eeb8ca9fc
|
|||
|
317a06bbc3
|
|||
|
f693adcd7c
|
|||
|
ac88d2bd50
|
|||
|
a427146de5
|
|||
|
a16bcddeaa
|
|||
|
74edf1fc07
|
|||
|
1e32639873
|
|||
|
0704d2640a
|
|||
|
26a6368d79
|
|||
|
54af66d115
|
|||
|
850799c21a
|
|||
| d4834d7541 | |||
|
2895dd9d13
|
|||
|
eb9a0b66c4
|
|||
|
8d0432b961
|
|||
|
ab2c01d1c9
|
|||
|
fffaa65b7f
|
|||
|
703be0a706
|
|||
|
4be97ffd7c
|
|||
|
009f9211a9
|
|||
|
109187eb6f
|
|||
|
e881705323
|
|||
|
ea06c155a7
|
|||
|
d4732e15a7
|
|||
|
db6f784a1f
|
|||
|
82e3837dd9
|
|||
|
957c5918b8
|
|||
|
9d4c923649
|
|||
|
24c36ef856
|
|||
|
2783b8f693
|
|||
|
d5a680e3c6
|
|||
|
d1075987de
|
|||
|
e116a2392e
|
|||
|
7dd6f1f4a4
|
|||
|
4d82c37539
|
|||
|
801b1edfa7
|
|||
|
c1b67e1787
|
|||
|
70dd106549
|
|||
|
b098aa4e65
|
|||
|
74b784fcfb
|
|||
|
673db344d6
|
|||
|
5594a19c02
|
|||
|
|
a5bc13fe50 | ||
|
a5f2067d76
|
|||
|
be8fa57be1
|
|||
|
6ad9963889
|
|||
|
bcddb05b1d
|
|||
|
f7d2033e25
|
|||
|
6ce7649cfe
|
|||
|
cb0d8b80c3
|
|||
|
95869f9560
|
|||
|
e8586cf993
|
|||
|
d195a3f86c
|
|||
|
b171afa09d
|
|||
|
5cf49bffac
|
|||
|
5659de8516
|
|||
|
0cd2b6d549
|
|||
|
ae092de4b6
|
|||
|
a7e6e7c27d
|
|||
|
175a301a0d
|
|||
|
823458910b
|
|||
|
2abcb46199
|
|||
|
75b891147a
|
|||
|
de208f004e
|
|||
|
ecb0676fea
|
|||
|
957867ff1c
|
|||
|
b1b21f000d
|
|||
|
fbbafc33be
|
|||
|
4a46de4c49
|
|||
|
77419ea41d
|
|||
|
043500e8e8
|
|||
|
e924ad8278
|
|||
|
010db93b93
|
|||
|
9fdc6eebe8
|
|||
|
7c8d013b6e
|
|||
|
96eb0c3532
|
|||
|
94c01ee362
|
|||
|
4297a46f13
|
|||
|
c07e1bbc8f
|
|||
|
9ee2df3841
|
|||
|
3c5505d222
|
|||
|
|
70df740f9d | ||
|
|
761f3253c3 | ||
|
787edc17af
|
|||
|
9902adab6d
|
|||
|
156b4724f3
|
|||
|
e9575aba5c
|
|||
|
81c7f6a32a
|
|||
|
|
ab97c80b80 | ||
|
|
04369673ef | ||
|
|
63dfdc2da6 | ||
|
14de382129
|
|||
|
d97c10dbe6
|
|||
|
|
8420bf093e | ||
|
|
5e28074522 | ||
|
c842c41a78
|
|||
|
8b93eaad59
|
|||
|
2cba97cf1c
|
|||
|
7d74178295
|
|||
|
c37bef55e9
|
|||
|
837ba8b46a
|
|||
|
|
c25e73408a | ||
|
|
71c3172cf5 | ||
|
|
1f2855a107 | ||
|
|
d949c4375e | ||
|
|
22f0081303 | ||
|
5562be18e3
|
|||
|
6baa891424
|
|||
|
a544feffb3
|
|||
|
3b6bb0df46
|
|||
|
60299b6bb8
|
|||
|
4d20f4e07c
|
|||
|
5f6b5f845d
|
|||
|
b0fecce0d1
|
|||
|
|
27c06ddde7 | ||
|
3154d2839b
|
|||
|
|
511d8d5ed8 | ||
|
fe22405ee1
|
|||
|
ea828cd13a
|
|||
|
00fa70b9de
|
|||
|
823275363c
|
|||
|
2f299ee48d
|
|||
|
284fe1b3b6
|
|||
|
35bda8d67a
|
|||
|
7a2a5074fa
|
|||
|
ce239ab88e
|
|||
|
f3c703d655
|
|||
|
b6ff5bc764
|
|||
|
b8aeb1f935
|
|||
|
9673d28d3e
|
|||
|
99a51d67a1
|
|||
|
b0ef0590a2
|
|||
|
256e1942f2
|
|||
|
aa71f0dfa1
|
|||
|
04d527c98a
|
|||
|
|
ca5c5550ab | ||
|
7b59621179
|
|||
|
9d59463ded
|
|||
|
|
3d49f79beb | ||
|
|
e9740d13fc | ||
|
|
2bd5a8fe1a | ||
|
|
0acccae523 | ||
|
974112016e
|
|||
|
9fb2889696
|
|||
|
63f22b28d7
|
|||
|
9a72fa13d5
|
|||
|
86a8a32032
|
|||
|
13e01ab453
|
|||
|
873dd77a6f
|
|||
|
544c618473
|
|||
|
a264cb088e
|
|||
|
1a43fddca9
|
|||
|
|
9ceb66ef21 | ||
|
|
7cbe38b011 | ||
|
|
3bbc1edb19 | ||
|
|
b8dac2d7cd | ||
|
bdfb1a3a9b
|
|||
|
9b8b3e8126
|
|||
|
d657c17df4
|
|||
|
|
0e1fd68d93 | ||
|
|
c7eceb2330 | ||
|
|
e143c06697 | ||
|
|
29da21f5dc | ||
|
028696d4be
|
|||
|
4022edb12e
|
|||
|
fde5044194
|
|||
|
3af1286ab7
|
|||
|
bcff46d3d4
|
|||
|
d1c72cdff4
|
|||
|
565bb59f45
|
|||
|
aae3f31c50
|
|||
|
0ce9b5d352
|
|||
|
bf0e5b37ca
|
|||
|
fe620835be
|
|||
|
c7dc77e6bc
|
|||
|
05c72a3de6
|
|||
|
0653844931
|
|||
|
7661046bcb
|
|||
|
16888a12d4
|
|||
|
9f7df33692
|
|||
|
b7007aa100
|
|||
|
03dfd0cba0
|
|||
|
0e64d1f22f
|
|||
|
c7774450bf
|
|||
|
9375255452
|
|||
|
b8b3a16589
|
|||
|
e1d86c77d0
|
|||
|
001d33eabb
|
|||
|
2845425099
|
|||
|
c56b9ec3ce
|
|||
|
68c81577a4
|
|||
|
b5fb8772fe
|
|||
|
5741e069ad
|
|||
|
df89ddcdf5
|
|||
|
c9e1261af2
|
|||
|
d5efc86d85
|
|||
|
430b655785
|
|||
|
1cffa358b8
|
|||
|
ca89112a8e
|
|||
|
65f02a5a7a
|
|||
|
9ccf29903e
|
|||
|
e4b8c9748a
|
|||
|
3318c30cee
|
|||
|
b9aba98cd5
|
|||
|
55fdc41137
|
|||
|
c9790e5823
|
|||
|
fa924eac15
|
|||
|
db4e411dfd
|
|||
|
48aee1e76c
|
|||
|
2a2ace603b
|
|||
|
25f9ac71ca
|
|||
|
61e2801838
|
|||
|
e60b8ee238
|
|||
|
dc0ea5a59c
|
|||
|
10e704cd73
|
|||
|
8004cc0537
|
|||
|
0a2373f407
|
|||
|
96f87eaf5f
|
|||
|
e9bd687b8f
|
|||
|
3ffa38cf98
|
|||
|
a770c4bcca
|
|||
|
f648a6e698
|
|||
|
a72a12b96d
|
|||
|
591c54b5f7
|
|||
|
a6a54f34cf
|
|||
|
f7811961b5
|
|||
|
ee778e1177
|
|||
|
5787a662ed
|
|||
|
fce654f3c7
|
|||
|
0f052c3465
|
|||
|
c733810fdc
|
|||
|
5130cb013b
|
|||
|
991e540c11
|
|||
|
a34d9b7b89
|
|||
|
4e62f559fa
|
|||
|
8c3d2b6740
|
|||
|
b6779f4d75
|
|||
|
b036c9861f
|
|||
|
02cd773c2a
|
|||
|
3964d06f5d
|
|||
|
|
e83612a06c | ||
|
cf6c666b59
|
|||
|
ee0ec370c7
|
|||
|
ea0e35ddf0
|
|||
|
99c8501d47
|
|||
|
f8a1fed1f2
|
|||
|
9ad1f7cb97
|
|||
|
0856a96738
|
|||
|
ee9801a8c2
|
|||
|
cfecc11b43
|
|||
|
3d36348563
|
|||
|
dcbee9c7dc
|
|||
|
2d88b1197e
|
|||
|
6c12dc0d6f
|
|||
|
a4b69f29dc
|
|||
|
1680c5c448
|
|||
|
e74fb45680
|
|||
|
d19ab05a11
|
|||
|
433c73b23c
|
|||
|
2aa5211886
|
|||
|
81e7c02807
|
|||
|
a2373f2056
|
|||
|
ba8e4f6ac6
|
|||
|
76acc9a5f5
|
|||
|
92bd333552
|
|||
|
70a451b63e
|
|||
|
cfe6c47cd7
|
|||
|
8eeb32c495
|
|||
|
fdcd6822c4
|
|||
|
71390c84da
|
|||
|
84d01b1091
|
|||
|
8f9faaa39e
|
|||
|
0898244b2a
|
|||
|
0c70feb09c
|
|||
|
f9a38e616d
|
|||
|
e511fc3c0a
|
|||
|
3ff670134c
|
|||
|
4c0160bb28
|
|||
|
c1e0baedd3
|
|||
|
8f7d937e26
|
|||
|
604a6fc92b
|
|||
|
8c205fd18c
|
|||
|
41ecf897fb
|
|||
|
4c9c6e9223
|
|||
|
8be71c4c5c
|
|||
|
01d310e630
|
|||
|
96cb99e1b5
|
|||
|
2e08efeed7
|
|||
|
04fceb3134
|
|||
|
1f0a891bab
|
|||
|
6c63a65983
|
|||
|
199d3b7aee
|
|||
|
04fc04f586
|
|||
|
3f96a6460a
|
|||
|
bfcaa7f6fb
|
|||
|
e2bd4c4880
|
|||
|
ab702bba9b
|
|||
|
8afabf3ffb
|
|||
|
ebf6c60a10
|
|||
|
9a8291d391
|
|||
|
a6426901c5
|
|||
|
3b7dd36aa6
|
|||
|
dc635a6601
|
|||
|
08ec1bd923
|
|||
|
b78aab884e
|
|||
|
36e192ec32
|
|||
|
510675622b
|
|||
|
651722b935
|
|||
|
7a0d5a95c1
|
|||
|
2c583bcae9
|
|||
|
ab36d4418e
|
|||
|
f146c77797
|
|||
|
d863ac570b
|
|||
|
d05fad49a1
|
|||
|
fbbc4497ca
|
|||
|
4223586e62
|
|||
|
c859b3ee2b
|
|||
|
8a16b0de7c
|
|||
|
9faf17634b
|
|||
|
66a62c170c
|
|||
|
5186d959bc
|
|||
|
09a8a0bda0
|
|||
|
191f49adfc
|
|||
|
|
26b79c5763 | ||
|
c72841ca58
|
|||
|
63350dab71
|
|||
|
d110d20879
|
|||
|
b4e58478c3
|
|||
|
12d2acd7fd
|
|||
|
6073ebe476
|
|||
|
5c026591cb
|
|||
|
907365ddff
|
|||
|
684953464b
|
|||
|
6b978b42bc
|
|||
|
6831337289
|
|||
|
e40777a5d3
|
|||
|
51690d1df3
|
|||
|
72a06e964c
|
|||
|
9ffd402481
|
|||
|
dee8d4bc09
|
|||
|
6c57661797
|
|||
|
b9ff7c5af4
|
|||
|
072161ada2
|
|||
|
a67b3e8a57
|
|||
|
c9216fb444
|
|||
|
2aac17ac5f
|
|||
|
17a403b8ce
|
|||
|
b245c11b1d
|
|||
|
2ed047515e
|
|||
|
b16e561384
|
|||
|
|
2ebff1e887 | ||
|
655ee432f8
|
|||
|
67b7b2f292
|
|||
|
66961101c6
|
|||
|
326af49a8f
|
|||
|
3a7ed5ee2d
|
|||
|
56fa798406
|
|||
|
|
3fd9fae66a | ||
|
|
5d43168370 | ||
|
|
f8548fefb3 | ||
|
|
3565c32d51 | ||
|
7fab328acc
|
|||
|
a043b82b27
|
|||
|
20652fed94
|
|||
|
6fc52a4ec7
|
|||
|
834bcfa02c
|
|||
|
c99ecc0a66
|
|||
|
061e5dd832
|
|||
|
c97ade81fa
|
|||
|
82a22fe993
|
|||
|
dbadcf1858
|
|||
|
ff8865c5c3
|
|||
|
9833dee925
|
|||
|
aac2874f8f
|
|||
|
17524b21b3
|
|||
|
3f0befe30d
|
|||
|
76c286f95e
|
|||
|
0c415314b6
|
|||
|
717f386077
|
|||
|
7a841a480b
|
|||
|
43ea85b495
|
|||
|
8a6badca1d
|
|||
|
4064803e23
|
|||
|
2e03b075f8
|
|||
|
fe9c125bd6
|
|||
|
503fd57d7c
|
|||
|
e74e746213
|
|||
|
065f9c4965
|
|||
|
32f3c36589
|
|||
|
c2a8d39fb4
|
|||
|
f08cbe70fb
|
|||
|
a9630d0802
|
|||
|
c5c6c431b5
|
|||
|
71d78d2d72
|
|||
|
ccecda2eff
|
|||
|
3a5f8d6139
|
|||
|
74e0f39bc2
|
|||
|
274978a8a7
|
|||
|
8eea9bd6a5
|
|||
|
626a2dd020
|
|||
|
6b6ce221e0
|
|||
|
d038c361c0
|
|||
|
c05876cc60
|
|||
|
b9c4c9a0b7
|
|||
|
6697e804ee
|
|||
|
2c57def8f1
|
|||
|
62b16e957b
|
|||
|
18d7bdd85c
|
|||
|
190b5dedba
|
|||
|
886e45f788
|
|||
|
360daf2a09
|
|||
|
7bb67dd4c6
|
|||
|
72c4ea70c4
|
|||
|
0ae42dd71e
|
|||
|
1df1e7eb98
|
|||
|
9592021c48
|
|||
|
9a9c3b340e
|
|||
|
abd64cb3fa
|
|||
|
b366a50af1
|
|||
|
e4b9eeefc6
|
|||
|
4d7a8557eb
|
|||
|
c23357df81
|
|||
|
f728d5aa23
|
|||
|
ac59563adf
|
|||
|
b2d2996077
|
|||
|
df2337abf9
|
|||
|
d68ab3b657
|
|||
|
c10821c332
|
|||
|
219cba5fc7
|
|||
|
8e3c74958a
|
|||
|
ed08e0b166
|
|||
|
168f2e6d16
|
26
.cirrus.yml
Normal file
26
.cirrus.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
freebsd_instance:
|
||||||
|
image_family: freebsd-13-1
|
||||||
|
|
||||||
|
build_task:
|
||||||
|
name: build
|
||||||
|
env:
|
||||||
|
GHC_VER: 9.2.4
|
||||||
|
CABAL_VER: 3.8.1.0
|
||||||
|
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
||||||
|
ARCH: 64
|
||||||
|
RUNNER_OS: FreeBSD
|
||||||
|
DISTRO: na
|
||||||
|
GITHUB_WORKSPACE: ${CIRRUS_WORKING_DIR}
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
CIRRUS_CLONE_SUBMODULES: true
|
||||||
|
AWS_ACCESS_KEY_ID: ENCRYPTED[6ed6287e2dd78ab5f84b22232c5245834ab042bd8ba443883aaf4b4d1ecc0481add1fdfad5ae6f6a8cfb418e6f19b2fc]
|
||||||
|
AWS_SECRET_ACCESS_KEY: ENCRYPTED[16f3cda2954c7cee99444e6788eb5997382aa4ce1477e7523fef2586077541f43b5c816156961fc6b4677259679875a7]
|
||||||
|
S3_HOST: ENCRYPTED[ce961780a33159f7d1d8046956b5ac6ebc3bfc8149428e5f538576cda51d9f3d0c35b79cdd1e325793639ff6e31f889d]
|
||||||
|
install_script: pkg install -y ghc hs-cabal-install git bash misc/compat10x misc/compat11x misc/compat12x gmake llvm14
|
||||||
|
script:
|
||||||
|
- tzsetup Etc/GMT
|
||||||
|
- adjkerntz -a
|
||||||
|
- bash .github/scripts/build.sh
|
||||||
|
- bash .github/scripts/test.sh
|
||||||
|
binaries_artifacts:
|
||||||
|
path: "out/*"
|
||||||
4946
.github/ghc-8.10.3-linux.alpine.files
vendored
Normal file
4946
.github/ghc-8.10.3-linux.alpine.files
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8734
.github/ghc-8.10.3-linux.files
vendored
Normal file
8734
.github/ghc-8.10.3-linux.files
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10321
.github/ghc-8.10.3-windows.files
vendored
Normal file
10321
.github/ghc-8.10.3-windows.files
vendored
Normal file
File diff suppressed because it is too large
Load Diff
37
.github/ghcup-run.files
vendored
Normal file
37
.github/ghcup-run.files
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.
|
||||||
|
./cabal
|
||||||
|
./ghc
|
||||||
|
./ghc-8.10.7
|
||||||
|
./ghc-pkg
|
||||||
|
./ghc-pkg-8.10.7
|
||||||
|
./ghci
|
||||||
|
./ghci-8.10.7
|
||||||
|
./haddock
|
||||||
|
./haddock-8.10.7
|
||||||
|
./haskell-language-server-8.10.6
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0
|
||||||
|
./haskell-language-server-8.10.7
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0
|
||||||
|
./haskell-language-server-8.6.5
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0
|
||||||
|
./haskell-language-server-8.8.4
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0
|
||||||
|
./haskell-language-server-9.0.1
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0
|
||||||
|
./haskell-language-server-9.0.2
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0
|
||||||
|
./haskell-language-server-9.2.1
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0
|
||||||
|
./haskell-language-server-wrapper
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0
|
||||||
|
./hp2ps
|
||||||
|
./hp2ps-8.10.7
|
||||||
|
./hpc
|
||||||
|
./hpc-8.10.7
|
||||||
|
./hsc2hs
|
||||||
|
./hsc2hs-8.10.7
|
||||||
|
./runghc
|
||||||
|
./runghc-8.10.7
|
||||||
|
./runhaskell
|
||||||
|
./runhaskell-8.10.7
|
||||||
|
./stack
|
||||||
31
.github/ghcup-run.files.alpine
vendored
Normal file
31
.github/ghcup-run.files.alpine
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
.
|
||||||
|
./cabal
|
||||||
|
./ghc
|
||||||
|
./ghc-8.10.7
|
||||||
|
./ghc-pkg
|
||||||
|
./ghc-pkg-8.10.7
|
||||||
|
./ghci
|
||||||
|
./ghci-8.10.7
|
||||||
|
./haddock
|
||||||
|
./haddock-8.10.7
|
||||||
|
./haskell-language-server-8.10.7
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0
|
||||||
|
./haskell-language-server-8.8.4
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0
|
||||||
|
./haskell-language-server-9.0.2
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0
|
||||||
|
./haskell-language-server-9.2.1
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0
|
||||||
|
./haskell-language-server-wrapper
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0
|
||||||
|
./hp2ps
|
||||||
|
./hp2ps-8.10.7
|
||||||
|
./hpc
|
||||||
|
./hpc-8.10.7
|
||||||
|
./hsc2hs
|
||||||
|
./hsc2hs-8.10.7
|
||||||
|
./runghc
|
||||||
|
./runghc-8.10.7
|
||||||
|
./runhaskell
|
||||||
|
./runhaskell-8.10.7
|
||||||
|
./stack
|
||||||
81
.github/ghcup-run.files.windows
vendored
Normal file
81
.github/ghcup-run.files.windows
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
.
|
||||||
|
./cabal.exe
|
||||||
|
./cabal.shim
|
||||||
|
./ghc-8.10.7.exe
|
||||||
|
./ghc-8.10.7.shim
|
||||||
|
./ghc-pkg-8.10.7.exe
|
||||||
|
./ghc-pkg-8.10.7.shim
|
||||||
|
./ghc-pkg.exe
|
||||||
|
./ghc-pkg.shim
|
||||||
|
./ghc.exe
|
||||||
|
./ghc.shim
|
||||||
|
./ghci-8.10.7.exe
|
||||||
|
./ghci-8.10.7.shim
|
||||||
|
./ghci.exe
|
||||||
|
./ghci.shim
|
||||||
|
./ghcii-8.10.7.sh-8.10.7.exe
|
||||||
|
./ghcii-8.10.7.sh-8.10.7.shim
|
||||||
|
./ghcii-8.10.7.sh.exe
|
||||||
|
./ghcii-8.10.7.sh.shim
|
||||||
|
./ghcii.sh-8.10.7.exe
|
||||||
|
./ghcii.sh-8.10.7.shim
|
||||||
|
./ghcii.sh.exe
|
||||||
|
./ghcii.sh.shim
|
||||||
|
./haddock-8.10.7.exe
|
||||||
|
./haddock-8.10.7.shim
|
||||||
|
./haddock.exe
|
||||||
|
./haddock.shim
|
||||||
|
./haskell-language-server-8.10.6.exe
|
||||||
|
./haskell-language-server-8.10.6.shim
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.10.7.exe
|
||||||
|
./haskell-language-server-8.10.7.shim
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.6.5.exe
|
||||||
|
./haskell-language-server-8.6.5.shim
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.8.4.exe
|
||||||
|
./haskell-language-server-8.8.4.shim
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.0.1.exe
|
||||||
|
./haskell-language-server-9.0.1.shim
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.0.2.exe
|
||||||
|
./haskell-language-server-9.0.2.shim
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.2.1.exe
|
||||||
|
./haskell-language-server-9.2.1.shim
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0.shim
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0.exe
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0.shim
|
||||||
|
./haskell-language-server-wrapper.exe
|
||||||
|
./haskell-language-server-wrapper.shim
|
||||||
|
./hp2ps-8.10.7.exe
|
||||||
|
./hp2ps-8.10.7.shim
|
||||||
|
./hp2ps.exe
|
||||||
|
./hp2ps.shim
|
||||||
|
./hpc-8.10.7.exe
|
||||||
|
./hpc-8.10.7.shim
|
||||||
|
./hpc.exe
|
||||||
|
./hpc.shim
|
||||||
|
./hsc2hs-8.10.7.exe
|
||||||
|
./hsc2hs-8.10.7.shim
|
||||||
|
./hsc2hs.exe
|
||||||
|
./hsc2hs.shim
|
||||||
|
./runghc-8.10.7.exe
|
||||||
|
./runghc-8.10.7.shim
|
||||||
|
./runghc.exe
|
||||||
|
./runghc.shim
|
||||||
|
./runhaskell-8.10.7.exe
|
||||||
|
./runhaskell-8.10.7.shim
|
||||||
|
./runhaskell.exe
|
||||||
|
./runhaskell.shim
|
||||||
|
./stack.exe
|
||||||
|
./stack.shim
|
||||||
18
.github/scripts/bootstrap.sh
vendored
Normal file
18
.github/scripts/bootstrap.sh
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
. .github/scripts/env.sh
|
||||||
|
|
||||||
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
|
|
||||||
|
git describe --always
|
||||||
|
|
||||||
|
### build
|
||||||
|
|
||||||
|
./scripts/bootstrap/bootstrap-haskell
|
||||||
|
|
||||||
|
[ "$(ghc --numeric-version)" = "${BOOTSTRAP_HASKELL_GHC_VERSION}" ]
|
||||||
|
# https://github.com/actions/runner-images/issues/7061
|
||||||
|
[ "$(ghcup config | grep --color=never meta-mode)" = "meta-mode: Lax" ]
|
||||||
|
|
||||||
27
.github/scripts/brew.sh
vendored
Normal file
27
.github/scripts/brew.sh
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
. .github/scripts/env.sh
|
||||||
|
|
||||||
|
if [ -e "$HOME/.brew" ] ; then
|
||||||
|
(
|
||||||
|
cd "$HOME/.brew"
|
||||||
|
git fetch --depth 1
|
||||||
|
git reset --hard origin/master
|
||||||
|
)
|
||||||
|
else
|
||||||
|
git clone --depth=1 https://github.com/Homebrew/brew "$HOME/.brew"
|
||||||
|
fi
|
||||||
|
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH"
|
||||||
|
|
||||||
|
mkdir -p $CI_PROJECT_DIR/.brew_cache
|
||||||
|
export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
||||||
|
mkdir -p $CI_PROJECT_DIR/.brew_logs
|
||||||
|
export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
||||||
|
mkdir -p /private/tmp/.brew_tmp
|
||||||
|
export HOMEBREW_TEMP=/private/tmp/.brew_tmp
|
||||||
|
|
||||||
|
brew update
|
||||||
|
brew install ${1+"$@"}
|
||||||
|
|
||||||
35
.github/scripts/build.sh
vendored
Normal file
35
.github/scripts/build.sh
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
. .github/scripts/common.sh
|
||||||
|
|
||||||
|
git_describe
|
||||||
|
|
||||||
|
# ensure ghcup
|
||||||
|
install_ghcup
|
||||||
|
|
||||||
|
# ensure cabal-cache
|
||||||
|
download_cabal_cache "$HOME/.local/bin/cabal-cache"
|
||||||
|
|
||||||
|
# install toolchain (if necessary)
|
||||||
|
ghcup -v install ghc --set --force "$GHC_VER"
|
||||||
|
ghcup -v install cabal --force "$CABAL_VER"
|
||||||
|
ghc --version
|
||||||
|
cabal --version
|
||||||
|
GHC="ghc-${GHC_VER}"
|
||||||
|
|
||||||
|
# build
|
||||||
|
ecabal update
|
||||||
|
build_with_cache --project-file=cabal.project.release -w "${GHC}" --enable-tests
|
||||||
|
|
||||||
|
# set up artifacts
|
||||||
|
mkdir -p out
|
||||||
|
binary=$(cabal --project-file=cabal.project.release list-bin ghcup)
|
||||||
|
binary_test=$(cabal --project-file=cabal.project.release list-bin ghcup-test)
|
||||||
|
ver=$("${binary}" --numeric-version)
|
||||||
|
strip_binary "${binary}"
|
||||||
|
cp "${binary}" "out/${ARTIFACT}-${ver}${ext}"
|
||||||
|
cp "${binary_test}" "out/test-${ARTIFACT}-${ver}${ext}"
|
||||||
|
cp ./dist-newstyle/cache/plan.json "out/${ARTIFACT}.plan.json"
|
||||||
|
|
||||||
170
.github/scripts/common.sh
vendored
Normal file
170
.github/scripts/common.sh
vendored
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. .github/scripts/env.sh
|
||||||
|
|
||||||
|
ecabal() {
|
||||||
|
cabal "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
nonfatal() {
|
||||||
|
"$@" || "$* failed"
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_from() {
|
||||||
|
if [ "${RUNNER_OS}" != "Windows" ] ; then
|
||||||
|
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cabal-cache sync-from-archive \
|
||||||
|
--host-name-override=${S3_HOST} \
|
||||||
|
--host-port-override=443 \
|
||||||
|
--host-ssl-override=True \
|
||||||
|
--region us-west-2 \
|
||||||
|
$([ "${RUNNER_OS}" != "Windows" ] && echo --store-path="$cabal_store_path") \
|
||||||
|
--archive-uri "s3://ghcup-hs/${RUNNER_OS}-${ARCH}-${DISTRO}"
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_to() {
|
||||||
|
if [ "${RUNNER_OS}" != "Windows" ] ; then
|
||||||
|
cabal_store_path="$(dirname "$(cabal help user-config | tail -n 1 | xargs)")/store"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cabal-cache sync-to-archive \
|
||||||
|
--host-name-override=${S3_HOST} \
|
||||||
|
--host-port-override=443 \
|
||||||
|
--host-ssl-override=True \
|
||||||
|
--region us-west-2 \
|
||||||
|
$([ "${RUNNER_OS}" != "Windows" ] && echo --store-path="$cabal_store_path") \
|
||||||
|
--archive-uri "s3://ghcup-hs/${RUNNER_OS}-${ARCH}-${DISTRO}"
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_eghcup() {
|
||||||
|
"$GHCUP_BIN/ghcup${ext}" -v -c "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
eghcup() {
|
||||||
|
if [ "${OS}" = "Windows" ] ; then
|
||||||
|
"$GHCUP_BIN/ghcup${ext}" -c -s "file:/$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$@"
|
||||||
|
else
|
||||||
|
"$GHCUP_BIN/ghcup${ext}" -c -s "file://$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
sha_sum() {
|
||||||
|
if [ "${OS}" = "FreeBSD" ] ; then
|
||||||
|
sha256 "$@"
|
||||||
|
else
|
||||||
|
sha256sum "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
git_describe() {
|
||||||
|
git config --global --get-all safe.directory | grep '^\*$' || git config --global --add safe.directory "*"
|
||||||
|
git describe --always
|
||||||
|
}
|
||||||
|
|
||||||
|
download_cabal_cache() {
|
||||||
|
(
|
||||||
|
set -e
|
||||||
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
dest="$HOME/.local/bin/cabal-cache"
|
||||||
|
url=""
|
||||||
|
exe=""
|
||||||
|
cd /tmp
|
||||||
|
case "${RUNNER_OS}" in
|
||||||
|
"Linux")
|
||||||
|
case "${ARCH}" in
|
||||||
|
"32") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/i386-linux-cabal-cache
|
||||||
|
;;
|
||||||
|
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/x86_64-linux-cabal-cache
|
||||||
|
;;
|
||||||
|
"ARM64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/aarch64-linux-cabal-cache
|
||||||
|
;;
|
||||||
|
"ARM") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/armv7-linux-cabal-cache
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
"FreeBSD")
|
||||||
|
url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/x86_64-portbld-freebsd-cabal-cache
|
||||||
|
;;
|
||||||
|
"Windows")
|
||||||
|
exe=".exe"
|
||||||
|
url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/x86_64-mingw64-cabal-cache
|
||||||
|
;;
|
||||||
|
"macOS")
|
||||||
|
case "${ARCH}" in
|
||||||
|
"ARM64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/aarch64-apple-darwin-cabal-cache
|
||||||
|
;;
|
||||||
|
"64") url=https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal-cache/experimental5/x86_64-apple-darwin-cabal-cache
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -n "${url}" ] ; then
|
||||||
|
case "${url##*.}" in
|
||||||
|
"gz")
|
||||||
|
curl -L -o - "${url}" | gunzip > cabal-cache${exe}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
curl -o cabal-cache${exe} -L "${url}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
sha_sum cabal-cache${exe}
|
||||||
|
mv "cabal-cache${exe}" "${dest}${exe}"
|
||||||
|
chmod +x "${dest}${exe}"
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
build_with_cache() {
|
||||||
|
ecabal configure "$@"
|
||||||
|
ecabal build --dependencies-only "$@" --dry-run
|
||||||
|
sync_from
|
||||||
|
ecabal build --dependencies-only "$@" || sync_to
|
||||||
|
sync_to
|
||||||
|
ecabal build "$@"
|
||||||
|
sync_to
|
||||||
|
}
|
||||||
|
|
||||||
|
install_ghcup() {
|
||||||
|
case "${RUNNER_OS}" in
|
||||||
|
"Linux")
|
||||||
|
case "${ARCH}" in
|
||||||
|
"ARM"*)
|
||||||
|
if command -v ghcup ; then
|
||||||
|
mkdir -p "$GHCUP_BIN"
|
||||||
|
cp "$(command -v ghcup)" "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
else
|
||||||
|
install_ghcup_curl_sh
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*) install_ghcup_curl_sh
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*) install_ghcup_curl_sh
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
install_ghcup_curl_sh() {
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 BOOTSTRAP_HASKELL_INSTALL_NO_STACK=yes sh
|
||||||
|
}
|
||||||
|
|
||||||
|
strip_binary() {
|
||||||
|
(
|
||||||
|
set -e
|
||||||
|
local binary=$1
|
||||||
|
case "$(uname -s)" in
|
||||||
|
"Darwin"|"darwin")
|
||||||
|
;;
|
||||||
|
MSYS_*|MINGW*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
strip -s "${binary}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
)
|
||||||
|
}
|
||||||
30
.github/scripts/env.sh
vendored
Normal file
30
.github/scripts/env.sh
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "${RUNNER_OS}" = "Windows" ] ; then
|
||||||
|
ext=".exe"
|
||||||
|
else
|
||||||
|
ext=''
|
||||||
|
fi
|
||||||
|
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
export TZ=Asia/Singapore
|
||||||
|
|
||||||
|
export OS="$RUNNER_OS"
|
||||||
|
export PATH="$HOME/.local/bin:$PATH"
|
||||||
|
|
||||||
|
if [ "${RUNNER_OS}" = "Windows" ] ; then
|
||||||
|
# on windows use pwd to get unix style path
|
||||||
|
CI_PROJECT_DIR="$(pwd)"
|
||||||
|
export CI_PROJECT_DIR
|
||||||
|
export GHCUP_INSTALL_BASE_PREFIX="/c"
|
||||||
|
export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin"
|
||||||
|
export PATH="$GHCUP_BIN:$PATH"
|
||||||
|
export CABAL_DIR="C:\\Users\\runneradmin\\AppData\\Roaming\\cabal"
|
||||||
|
else
|
||||||
|
export CI_PROJECT_DIR="${GITHUB_WORKSPACE}"
|
||||||
|
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
||||||
|
export GHCUP_BIN="$GHCUP_INSTALL_BASE_PREFIX/.ghcup/bin"
|
||||||
|
export PATH="$GHCUP_BIN:$PATH"
|
||||||
|
export CABAL_DIR="$CI_PROJECT_DIR/cabal"
|
||||||
|
export CABAL_CACHE="$CI_PROJECT_DIR/cabal-cache"
|
||||||
|
fi
|
||||||
72
.github/scripts/hls.sh
vendored
Normal file
72
.github/scripts/hls.sh
vendored
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
. .github/scripts/common.sh
|
||||||
|
|
||||||
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
|
|
||||||
|
### build
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ "${OS}" = "Windows" ] ; then
|
||||||
|
GHCUP_DIR="${GHCUP_INSTALL_BASE_PREFIX}"/ghcup
|
||||||
|
else
|
||||||
|
GHCUP_DIR="${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "${GHCUP_DIR}"
|
||||||
|
mkdir -p "${GHCUP_BIN}"
|
||||||
|
|
||||||
|
ls -lah out
|
||||||
|
find out
|
||||||
|
cp "out/${ARTIFACT}"-* "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
chmod +x "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
echo "$PATH"
|
||||||
|
|
||||||
|
"$GHCUP_BIN/ghcup${ext}" --version
|
||||||
|
eghcup --version
|
||||||
|
sha_sum "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
sha_sum "$(raw_eghcup --offline whereis ghcup)"
|
||||||
|
|
||||||
|
git_describe
|
||||||
|
|
||||||
|
eghcup install ghc "${GHC_VERSION}"
|
||||||
|
eghcup install cabal "${CABAL_VERSION}"
|
||||||
|
|
||||||
|
ecabal update
|
||||||
|
|
||||||
|
if ! command -v cabal-cache ; then
|
||||||
|
download_cabal_cache "$HOME/.local/bin/cabal-cache"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! cabal-cache version ; then
|
||||||
|
build_cabal_cache "$HOME/.local/bin"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
eghcup debug-info
|
||||||
|
|
||||||
|
(
|
||||||
|
cd /tmp
|
||||||
|
git clone --depth 1 --branch "${HLS_TARGET_VERSION}" \
|
||||||
|
https://github.com/haskell/haskell-language-server.git \
|
||||||
|
"haskell-language-server-${HLS_TARGET_VERSION}"
|
||||||
|
cd "haskell-language-server-${HLS_TARGET_VERSION}/"
|
||||||
|
ecabal configure -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)"
|
||||||
|
ecabal build --dependencies-only -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)" --dry-run
|
||||||
|
sync_from
|
||||||
|
ecabal build --dependencies-only -w "ghc-${GHC_VERSION}" --disable-profiling --disable-tests --jobs="$(nproc)" || sync_to
|
||||||
|
sync_to
|
||||||
|
)
|
||||||
|
|
||||||
|
eghcup -v compile hls -j "$(nproc)" -g "${HLS_TARGET_VERSION}" --ghc "${GHC_VERSION}"
|
||||||
|
|
||||||
|
[ "$($(eghcup whereis hls "${HLS_TARGET_VERSION}") --numeric-version)" = "${HLS_TARGET_VERSION}" ] ||
|
||||||
|
[ "$($(eghcup whereis hls "${HLS_TARGET_VERSION}") --numeric-version | sed 's/.0$//')" = "${HLS_TARGET_VERSION}" ]
|
||||||
|
|
||||||
|
# nuke
|
||||||
|
eghcup nuke
|
||||||
|
[ ! -e "${GHCUP_DIR}" ]
|
||||||
|
|
||||||
262
.github/scripts/test.sh
vendored
Normal file
262
.github/scripts/test.sh
vendored
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
. .github/scripts/common.sh
|
||||||
|
|
||||||
|
|
||||||
|
if [ "${OS}" = "Windows" ] ; then
|
||||||
|
GHCUP_DIR="${GHCUP_INSTALL_BASE_PREFIX}"/ghcup
|
||||||
|
else
|
||||||
|
GHCUP_DIR="${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup
|
||||||
|
fi
|
||||||
|
|
||||||
|
git_describe
|
||||||
|
|
||||||
|
rm -rf "${GHCUP_DIR}"
|
||||||
|
mkdir -p "${GHCUP_BIN}"
|
||||||
|
|
||||||
|
cp "out/${ARTIFACT}"-* "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
cp "out/test-${ARTIFACT}"-* "ghcup-test${ext}"
|
||||||
|
chmod +x "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
chmod +x "ghcup-test${ext}"
|
||||||
|
|
||||||
|
"$GHCUP_BIN/ghcup${ext}" --version
|
||||||
|
eghcup --version
|
||||||
|
sha_sum "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
sha_sum "$(raw_eghcup --offline whereis ghcup)"
|
||||||
|
|
||||||
|
### Haskell test suite
|
||||||
|
|
||||||
|
./ghcup-test${ext}
|
||||||
|
rm ghcup-test${ext}
|
||||||
|
|
||||||
|
### manual cli based testing
|
||||||
|
|
||||||
|
eghcup --numeric-version
|
||||||
|
|
||||||
|
eghcup install ghc ${GHC_VER}
|
||||||
|
eghcup unset ghc ${GHC_VER}
|
||||||
|
ls -lah "$(eghcup whereis -d ghc ${GHC_VER})"
|
||||||
|
[ "`$(eghcup whereis ghc ${GHC_VER}) --numeric-version`" = "${GHC_VER}" ]
|
||||||
|
[ "`eghcup run --ghc ${GHC_VER} -- ghc --numeric-version`" = "${GHC_VER}" ]
|
||||||
|
[ "`ghcup run --ghc ${GHC_VER} -- ghc -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)'`" = "`$(ghcup whereis ghc ${GHC_VER}) -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)'`" ]
|
||||||
|
eghcup set ghc ${GHC_VER}
|
||||||
|
eghcup install cabal ${CABAL_VER}
|
||||||
|
[ "`$(eghcup whereis cabal ${CABAL_VER}) --numeric-version`" = "${CABAL_VER}" ]
|
||||||
|
eghcup unset cabal
|
||||||
|
"$GHCUP_BIN"/cabal --version && exit 1 || echo yes
|
||||||
|
|
||||||
|
# make sure no cabal is set when running 'ghcup run' to check that PATH propagages properly
|
||||||
|
# https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
||||||
|
[ "`eghcup run --cabal ${CABAL_VER} -- cabal --numeric-version`" = "${CABAL_VER}" ]
|
||||||
|
eghcup set cabal ${CABAL_VER}
|
||||||
|
|
||||||
|
[ "`$(eghcup whereis cabal ${CABAL_VER}) --numeric-version`" = "${CABAL_VER}" ]
|
||||||
|
|
||||||
|
if [ "${OS}" != "FreeBSD" ] ; then
|
||||||
|
if [ "${ARCH}" = "64" ] && [ "${DISTRO}" != "Alpine" ] ; then
|
||||||
|
eghcup run --ghc 8.10.7 --cabal 3.4.1.0 --hls 1.6.1.0 --stack 2.7.3 --install --bindir "$(pwd)/.bin"
|
||||||
|
if [ "${OS}" = "Windows" ] ; then
|
||||||
|
cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup-run.files.windows" | sort > expected.txt
|
||||||
|
elif [ "${DISTRO}" = "Alpine" ] ; then
|
||||||
|
cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup-run.files.alpine" | sort > expected.txt
|
||||||
|
else
|
||||||
|
cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup-run.files" | sort > expected.txt
|
||||||
|
fi
|
||||||
|
(cd ".bin" && find . | sort) > actual.txt
|
||||||
|
diff --strip-trailing-cr -w -u actual.txt expected.txt
|
||||||
|
rm actual.txt expected.txt
|
||||||
|
rm -rf .bin
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cabal --version
|
||||||
|
|
||||||
|
eghcup debug-info
|
||||||
|
|
||||||
|
# also test etags
|
||||||
|
eghcup list
|
||||||
|
eghcup list -t ghc
|
||||||
|
eghcup list -t cabal
|
||||||
|
|
||||||
|
ghc_ver=$(ghc --numeric-version)
|
||||||
|
ghc --version
|
||||||
|
ghc-${ghc_ver} --version
|
||||||
|
if [ "${OS}" != "Windows" ] ; then
|
||||||
|
ghci --version
|
||||||
|
ghci-${ghc_ver} --version
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "${OS}" = "macOS" ] && [ "${ARCH}" = "ARM64" ] ; then
|
||||||
|
# missing bindists
|
||||||
|
echo
|
||||||
|
elif [ "${OS}" = "FreeBSD" ] ; then
|
||||||
|
# not enough space
|
||||||
|
echo
|
||||||
|
else
|
||||||
|
# test installing new ghc doesn't mess with currently set GHC
|
||||||
|
# https://gitlab.haskell.org/haskell/ghcup-hs/issues/7
|
||||||
|
if [ "${OS}" = "Linux" ] ; then
|
||||||
|
eghcup --downloader=wget prefetch ghc 8.10.3
|
||||||
|
eghcup --offline install ghc 8.10.3
|
||||||
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
|
if [ "${DISTRO}" = "Alpine" ] ; then
|
||||||
|
(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-linux.alpine.files" | sort) > expected.txt
|
||||||
|
else
|
||||||
|
(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-linux.files" | sort) > expected.txt
|
||||||
|
fi
|
||||||
|
(cd "${GHCUP_DIR}/ghc/8.10.3/" && find . | sort) > actual.txt
|
||||||
|
# ignore docs
|
||||||
|
sed -i '/share\/doc/d' actual.txt
|
||||||
|
sed -i '/share\/doc/d' expected.txt
|
||||||
|
diff --strip-trailing-cr -w -u actual.txt expected.txt
|
||||||
|
rm actual.txt expected.txt
|
||||||
|
fi
|
||||||
|
elif [ "${OS}" = "Windows" ] ; then
|
||||||
|
eghcup prefetch ghc 8.10.3
|
||||||
|
eghcup --offline install ghc 8.10.3
|
||||||
|
(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-windows.files" | sort) > expected.txt
|
||||||
|
(cd "${GHCUP_DIR}/ghc/8.10.3/" && find . | sort) > actual.txt
|
||||||
|
diff --strip-trailing-cr -w -u actual.txt expected.txt
|
||||||
|
rm actual.txt expected.txt
|
||||||
|
else
|
||||||
|
eghcup prefetch ghc 8.10.3
|
||||||
|
eghcup --offline install ghc 8.10.3
|
||||||
|
fi
|
||||||
|
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||||
|
eghcup --offline set 8.10.3
|
||||||
|
eghcup set 8.10.3
|
||||||
|
[ "$(ghc --numeric-version)" = "8.10.3" ]
|
||||||
|
eghcup set ${GHC_VER}
|
||||||
|
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||||
|
eghcup unset ghc
|
||||||
|
"$GHCUP_BIN"/ghc --numeric-version && exit 1 || echo yes
|
||||||
|
eghcup set ${GHC_VER}
|
||||||
|
eghcup --offline rm 8.10.3
|
||||||
|
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||||
|
|
||||||
|
|
||||||
|
ls -lah "$GHCUP_BIN"
|
||||||
|
|
||||||
|
if [ "${OS}" = "macOS" ] ; then
|
||||||
|
eghcup install hls
|
||||||
|
$(eghcup whereis hls) --version
|
||||||
|
|
||||||
|
eghcup install stack
|
||||||
|
$(eghcup whereis stack) --version
|
||||||
|
elif [ "${OS}" = "Linux" ] ; then
|
||||||
|
if [ "${ARCH}" = "64" ] && [ "${DISTRO}" != "Alpine" ] ; then
|
||||||
|
eghcup install hls
|
||||||
|
haskell-language-server-wrapper --version
|
||||||
|
eghcup unset hls
|
||||||
|
"$GHCUP_BIN"/haskell-language-server-wrapper --version && exit 1 || echo yes
|
||||||
|
|
||||||
|
eghcup install stack
|
||||||
|
stack --version
|
||||||
|
eghcup unset stack
|
||||||
|
"$GHCUP_BIN"/stack --version && exit 1 || echo yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# check that lazy loading works for 'whereis'
|
||||||
|
cp "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml.bak"
|
||||||
|
echo '**' > "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml"
|
||||||
|
eghcup whereis ghc $(ghc --numeric-version)
|
||||||
|
mv -f "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml.bak" "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml"
|
||||||
|
|
||||||
|
eghcup rm $(ghc --numeric-version)
|
||||||
|
|
||||||
|
# https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/116
|
||||||
|
if [ "${OS}" = "Linux" ] ; then
|
||||||
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
|
eghcup install cabal -u https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal/3.7.0.0-pre20220407/cabal-install-3.7-x86_64-linux-alpine.tar.xz 3.4.0.0-rc4
|
||||||
|
eghcup rm cabal 3.4.0.0-rc4
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
eghcup gc -c
|
||||||
|
|
||||||
|
# test etags
|
||||||
|
rm -f "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
||||||
|
raw_eghcup -s https://www.haskell.org/ghcup/data/ghcup-${JSON_VERSION}.yaml list
|
||||||
|
# snapshot yaml and etags file
|
||||||
|
etag=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
||||||
|
sha=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||||
|
# invalidate access time timer, which is 5minutes, so we re-download
|
||||||
|
touch -a -m -t '199901010101' "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
||||||
|
# redownload same file with some newlines added
|
||||||
|
raw_eghcup -s https://raw.githubusercontent.com/haskell/ghcup-metadata/exp/ghcup-0.0.7.yaml list
|
||||||
|
# snapshot new yaml and etags file
|
||||||
|
etag2=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
||||||
|
sha2=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||||
|
# compare
|
||||||
|
[ "${etag}" != "${etag2}" ]
|
||||||
|
[ "${sha}" != "${sha2}" ]
|
||||||
|
# invalidate access time timer, which is 5minutes, but don't expect a re-download
|
||||||
|
touch -a -m -t '199901010101' "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml"
|
||||||
|
# this time, we expect the same hash and etag
|
||||||
|
raw_eghcup -s https://raw.githubusercontent.com/haskell/ghcup-metadata/exp/ghcup-0.0.7.yaml list
|
||||||
|
etag3=$(cat "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml.etags")
|
||||||
|
sha3=$(sha_sum "${GHCUP_DIR}/cache/ghcup-${JSON_VERSION}.yaml")
|
||||||
|
[ "${etag2}" = "${etag3}" ]
|
||||||
|
[ "${sha2}" = "${sha3}" ]
|
||||||
|
|
||||||
|
# test isolated installs
|
||||||
|
if [ "${DISTRO}" != "Alpine" ] ; then
|
||||||
|
eghcup install ghc -i "$(pwd)/isolated" 8.10.5
|
||||||
|
[ "$(isolated/bin/ghc --numeric-version)" = "8.10.5" ]
|
||||||
|
! eghcup install ghc -i "$(pwd)/isolated" 8.10.5
|
||||||
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
|
if [ "${OS}" = "Linux" ] || [ "${OS}" = "Windows" ] ; then
|
||||||
|
eghcup install cabal -i "$(pwd)/isolated" 3.4.0.0
|
||||||
|
[ "$(isolated/cabal --numeric-version)" = "3.4.0.0" ]
|
||||||
|
eghcup install stack -i "$(pwd)/isolated" 2.7.3
|
||||||
|
[ "$(isolated/stack --numeric-version)" = "2.7.3" ]
|
||||||
|
eghcup install hls -i "$(pwd)/isolated" 1.3.0
|
||||||
|
[ "$(isolated/haskell-language-server-wrapper --numeric-version)" = "1.3.0" ] ||
|
||||||
|
[ "$(isolated/haskell-language-server-wrapper --numeric-version)" = "1.3.0.0" ]
|
||||||
|
|
||||||
|
# test that isolated installs don't clean up target directory
|
||||||
|
cat <<EOF > "${GHCUP_BIN}/gmake"
|
||||||
|
#!/bin/bash
|
||||||
|
exit 1
|
||||||
|
EOF
|
||||||
|
chmod +x "${GHCUP_BIN}/gmake"
|
||||||
|
mkdir isolated_tainted/
|
||||||
|
touch isolated_tainted/lol
|
||||||
|
|
||||||
|
! eghcup install ghc -i "$(pwd)/isolated_tainted" 8.10.5 --force
|
||||||
|
[ -e "$(pwd)/isolated_tainted/lol" ]
|
||||||
|
rm "${GHCUP_BIN}/gmake"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
eghcup upgrade
|
||||||
|
eghcup upgrade -f
|
||||||
|
|
||||||
|
# restore old ghcup, because we want to test nuke
|
||||||
|
cp "out/${ARTIFACT}"-* "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
chmod +x "$GHCUP_BIN/ghcup${ext}"
|
||||||
|
|
||||||
|
# test that doing fishy symlinks into GHCup dir doesn't cause weird stuff on 'ghcup nuke'
|
||||||
|
mkdir no_nuke/
|
||||||
|
mkdir no_nuke/bar
|
||||||
|
echo 'foo' > no_nuke/file
|
||||||
|
echo 'bar' > no_nuke/bar/file
|
||||||
|
ln -s "$CI_PROJECT_DIR"/no_nuke/ "${GHCUP_DIR}"/cache/no_nuke
|
||||||
|
ln -s "$CI_PROJECT_DIR"/no_nuke/ "${GHCUP_DIR}"/logs/no_nuke
|
||||||
|
|
||||||
|
# nuke
|
||||||
|
eghcup nuke
|
||||||
|
[ ! -e "${GHCUP_DIR}" ]
|
||||||
|
|
||||||
|
# make sure nuke doesn't resolve symlinks
|
||||||
|
[ -e "$CI_PROJECT_DIR"/no_nuke/file ]
|
||||||
|
[ -e "$CI_PROJECT_DIR"/no_nuke/bar/file ]
|
||||||
|
|
||||||
55
.github/workflows/bootstrap.yaml
vendored
Normal file
55
.github/workflows/bootstrap.yaml
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
name: Bootstrap tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
bootstrap:
|
||||||
|
name: bootstrap
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
BOOTSTRAP_HASKELL_CABAL_VERSION: 3.6.2.0
|
||||||
|
BOOTSTRAP_HASKELL_GHC_VERSION: 8.10.7
|
||||||
|
BOOTSTRAP_HASKELL_NONINTERACTIVE: yes
|
||||||
|
ARCH: 64
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
- os: macOS-10.15
|
||||||
|
DISTRO: na
|
||||||
|
- os: windows-latest
|
||||||
|
DISTRO: na
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- if: runner.os == 'Linux'
|
||||||
|
name: Run bootstrap
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip
|
||||||
|
sh ./.github/scripts/bootstrap.sh
|
||||||
|
env:
|
||||||
|
DISTRO: ${{ matrix.DISTRO }}
|
||||||
|
|
||||||
|
- if: runner.os == 'macOS'
|
||||||
|
name: Run bootstrap
|
||||||
|
run: sh ./.github/scripts/bootstrap.sh
|
||||||
|
env:
|
||||||
|
DISTRO: ${{ matrix.DISTRO }}
|
||||||
|
|
||||||
|
- if: runner.os == 'Windows'
|
||||||
|
name: Run bootstrap
|
||||||
|
run: ./scripts/bootstrap/bootstrap-haskell.ps1 -InstallDir ${GITHUB_WORKSPACE} -BootstrapUrl ${GITHUB_WORKSPACE}/bootstrap-haskell -InBash
|
||||||
|
shell: pwsh
|
||||||
37
.github/workflows/cache.yaml
vendored
Normal file
37
.github/workflows/cache.yaml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: Cache eviction
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
key:
|
||||||
|
description: Which cache to evict
|
||||||
|
required: true
|
||||||
|
default: '/'
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- FreeBSD-64-na
|
||||||
|
- Linux-32-Alpine
|
||||||
|
- Linux-64-Alpine
|
||||||
|
- Linux-64-Ubuntu
|
||||||
|
- Linux-ARM-Ubuntu
|
||||||
|
- Linux-ARM64-Ubuntu
|
||||||
|
- Windows-64-na
|
||||||
|
- macOS-64-na
|
||||||
|
- macOS-ARM64-na
|
||||||
|
- /
|
||||||
|
jobs:
|
||||||
|
evict:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Remove from S3
|
||||||
|
uses: vitorsgomes/s3-rm-action@master
|
||||||
|
with:
|
||||||
|
args: --recursive
|
||||||
|
env:
|
||||||
|
AWS_S3_ENDPOINT: https://${{ secrets.S3_HOST }}
|
||||||
|
AWS_S3_BUCKET: ghcup-hs
|
||||||
|
AWS_REGION: us-west-2
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
PATH_TO_DELETE: ${{ github.event.inputs.key }}
|
||||||
125
.github/workflows/docker.yaml
vendored
Normal file
125
.github/workflows/docker.yaml
vendored
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
name: Docker image builds
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker-alpine32:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- name: Build and push (alpine 32bit)
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: ./docker/alpine32
|
||||||
|
push: true
|
||||||
|
tags: hasufell/i386-alpine-haskell:3.12
|
||||||
|
platforms: |
|
||||||
|
linux/i386
|
||||||
|
linux/amd64
|
||||||
|
|
||||||
|
docker-alpine:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- name: Build and push (alpine 64bit)
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: ./docker/alpine64
|
||||||
|
push: true
|
||||||
|
tags: hasufell/alpine-haskell:3.12
|
||||||
|
platforms: linux/amd64
|
||||||
|
|
||||||
|
docker-arm32:
|
||||||
|
runs-on: [self-hosted, Linux, ARM64, aarch32-linux]
|
||||||
|
steps:
|
||||||
|
- uses: docker://arm64v8/ubuntu:focal
|
||||||
|
name: Cleanup (aarch64 linux)
|
||||||
|
with:
|
||||||
|
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push (debian buster)
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: ./docker/arm32v7/buster
|
||||||
|
push: true
|
||||||
|
tags: hasufell/arm32v7-debian-haskell:10
|
||||||
|
platforms: linux/arm
|
||||||
|
|
||||||
|
- name: Build and push (ubuntu focal)
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: ./docker/arm32v7/focal
|
||||||
|
push: true
|
||||||
|
tags: hasufell/arm32v7-debian-haskell:10
|
||||||
|
platforms: linux/arm
|
||||||
|
|
||||||
|
docker-aarch:
|
||||||
|
runs-on: [self-hosted, Linux, ARM64]
|
||||||
|
steps:
|
||||||
|
- uses: docker://arm64v8/ubuntu:focal
|
||||||
|
name: Cleanup (aarch64 linux)
|
||||||
|
with:
|
||||||
|
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push (debian buster)
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: ./docker/arm64v8/buster
|
||||||
|
push: true
|
||||||
|
tags: hasufell/arm64v8-debian-haskell:10
|
||||||
|
platforms: linux/arm64
|
||||||
|
|
||||||
|
- name: Build and push (ubuntu focal)
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: ./docker/arm64v8/focal
|
||||||
|
push: true
|
||||||
|
tags: hasufell/arm64v8-debian-haskell:10
|
||||||
|
platforms: linux/arm64
|
||||||
26
.github/workflows/hlint.yaml
vendored
Normal file
26
.github/workflows/hlint.yaml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: Hlint
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hlint:
|
||||||
|
name: hlint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- name: Run hlint
|
||||||
|
run: curl -sSL https://raw.github.com/ndmitchell/hlint/master/misc/run.sh | sh -s -- -r lib/ test/
|
||||||
33
.github/workflows/mkdocs.yaml
vendored
Normal file
33
.github/workflows/mkdocs.yaml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
name: MkDocs
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
mkdocs:
|
||||||
|
name: mkdocs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- name: Install mkdocs deps
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install -y python3-pip
|
||||||
|
sudo pip3 install mkdocs
|
||||||
|
|
||||||
|
- name: Run mkdocs
|
||||||
|
run: |
|
||||||
|
mkdocs build
|
||||||
581
.github/workflows/release.yaml
vendored
581
.github/workflows/release.yaml
vendored
@@ -1,109 +1,514 @@
|
|||||||
name: Create Release
|
name: Build and release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
tags:
|
tags:
|
||||||
- 'v*'
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
schedule:
|
||||||
|
- cron: '0 2 * * *'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
draft_release:
|
build-linux:
|
||||||
name: Draft Release
|
name: Build linux binary
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Create Release
|
|
||||||
id: create_release
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
tag_name: ${{ github.ref }}
|
|
||||||
release_name: Release ${{ github.ref }}
|
|
||||||
body: |
|
|
||||||
Changes in this Release
|
|
||||||
- First Change
|
|
||||||
- Second Change
|
|
||||||
draft: true
|
|
||||||
prerelease: false
|
|
||||||
|
|
||||||
release-mac:
|
|
||||||
name: Create Release
|
|
||||||
needs: draft_release
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
MACOSX_DEPLOYMENT_TARGET: 10.13
|
CABAL_VER: 3.8.1.0
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ secrets.S3_HOST }}
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
os:
|
include:
|
||||||
- macOS-10.15
|
- os: ubuntu-latest
|
||||||
|
ARTIFACT: "i386-linux-ghcup"
|
||||||
|
GHC_VER: 8.10.7
|
||||||
|
ARCH: 32
|
||||||
|
- os: ubuntu-latest
|
||||||
|
ARTIFACT: "x86_64-linux-ghcup"
|
||||||
|
GHC_VER: 8.10.7
|
||||||
|
ARCH: 64
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- uses: haskell/actions/setup@v1.2
|
|
||||||
with:
|
with:
|
||||||
ghc-version: 8.10.4
|
submodules: 'true'
|
||||||
cabal-version: 3.4.0.0
|
|
||||||
|
|
||||||
- name: create ~/.local/bin
|
- if: matrix.ARCH == '32'
|
||||||
run: mkdir -p "$HOME/.local/bin"
|
name: Run build (32 bit linux)
|
||||||
shell: bash
|
uses: docker://hasufell/i386-alpine-haskell:3.12
|
||||||
|
with:
|
||||||
- name: Add ~/.local/bin to PATH
|
args: sh .github/scripts/build.sh
|
||||||
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Update cabal cache
|
|
||||||
run: cabal update
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Install cabal dependencies
|
|
||||||
run: cabal build --only-dependencies --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" -ftui
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cabal build --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" -ftui
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Install
|
|
||||||
run: cp "$(cabal list-bin exe:ghcup)" ~/.local/bin/ghcup
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Strip
|
|
||||||
run: strip ~/.local/bin/ghcup
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: cabal test --constraint="zlib +bundled-c-zlib" --constraint="lzma +static" all
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Install git
|
|
||||||
run: brew install git
|
|
||||||
|
|
||||||
- name: set HOME
|
|
||||||
run: echo "HOME=$HOME" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Set ASSET_PATH
|
|
||||||
run: echo "ASSET_PATH=$HOME/.local/bin/ghcup" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Upload Release Asset
|
|
||||||
id: upload-release-asset
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: Alpine
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ env.S3_HOST }}
|
||||||
|
|
||||||
|
- if: matrix.ARCH == '64'
|
||||||
|
name: Run build (64 bit linux)
|
||||||
|
uses: docker://hasufell/alpine-haskell:3.12
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ needs.draft_release.outputs.upload_url }}
|
args: sh .github/scripts/build.sh
|
||||||
asset_path: ${{ env.ASSET_PATH }}
|
env:
|
||||||
asset_name: ghcup-${{ matrix.os }}
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
asset_content_type: application/octet-stream
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: Alpine
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ env.S3_HOST }}
|
||||||
|
|
||||||
- if: always()
|
- if: always()
|
||||||
uses: actions/upload-artifact@v2
|
name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: plan.json
|
name: artifacts
|
||||||
path: ./dist-newstyle/cache/plan.json
|
path: |
|
||||||
|
./out/*
|
||||||
|
|
||||||
|
|
||||||
|
build-arm:
|
||||||
|
name: Build ARM binary
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
CABAL_VER: 3.8.1.0
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ secrets.S3_HOST }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: [self-hosted, Linux, ARM64, aarch32-linux]
|
||||||
|
ARTIFACT: "armv7-linux-ghcup"
|
||||||
|
GHC_VER: 9.2.2
|
||||||
|
ARCH: ARM
|
||||||
|
- os: [self-hosted, Linux, ARM64]
|
||||||
|
ARTIFACT: "aarch64-linux-ghcup"
|
||||||
|
GHC_VER: 9.2.5
|
||||||
|
ARCH: ARM64
|
||||||
|
steps:
|
||||||
|
- uses: docker://arm64v8/debian:10
|
||||||
|
name: Cleanup (aarch64 linux)
|
||||||
|
with:
|
||||||
|
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||||
|
|
||||||
|
- name: git config
|
||||||
|
run: |
|
||||||
|
git config --global --get-all safe.directory | grep '^\*$' || git config --global --add safe.directory "*"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- if: matrix.ARCH == 'ARM'
|
||||||
|
uses: docker://hasufell/arm32v7-debian-haskell:10
|
||||||
|
name: Run build (armv7 linux)
|
||||||
|
with:
|
||||||
|
args: sh .github/scripts/build.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ env.S3_HOST }}
|
||||||
|
|
||||||
|
- if: matrix.ARCH == 'ARM64'
|
||||||
|
uses: docker://hasufell/arm64v8-debian-haskell:10
|
||||||
|
name: Run build (aarch64 linux)
|
||||||
|
with:
|
||||||
|
args: sh .github/scripts/build.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ env.S3_HOST }}
|
||||||
|
|
||||||
|
- if: always()
|
||||||
|
name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifacts
|
||||||
|
path: |
|
||||||
|
./out/*
|
||||||
|
|
||||||
|
build-macwin:
|
||||||
|
name: Build binary (Mac/Win)
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
CABAL_VER: 3.8.1.0
|
||||||
|
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ secrets.S3_HOST }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: [self-hosted, macOS, ARM64]
|
||||||
|
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
||||||
|
GHC_VER: 9.2.5
|
||||||
|
ARCH: ARM64
|
||||||
|
- os: macOS-10.15
|
||||||
|
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
||||||
|
GHC_VER: 9.2.5
|
||||||
|
ARCH: 64
|
||||||
|
- os: windows-latest
|
||||||
|
ARTIFACT: "x86_64-mingw64-ghcup"
|
||||||
|
GHC_VER: 8.10.7
|
||||||
|
ARCH: 64
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- if: matrix.ARCH == 'ARM64' && runner.os == 'macOS'
|
||||||
|
name: Run build
|
||||||
|
run: |
|
||||||
|
bash .github/scripts/brew.sh git coreutils llvm@11 autoconf automake
|
||||||
|
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$HOME/.brew/opt/llvm@11/bin:$PATH"
|
||||||
|
export CC="$HOME/.brew/opt/llvm@11/bin/clang"
|
||||||
|
export CXX="$HOME/.brew/opt/llvm@11/bin/clang++"
|
||||||
|
export LD=ld
|
||||||
|
export AR="$HOME/.brew/opt/llvm@11/bin/llvm-ar"
|
||||||
|
export RANLIB="$HOME/.brew/opt/llvm@11/bin/llvm-ranlib"
|
||||||
|
bash .github/scripts/build.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: na
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ env.S3_HOST }}
|
||||||
|
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
|
||||||
|
|
||||||
|
- if: matrix.ARCH == '64' && runner.os == 'macOS'
|
||||||
|
name: Run build (windows/mac)
|
||||||
|
run: |
|
||||||
|
bash .github/scripts/brew.sh coreutils
|
||||||
|
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH"
|
||||||
|
bash .github/scripts/build.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: na
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ env.S3_HOST }}
|
||||||
|
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
|
||||||
|
|
||||||
|
- if: runner.os == 'Windows'
|
||||||
|
name: Run build (windows/mac)
|
||||||
|
run: |
|
||||||
|
bash .github/scripts/brew.sh git coreutils autoconf automake
|
||||||
|
bash .github/scripts/build.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: na
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ env.S3_HOST }}
|
||||||
|
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
|
||||||
|
|
||||||
|
- if: always()
|
||||||
|
name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifacts
|
||||||
|
path: |
|
||||||
|
./out/*
|
||||||
|
|
||||||
|
test-linux:
|
||||||
|
name: Test linux
|
||||||
|
needs: "build-linux"
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
CABAL_VER: 3.8.1.0
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
ARTIFACT: "i386-linux-ghcup"
|
||||||
|
GHC_VER: 8.10.7
|
||||||
|
ARCH: 32
|
||||||
|
DISTRO: Alpine
|
||||||
|
- os: ubuntu-latest
|
||||||
|
ARTIFACT: "x86_64-linux-ghcup"
|
||||||
|
GHC_VER: 8.10.7
|
||||||
|
ARCH: 64
|
||||||
|
DISTRO: Alpine
|
||||||
|
- os: ubuntu-latest
|
||||||
|
ARTIFACT: "x86_64-linux-ghcup"
|
||||||
|
GHC_VER: 8.10.7
|
||||||
|
ARCH: 64
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifacts
|
||||||
|
path: ./out
|
||||||
|
|
||||||
|
- if: matrix.ARCH == '32' && matrix.DISTRO == 'Alpine'
|
||||||
|
name: Run test (32 bit linux Alpine)
|
||||||
|
uses: docker://hasufell/i386-alpine-haskell:3.12
|
||||||
|
with:
|
||||||
|
args: sh .github/scripts/test.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: ${{ matrix.DISTRO }}
|
||||||
|
|
||||||
|
- if: matrix.ARCH == '64' && matrix.DISTRO == 'Alpine'
|
||||||
|
name: Run test (64 bit linux Alpine)
|
||||||
|
uses: docker://hasufell/alpine-haskell:3.12
|
||||||
|
with:
|
||||||
|
args: sh .github/scripts/test.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: ${{ matrix.DISTRO }}
|
||||||
|
|
||||||
|
- if: matrix.DISTRO != 'Alpine'
|
||||||
|
name: Run test (64 bit linux)
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip
|
||||||
|
sh .github/scripts/test.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: ${{ matrix.DISTRO }}
|
||||||
|
|
||||||
|
- if: failure()
|
||||||
|
name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: testfiles
|
||||||
|
path: |
|
||||||
|
./test/golden/unix/GHCupInfo*json
|
||||||
|
|
||||||
|
test-arm:
|
||||||
|
name: Test ARM
|
||||||
|
needs: "build-arm"
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
CABAL_VER: 3.8.1.0
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: [self-hosted, Linux, ARM64, aarch32-linux]
|
||||||
|
ARTIFACT: "armv7-linux-ghcup"
|
||||||
|
GHC_VER: 9.2.2
|
||||||
|
ARCH: ARM
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
- os: [self-hosted, Linux, ARM64]
|
||||||
|
ARTIFACT: "aarch64-linux-ghcup"
|
||||||
|
GHC_VER: 9.2.5
|
||||||
|
ARCH: ARM64
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: docker://arm64v8/debian:10
|
||||||
|
name: Cleanup (aarch64 linux)
|
||||||
|
with:
|
||||||
|
args: "find . -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +"
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifacts
|
||||||
|
path: ./out
|
||||||
|
|
||||||
|
- if: matrix.ARCH == 'ARM'
|
||||||
|
uses: docker://hasufell/arm32v7-debian-haskell:10
|
||||||
|
name: Run test (armv7 linux)
|
||||||
|
with:
|
||||||
|
args: sh .github/scripts/test.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
|
||||||
|
- if: matrix.ARCH == 'ARM64'
|
||||||
|
uses: docker://hasufell/arm64v8-debian-haskell:10
|
||||||
|
name: Run test (aarch64 linux)
|
||||||
|
with:
|
||||||
|
args: sh .github/scripts/test.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
|
||||||
|
- if: failure()
|
||||||
|
name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: testfiles
|
||||||
|
path: |
|
||||||
|
./test/golden/unix/GHCupInfo*json
|
||||||
|
|
||||||
|
test-macwin:
|
||||||
|
name: Test Mac/Win
|
||||||
|
needs: "build-macwin"
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
CABAL_VER: 3.8.1.0
|
||||||
|
MACOSX_DEPLOYMENT_TARGET: 10.13
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: [self-hosted, macOS, ARM64]
|
||||||
|
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
||||||
|
GHC_VER: 9.2.5
|
||||||
|
ARCH: ARM64
|
||||||
|
DISTRO: na
|
||||||
|
- os: macOS-10.15
|
||||||
|
ARTIFACT: "x86_64-apple-darwin-ghcup"
|
||||||
|
GHC_VER: 9.2.5
|
||||||
|
ARCH: 64
|
||||||
|
DISTRO: na
|
||||||
|
- os: windows-latest
|
||||||
|
ARTIFACT: "x86_64-mingw64-ghcup"
|
||||||
|
GHC_VER: 8.10.7
|
||||||
|
ARCH: 64
|
||||||
|
DISTRO: na
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifacts
|
||||||
|
path: ./out
|
||||||
|
|
||||||
|
- if: runner.os == 'macOS'
|
||||||
|
name: Run test
|
||||||
|
run: |
|
||||||
|
bash .github/scripts/brew.sh coreutils
|
||||||
|
export PATH="$HOME/.brew/bin:$HOME/.brew/sbin:$PATH"
|
||||||
|
bash .github/scripts/test.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: ${{ matrix.DISTRO }}
|
||||||
|
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
|
||||||
|
|
||||||
|
- if: runner.os != 'macOS'
|
||||||
|
name: Run test
|
||||||
|
run: bash .github/scripts/test.sh
|
||||||
|
env:
|
||||||
|
ARTIFACT: ${{ matrix.ARTIFACT }}
|
||||||
|
ARCH: ${{ matrix.ARCH }}
|
||||||
|
GHC_VER: ${{ matrix.GHC_VER }}
|
||||||
|
DISTRO: ${{ matrix.DISTRO }}
|
||||||
|
HOMEBREW_CHANGE_ARCH_TO_ARM: 1
|
||||||
|
|
||||||
|
- if: failure() && runner.os == 'Windows'
|
||||||
|
name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: testfiles
|
||||||
|
path: |
|
||||||
|
./test/golden/windows/GHCupInfo*json
|
||||||
|
|
||||||
|
- if: failure() && runner.os != 'Windows'
|
||||||
|
name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: testfiles
|
||||||
|
path: |
|
||||||
|
./test/golden/unix/GHCupInfo*json
|
||||||
|
hls:
|
||||||
|
name: hls
|
||||||
|
needs: build-linux
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
GHC_VERSION: "8.10.7"
|
||||||
|
HLS_TARGET_VERSION: "1.8.0.0"
|
||||||
|
CABAL_VERSION: "3.8.1.0"
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
ARTIFACT: "x86_64-linux-ghcup"
|
||||||
|
DISTRO: Ubuntu
|
||||||
|
ARCH: 64
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
S3_HOST: ${{ secrets.S3_HOST }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifacts
|
||||||
|
path: ./out
|
||||||
|
|
||||||
|
- name: Run hls build
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip
|
||||||
|
sh .github/scripts/hls.sh
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: release
|
||||||
|
needs: ["test-linux", "test-arm", "test-macwin", "hls"]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
|
steps:
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifacts
|
||||||
|
path: ./out
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
draft: true
|
||||||
|
files: |
|
||||||
|
./out/*
|
||||||
|
|||||||
28
.github/workflows/shellcheck.yaml
vendored
Normal file
28
.github/workflows/shellcheck.yaml
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
name: Shellcheck
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
shellcheck:
|
||||||
|
name: shellcheck
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
JSON_VERSION: "0.0.7"
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
|
||||||
|
- name: Run shellcheck
|
||||||
|
uses: docker://koalaman/shellcheck-alpine
|
||||||
|
with:
|
||||||
|
args: shellcheck scripts/bootstrap/bootstrap-haskell
|
||||||
157
.gitlab-ci.yml
157
.gitlab-ci.yml
@@ -11,6 +11,13 @@ variables:
|
|||||||
# Commit of ghc/ci-images repository from which to pull Docker images
|
# Commit of ghc/ci-images repository from which to pull Docker images
|
||||||
DOCKER_REV: 8d0224e6b2a08157649651e69302380b2bd24e11
|
DOCKER_REV: 8d0224e6b2a08157649651e69302380b2bd24e11
|
||||||
|
|
||||||
|
# Sequential version number of all cached things.
|
||||||
|
# Bump to invalidate GitLab CI cache.
|
||||||
|
CACHE_REV: 1
|
||||||
|
|
||||||
|
GIT_SUBMODULE_STRATEGY: recursive
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# CI Step
|
# CI Step
|
||||||
############################################################
|
############################################################
|
||||||
@@ -111,13 +118,17 @@ variables:
|
|||||||
script:
|
script:
|
||||||
- bash ./.gitlab/script/ghcup_version.sh
|
- bash ./.gitlab/script/ghcup_version.sh
|
||||||
variables:
|
variables:
|
||||||
JSON_VERSION: "0.0.6"
|
JSON_VERSION: "0.0.7"
|
||||||
artifacts:
|
artifacts:
|
||||||
expire_in: 2 week
|
expire_in: 2 week
|
||||||
paths:
|
paths:
|
||||||
- test/golden
|
- test/golden
|
||||||
- dist-newstyle/cache/
|
- dist-newstyle/cache/
|
||||||
when: on_failure
|
when: on_failure
|
||||||
|
cache:
|
||||||
|
key: ghcup-test-$CACHE_REV
|
||||||
|
paths:
|
||||||
|
- cabal-cache
|
||||||
|
|
||||||
# .test_ghcup_scoop:
|
# .test_ghcup_scoop:
|
||||||
# script:
|
# script:
|
||||||
@@ -129,6 +140,10 @@ variables:
|
|||||||
- .debian
|
- .debian
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/linux/install_deps.sh
|
- ./.gitlab/before_script/linux/install_deps.sh
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
after_script:
|
||||||
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
|
- bash ./.gitlab/after_script.sh
|
||||||
|
|
||||||
.test_ghcup_version:linux32:
|
.test_ghcup_version:linux32:
|
||||||
extends:
|
extends:
|
||||||
@@ -136,6 +151,10 @@ variables:
|
|||||||
- .alpine:32bit
|
- .alpine:32bit
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/linux/alpine/install_deps.sh
|
- ./.gitlab/before_script/linux/alpine/install_deps.sh
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
after_script:
|
||||||
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
|
- bash ./.gitlab/after_script.sh
|
||||||
|
|
||||||
.test_ghcup_version:armv7:
|
.test_ghcup_version:armv7:
|
||||||
extends:
|
extends:
|
||||||
@@ -143,6 +162,10 @@ variables:
|
|||||||
- .linux:armv7
|
- .linux:armv7
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/linux/install_deps.sh
|
- ./.gitlab/before_script/linux/install_deps.sh
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
after_script:
|
||||||
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
|
- bash ./.gitlab/after_script.sh
|
||||||
|
|
||||||
.test_ghcup_version:aarch64:
|
.test_ghcup_version:aarch64:
|
||||||
extends:
|
extends:
|
||||||
@@ -150,71 +173,96 @@ variables:
|
|||||||
- .linux:aarch64
|
- .linux:aarch64
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/linux/install_deps.sh
|
- ./.gitlab/before_script/linux/install_deps.sh
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
after_script:
|
||||||
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
|
- bash ./.gitlab/after_script.sh
|
||||||
|
|
||||||
.test_ghcup_version:darwin:
|
.test_ghcup_version:darwin:
|
||||||
extends:
|
extends:
|
||||||
- .test_ghcup_version
|
- .test_ghcup_version
|
||||||
- .darwin
|
- .darwin
|
||||||
- .root_cleanup
|
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/darwin/install_deps.sh
|
- ./.gitlab/before_script/darwin/install_deps.sh
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
after_script:
|
||||||
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
|
- bash ./.gitlab/after_script.sh
|
||||||
|
|
||||||
.test_ghcup_version:darwin:aarch64:
|
.test_ghcup_version:darwin:aarch64:
|
||||||
extends:
|
extends:
|
||||||
- .test_ghcup_version
|
- .test_ghcup_version
|
||||||
- .darwin:aarch64
|
- .darwin:aarch64
|
||||||
- .root_cleanup
|
cache:
|
||||||
|
key: darwin-brew-$CACHE_REV
|
||||||
|
paths:
|
||||||
|
- brew_cache
|
||||||
|
key: ghcup-test-$CACHE_REV
|
||||||
|
paths:
|
||||||
|
- cabal-cache
|
||||||
|
before_script:
|
||||||
|
# extract brew cache
|
||||||
|
- ./.gitlab/script/ci.sh extract_brew_cache
|
||||||
|
# otherwise we seem to get intel binaries
|
||||||
|
- export HOMEBREW_CHANGE_ARCH_TO_ARM=1
|
||||||
|
# update and install packages
|
||||||
|
- /bin/bash ./.gitlab/script/brew.sh llvm autoconf automake coreutils
|
||||||
|
# extract cabal cache
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
script: |
|
script: |
|
||||||
set -Eeuo pipefail
|
export PATH="$CI_PROJECT_DIR/.brew/opt/llvm/bin:$CI_PROJECT_DIR/.brew/bin:$CI_PROJECT_DIR/.brew/sbin:$PATH"
|
||||||
function runInNixShell() {
|
export CC=$CI_PROJECT_DIR/.brew/opt/llvm/bin/clang
|
||||||
time nix-shell $CI_PROJECT_DIR/.gitlab/shell.nix \
|
export CXX=$CI_PROJECT_DIR/.brew/opt/llvm/bin/clang++
|
||||||
-I nixpkgs=https://github.com/angerman/nixpkgs/archive/75f7281738b.tar.gz \
|
export LD=ld
|
||||||
--argstr system "aarch64-darwin" \
|
export AR=$CI_PROJECT_DIR/.brew/opt/llvm/bin/llvm-ar
|
||||||
--pure \
|
export RANLIB=$CI_PROJECT_DIR/.brew/opt/llvm/bin/llvm-ranlib
|
||||||
--keep CI_PROJECT_DIR \
|
./.gitlab/before_script/darwin/install_deps.sh
|
||||||
--keep MACOSX_DEPLOYMENT_TARGET \
|
./.gitlab/script/ghcup_version.sh
|
||||||
--keep JSON_VERSION \
|
after_script:
|
||||||
--keep ARTIFACT \
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
--keep OS \
|
- ./.gitlab/script/ci.sh save_brew_cache
|
||||||
--keep ARCH \
|
- bash ./.gitlab/after_script.sh
|
||||||
--keep CABAL_DIR \
|
|
||||||
--keep GHC_VERSION \
|
|
||||||
--keep CABAL_VERSION \
|
|
||||||
--run "$1" 2>&1
|
|
||||||
}
|
|
||||||
runInNixShell ./.gitlab/before_script/darwin/install_deps.sh 2>&1
|
|
||||||
runInNixShell ./.gitlab/script/ghcup_version.sh 2>&1
|
|
||||||
|
|
||||||
.test_ghcup_version:freebsd12:
|
.test_ghcup_version:freebsd12:
|
||||||
extends:
|
extends:
|
||||||
- .test_ghcup_version
|
- .test_ghcup_version
|
||||||
- .freebsd12
|
- .freebsd12
|
||||||
- .root_cleanup
|
|
||||||
before_script:
|
before_script:
|
||||||
- ./.gitlab/before_script/freebsd/install_deps.sh
|
- ./.gitlab/before_script/freebsd/install_deps.sh
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
after_script:
|
||||||
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
|
- bash ./.gitlab/after_script.sh
|
||||||
|
|
||||||
.test_ghcup_version:freebsd13:
|
.test_ghcup_version:freebsd13:
|
||||||
extends:
|
extends:
|
||||||
- .test_ghcup_version
|
- .test_ghcup_version
|
||||||
- .freebsd13
|
- .freebsd13
|
||||||
- .root_cleanup
|
|
||||||
before_script:
|
before_script:
|
||||||
|
- sudo pkg update
|
||||||
|
- sudo pkg install --yes compat12x-amd64
|
||||||
|
- sudo ln -s libncurses.so.6 /usr/local/lib/libncurses.so.6.2
|
||||||
- ./.gitlab/before_script/freebsd/install_deps.sh
|
- ./.gitlab/before_script/freebsd/install_deps.sh
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
after_script:
|
||||||
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
|
- bash ./.gitlab/after_script.sh
|
||||||
|
|
||||||
.test_ghcup_version:windows:
|
.test_ghcup_version:windows:
|
||||||
extends:
|
extends:
|
||||||
- .test_ghcup_version
|
- .test_ghcup_version
|
||||||
- .windows
|
- .windows
|
||||||
- .root_cleanup
|
|
||||||
before_script:
|
before_script:
|
||||||
- set CABAL_DIR="$CI_PROJECT_DIR/cabal"
|
|
||||||
- bash ./.gitlab/before_script/windows/install_deps.sh
|
- bash ./.gitlab/before_script/windows/install_deps.sh
|
||||||
|
- bash ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
after_script:
|
||||||
|
- bash ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
|
- bash ./.gitlab/after_script.sh
|
||||||
|
|
||||||
# .test_ghcup_scoop:windows:
|
# .test_ghcup_scoop:windows:
|
||||||
# extends:
|
# extends:
|
||||||
# - .windows
|
# - .windows
|
||||||
# - .test_ghcup_scoop
|
# - .test_ghcup_scoop
|
||||||
# - .root_cleanup
|
|
||||||
|
|
||||||
.release_ghcup:
|
.release_ghcup:
|
||||||
script:
|
script:
|
||||||
@@ -227,16 +275,19 @@ variables:
|
|||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
variables:
|
variables:
|
||||||
JSON_VERSION: "0.0.6"
|
JSON_VERSION: "0.0.7"
|
||||||
|
|
||||||
######## stack test ########
|
######## stack test ########
|
||||||
|
|
||||||
test:linux:stack:
|
test:linux:stack:
|
||||||
stage: test
|
stage: test
|
||||||
before_script:
|
before_script:
|
||||||
|
- ./.gitlab/script/ci.sh extract_stack_cache
|
||||||
- ./.gitlab/before_script/linux/install_deps_minimal.sh
|
- ./.gitlab/before_script/linux/install_deps_minimal.sh
|
||||||
script:
|
script:
|
||||||
- ./.gitlab/script/ghcup_stack.sh
|
- ./.gitlab/script/ghcup_stack.sh
|
||||||
|
after_script:
|
||||||
|
- ./.gitlab/script/ci.sh save_stack_cache
|
||||||
extends:
|
extends:
|
||||||
- .debian
|
- .debian
|
||||||
needs: []
|
needs: []
|
||||||
@@ -266,6 +317,7 @@ test:windows:bootstrap_powershell_script:
|
|||||||
- "[Environment]::SetEnvironmentVariable('GHCUP_MSYS2', $null, [System.EnvironmentVariableTarget]::User)"
|
- "[Environment]::SetEnvironmentVariable('GHCUP_MSYS2', $null, [System.EnvironmentVariableTarget]::User)"
|
||||||
- "[Environment]::SetEnvironmentVariable('CABAL_DIR', $null, [System.EnvironmentVariableTarget]::User)"
|
- "[Environment]::SetEnvironmentVariable('CABAL_DIR', $null, [System.EnvironmentVariableTarget]::User)"
|
||||||
- bash ./.gitlab/after_script.sh
|
- bash ./.gitlab/after_script.sh
|
||||||
|
- bash ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
variables:
|
variables:
|
||||||
GHC_VERSION: "8.10.7"
|
GHC_VERSION: "8.10.7"
|
||||||
CABAL_VERSION: "3.6.2.0"
|
CABAL_VERSION: "3.6.2.0"
|
||||||
@@ -388,6 +440,7 @@ test:mac:aarch64:
|
|||||||
CABAL_VERSION: "3.6.2.0"
|
CABAL_VERSION: "3.6.2.0"
|
||||||
needs: []
|
needs: []
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
|
||||||
######## freebsd test ########
|
######## freebsd test ########
|
||||||
@@ -508,32 +561,39 @@ release:darwin:aarch64:
|
|||||||
- .darwin:aarch64
|
- .darwin:aarch64
|
||||||
- .release_ghcup
|
- .release_ghcup
|
||||||
- .root_cleanup
|
- .root_cleanup
|
||||||
|
cache:
|
||||||
|
key: darwin-brew-$CACHE_REV
|
||||||
|
paths:
|
||||||
|
- brew_cache
|
||||||
|
key: ghcup-test-$CACHE_REV
|
||||||
|
paths:
|
||||||
|
- cabal-cache
|
||||||
|
before_script:
|
||||||
|
- ./.gitlab/script/ci.sh extract_brew_cache
|
||||||
|
- ./.gitlab/script/ci.sh extract_cabal_cache
|
||||||
|
# otherwise we seem to get intel binaries
|
||||||
|
- export HOMEBREW_CHANGE_ARCH_TO_ARM=1
|
||||||
|
# update and install packages
|
||||||
|
- /bin/bash ./.gitlab/script/brew.sh llvm autoconf automake coreutils
|
||||||
script: |
|
script: |
|
||||||
set -Eeuo pipefail
|
export PATH="$CI_PROJECT_DIR/.brew/opt/llvm/bin:$CI_PROJECT_DIR/.brew/bin:$CI_PROJECT_DIR/.brew/sbin:$PATH"
|
||||||
function runInNixShell() {
|
export CC=$CI_PROJECT_DIR/.brew/opt/llvm/bin/clang
|
||||||
time nix-shell $CI_PROJECT_DIR/.gitlab/shell.nix \
|
export CXX=$CI_PROJECT_DIR/.brew/opt/llvm/bin/clang++
|
||||||
-I nixpkgs=https://github.com/angerman/nixpkgs/archive/75f7281738b.tar.gz \
|
export LD=ld
|
||||||
--argstr system "aarch64-darwin" \
|
export AR=$CI_PROJECT_DIR/.brew/opt/llvm/bin/llvm-ar
|
||||||
--pure \
|
export RANLIB=$CI_PROJECT_DIR/.brew/opt/llvm/bin/llvm-ranlib
|
||||||
--keep CI_PROJECT_DIR \
|
./.gitlab/before_script/darwin/install_deps.sh
|
||||||
--keep MACOSX_DEPLOYMENT_TARGET \
|
./.gitlab/script/ghcup_release.sh
|
||||||
--keep JSON_VERSION \
|
after_script:
|
||||||
--keep ARTIFACT \
|
- ./.gitlab/script/ci.sh save_cabal_cache
|
||||||
--keep OS \
|
- ./.gitlab/script/ci.sh save_brew_cache
|
||||||
--keep ARCH \
|
|
||||||
--keep CABAL_DIR \
|
|
||||||
--keep GHC_VERSION \
|
|
||||||
--keep CABAL_VERSION \
|
|
||||||
--run "$1" 2>&1
|
|
||||||
}
|
|
||||||
runInNixShell ./.gitlab/before_script/darwin/install_deps.sh 2>&1
|
|
||||||
runInNixShell ./.gitlab/script/ghcup_release.sh 2>&1
|
|
||||||
variables:
|
variables:
|
||||||
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
ARTIFACT: "aarch64-apple-darwin-ghcup"
|
||||||
GHC_VERSION: "8.10.7"
|
GHC_VERSION: "8.10.7"
|
||||||
CABAL_VERSION: "3.6.2.0"
|
CABAL_VERSION: "3.6.2.0"
|
||||||
MACOSX_DEPLOYMENT_TARGET: "10.7"
|
MACOSX_DEPLOYMENT_TARGET: "10.7"
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
|
||||||
######## freebsd release ########
|
######## freebsd release ########
|
||||||
@@ -561,6 +621,9 @@ release:freebsd13:
|
|||||||
- .release_ghcup
|
- .release_ghcup
|
||||||
- .root_cleanup
|
- .root_cleanup
|
||||||
before_script:
|
before_script:
|
||||||
|
- sudo pkg update
|
||||||
|
- sudo pkg install --yes compat12x-amd64
|
||||||
|
- sudo ln -s libncurses.so.6 /usr/local/lib/libncurses.so.6.2
|
||||||
- ./.gitlab/before_script/freebsd/install_deps.sh
|
- ./.gitlab/before_script/freebsd/install_deps.sh
|
||||||
variables:
|
variables:
|
||||||
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
ARTIFACT: "x86_64-portbld-freebsd-ghcup"
|
||||||
|
|||||||
@@ -12,4 +12,8 @@ if [ "${OS}" = "WINDOWS" ] ; then
|
|||||||
rm -Rf /c/ghcup
|
rm -Rf /c/ghcup
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
|
rm -Rf /private/tmp/.brew_tmp
|
||||||
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -8,7 +8,15 @@ set -eux
|
|||||||
|
|
||||||
mkdir -p "${TMPDIR}"
|
mkdir -p "${TMPDIR}"
|
||||||
|
|
||||||
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-portbld-freebsd-ghcup > ./ghcup-bin
|
if freebsd-version | grep -E '^12.*' ; then
|
||||||
|
freebsd_ver=12
|
||||||
|
elif freebsd-version | grep -E '^13.*' ; then
|
||||||
|
freebsd_ver=13
|
||||||
|
else
|
||||||
|
(>&2 echo "Unsupported FreeBSD version! Please report a bug at https://gitlab.haskell.org/haskell/ghcup-hs/-/issues")
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-freebsd${freebsd_ver}-ghcup > ./ghcup-bin
|
||||||
chmod +x ghcup-bin
|
chmod +x ghcup-bin
|
||||||
|
|
||||||
./ghcup-bin -v upgrade -i -f
|
./ghcup-bin -v upgrade -i -f
|
||||||
|
|||||||
37
.gitlab/ghcup-run.files
Normal file
37
.gitlab/ghcup-run.files
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.
|
||||||
|
./cabal
|
||||||
|
./ghc
|
||||||
|
./ghc-8.10.7
|
||||||
|
./ghc-pkg
|
||||||
|
./ghc-pkg-8.10.7
|
||||||
|
./ghci
|
||||||
|
./ghci-8.10.7
|
||||||
|
./haddock
|
||||||
|
./haddock-8.10.7
|
||||||
|
./haskell-language-server-8.10.6
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0
|
||||||
|
./haskell-language-server-8.10.7
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0
|
||||||
|
./haskell-language-server-8.6.5
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0
|
||||||
|
./haskell-language-server-8.8.4
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0
|
||||||
|
./haskell-language-server-9.0.1
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0
|
||||||
|
./haskell-language-server-9.0.2
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0
|
||||||
|
./haskell-language-server-9.2.1
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0
|
||||||
|
./haskell-language-server-wrapper
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0
|
||||||
|
./hp2ps
|
||||||
|
./hp2ps-8.10.7
|
||||||
|
./hpc
|
||||||
|
./hpc-8.10.7
|
||||||
|
./hsc2hs
|
||||||
|
./hsc2hs-8.10.7
|
||||||
|
./runghc
|
||||||
|
./runghc-8.10.7
|
||||||
|
./runhaskell
|
||||||
|
./runhaskell-8.10.7
|
||||||
|
./stack
|
||||||
81
.gitlab/ghcup-run.files.windows
Normal file
81
.gitlab/ghcup-run.files.windows
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
.
|
||||||
|
./cabal.exe
|
||||||
|
./cabal.shim
|
||||||
|
./ghc-8.10.7.exe
|
||||||
|
./ghc-8.10.7.shim
|
||||||
|
./ghc-pkg-8.10.7.exe
|
||||||
|
./ghc-pkg-8.10.7.shim
|
||||||
|
./ghc-pkg.exe
|
||||||
|
./ghc-pkg.shim
|
||||||
|
./ghc.exe
|
||||||
|
./ghc.shim
|
||||||
|
./ghci-8.10.7.exe
|
||||||
|
./ghci-8.10.7.shim
|
||||||
|
./ghci.exe
|
||||||
|
./ghci.shim
|
||||||
|
./ghcii-8.10.7.sh-8.10.7.exe
|
||||||
|
./ghcii-8.10.7.sh-8.10.7.shim
|
||||||
|
./ghcii-8.10.7.sh.exe
|
||||||
|
./ghcii-8.10.7.sh.shim
|
||||||
|
./ghcii.sh-8.10.7.exe
|
||||||
|
./ghcii.sh-8.10.7.shim
|
||||||
|
./ghcii.sh.exe
|
||||||
|
./ghcii.sh.shim
|
||||||
|
./haddock-8.10.7.exe
|
||||||
|
./haddock-8.10.7.shim
|
||||||
|
./haddock.exe
|
||||||
|
./haddock.shim
|
||||||
|
./haskell-language-server-8.10.6.exe
|
||||||
|
./haskell-language-server-8.10.6.shim
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.10.6~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.10.7.exe
|
||||||
|
./haskell-language-server-8.10.7.shim
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.10.7~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.6.5.exe
|
||||||
|
./haskell-language-server-8.6.5.shim
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.6.5~1.6.1.0.shim
|
||||||
|
./haskell-language-server-8.8.4.exe
|
||||||
|
./haskell-language-server-8.8.4.shim
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0.exe
|
||||||
|
./haskell-language-server-8.8.4~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.0.1.exe
|
||||||
|
./haskell-language-server-9.0.1.shim
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.0.1~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.0.2.exe
|
||||||
|
./haskell-language-server-9.0.2.shim
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.0.2~1.6.1.0.shim
|
||||||
|
./haskell-language-server-9.2.1.exe
|
||||||
|
./haskell-language-server-9.2.1.shim
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0.exe
|
||||||
|
./haskell-language-server-9.2.1~1.6.1.0.shim
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0.exe
|
||||||
|
./haskell-language-server-wrapper-1.6.1.0.shim
|
||||||
|
./haskell-language-server-wrapper.exe
|
||||||
|
./haskell-language-server-wrapper.shim
|
||||||
|
./hp2ps-8.10.7.exe
|
||||||
|
./hp2ps-8.10.7.shim
|
||||||
|
./hp2ps.exe
|
||||||
|
./hp2ps.shim
|
||||||
|
./hpc-8.10.7.exe
|
||||||
|
./hpc-8.10.7.shim
|
||||||
|
./hpc.exe
|
||||||
|
./hpc.shim
|
||||||
|
./hsc2hs-8.10.7.exe
|
||||||
|
./hsc2hs-8.10.7.shim
|
||||||
|
./hsc2hs.exe
|
||||||
|
./hsc2hs.shim
|
||||||
|
./runghc-8.10.7.exe
|
||||||
|
./runghc-8.10.7.shim
|
||||||
|
./runghc.exe
|
||||||
|
./runghc.shim
|
||||||
|
./runhaskell-8.10.7.exe
|
||||||
|
./runhaskell-8.10.7.shim
|
||||||
|
./runhaskell.exe
|
||||||
|
./runhaskell.shim
|
||||||
|
./stack.exe
|
||||||
|
./stack.shim
|
||||||
@@ -1,11 +1,23 @@
|
|||||||
if [ "${OS}" = "WINDOWS" ] ; then
|
if [ "${OS}" = "WINDOWS" ] ; then
|
||||||
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
||||||
export GHCUP_BIN="$CI_PROJECT_DIR/ghcup/bin"
|
export GHCUP_BIN="$CI_PROJECT_DIR/ghcup/bin"
|
||||||
export PATH="$GHCUP_BIN:$CI_PROJECT_DIR/.local/bin:$PATH"
|
export PATH="$GHCUP_BIN:$CI_PROJECT_DIR/.local/bin:$PATH"
|
||||||
export TMPDIR="$CI_PROJECT_DIR/tmp"
|
export TMPDIR="$CI_PROJECT_DIR/tmp"
|
||||||
|
export CABAL_DIR="$CI_PROJECT_DIR/cabal"
|
||||||
|
export CABAL_CACHE="$CI_PROJECT_DIR/cabal-cache"
|
||||||
|
export STACK_ROOT="$CI_PROJECT_DIR/stack"
|
||||||
|
export STACK_CACHE="$CI_PROJECT_DIR/stack-cache"
|
||||||
|
export BREW_DIR="$CI_PROJECT_DIR/.brew_cache"
|
||||||
|
export BREW_CACHE="$CI_PROJECT_DIR/brew-cache"
|
||||||
else
|
else
|
||||||
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR"
|
||||||
export GHCUP_BIN="$CI_PROJECT_DIR/.ghcup/bin"
|
export GHCUP_BIN="$CI_PROJECT_DIR/.ghcup/bin"
|
||||||
export PATH="$GHCUP_BIN:$CI_PROJECT_DIR/.local/bin:/opt/llvm/bin:$PATH"
|
export PATH="$GHCUP_BIN:$CI_PROJECT_DIR/.local/bin:$PATH"
|
||||||
export TMPDIR="$CI_PROJECT_DIR/tmp"
|
export TMPDIR="$CI_PROJECT_DIR/tmp"
|
||||||
|
export CABAL_DIR="$CI_PROJECT_DIR/cabal"
|
||||||
|
export CABAL_CACHE="$CI_PROJECT_DIR/cabal-cache"
|
||||||
|
export STACK_ROOT="$CI_PROJECT_DIR/stack"
|
||||||
|
export STACK_CACHE="$CI_PROJECT_DIR/stack-cache"
|
||||||
|
export BREW_DIR="$CI_PROJECT_DIR/.brew_cache"
|
||||||
|
export BREW_CACHE="$CI_PROJECT_DIR/brew-cache"
|
||||||
fi
|
fi
|
||||||
|
|||||||
19
.gitlab/script/brew.sh
Executable file
19
.gitlab/script/brew.sh
Executable file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -Eeuxo pipefail
|
||||||
|
|
||||||
|
# Install brew locally in the project dir. Packages will also be installed here.
|
||||||
|
[ -e "$CI_PROJECT_DIR/.brew" ] || git clone --depth=1 https://github.com/Homebrew/brew $CI_PROJECT_DIR/.brew
|
||||||
|
export PATH="$CI_PROJECT_DIR/.brew/bin:$CI_PROJECT_DIR/.brew/sbin:$PATH"
|
||||||
|
|
||||||
|
# make sure to not pollute the machine with temp files etc
|
||||||
|
mkdir -p $CI_PROJECT_DIR/.brew_cache
|
||||||
|
export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
||||||
|
mkdir -p $CI_PROJECT_DIR/.brew_logs
|
||||||
|
export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
||||||
|
mkdir -p /private/tmp/.brew_tmp
|
||||||
|
export HOMEBREW_TEMP=/private/tmp/.brew_tmp
|
||||||
|
|
||||||
|
# update and install packages
|
||||||
|
brew update
|
||||||
|
brew install ${1+"$@"}
|
||||||
70
.gitlab/script/ci.sh
Executable file
70
.gitlab/script/ci.sh
Executable file
@@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
TOP="$( cd "$(dirname "$0")" ; pwd -P )"
|
||||||
|
. "${TOP}/../ghcup_env"
|
||||||
|
|
||||||
|
function save_cabal_cache () {
|
||||||
|
echo "Storing cabal cache from $CABAL_DIR to $CABAL_CACHE..."
|
||||||
|
rm -Rf "$CABAL_CACHE"
|
||||||
|
mkdir -p "$CABAL_CACHE"
|
||||||
|
if [ -d "$CABAL_DIR" ]; then
|
||||||
|
cp -Rf "$CABAL_DIR" "$CABAL_CACHE/"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function extract_cabal_cache () {
|
||||||
|
if [ -d "$CABAL_CACHE" ]; then
|
||||||
|
echo "Extracting cabal cache from $CABAL_CACHE to $CABAL_DIR..."
|
||||||
|
mkdir -p "$CABAL_DIR"
|
||||||
|
cp -Rf "$CABAL_CACHE"/* "$CABAL_DIR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_stack_cache () {
|
||||||
|
echo "Storing stack cache from $STACK_ROOT to $STACK_CACHE..."
|
||||||
|
rm -Rf "$STACK_CACHE"
|
||||||
|
mkdir -p "$STACK_CACHE"
|
||||||
|
if [ -d "$STACK_ROOT" ]; then
|
||||||
|
cp -Rf "$STACK_DIR" "$STACK_CACHE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function extract_stack_cache () {
|
||||||
|
if [ -d "$STACK_CACHE" ]; then
|
||||||
|
echo "Extracting stack cache from $STACK_CACHE to $STACK_ROOT..."
|
||||||
|
mkdir -p "$STACK_ROOT"
|
||||||
|
cp -Rf "$STACK_CACHE"/* "$STACK_ROOT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_brew_cache () {
|
||||||
|
echo "Storing brew cache from $BREW_DIR to $BREW_CACHE..."
|
||||||
|
rm -Rf "$BREW_CACHE"
|
||||||
|
mkdir -p "$BREW_CACHE"
|
||||||
|
if [ -d "$BREW_DIR" ]; then
|
||||||
|
cp -Rf "$BREW_DIR" "$BREW_CACHE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function extract_brew_cache () {
|
||||||
|
if [ -d "$BREW_CACHE" ]; then
|
||||||
|
echo "Extracting stack cache from $BREW_CACHE to $BREW_DIR..."
|
||||||
|
mkdir -p "$BREW_DIR"
|
||||||
|
cp -Rf "$BREW_CACHE"/* "$BREW_DIR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
extract_cabal_cache) extract_cabal_cache ;;
|
||||||
|
save_cabal_cache) save_cabal_cache ;;
|
||||||
|
extract_stack_cache) extract_stack_cache ;;
|
||||||
|
save_stack_cache) save_stack_cache ;;
|
||||||
|
extract_brew_cache) extract_brew_cache ;;
|
||||||
|
save_brew_cache) save_brew_cache ;;
|
||||||
|
*) echo "unknown mode $1" ; exit 11 ;;
|
||||||
|
esac
|
||||||
@@ -6,20 +6,10 @@ set -eux
|
|||||||
|
|
||||||
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
||||||
|
|
||||||
ecabal() {
|
|
||||||
cabal "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
eghcup() {
|
|
||||||
ghcup -v -c -s file://$(pwd)/ghcup-${JSON_VERSION}.yaml "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
git describe --always
|
git describe --always
|
||||||
|
|
||||||
### build
|
### build
|
||||||
|
|
||||||
ecabal update
|
|
||||||
|
|
||||||
export BOOTSTRAP_HASKELL_NONINTERACTIVE=yes
|
export BOOTSTRAP_HASKELL_NONINTERACTIVE=yes
|
||||||
export BOOTSTRAP_HASKELL_GHC_VERSION=$GHC_VERSION
|
export BOOTSTRAP_HASKELL_GHC_VERSION=$GHC_VERSION
|
||||||
export BOOTSTRAP_HASKELL_CABAL_VERSION=$CABAL_VERSION
|
export BOOTSTRAP_HASKELL_CABAL_VERSION=$CABAL_VERSION
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ cabal --version
|
|||||||
|
|
||||||
eghcup debug-info
|
eghcup debug-info
|
||||||
|
|
||||||
eghcup compile hls -j $(nproc) -v ${HLS_TARGET_VERSION} ${GHC_VERSION}
|
eghcup compile hls -j $(nproc) -v ${HLS_TARGET_VERSION} --ghc ${GHC_VERSION}
|
||||||
|
|
||||||
[ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version` = "${HLS_TARGET_VERSION}" ] || [ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version | sed 's/.0$//'` = "${HLS_TARGET_VERSION}" ]
|
[ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version` = "${HLS_TARGET_VERSION}" ] || [ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version | sed 's/.0$//'` = "${HLS_TARGET_VERSION}" ]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -eux
|
set -eux
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@ mkdir -p "$CI_PROJECT_DIR"/.local/bin
|
|||||||
|
|
||||||
CI_PROJECT_DIR=$(pwd)
|
CI_PROJECT_DIR=$(pwd)
|
||||||
|
|
||||||
|
|
||||||
ecabal() {
|
ecabal() {
|
||||||
cabal "$@"
|
cabal "$@"
|
||||||
}
|
}
|
||||||
@@ -34,6 +35,8 @@ git describe --always
|
|||||||
|
|
||||||
### build
|
### build
|
||||||
|
|
||||||
|
rm -rf "${GHCUP_DIR}"/share
|
||||||
|
|
||||||
ecabal update
|
ecabal update
|
||||||
|
|
||||||
if [ "${OS}" = "DARWIN" ] ; then
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
@@ -83,7 +86,6 @@ else
|
|||||||
ext=''
|
ext=''
|
||||||
fi
|
fi
|
||||||
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" "$CI_PROJECT_DIR"/.local/bin/ghcup${ext}
|
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" "$CI_PROJECT_DIR"/.local/bin/ghcup${ext}
|
||||||
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup-gen')" "$CI_PROJECT_DIR"/.local/bin/ghcup-gen${ext}
|
|
||||||
|
|
||||||
### cleanup
|
### cleanup
|
||||||
|
|
||||||
@@ -92,19 +94,41 @@ rm -rf "${GHCUP_DIR}"
|
|||||||
### manual cli based testing
|
### manual cli based testing
|
||||||
|
|
||||||
|
|
||||||
ghcup-gen check -f data/metadata/ghcup-${JSON_VERSION}.yaml
|
|
||||||
|
|
||||||
eghcup --numeric-version
|
eghcup --numeric-version
|
||||||
|
|
||||||
eghcup install ghc ${GHC_VERSION}
|
eghcup install ghc ${GHC_VERSION}
|
||||||
[ `$(eghcup whereis ghc ${GHC_VERSION}) --numeric-version` = "${GHC_VERSION}" ]
|
eghcup unset ghc ${GHC_VERSION}
|
||||||
|
ls -lah "$(eghcup whereis -d ghc ${GHC_VERSION})"
|
||||||
|
[ "`$(eghcup whereis ghc ${GHC_VERSION}) --numeric-version`" = "${GHC_VERSION}" ]
|
||||||
|
[ "`eghcup run --ghc ${GHC_VERSION} -- ghc --numeric-version`" = "${GHC_VERSION}" ]
|
||||||
|
[ "`ghcup run --ghc ${GHC_VERSION} -- ghc -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)'`" = "`$(ghcup whereis ghc ${GHC_VERSION}) -e 'Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)'`" ]
|
||||||
eghcup set ghc ${GHC_VERSION}
|
eghcup set ghc ${GHC_VERSION}
|
||||||
eghcup install cabal ${CABAL_VERSION}
|
eghcup install cabal ${CABAL_VERSION}
|
||||||
[ `$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version` = "${CABAL_VERSION}" ]
|
[ "`$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version`" = "${CABAL_VERSION}" ]
|
||||||
eghcup unset cabal
|
eghcup unset cabal
|
||||||
"$GHCUP_BIN"/cabal --version && exit || echo yes
|
"$GHCUP_BIN"/cabal --version && exit 1 || echo yes
|
||||||
|
|
||||||
|
# make sure no cabal is set when running 'ghcup run' to check that PATH propagages properly
|
||||||
|
# https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
||||||
|
[ "`eghcup run --cabal ${CABAL_VERSION} -- cabal --numeric-version`" = "${CABAL_VERSION}" ]
|
||||||
eghcup set cabal ${CABAL_VERSION}
|
eghcup set cabal ${CABAL_VERSION}
|
||||||
[ `$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version` = "${CABAL_VERSION}" ]
|
|
||||||
|
[ "`$(eghcup whereis cabal ${CABAL_VERSION}) --numeric-version`" = "${CABAL_VERSION}" ]
|
||||||
|
|
||||||
|
if [ "${OS}" != "FREEBSD" ] ; then
|
||||||
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
|
eghcup run --ghc 8.10.7 --cabal 3.4.1.0 --hls 1.6.1.0 --stack 2.7.3 --install --bindir "$(pwd)/.bin"
|
||||||
|
if [ "${OS}" == "WINDOWS" ] ; then
|
||||||
|
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup-run.files.windows" | sort)
|
||||||
|
else
|
||||||
|
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghcup-run.files" | sort)
|
||||||
|
fi
|
||||||
|
actual=$(cd ".bin" && find . | sort)
|
||||||
|
[ "${actual}" = "${expected}" ]
|
||||||
|
unset actual expected
|
||||||
|
rm -rf .bin
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
cabal --version
|
cabal --version
|
||||||
|
|
||||||
@@ -134,7 +158,7 @@ else
|
|||||||
eghcup --offline install ghc 8.10.3
|
eghcup --offline install ghc 8.10.3
|
||||||
if [ "${ARCH}" = "64" ] ; then
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-linux.files" | sort)
|
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-linux.files" | sort)
|
||||||
actual=$(cd "${GHCUP_DIR}/ghc/8.10.3/" && find | sort)
|
actual=$(cd "${GHCUP_DIR}/ghc/8.10.3/" && find . | sort)
|
||||||
[ "${actual}" = "${expected}" ]
|
[ "${actual}" = "${expected}" ]
|
||||||
unset actual expected
|
unset actual expected
|
||||||
fi
|
fi
|
||||||
@@ -142,7 +166,7 @@ else
|
|||||||
eghcup prefetch ghc 8.10.3
|
eghcup prefetch ghc 8.10.3
|
||||||
eghcup --offline install ghc 8.10.3
|
eghcup --offline install ghc 8.10.3
|
||||||
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-windows.files" | sort)
|
expected=$(cat "$( cd "$(dirname "$0")" ; pwd -P )/../ghc-8.10.3-windows.files" | sort)
|
||||||
actual=$(cd "${GHCUP_DIR}/ghc/8.10.3/" && find | sort)
|
actual=$(cd "${GHCUP_DIR}/ghc/8.10.3/" && find . | sort)
|
||||||
[ "${actual}" = "${expected}" ]
|
[ "${actual}" = "${expected}" ]
|
||||||
unset actual expected
|
unset actual expected
|
||||||
else
|
else
|
||||||
@@ -156,12 +180,14 @@ else
|
|||||||
eghcup set ${GHC_VERSION}
|
eghcup set ${GHC_VERSION}
|
||||||
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||||
eghcup unset ghc
|
eghcup unset ghc
|
||||||
"$GHCUP_BIN"/ghc --numeric-version && exit || echo yes
|
"$GHCUP_BIN"/ghc --numeric-version && exit 1 || echo yes
|
||||||
eghcup set ${GHC_VERSION}
|
eghcup set ${GHC_VERSION}
|
||||||
eghcup --offline rm 8.10.3
|
eghcup --offline rm 8.10.3
|
||||||
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
[ "$(ghc --numeric-version)" = "${ghc_ver}" ]
|
||||||
|
|
||||||
|
|
||||||
|
ls -lah "$GHCUP_BIN"
|
||||||
|
|
||||||
if [ "${OS}" = "DARWIN" ] ; then
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
eghcup install hls
|
eghcup install hls
|
||||||
$(eghcup whereis hls) --version
|
$(eghcup whereis hls) --version
|
||||||
@@ -173,16 +199,18 @@ else
|
|||||||
eghcup install hls
|
eghcup install hls
|
||||||
haskell-language-server-wrapper --version
|
haskell-language-server-wrapper --version
|
||||||
eghcup unset hls
|
eghcup unset hls
|
||||||
"$GHCUP_BIN"/haskell-language-server-wrapper --version && exit || echo yes
|
"$GHCUP_BIN"/haskell-language-server-wrapper --version && exit 1 || echo yes
|
||||||
|
|
||||||
eghcup install stack
|
eghcup install stack
|
||||||
stack --version
|
stack --version
|
||||||
eghcup unset hls
|
eghcup unset stack
|
||||||
"$GHCUP_BIN"/stack --version && exit || echo yes
|
"$GHCUP_BIN"/stack --version && exit 1 || echo yes
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# check that lazy loading works for 'whereis'
|
# check that lazy loading works for 'whereis'
|
||||||
cp "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml.bak"
|
cp "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml" "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml.bak"
|
||||||
echo '**' > "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml"
|
echo '**' > "$CI_PROJECT_DIR/data/metadata/ghcup-${JSON_VERSION}.yaml"
|
||||||
@@ -194,11 +222,13 @@ eghcup rm $(ghc --numeric-version)
|
|||||||
# https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/116
|
# https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/116
|
||||||
if [ "${OS}" = "LINUX" ] ; then
|
if [ "${OS}" = "LINUX" ] ; then
|
||||||
if [ "${ARCH}" = "64" ] ; then
|
if [ "${ARCH}" = "64" ] ; then
|
||||||
eghcup install cabal -u https://oleg.fi/cabal-install-3.4.0.0-rc4/cabal-install-3.4.0.0-x86_64-ubuntu-16.04.tar.xz 3.4.0.0-rc4
|
eghcup install cabal -u https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal/3.7.0.0-pre20220407/cabal-install-3.7-x86_64-linux-alpine.tar.xz 3.4.0.0-rc4
|
||||||
eghcup rm cabal 3.4.0.0-rc4
|
eghcup rm cabal 3.4.0.0-rc4
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
eghcup gc -c
|
||||||
|
|
||||||
sha_sum() {
|
sha_sum() {
|
||||||
if [ "${OS}" = "FREEBSD" ] ; then
|
if [ "${OS}" = "FREEBSD" ] ; then
|
||||||
sha256 "$@"
|
sha256 "$@"
|
||||||
@@ -246,13 +276,39 @@ if [ "${ARCH}" = "64" ] ; then
|
|||||||
eghcup install hls -i "$(pwd)/isolated" 1.3.0
|
eghcup install hls -i "$(pwd)/isolated" 1.3.0
|
||||||
[ "$(isolated/haskell-language-server-wrapper --numeric-version)" = "1.3.0" ] ||
|
[ "$(isolated/haskell-language-server-wrapper --numeric-version)" = "1.3.0" ] ||
|
||||||
[ "$(isolated/haskell-language-server-wrapper --numeric-version)" = "1.3.0.0" ]
|
[ "$(isolated/haskell-language-server-wrapper --numeric-version)" = "1.3.0.0" ]
|
||||||
|
|
||||||
|
# test that isolated installs don't clean up target directory
|
||||||
|
cat <<EOF > "${GHCUP_BIN}/gmake"
|
||||||
|
#!/bin/bash
|
||||||
|
exit 1
|
||||||
|
EOF
|
||||||
|
chmod +x "${GHCUP_BIN}/gmake"
|
||||||
|
mkdir isolated_tainted/
|
||||||
|
touch isolated_tainted/lol
|
||||||
|
|
||||||
|
! eghcup install ghc -i "$(pwd)/isolated_tainted" 8.10.5 --force
|
||||||
|
[ -e "$(pwd)/isolated_tainted/lol" ]
|
||||||
|
rm "${GHCUP_BIN}/gmake"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
eghcup upgrade
|
eghcup upgrade
|
||||||
eghcup upgrade -f
|
eghcup upgrade -f
|
||||||
|
|
||||||
|
# test that doing fishy symlinks into GHCup dir doesn't cause weird stuff on 'ghcup nuke'
|
||||||
|
mkdir no_nuke/
|
||||||
|
mkdir no_nuke/bar
|
||||||
|
echo 'foo' > no_nuke/file
|
||||||
|
echo 'bar' > no_nuke/bar/file
|
||||||
|
ln -s "$CI_PROJECT_DIR"/no_nuke/ "${GHCUP_DIR}"/cache/no_nuke
|
||||||
|
ln -s "$CI_PROJECT_DIR"/no_nuke/ "${GHCUP_DIR}"/logs/no_nuke
|
||||||
|
|
||||||
# nuke
|
# nuke
|
||||||
eghcup nuke
|
eghcup nuke
|
||||||
[ ! -e "${GHCUP_DIR}" ]
|
[ ! -e "${GHCUP_DIR}" ]
|
||||||
|
|
||||||
|
# make sure nuke doesn't resolve symlinks
|
||||||
|
[ -e "$CI_PROJECT_DIR"/no_nuke/file ]
|
||||||
|
[ -e "$CI_PROJECT_DIR"/no_nuke/bar/file ]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
{ system ? "aarch64-darwin"
|
|
||||||
#, nixpkgs ? fetchTarball https://github.com/angerman/nixpkgs/archive/257cb120334.tar.gz #apple-silicon.tar.gz
|
|
||||||
, pkgs ? import <nixpkgs> { inherit system; }
|
|
||||||
, compiler ? if system == "aarch64-darwin" then "ghc8103Binary" else "ghc8103"
|
|
||||||
}: pkgs.mkShell {
|
|
||||||
# this prevents nix from trying to write the env-vars file.
|
|
||||||
# we can't really, as NIX_BUILD_TOP/env-vars is not set.
|
|
||||||
noDumpEnvVars=1;
|
|
||||||
|
|
||||||
# stop polluting LDFLAGS with -liconv
|
|
||||||
dontAddExtraLibs = true;
|
|
||||||
|
|
||||||
# we need to inject ncurses into --with-curses-libraries.
|
|
||||||
# the real fix is to teach terminfo to use libcurses on macOS.
|
|
||||||
# CONFIGURE_ARGS = "--with-intree-gmp --with-curses-libraries=${pkgs.ncurses.out}/lib";
|
|
||||||
CONFIGURE_ARGS = "--with-intree-gmp --with-curses-libraries=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib --with-iconv-includes=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include --with-iconv-libraries=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib SH=/bin/bash";
|
|
||||||
|
|
||||||
# magic speedup pony :facepalm:
|
|
||||||
#
|
|
||||||
# nix has the ugly habbit of duplicating ld flags more than necessary. This
|
|
||||||
# somewhat consolidates this.
|
|
||||||
shellHook = ''
|
|
||||||
export NIX_LDFLAGS=$(for a in $NIX_LDFLAGS; do echo $a; done |sort|uniq|xargs)
|
|
||||||
export NIX_LDFLAGS_FOR_TARGET=$(for a in $NIX_LDFLAGS_FOR_TARGET; do echo $a; done |sort|uniq|xargs)
|
|
||||||
export NIX_LDFLAGS_FOR_TARGET=$(comm -3 <(for l in $NIX_LDFLAGS_FOR_TARGET; do echo $l; done) <(for l in $NIX_LDFLAGS; do echo $l; done))
|
|
||||||
|
|
||||||
|
|
||||||
# Impurity hack for GHC releases.
|
|
||||||
#################################
|
|
||||||
# We don't want binary releases to depend on nix, thus we'll need to make sure we don't leak in references.
|
|
||||||
# GHC externally depends only on iconv and curses. However we can't force a specific curses library for
|
|
||||||
# the terminfo package, as such we'll need to make sure we only look in the system path for the curses library
|
|
||||||
# and not pick up the tinfo from the nix provided ncurses package.
|
|
||||||
#
|
|
||||||
# We also need to force us to use the systems COREFOUNDATION, not the one that nix builds. Again this is impure,
|
|
||||||
# but it will allow us to have proper binary distributions.
|
|
||||||
#
|
|
||||||
# do not use nixpkgs provided core foundation
|
|
||||||
export NIX_COREFOUNDATION_RPATH=/System/Library/Frameworks
|
|
||||||
# drop curses from the LDFLAGS, we really want the system ones, not the nix ones.
|
|
||||||
export NIX_LDFLAGS=$(for lib in $NIX_LDFLAGS; do case "$lib" in *curses*);; *) echo -n "$lib ";; esac; done;)
|
|
||||||
export NIX_CFLAGS_COMPILE+=" -Wno-nullability-completeness -Wno-availability -Wno-expansion-to-defined -Wno-builtin-requires-header -Wno-unused-command-line-argument"
|
|
||||||
|
|
||||||
# unconditionally add the MacOSX.sdk and TargetConditional.h
|
|
||||||
export NIX_CFLAGS_COMPILE+=" -isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include"
|
|
||||||
export NIX_LDFLAGS="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib $NIX_LDFLAGS"
|
|
||||||
|
|
||||||
'';
|
|
||||||
|
|
||||||
nativeBuildInputs = (with pkgs; [
|
|
||||||
# This needs to come *before* ghc,
|
|
||||||
# otherwise we migth end up with the clang from
|
|
||||||
# the bootstrap GHC in PATH with higher priority.
|
|
||||||
clang_11
|
|
||||||
llvm_11
|
|
||||||
|
|
||||||
haskell.compiler.${compiler}
|
|
||||||
haskell.packages.${compiler}.cabal-install
|
|
||||||
haskell.packages.${compiler}.alex
|
|
||||||
haskell.packages.${compiler}.happy # _1_19_12 is needed for older GHCs.
|
|
||||||
|
|
||||||
automake
|
|
||||||
autoconf
|
|
||||||
m4
|
|
||||||
|
|
||||||
gmp
|
|
||||||
zlib.out
|
|
||||||
zlib.dev
|
|
||||||
glibcLocales
|
|
||||||
# locale doesn't build yet :-/
|
|
||||||
# locale
|
|
||||||
|
|
||||||
git
|
|
||||||
|
|
||||||
python3
|
|
||||||
# python3Full
|
|
||||||
# python3Packages.sphinx
|
|
||||||
perl
|
|
||||||
|
|
||||||
which
|
|
||||||
wget
|
|
||||||
curl
|
|
||||||
file
|
|
||||||
|
|
||||||
xz
|
|
||||||
xlibs.lndir
|
|
||||||
|
|
||||||
cacert ])
|
|
||||||
++ (with pkgs.darwin.apple_sdk.frameworks; [ Foundation Security ]);
|
|
||||||
}
|
|
||||||
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[submodule "data/metadata"]
|
||||||
|
path = data/metadata
|
||||||
|
url = https://github.com/haskell/ghcup-metadata.git
|
||||||
|
branch = master
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
- ignore: {name: "Avoid lambda"}
|
- ignore: {name: "Avoid lambda"}
|
||||||
- ignore: {name: "Use uncurry"}
|
- ignore: {name: "Use uncurry"}
|
||||||
- ignore: {name: "Use replicateM"}
|
- ignore: {name: "Use replicateM"}
|
||||||
|
- ignore: {name: "Use unless"}
|
||||||
- ignore: {name: "Redundant irrefutable pattern"}
|
- ignore: {name: "Redundant irrefutable pattern"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
25
.travis.yml
25
.travis.yml
@@ -1,25 +0,0 @@
|
|||||||
jobs:
|
|
||||||
include:
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode10.1
|
|
||||||
language: generic
|
|
||||||
env: ARTIFACT=x86_64-apple-darwin-10.13-ghcup
|
|
||||||
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode11.3
|
|
||||||
language: generic
|
|
||||||
env: ARTIFACT=x86_64-apple-darwin-10.14-ghcup
|
|
||||||
|
|
||||||
|
|
||||||
script: ".travis/build.sh"
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
provider: releases
|
|
||||||
api_key:
|
|
||||||
secure: "hT2od8Iy04tdFVuonPSWv0NX5hZDmv4al8Q0GbIWmviUetROuM7c6/MCHUcgyiw6H2L3pmH4F24GBYWpKBT3ZMbxrKXhZOZ3KPLXzlnuRlm1qymKqqwsJs3466bMftaiBr16rx1VpAuditN4A32oSmTFcQAJc84Bxn2WZ4t8hk9muS8YPyLhqg3/NxT6ob8dzNp9eS2cA0WODMb/fMzaMruRtepSK8JvuXb/SnTvaDcl9plmPzEa+eW54jwVsDps8ZpQMQlTtGIjYHIwTQ36/iLH4LoAvD7OEnB7qf753LOzmI/bvlB75xYGsLxe1qgpzPMjuG3AK0jb2KGSZCzyAyrbBFSQMIyC1gNKMtab3CohnA9WdQqAT1xrzPzA9zNw516G5Fn/z+t9Ek1f6L2OYO2hJfweNhWh+ChAIsOags2QBpqc0qjkwUS4wqxCWBdyVfgPTUoGelvjCfjQgypgIyLEHFvXt9rlj+kd97FY7nG3vxZrsvWTKKKT551OqUYX5zWTyvGR71jKyNst/p93Pg3DkRy31gHrGnG9zfNgN5tWxJqDd/suR/BAFTp0VtkFb8fR3ct7WMVeJXtE2+bKqxO5Fnocs1VjEm8pKPk7glnp0muu08kaO0h54wiSOCbk1RvO1KZtHue4wKWrHcI18dwW2WtzoBQ4P1lOSkS81UY="
|
|
||||||
file: $ARTIFACT
|
|
||||||
on:
|
|
||||||
repo: hasufell/ghcup-hs
|
|
||||||
tags: true
|
|
||||||
skip_cleanup: true
|
|
||||||
draft: true
|
|
||||||
122
CHANGELOG.md
122
CHANGELOG.md
@@ -1,5 +1,127 @@
|
|||||||
# Revision history for ghcup
|
# Revision history for ghcup
|
||||||
|
|
||||||
|
## 0.1.19.1 -- 2023-2-19
|
||||||
|
|
||||||
|
* Fix GHCup on JFS/ReiserFS and other filesystem that don't support `d_type`, fixes [#766](https://github.com/haskell/ghcup-hs/issues/766)
|
||||||
|
* Don't fail on setModificationTime, fixes [#784](https://github.com/haskell/ghcup-hs/issues/784) and many GitHub actions issues
|
||||||
|
* Make armv7/aarch64 linux binaries more portable (built on Debian buster)
|
||||||
|
* Improve usability on 'ghcup config add-release-channel', fixes [#751](https://github.com/haskell/ghcup-hs/issues/751)
|
||||||
|
* Make version shortcuts work with 'ghcup set', fixes [#757](https://github.com/haskell/ghcup-hs/issues/757)
|
||||||
|
* Don't implicitly smuggle in config options in `ghcup config set` wrt [#775](https://github.com/haskell/ghcup-hs/issues/775)
|
||||||
|
* Fix build on unix with -ftui
|
||||||
|
|
||||||
|
## 0.1.19.0 -- 2023-1-13
|
||||||
|
|
||||||
|
* restore proper support for FreeBSD and Linux armv7
|
||||||
|
* integrate with [errors.haskell.org](https://errors.haskell.org/index.html), wrt [#434](https://github.com/haskell/ghcup-hs/issues/434)
|
||||||
|
* allow to overwrite distro detection via config wrt [#421](https://github.com/haskell/ghcup-hs/issues/421)
|
||||||
|
- this is particularly useful for e.g. Ubuntu derivates, where ghcup doesn't pick the optimal bindist, also see the [GHCup documentation on overriding distro detection](https://www.haskell.org/ghcup/guide/#overriding-distro-detection)
|
||||||
|
* Add proper support for mirrors wrt [#357](https://github.com/haskell/ghcup-hs/issues/357)
|
||||||
|
* fix a (harmless) bug in `ghcup nuke` on windows
|
||||||
|
* improvements to `ghcup add-release-channel` wrt [#708](https://github.com/haskell/ghcup-hs/issues/708)
|
||||||
|
* fix building newer GHC from source wrt [#433](https://github.com/haskell/ghcup-hs/issues/433)
|
||||||
|
* Fix `ghcup install hls -u` on windows
|
||||||
|
* Fix failure with `--isolate=dir --force`
|
||||||
|
* Add `--metadata-fetching-mode` arg, fixes [#440](https://github.com/haskell/ghcup-hs/issues/440)
|
||||||
|
* Add content-length property to downloads
|
||||||
|
* [Fix a grave bug on armv7](https://github.com/haskell/ghcup-hs/commit/78ee956df2618862f421178a565c82548ff7e578) during installation wrt [#415](https://github.com/haskell/ghcup-hs/issues/415)
|
||||||
|
* improve many warning/error messages (contributions by @taylorfausak)
|
||||||
|
* some minor optimization in `ghcup whereis ghcup`
|
||||||
|
* improve `--keep=always` to not clean up directories in certain circumstances
|
||||||
|
|
||||||
|
## 0.1.18.1 -- 2022-08-06
|
||||||
|
|
||||||
|
* fix sdist and unbreak hackage, wrt [#399](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/399)
|
||||||
|
|
||||||
|
## 0.1.18.0 -- 2022-07-30
|
||||||
|
|
||||||
|
* Fix tui set wrt [#266](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/266) by Arjun Kathuria
|
||||||
|
- Ask the user to install the tool via prompt when setting an non-installed version
|
||||||
|
* improvements to safe (un-)installations
|
||||||
|
- bindists that don't support `make DESTDIR=/some/tmp/dir install` are now unsupported
|
||||||
|
- installed GHC files are now recorded to avoid use of `removePathForcibly`
|
||||||
|
- internally uses a newtype wrapper for user-input paths and restrict destructive operations to validated paths
|
||||||
|
* Add `--disable-ld-override` for darwin bindists wrt #391
|
||||||
|
* Allow passing bindist configure args wrt #377
|
||||||
|
* use of `TMPDIR` is dropped... now uses an internal tmp dir `~/.ghcup/tmp`
|
||||||
|
* improvements to error handling and warnings
|
||||||
|
* Require --isolate to have an absolute directory, fixes #367
|
||||||
|
* Fix mingw PATH handling wrt #371
|
||||||
|
* Add --mingw-path switch to `ghcup run`
|
||||||
|
* Fix `ghcup run` on windows, fixes #375
|
||||||
|
* Improve `ghcup compile <hls|ghc>`
|
||||||
|
- short hashes now work
|
||||||
|
- print the long hash in addition to the detected version
|
||||||
|
* Improve `ghcup compile hls`
|
||||||
|
- add `--git-describe-version` switch as an alternative to `--overwrite-version`
|
||||||
|
- Allow to build HLS from hackage (now is the default)
|
||||||
|
- Allow to run 'cabal update' automatically before the HLS build
|
||||||
|
- Fix parser and completer for 'ghcup compile hls --version'
|
||||||
|
* Improve `ghcup compile ghc`
|
||||||
|
- Allow to build from arbitrary GHC source dists
|
||||||
|
|
||||||
|
## 0.1.17.10 -- 2022-05-12
|
||||||
|
|
||||||
|
* windows hotfix (hackage-only release)
|
||||||
|
|
||||||
|
## 0.1.17.9 -- 2022-05-12
|
||||||
|
|
||||||
|
* broken sdist (hackage-only release)
|
||||||
|
|
||||||
|
## 0.1.17.8 -- 2022-05-11
|
||||||
|
|
||||||
|
* Fix a serious (but hard to trigger) bug when combining `--isolate <DIR>` with `--force`, please make sure to upgrade or avoid `--force`
|
||||||
|
* Fix HLS build not cleaning up properly on failed installations, fixes [#361](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/361)
|
||||||
|
* Fix parsing of symlinks with multiple slashes, wrt [#353](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/353)
|
||||||
|
* Re-enable upgrade functionality for all configurations wrt [MR #250](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/250) and [VSCode haskell issue #601](https://github.com/haskell/vscode-haskell/issues/601)
|
||||||
|
* Fix `ghcup run --ghc 8.10` (for short versions) wrt [#360](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/360)
|
||||||
|
- this also introduces a `--quick` switch for `ghcup run`
|
||||||
|
|
||||||
|
## 0.1.17.7 -- 2022-04-21
|
||||||
|
|
||||||
|
* Fix `ghcup run` on windows wrt [#345](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/345)
|
||||||
|
|
||||||
|
## 0.1.17.6 -- 2022-03-18
|
||||||
|
|
||||||
|
* Vastly improve shell completions wrt [#242](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/242)
|
||||||
|
* Fix 'ghcup install cabal/hls/stack --set' wrt [#324](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/324)
|
||||||
|
* Fix bad error message wrt [#323](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/323)
|
||||||
|
* Use predictable /tmp names for `ghcup run`, fixes [#329](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/329)
|
||||||
|
* Fix bug with isolated installation of not previously installed versions
|
||||||
|
* Add `--no-set` to install commands, fixes [#330](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/330)
|
||||||
|
* Fix serious bug in `ghcup list --raw-format -t <tool> -c installed`
|
||||||
|
* Overhaul metadata merging and add `ghcup config add-release-channel URI` wrt [#328](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/328)
|
||||||
|
* Fix max path issues on windows with `ghcup run`
|
||||||
|
|
||||||
|
## 0.1.17.5 -- 2022-02-26
|
||||||
|
|
||||||
|
* Implement `ghcup run` subcommand wrt [#137](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/137)
|
||||||
|
* Support installation of dynamic HLS bindists wrt [HLS #2675](https://github.com/haskell/haskell-language-server/pull/2675) and [#237](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/237)
|
||||||
|
* Fix XDG support when `~/.local/bin` is a symlink wrt [#311](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/311)
|
||||||
|
* Add support for quilt-style patches wrt [#230](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/230), by James Hobson
|
||||||
|
* Fix redundant upgrade warnings in `ghcup upgrade`
|
||||||
|
* Fix `ghcup whereis ghc` for non-standard versions wrt [#289](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/289)
|
||||||
|
* Don't print logs to stdout, but stderr
|
||||||
|
* Allow unpacking legacy lzma archives wrt [#307](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/307)
|
||||||
|
* Allow to disable self-upgrade functionality wrt [#305](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/305)
|
||||||
|
* Fix `ghcup install ghc --set` when ghc is already installed wrt [#291](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/291)
|
||||||
|
|
||||||
|
## 0.1.17.4 -- 2021-11-13
|
||||||
|
|
||||||
|
* add `--metadata-caching` option, allowing to also disable yaml metadata caching wrt [#278](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/278)
|
||||||
|
* make upgrading ghcup in TUI more pleasant wrt [#276](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/276)
|
||||||
|
* fix parsing of atypical GHC versions (e.g. `8.10.5-patch1`)
|
||||||
|
* fix compiling HLS dynamically linked, also see [#245](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/245)
|
||||||
|
* redo (and break) some of the `ghcup compile <tool>` interface, improving patch options and setting custom cabal.project files
|
||||||
|
* avoid redundant update warnings wrt [#283](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/283)
|
||||||
|
|
||||||
|
## 0.1.17.3 -- 2021-10-27
|
||||||
|
|
||||||
|
* clean up during unpack failures as well
|
||||||
|
* migrate te aeson-2.0.1.0
|
||||||
|
* switch to yaml-streamly to fix performance regression wrt [#270](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/270)
|
||||||
|
* use [github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata) for metadata file download (better caching)
|
||||||
|
|
||||||
## 0.1.17.2 -- 2021-09-30
|
## 0.1.17.2 -- 2021-09-30
|
||||||
|
|
||||||
* Honour GHC bootstrap compiler during git clone stages wrt [#250](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/250)
|
* Honour GHC bootstrap compiler during git clone stages wrt [#250](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/250)
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
[](https://gitter.im/haskell/ghcup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/haskell/ghcup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
<a href="https://opencollective.com/ghcup#category-CONTRIBUTE"><img src="https://opencollective.com/webpack/donate/button@2x.png?color=blue" alt="Donate" width="150"></a>
|
<a href="https://opencollective.com/ghcup#category-CONTRIBUTE"><img src="https://opencollective.com/webpack/donate/button@2x.png?color=blue" alt="Donate" width="150"></a>
|
||||||
|
|
||||||
GHCup is an installer for the general purpose language [Haskell](https://www.haskell.org/).
|
GHCup is the main installer for the general purpose language [Haskell](https://www.haskell.org/).
|
||||||
|
|
||||||
Visit the [documentation](https://www.haskell.org/ghcup/) for installation instructions.
|
Visit the [documentation](https://www.haskell.org/ghcup/) for installation instructions.
|
||||||
|
|
||||||
|
If you're looking for the metadata YAML files, see here: [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata)
|
||||||
|
|||||||
@@ -1,155 +0,0 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-# LANGUAGE DataKinds #-}
|
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE TypeApplications #-}
|
|
||||||
|
|
||||||
|
|
||||||
module Main where
|
|
||||||
|
|
||||||
import GHCup.Types
|
|
||||||
import GHCup.Errors
|
|
||||||
import GHCup.Platform
|
|
||||||
import GHCup.Utils.Dirs
|
|
||||||
import GHCup.Utils.Logger
|
|
||||||
import GHCup.Types.JSON ( )
|
|
||||||
|
|
||||||
import Control.Exception ( displayException )
|
|
||||||
import Control.Monad.Trans.Reader ( runReaderT )
|
|
||||||
import Control.Monad.IO.Class
|
|
||||||
import Data.Char ( toLower )
|
|
||||||
import Data.Maybe
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
|
||||||
import Data.Semigroup ( (<>) )
|
|
||||||
#endif
|
|
||||||
import Options.Applicative hiding ( style )
|
|
||||||
import Haskus.Utils.Variant.Excepts
|
|
||||||
import System.Console.Pretty
|
|
||||||
import System.Environment
|
|
||||||
import System.Exit
|
|
||||||
import System.IO ( stderr )
|
|
||||||
import Text.Regex.Posix
|
|
||||||
import Validate
|
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text.IO as T
|
|
||||||
import qualified Data.Text as T
|
|
||||||
import qualified Data.ByteString as B
|
|
||||||
import qualified Data.Yaml.Aeson as Y
|
|
||||||
|
|
||||||
|
|
||||||
data Options = Options
|
|
||||||
{ optCommand :: Command
|
|
||||||
}
|
|
||||||
|
|
||||||
data Command = ValidateYAML ValidateYAMLOpts
|
|
||||||
| ValidateTarballs ValidateYAMLOpts TarballFilter
|
|
||||||
|
|
||||||
|
|
||||||
data Input
|
|
||||||
= FileInput FilePath -- optsparse-applicative doesn't handle ByteString correctly anyway
|
|
||||||
| StdInput
|
|
||||||
|
|
||||||
fileInput :: Parser Input
|
|
||||||
fileInput =
|
|
||||||
FileInput
|
|
||||||
<$> strOption
|
|
||||||
(long "file" <> short 'f' <> metavar "FILENAME" <> help
|
|
||||||
"Input file to validate"
|
|
||||||
)
|
|
||||||
|
|
||||||
stdInput :: Parser Input
|
|
||||||
stdInput = flag'
|
|
||||||
StdInput
|
|
||||||
(short 'i' <> long "stdin" <> help "Validate from stdin (default)")
|
|
||||||
|
|
||||||
inputP :: Parser Input
|
|
||||||
inputP = fileInput <|> stdInput
|
|
||||||
|
|
||||||
data ValidateYAMLOpts = ValidateYAMLOpts
|
|
||||||
{ vInput :: Maybe Input
|
|
||||||
}
|
|
||||||
|
|
||||||
validateYAMLOpts :: Parser ValidateYAMLOpts
|
|
||||||
validateYAMLOpts = ValidateYAMLOpts <$> optional inputP
|
|
||||||
|
|
||||||
tarballFilterP :: Parser TarballFilter
|
|
||||||
tarballFilterP = option readm $
|
|
||||||
long "tarball-filter" <> short 'u' <> metavar "<tool>-<version>" <> value def
|
|
||||||
<> help "Only check certain tarballs (format: <tool>-<version>)"
|
|
||||||
where
|
|
||||||
def = TarballFilter (Right Nothing) (makeRegex ("" :: String))
|
|
||||||
readm = do
|
|
||||||
s <- str
|
|
||||||
case span (/= '-') s of
|
|
||||||
(_, []) -> fail "invalid format, missing '-' after the tool name"
|
|
||||||
(t, v) | [tool] <- [ tool | tool <- [minBound..maxBound], low (show tool) == low t ] ->
|
|
||||||
pure (TarballFilter $ Right $ Just tool) <*> makeRegexOptsM compIgnoreCase execBlank (drop 1 v)
|
|
||||||
(t, v) | [tool] <- [ tool | tool <- [minBound..maxBound], low (show tool) == low t ] ->
|
|
||||||
pure (TarballFilter $ Left tool) <*> makeRegexOptsM compIgnoreCase execBlank (drop 1 v)
|
|
||||||
_ -> fail "invalid tool"
|
|
||||||
low = fmap toLower
|
|
||||||
|
|
||||||
|
|
||||||
opts :: Parser Options
|
|
||||||
opts = Options <$> com
|
|
||||||
|
|
||||||
com :: Parser Command
|
|
||||||
com = subparser
|
|
||||||
( command
|
|
||||||
"check"
|
|
||||||
( ValidateYAML
|
|
||||||
<$> info (validateYAMLOpts <**> helper)
|
|
||||||
(progDesc "Validate the YAML")
|
|
||||||
)
|
|
||||||
<> command
|
|
||||||
"check-tarballs"
|
|
||||||
(info
|
|
||||||
((ValidateTarballs <$> validateYAMLOpts <*> tarballFilterP) <**> helper)
|
|
||||||
(progDesc "Validate all tarballs (download and checksum)")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
no_color <- isJust <$> lookupEnv "NO_COLOR"
|
|
||||||
let loggerConfig = LoggerConfig { lcPrintDebug = True
|
|
||||||
, consoleOutter = T.hPutStr stderr
|
|
||||||
, fileOutter = \_ -> pure ()
|
|
||||||
, fancyColors = not no_color
|
|
||||||
}
|
|
||||||
dirs <- liftIO getAllDirs
|
|
||||||
let leanAppstate = LeanAppState (Settings True False Never Curl True GHCupURL False GPGNone False) dirs defaultKeyBindings loggerConfig
|
|
||||||
|
|
||||||
pfreq <- (
|
|
||||||
flip runReaderT leanAppstate . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] $ platformRequest
|
|
||||||
) >>= \case
|
|
||||||
VRight r -> pure r
|
|
||||||
VLeft e -> do
|
|
||||||
flip runReaderT leanAppstate $ logError $ T.pack $ prettyShow e
|
|
||||||
liftIO $ exitWith (ExitFailure 2)
|
|
||||||
|
|
||||||
let appstate = AppState (Settings True False Never Curl True GHCupURL False GPGNone False) dirs defaultKeyBindings (GHCupInfo mempty mempty mempty) pfreq loggerConfig
|
|
||||||
|
|
||||||
_ <- customExecParser (prefs showHelpOnError) (info (opts <**> helper) idm)
|
|
||||||
>>= \Options {..} -> case optCommand of
|
|
||||||
ValidateYAML vopts -> withValidateYamlOpts vopts (\dl m -> flip runReaderT appstate $ validate dl m)
|
|
||||||
ValidateTarballs vopts tarballFilter -> withValidateYamlOpts vopts (\dl m -> flip runReaderT appstate $ validateTarballs tarballFilter dl m)
|
|
||||||
pure ()
|
|
||||||
|
|
||||||
where
|
|
||||||
withValidateYamlOpts vopts f = case vopts of
|
|
||||||
ValidateYAMLOpts { vInput = Nothing } ->
|
|
||||||
B.getContents >>= valAndExit f
|
|
||||||
ValidateYAMLOpts { vInput = Just StdInput } ->
|
|
||||||
B.getContents >>= valAndExit f
|
|
||||||
ValidateYAMLOpts { vInput = Just (FileInput file) } ->
|
|
||||||
B.readFile file >>= valAndExit f
|
|
||||||
valAndExit f contents = do
|
|
||||||
(GHCupInfo _ av gt) <- case Y.decodeEither' contents of
|
|
||||||
Right r -> pure r
|
|
||||||
Left e -> die (color Red $ displayException e)
|
|
||||||
f av gt
|
|
||||||
>>= exitWith
|
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-# LANGUAGE DataKinds #-}
|
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
|
||||||
{-# LANGUAGE TypeApplications #-}
|
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
|
|
||||||
module Validate where
|
|
||||||
|
|
||||||
import GHCup
|
|
||||||
import GHCup.Download
|
|
||||||
import GHCup.Errors
|
|
||||||
import GHCup.Types
|
|
||||||
import GHCup.Types.Optics
|
|
||||||
import GHCup.Utils
|
|
||||||
import GHCup.Utils.Logger
|
|
||||||
import GHCup.Utils.Version.QQ
|
|
||||||
|
|
||||||
import Codec.Archive
|
|
||||||
import Control.Applicative
|
|
||||||
import Control.Exception.Safe
|
|
||||||
import Control.Monad
|
|
||||||
import Control.Monad.IO.Class
|
|
||||||
import Control.Monad.Reader.Class
|
|
||||||
import Control.Monad.Trans.Class ( lift )
|
|
||||||
import Control.Monad.Trans.Reader ( runReaderT )
|
|
||||||
import Control.Monad.Trans.Resource ( runResourceT
|
|
||||||
, MonadUnliftIO
|
|
||||||
)
|
|
||||||
import Data.Containers.ListUtils ( nubOrd )
|
|
||||||
import Data.IORef
|
|
||||||
import Data.List
|
|
||||||
import Data.Versions
|
|
||||||
import Haskus.Utils.Variant.Excepts
|
|
||||||
import Optics
|
|
||||||
import System.FilePath
|
|
||||||
import System.Exit
|
|
||||||
import Text.ParserCombinators.ReadP
|
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
import Text.Regex.Posix
|
|
||||||
|
|
||||||
import qualified Data.Map.Strict as M
|
|
||||||
import qualified Data.Text as T
|
|
||||||
import qualified Data.Version as V
|
|
||||||
|
|
||||||
|
|
||||||
data ValidationError = InternalError String
|
|
||||||
deriving Show
|
|
||||||
|
|
||||||
instance Exception ValidationError
|
|
||||||
|
|
||||||
|
|
||||||
addError :: (MonadReader (IORef Int) m, MonadIO m, Monad m) => m ()
|
|
||||||
addError = do
|
|
||||||
ref <- ask
|
|
||||||
liftIO $ modifyIORef ref (+ 1)
|
|
||||||
|
|
||||||
|
|
||||||
validate :: (Monad m, MonadReader env m, HasLog env, MonadThrow m, MonadIO m, MonadUnliftIO m)
|
|
||||||
=> GHCupDownloads
|
|
||||||
-> M.Map GlobalTool DownloadInfo
|
|
||||||
-> m ExitCode
|
|
||||||
validate dls _ = do
|
|
||||||
ref <- liftIO $ newIORef 0
|
|
||||||
|
|
||||||
-- verify binary downloads --
|
|
||||||
flip runReaderT ref $ do
|
|
||||||
-- unique tags
|
|
||||||
forM_ (M.toList dls) $ \(t, _) -> checkUniqueTags t
|
|
||||||
|
|
||||||
-- required platforms
|
|
||||||
forM_ (M.toList dls) $ \(t, versions) ->
|
|
||||||
forM_ (M.toList versions) $ \(v, vi) ->
|
|
||||||
forM_ (M.toList $ _viArch vi) $ \(arch, pspecs) -> do
|
|
||||||
checkHasRequiredPlatforms t v (_viTags vi) arch (M.keys pspecs)
|
|
||||||
|
|
||||||
checkGHCVerIsValid
|
|
||||||
forM_ (M.toList dls) $ \(t, _) -> checkMandatoryTags t
|
|
||||||
_ <- checkGHCHasBaseVersion
|
|
||||||
|
|
||||||
-- exit
|
|
||||||
e <- liftIO $ readIORef ref
|
|
||||||
if e > 0
|
|
||||||
then pure $ ExitFailure e
|
|
||||||
else do
|
|
||||||
lift $ logInfo "All good"
|
|
||||||
pure ExitSuccess
|
|
||||||
where
|
|
||||||
checkHasRequiredPlatforms t v tags arch pspecs = do
|
|
||||||
let v' = prettyVer v
|
|
||||||
arch' = prettyShow arch
|
|
||||||
when (Linux UnknownLinux `notElem` pspecs) $ do
|
|
||||||
lift $ logError $
|
|
||||||
"Linux UnknownLinux missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
|
||||||
addError
|
|
||||||
when ((Darwin `notElem` pspecs) && arch == A_64) $ do
|
|
||||||
lift $ logError $ "Darwin missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
|
||||||
addError
|
|
||||||
when ((FreeBSD `notElem` pspecs) && arch == A_64) $ lift $ logWarn $
|
|
||||||
"FreeBSD missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
|
||||||
when (Windows `notElem` pspecs && arch == A_64) $ do
|
|
||||||
lift $ logError $ "Windows missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
|
||||||
addError
|
|
||||||
|
|
||||||
-- alpine needs to be set explicitly, because
|
|
||||||
-- we cannot assume that "Linux UnknownLinux" runs on Alpine
|
|
||||||
-- (although it could be static)
|
|
||||||
when (Linux Alpine `notElem` pspecs) $
|
|
||||||
case t of
|
|
||||||
GHCup | arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)) >> addError
|
|
||||||
Cabal | v > [vver|2.4.1.0|]
|
|
||||||
, arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)) >> addError
|
|
||||||
GHC | Latest `elem` tags || Recommended `elem` tags
|
|
||||||
, arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch))
|
|
||||||
_ -> lift $ logWarn $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)
|
|
||||||
|
|
||||||
checkUniqueTags tool = do
|
|
||||||
let allTags = _viTags =<< M.elems (availableToolVersions dls tool)
|
|
||||||
let nonUnique =
|
|
||||||
fmap fst
|
|
||||||
. filter (\(_, b) -> not b)
|
|
||||||
<$> ( mapM
|
|
||||||
(\case
|
|
||||||
[] -> throwM $ InternalError "empty inner list"
|
|
||||||
(t : ts) ->
|
|
||||||
pure $ (t, ) (not (isUniqueTag t) || null ts)
|
|
||||||
)
|
|
||||||
. group
|
|
||||||
. sort
|
|
||||||
$ allTags
|
|
||||||
)
|
|
||||||
case join nonUnique of
|
|
||||||
[] -> pure ()
|
|
||||||
xs -> do
|
|
||||||
lift $ logError $ "Tags not unique for " <> T.pack (prettyShow tool) <> ": " <> T.pack (prettyShow xs)
|
|
||||||
addError
|
|
||||||
where
|
|
||||||
isUniqueTag Latest = True
|
|
||||||
isUniqueTag Recommended = True
|
|
||||||
isUniqueTag Old = False
|
|
||||||
isUniqueTag Prerelease = False
|
|
||||||
isUniqueTag (Base _) = False
|
|
||||||
isUniqueTag (UnknownTag _) = False
|
|
||||||
|
|
||||||
checkGHCVerIsValid = do
|
|
||||||
let ghcVers = toListOf (ix GHC % to M.keys % folded) dls
|
|
||||||
forM_ ghcVers $ \v ->
|
|
||||||
case [ x | (x,"") <- readP_to_S V.parseVersion (T.unpack . prettyVer $ v) ] of
|
|
||||||
[_] -> pure ()
|
|
||||||
_ -> do
|
|
||||||
lift $ logError $ "GHC version " <> prettyVer v <> " is not valid"
|
|
||||||
addError
|
|
||||||
|
|
||||||
-- a tool must have at least one of each mandatory tags
|
|
||||||
checkMandatoryTags tool = do
|
|
||||||
let allTags = _viTags =<< M.elems (availableToolVersions dls tool)
|
|
||||||
forM_ [Latest, Recommended] $ \t -> case t `elem` allTags of
|
|
||||||
False -> do
|
|
||||||
lift $ logError $ "Tag " <> T.pack (prettyShow t) <> " missing from " <> T.pack (prettyShow tool)
|
|
||||||
addError
|
|
||||||
True -> pure ()
|
|
||||||
|
|
||||||
-- all GHC versions must have a base tag
|
|
||||||
checkGHCHasBaseVersion = do
|
|
||||||
let allTags = M.toList $ availableToolVersions dls GHC
|
|
||||||
forM allTags $ \(ver, _viTags -> tags) -> case any isBase tags of
|
|
||||||
False -> do
|
|
||||||
lift $ logError $ "Base tag missing from GHC ver " <> prettyVer ver
|
|
||||||
addError
|
|
||||||
True -> pure ()
|
|
||||||
|
|
||||||
isBase (Base _) = True
|
|
||||||
isBase _ = False
|
|
||||||
|
|
||||||
data TarballFilter = TarballFilter
|
|
||||||
{ tfTool :: Either GlobalTool (Maybe Tool)
|
|
||||||
, tfVersion :: Regex
|
|
||||||
}
|
|
||||||
|
|
||||||
validateTarballs :: ( Monad m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasLog env
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, MonadThrow m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadUnliftIO m
|
|
||||||
, MonadMask m
|
|
||||||
, Alternative m
|
|
||||||
, MonadFail m
|
|
||||||
)
|
|
||||||
=> TarballFilter
|
|
||||||
-> GHCupDownloads
|
|
||||||
-> M.Map GlobalTool DownloadInfo
|
|
||||||
-> m ExitCode
|
|
||||||
validateTarballs (TarballFilter etool versionRegex) dls gt = do
|
|
||||||
ref <- liftIO $ newIORef 0
|
|
||||||
|
|
||||||
-- download/verify all tarballs
|
|
||||||
let dlis = either (const []) (\tool -> nubOrd $ dls ^.. each %& indices (maybe (const True) (==) tool) %> each %& indices (matchTest versionRegex . T.unpack . prettyVer) % (viSourceDL % _Just `summing` viArch % each % each % each)) etool
|
|
||||||
let gdlis = nubOrd $ gt ^.. each
|
|
||||||
let allDls = either (const gdlis) (const dlis) etool
|
|
||||||
when (null allDls) $ logError "no tarballs selected by filter" *> runReaderT addError ref
|
|
||||||
forM_ allDls (downloadAll ref)
|
|
||||||
|
|
||||||
-- exit
|
|
||||||
e <- liftIO $ readIORef ref
|
|
||||||
if e > 0
|
|
||||||
then pure $ ExitFailure e
|
|
||||||
else do
|
|
||||||
logInfo "All good"
|
|
||||||
pure ExitSuccess
|
|
||||||
|
|
||||||
where
|
|
||||||
downloadAll :: ( MonadUnliftIO m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasLog env
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, MonadCatch m
|
|
||||||
, MonadMask m
|
|
||||||
, MonadThrow m
|
|
||||||
)
|
|
||||||
=> IORef Int
|
|
||||||
-> DownloadInfo
|
|
||||||
-> m ()
|
|
||||||
downloadAll ref dli = do
|
|
||||||
r <- runResourceT
|
|
||||||
. runE @'[DigestError
|
|
||||||
, GPGError
|
|
||||||
, DownloadFailed
|
|
||||||
, UnknownArchive
|
|
||||||
, ArchiveResult
|
|
||||||
]
|
|
||||||
$ do
|
|
||||||
case etool of
|
|
||||||
Right (Just GHCup) -> do
|
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
|
||||||
_ <- liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) tmpUnpack Nothing False
|
|
||||||
pure Nothing
|
|
||||||
Right _ -> do
|
|
||||||
p <- liftE $ downloadCached dli Nothing
|
|
||||||
fmap (Just . head . splitDirectories . head)
|
|
||||||
. liftE
|
|
||||||
. getArchiveFiles
|
|
||||||
$ p
|
|
||||||
Left ShimGen -> do
|
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
|
||||||
_ <- liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) tmpUnpack Nothing False
|
|
||||||
pure Nothing
|
|
||||||
case r of
|
|
||||||
VRight (Just basePath) -> do
|
|
||||||
case _dlSubdir dli of
|
|
||||||
Just (RealDir prel) -> do
|
|
||||||
logInfo
|
|
||||||
$ " verifying subdir: " <> T.pack prel
|
|
||||||
when (basePath /= prel) $ do
|
|
||||||
logError $
|
|
||||||
"Subdir doesn't match: expected " <> T.pack prel <> ", got " <> T.pack basePath
|
|
||||||
runReaderT addError ref
|
|
||||||
Just (RegexDir regexString) -> do
|
|
||||||
logInfo $
|
|
||||||
"verifying subdir (regex): " <> T.pack regexString
|
|
||||||
let regex = makeRegexOpts
|
|
||||||
compIgnoreCase
|
|
||||||
execBlank
|
|
||||||
regexString
|
|
||||||
unless (match regex basePath) $ do
|
|
||||||
logError $
|
|
||||||
"Subdir doesn't match: expected regex " <> T.pack regexString <> ", got " <> T.pack basePath
|
|
||||||
runReaderT addError ref
|
|
||||||
Nothing -> pure ()
|
|
||||||
VRight Nothing -> pure ()
|
|
||||||
VLeft e -> do
|
|
||||||
logError $
|
|
||||||
"Could not download (or verify hash) of " <> T.pack (show dli) <> ", Error was: " <> T.pack (prettyShow e)
|
|
||||||
runReaderT addError ref
|
|
||||||
@@ -10,11 +10,15 @@ module BrickMain where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
|
import GHCup.Types.Optics ( getDirs )
|
||||||
import GHCup.Types hiding ( LeanAppState(..) )
|
import GHCup.Types hiding ( LeanAppState(..) )
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.OptParse.Common (logGHCPostRm)
|
||||||
import GHCup.Utils.Prelude ( decUTF8Safe )
|
import GHCup.Prelude ( decUTF8Safe )
|
||||||
import GHCup.Utils.File
|
import GHCup.Prelude.File
|
||||||
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.Process
|
||||||
|
import GHCup.Prompts
|
||||||
|
|
||||||
import Brick
|
import Brick
|
||||||
import Brick.Widgets.Border
|
import Brick.Widgets.Border
|
||||||
@@ -26,6 +30,9 @@ import Brick.Widgets.List ( listSelectedFocusedAttr
|
|||||||
)
|
)
|
||||||
import Codec.Archive
|
import Codec.Archive
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
|
import Control.Monad.Fail ( MonadFail )
|
||||||
|
#endif
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Trans.Except
|
import Control.Monad.Trans.Except
|
||||||
import Control.Monad.Trans.Resource
|
import Control.Monad.Trans.Resource
|
||||||
@@ -40,14 +47,19 @@ import Data.Vector ( Vector
|
|||||||
import Data.Versions hiding ( str )
|
import Data.Versions hiding ( str )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
|
import System.FilePath
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import System.IO.Unsafe
|
import System.IO.Unsafe
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
import URI.ByteString
|
import URI.ByteString
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.Lazy.Builder as B
|
||||||
|
import qualified Data.Text.Lazy as L
|
||||||
import qualified Graphics.Vty as Vty
|
import qualified Graphics.Vty as Vty
|
||||||
import qualified Data.Vector as V
|
import qualified Data.Vector as V
|
||||||
|
import System.Environment (getExecutablePath)
|
||||||
|
import qualified System.Posix.Process as SPP
|
||||||
|
|
||||||
|
|
||||||
hiddenTools :: [Tool]
|
hiddenTools :: [Tool]
|
||||||
@@ -83,14 +95,14 @@ data BrickState = BrickState
|
|||||||
keyHandlers :: KeyBindings
|
keyHandlers :: KeyBindings
|
||||||
-> [ ( Vty.Key
|
-> [ ( Vty.Key
|
||||||
, BrickSettings -> String
|
, BrickSettings -> String
|
||||||
, BrickState -> EventM n (Next BrickState)
|
, BrickState -> EventM String BrickState ()
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
keyHandlers KeyBindings {..} =
|
keyHandlers KeyBindings {..} =
|
||||||
[ (bQuit, const "Quit" , halt)
|
[ (bQuit, const "Quit" , \_ -> halt)
|
||||||
, (bInstall, const "Install" , withIOAction install')
|
, (bInstall, const "Install" , withIOAction install')
|
||||||
, (bUninstall, const "Uninstall", withIOAction del')
|
, (bUninstall, const "Uninstall", withIOAction del')
|
||||||
, (bSet, const "Set" , withIOAction ((liftIO .) . set'))
|
, (bSet, const "Set" , withIOAction set')
|
||||||
, (bChangelog, const "ChangeLog", withIOAction changelog')
|
, (bChangelog, const "ChangeLog", withIOAction changelog')
|
||||||
, ( bShowAllVersions
|
, ( bShowAllVersions
|
||||||
, \BrickSettings {..} ->
|
, \BrickSettings {..} ->
|
||||||
@@ -102,14 +114,14 @@ keyHandlers KeyBindings {..} =
|
|||||||
if showAllTools then "Don't show all tools" else "Show all tools"
|
if showAllTools then "Don't show all tools" else "Show all tools"
|
||||||
, hideShowHandler showAllVersions (not . showAllTools)
|
, hideShowHandler showAllVersions (not . showAllTools)
|
||||||
)
|
)
|
||||||
, (bUp, const "Up", \BrickState {..} -> continue BrickState{ appState = moveCursor 1 appState Up, .. })
|
, (bUp, const "Up", \BrickState {..} -> put BrickState{ appState = moveCursor 1 appState Up, .. })
|
||||||
, (bDown, const "Down", \BrickState {..} -> continue BrickState{ appState = moveCursor 1 appState Down, .. })
|
, (bDown, const "Down", \BrickState {..} -> put BrickState{ appState = moveCursor 1 appState Down, .. })
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
hideShowHandler f p BrickState{..} =
|
hideShowHandler f p BrickState{..} =
|
||||||
let newAppSettings = appSettings { showAllVersions = f appSettings , showAllTools = p appSettings }
|
let newAppSettings = appSettings { showAllVersions = f appSettings , showAllTools = p appSettings }
|
||||||
newInternalState = constructList appData newAppSettings (Just appState)
|
newInternalState = constructList appData newAppSettings (Just appState)
|
||||||
in continue (BrickState appData newAppSettings newInternalState appKeys)
|
in put (BrickState appData newAppSettings newInternalState appKeys)
|
||||||
|
|
||||||
|
|
||||||
showKey :: Vty.Key -> String
|
showKey :: Vty.Key -> String
|
||||||
@@ -130,7 +142,7 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
|
|
||||||
where
|
where
|
||||||
footer =
|
footer =
|
||||||
withAttr "help"
|
withAttr (attrName "help")
|
||||||
. txtWrap
|
. txtWrap
|
||||||
. T.pack
|
. T.pack
|
||||||
. foldr1 (\x y -> x <> " " <> y)
|
. foldr1 (\x y -> x <> " " <> y)
|
||||||
@@ -145,9 +157,9 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
renderList' = withDefAttr listAttr . drawListElements renderItem True
|
renderList' = withDefAttr listAttr . drawListElements renderItem True
|
||||||
renderItem _ b listResult@ListResult{..} =
|
renderItem _ b listResult@ListResult{..} =
|
||||||
let marks = if
|
let marks = if
|
||||||
| lSet -> (withAttr "set" $ str "✔✔")
|
| lSet -> (withAttr (attrName "set") $ str "✔✔")
|
||||||
| lInstalled -> (withAttr "installed" $ str "✓ ")
|
| lInstalled -> (withAttr (attrName "installed") $ str "✓ ")
|
||||||
| otherwise -> (withAttr "not-installed" $ str "✗ ")
|
| otherwise -> (withAttr (attrName "not-installed") $ str "✗ ")
|
||||||
ver = case lCross of
|
ver = case lCross of
|
||||||
Nothing -> T.unpack . prettyVer $ lVer
|
Nothing -> T.unpack . prettyVer $ lVer
|
||||||
Just c -> T.unpack (c <> "-" <> prettyVer lVer)
|
Just c -> T.unpack (c <> "-" <> prettyVer lVer)
|
||||||
@@ -155,13 +167,13 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
| lNoBindist && not lInstalled
|
| lNoBindist && not lInstalled
|
||||||
&& not b -- TODO: overloading dim and active ignores active
|
&& not b -- TODO: overloading dim and active ignores active
|
||||||
-- so we hack around it here
|
-- so we hack around it here
|
||||||
= updateAttrMap (const dimAttrs) . withAttr "no-bindist"
|
= updateAttrMap (const dimAttrs) . withAttr (attrName "no-bindist")
|
||||||
| otherwise = id
|
| otherwise = id
|
||||||
hooray
|
hooray
|
||||||
| elem Latest lTag && not lInstalled =
|
| elem Latest lTag && not lInstalled =
|
||||||
withAttr "hooray"
|
withAttr (attrName "hooray")
|
||||||
| otherwise = id
|
| otherwise = id
|
||||||
active = if b then putCursor "GHCup" (Location (0,0)) . forceAttr "active" else id
|
active = if b then putCursor "GHCup" (Location (0,0)) . forceAttr (attrName "active") else id
|
||||||
in hooray $ active $ dim
|
in hooray $ active $ dim
|
||||||
( marks
|
( marks
|
||||||
<+> padLeft (Pad 2)
|
<+> padLeft (Pad 2)
|
||||||
@@ -183,9 +195,9 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
<+> vLimit 1 (fill ' ')
|
<+> vLimit 1 (fill ' ')
|
||||||
)
|
)
|
||||||
|
|
||||||
printTag Recommended = Just $ withAttr "recommended" $ str "recommended"
|
printTag Recommended = Just $ withAttr (attrName "recommended") $ str "recommended"
|
||||||
printTag Latest = Just $ withAttr "latest" $ str "latest"
|
printTag Latest = Just $ withAttr (attrName "latest") $ str "latest"
|
||||||
printTag Prerelease = Just $ withAttr "prerelease" $ str "prerelease"
|
printTag Prerelease = Just $ withAttr (attrName "prerelease") $ str "prerelease"
|
||||||
printTag (Base pvp'') = Just $ str ("base-" ++ T.unpack (prettyPVP pvp''))
|
printTag (Base pvp'') = Just $ str ("base-" ++ T.unpack (prettyPVP pvp''))
|
||||||
printTag Old = Nothing
|
printTag Old = Nothing
|
||||||
printTag (UnknownTag t) = Just $ str t
|
printTag (UnknownTag t) = Just $ str t
|
||||||
@@ -197,10 +209,10 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
printTool Stack = str "Stack"
|
printTool Stack = str "Stack"
|
||||||
|
|
||||||
printNotes ListResult {..} =
|
printNotes ListResult {..} =
|
||||||
(if hlsPowered then [withAttr "hls-powered" $ str "hls-powered"] else mempty
|
(if hlsPowered then [withAttr (attrName "hls-powered") $ str "hls-powered"] else mempty
|
||||||
)
|
)
|
||||||
++ (if fromSrc then [withAttr "compiled" $ str "compiled"] else mempty)
|
++ (if fromSrc then [withAttr (attrName "compiled") $ str "compiled"] else mempty)
|
||||||
++ (if lStray then [withAttr "stray" $ str "stray"] else mempty)
|
++ (if lStray then [withAttr (attrName "stray") $ str "stray"] else mempty)
|
||||||
|
|
||||||
-- | Draws the list elements.
|
-- | Draws the list elements.
|
||||||
--
|
--
|
||||||
@@ -230,8 +242,8 @@ ui dimAttrs BrickState{ appSettings = as@BrickSettings{}, ..}
|
|||||||
selItemAttr = if foc
|
selItemAttr = if foc
|
||||||
then withDefAttr listSelectedFocusedAttr
|
then withDefAttr listSelectedFocusedAttr
|
||||||
else withDefAttr listSelectedAttr
|
else withDefAttr listSelectedAttr
|
||||||
makeVisible = if isSelected then visible . selItemAttr else id
|
makeVisible' = if isSelected then visible . selItemAttr else id
|
||||||
in addSeparator $ makeVisible elemWidget
|
in addSeparator $ makeVisible' elemWidget
|
||||||
|
|
||||||
in render
|
in render
|
||||||
$ viewport "GHCup" Vertical
|
$ viewport "GHCup" Vertical
|
||||||
@@ -246,8 +258,8 @@ minHSize s' = hLimit s' . vLimit 1 . (<+> fill ' ')
|
|||||||
app :: AttrMap -> AttrMap -> App BrickState e String
|
app :: AttrMap -> AttrMap -> App BrickState e String
|
||||||
app attrs dimAttrs =
|
app attrs dimAttrs =
|
||||||
App { appDraw = \st -> [ui dimAttrs st]
|
App { appDraw = \st -> [ui dimAttrs st]
|
||||||
, appHandleEvent = eventHandler
|
, appHandleEvent = \be -> get >>= \s -> eventHandler s be
|
||||||
, appStartEvent = return
|
, appStartEvent = return ()
|
||||||
, appAttrMap = const attrs
|
, appAttrMap = const attrs
|
||||||
, appChooseCursor = showFirstCursor
|
, appChooseCursor = showFirstCursor
|
||||||
}
|
}
|
||||||
@@ -255,18 +267,18 @@ app attrs dimAttrs =
|
|||||||
defaultAttributes :: Bool -> AttrMap
|
defaultAttributes :: Bool -> AttrMap
|
||||||
defaultAttributes no_color = attrMap
|
defaultAttributes no_color = attrMap
|
||||||
Vty.defAttr
|
Vty.defAttr
|
||||||
[ ("active" , Vty.defAttr `withBackColor` Vty.blue)
|
[ (attrName "active" , Vty.defAttr `withBackColor` Vty.blue)
|
||||||
, ("not-installed", Vty.defAttr `withForeColor` Vty.red)
|
, (attrName "not-installed", Vty.defAttr `withForeColor` Vty.red)
|
||||||
, ("set" , Vty.defAttr `withForeColor` Vty.green)
|
, (attrName "set" , Vty.defAttr `withForeColor` Vty.green)
|
||||||
, ("installed" , Vty.defAttr `withForeColor` Vty.green)
|
, (attrName "installed" , Vty.defAttr `withForeColor` Vty.green)
|
||||||
, ("recommended" , Vty.defAttr `withForeColor` Vty.green)
|
, (attrName "recommended" , Vty.defAttr `withForeColor` Vty.green)
|
||||||
, ("hls-powered" , Vty.defAttr `withForeColor` Vty.green)
|
, (attrName "hls-powered" , Vty.defAttr `withForeColor` Vty.green)
|
||||||
, ("latest" , Vty.defAttr `withForeColor` Vty.yellow)
|
, (attrName "latest" , Vty.defAttr `withForeColor` Vty.yellow)
|
||||||
, ("prerelease" , Vty.defAttr `withForeColor` Vty.red)
|
, (attrName "prerelease" , Vty.defAttr `withForeColor` Vty.red)
|
||||||
, ("compiled" , Vty.defAttr `withForeColor` Vty.blue)
|
, (attrName "compiled" , Vty.defAttr `withForeColor` Vty.blue)
|
||||||
, ("stray" , Vty.defAttr `withForeColor` Vty.blue)
|
, (attrName "stray" , Vty.defAttr `withForeColor` Vty.blue)
|
||||||
, ("help" , Vty.defAttr `withStyle` Vty.italic)
|
, (attrName "help" , Vty.defAttr `withStyle` Vty.italic)
|
||||||
, ("hooray" , Vty.defAttr `withForeColor` Vty.brightWhite)
|
, (attrName "hooray" , Vty.defAttr `withForeColor` Vty.brightWhite)
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
withForeColor | no_color = const
|
withForeColor | no_color = const
|
||||||
@@ -280,31 +292,31 @@ defaultAttributes no_color = attrMap
|
|||||||
dimAttributes :: Bool -> AttrMap
|
dimAttributes :: Bool -> AttrMap
|
||||||
dimAttributes no_color = attrMap
|
dimAttributes no_color = attrMap
|
||||||
(Vty.defAttr `Vty.withStyle` Vty.dim)
|
(Vty.defAttr `Vty.withStyle` Vty.dim)
|
||||||
[ ("active" , Vty.defAttr `withBackColor` Vty.blue) -- has no effect ??
|
[ (attrName "active" , Vty.defAttr `withBackColor` Vty.blue) -- has no effect ??
|
||||||
, ("no-bindist", Vty.defAttr `Vty.withStyle` Vty.dim)
|
, (attrName "no-bindist", Vty.defAttr `Vty.withStyle` Vty.dim)
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
withBackColor | no_color = \attr _ -> attr `Vty.withStyle` Vty.reverseVideo
|
withBackColor | no_color = \attr _ -> attr `Vty.withStyle` Vty.reverseVideo
|
||||||
| otherwise = Vty.withBackColor
|
| otherwise = Vty.withBackColor
|
||||||
|
|
||||||
eventHandler :: BrickState -> BrickEvent n e -> EventM n (Next BrickState)
|
eventHandler :: BrickState -> BrickEvent String e -> EventM String BrickState ()
|
||||||
eventHandler st@BrickState{..} ev = do
|
eventHandler st@BrickState{..} ev = do
|
||||||
AppState { keyBindings = kb } <- liftIO $ readIORef settings'
|
AppState { keyBindings = kb } <- liftIO $ readIORef settings'
|
||||||
case ev of
|
case ev of
|
||||||
(MouseDown _ Vty.BScrollUp _ _) ->
|
(MouseDown _ Vty.BScrollUp _ _) ->
|
||||||
continue (BrickState { appState = moveCursor 1 appState Up, .. })
|
put (BrickState { appState = moveCursor 1 appState Up, .. })
|
||||||
(MouseDown _ Vty.BScrollDown _ _) ->
|
(MouseDown _ Vty.BScrollDown _ _) ->
|
||||||
continue (BrickState { appState = moveCursor 1 appState Down, .. })
|
put (BrickState { appState = moveCursor 1 appState Down, .. })
|
||||||
(VtyEvent (Vty.EvResize _ _)) -> continue st
|
(VtyEvent (Vty.EvResize _ _)) -> put st
|
||||||
(VtyEvent (Vty.EvKey Vty.KUp _)) ->
|
(VtyEvent (Vty.EvKey Vty.KUp _)) ->
|
||||||
continue BrickState{ appState = moveCursor 1 appState Up, .. }
|
put BrickState{ appState = moveCursor 1 appState Up, .. }
|
||||||
(VtyEvent (Vty.EvKey Vty.KDown _)) ->
|
(VtyEvent (Vty.EvKey Vty.KDown _)) ->
|
||||||
continue BrickState{ appState = moveCursor 1 appState Down, .. }
|
put BrickState{ appState = moveCursor 1 appState Down, .. }
|
||||||
(VtyEvent (Vty.EvKey key _)) ->
|
(VtyEvent (Vty.EvKey key _)) ->
|
||||||
case find (\(key', _, _) -> key' == key) (keyHandlers kb) of
|
case find (\(key', _, _) -> key' == key) (keyHandlers kb) of
|
||||||
Nothing -> continue st
|
Nothing -> put st
|
||||||
Just (_, _, handler) -> handler st
|
Just (_, _, handler) -> handler st
|
||||||
_ -> continue st
|
_ -> put st
|
||||||
|
|
||||||
|
|
||||||
moveCursor :: Int -> BrickInternalState -> Direction -> BrickInternalState
|
moveCursor :: Int -> BrickInternalState -> Direction -> BrickInternalState
|
||||||
@@ -317,13 +329,14 @@ moveCursor steps ais@BrickInternalState{..} direction =
|
|||||||
|
|
||||||
-- | Suspend the current UI and run an IO action in terminal. If the
|
-- | Suspend the current UI and run an IO action in terminal. If the
|
||||||
-- IO action returns a Left value, then it's thrown as userError.
|
-- IO action returns a Left value, then it's thrown as userError.
|
||||||
withIOAction :: (BrickState
|
withIOAction :: Ord n
|
||||||
|
=> (BrickState
|
||||||
-> (Int, ListResult)
|
-> (Int, ListResult)
|
||||||
-> ReaderT AppState IO (Either String a))
|
-> ReaderT AppState IO (Either String a))
|
||||||
-> BrickState
|
-> BrickState
|
||||||
-> EventM n (Next BrickState)
|
-> EventM n BrickState ()
|
||||||
withIOAction action as = case listSelectedElement' (appState as) of
|
withIOAction action as = case listSelectedElement' (appState as) of
|
||||||
Nothing -> continue as
|
Nothing -> put as
|
||||||
Just (ix, e) -> do
|
Just (ix, e) -> do
|
||||||
suspendAndResume $ do
|
suspendAndResume $ do
|
||||||
settings <- readIORef settings'
|
settings <- readIORef settings'
|
||||||
@@ -422,6 +435,7 @@ install' _ (_, ListResult {..}) = do
|
|||||||
, BuildFailed
|
, BuildFailed
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DigestError
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
, GPGError
|
, GPGError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, DirNotEmpty
|
, DirNotEmpty
|
||||||
@@ -429,40 +443,61 @@ install' _ (_, ListResult {..}) = do
|
|||||||
, TarDirDoesNotExist
|
, TarDirDoesNotExist
|
||||||
, FileAlreadyExistsError
|
, FileAlreadyExistsError
|
||||||
, ProcessError
|
, ProcessError
|
||||||
|
, ToolShadowed
|
||||||
|
, UninstallFailed
|
||||||
|
, MergeFileTreeError
|
||||||
]
|
]
|
||||||
|
|
||||||
run (do
|
run (do
|
||||||
|
ce <- liftIO $ fmap (either (const Nothing) Just) $
|
||||||
|
try @_ @SomeException $ getExecutablePath >>= canonicalizePath
|
||||||
|
dirs <- lift getDirs
|
||||||
case lTool of
|
case lTool of
|
||||||
GHC -> do
|
GHC -> do
|
||||||
let vi = getVersionInfo lVer GHC dls
|
let vi = getVersionInfo lVer GHC dls
|
||||||
liftE $ installGHCBin lVer Nothing False $> vi
|
liftE $ installGHCBin lVer GHCupInternal False [] $> (vi, dirs, ce)
|
||||||
Cabal -> do
|
Cabal -> do
|
||||||
let vi = getVersionInfo lVer Cabal dls
|
let vi = getVersionInfo lVer Cabal dls
|
||||||
liftE $ installCabalBin lVer Nothing False $> vi
|
liftE $ installCabalBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
GHCup -> do
|
GHCup -> do
|
||||||
let vi = snd <$> getLatest dls GHCup
|
let vi = snd <$> getLatest dls GHCup
|
||||||
liftE $ upgradeGHCup Nothing False $> vi
|
liftE $ upgradeGHCup Nothing False False $> (vi, dirs, ce)
|
||||||
HLS -> do
|
HLS -> do
|
||||||
let vi = getVersionInfo lVer HLS dls
|
let vi = getVersionInfo lVer HLS dls
|
||||||
liftE $ installHLSBin lVer Nothing False $> vi
|
liftE $ installHLSBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
Stack -> do
|
Stack -> do
|
||||||
let vi = getVersionInfo lVer Stack dls
|
let vi = getVersionInfo lVer Stack dls
|
||||||
liftE $ installStackBin lVer Nothing False $> vi
|
liftE $ installStackBin lVer GHCupInternal False $> (vi, dirs, ce)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight (vi, Dirs{..}, Just ce) -> do
|
||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo msg
|
||||||
logInfo msg
|
case lTool of
|
||||||
|
GHCup -> do
|
||||||
|
up <- liftIO $ fmap (either (const Nothing) Just)
|
||||||
|
$ try @_ @SomeException $ canonicalizePath (binDir </> "ghcup" <.> exeExt)
|
||||||
|
when ((normalise <$> up) == Just (normalise ce)) $
|
||||||
|
-- TODO: track cli arguments of previous invocation
|
||||||
|
liftIO $ SPP.executeFile ce False ["tui"] Nothing
|
||||||
|
logInfo "Please restart 'ghcup' for the changes to take effect"
|
||||||
|
_ -> pure ()
|
||||||
|
pure $ Right ()
|
||||||
|
VRight (vi, _, _) -> do
|
||||||
|
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo msg
|
||||||
|
logInfo "Please restart 'ghcup' for the changes to take effect"
|
||||||
pure $ Right ()
|
pure $ Right ()
|
||||||
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
||||||
VLeft (V NoUpdate) -> pure $ Right ()
|
VLeft (V NoUpdate) -> pure $ Right ()
|
||||||
VLeft e -> pure $ Left $ prettyShow e <> "\n"
|
VLeft e -> pure $ Left $ prettyHFError e <> "\n"
|
||||||
<> "Also check the logs in ~/.ghcup/logs"
|
<> "Also check the logs in ~/.ghcup/logs"
|
||||||
|
|
||||||
|
|
||||||
set' :: BrickState -> (Int, ListResult) -> IO (Either String ())
|
set' :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m, MonadMask m, MonadUnliftIO m)
|
||||||
set' _ (_, ListResult {..}) = do
|
=> BrickState
|
||||||
settings <- readIORef settings'
|
-> (Int, ListResult)
|
||||||
|
-> m (Either String ())
|
||||||
|
set' bs input@(_, ListResult {..}) = do
|
||||||
|
settings <- liftIO $ readIORef settings'
|
||||||
|
|
||||||
let run =
|
let run =
|
||||||
flip runReaderT settings
|
flip runReaderT settings
|
||||||
@@ -470,15 +505,36 @@ set' _ (_, ListResult {..}) = do
|
|||||||
|
|
||||||
run (do
|
run (do
|
||||||
case lTool of
|
case lTool of
|
||||||
GHC -> liftE $ setGHC (GHCTargetVersion lCross lVer) SetGHCOnly $> ()
|
GHC -> liftE $ setGHC (GHCTargetVersion lCross lVer) SetGHCOnly Nothing $> ()
|
||||||
Cabal -> liftE $ setCabal lVer $> ()
|
Cabal -> liftE $ setCabal lVer $> ()
|
||||||
HLS -> liftE $ setHLS lVer $> ()
|
HLS -> liftE $ setHLS lVer SetHLSOnly Nothing $> ()
|
||||||
Stack -> liftE $ setStack lVer $> ()
|
Stack -> liftE $ setStack lVer $> ()
|
||||||
GHCup -> pure ()
|
GHCup -> pure ()
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight _ -> pure $ Right ()
|
VRight _ -> pure $ Right ()
|
||||||
VLeft e -> pure $ Left (prettyShow e)
|
VLeft e -> case e of
|
||||||
|
(V (NotInstalled tool _)) -> do
|
||||||
|
promptAnswer <- getUserPromptResponse userPrompt
|
||||||
|
case promptAnswer of
|
||||||
|
PromptYes -> do
|
||||||
|
res <- install' bs input
|
||||||
|
case res of
|
||||||
|
(Left err) -> pure $ Left err
|
||||||
|
(Right _) -> do
|
||||||
|
logInfo "Setting now..."
|
||||||
|
set' bs input
|
||||||
|
|
||||||
|
PromptNo -> pure $ Left (prettyHFError e)
|
||||||
|
where
|
||||||
|
userPrompt = L.toStrict . B.toLazyText . B.fromString $
|
||||||
|
"This Version of "
|
||||||
|
<> show tool
|
||||||
|
<> " you are trying to set is not installed.\n"
|
||||||
|
<> "Would you like to install it first? [Y/N]: "
|
||||||
|
|
||||||
|
_ -> pure $ Left (prettyHFError e)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
del' :: (MonadReader AppState m, MonadIO m, MonadFail m, MonadMask m, MonadUnliftIO m)
|
del' :: (MonadReader AppState m, MonadIO m, MonadFail m, MonadMask m, MonadUnliftIO m)
|
||||||
@@ -488,7 +544,7 @@ del' :: (MonadReader AppState m, MonadIO m, MonadFail m, MonadMask m, MonadUnlif
|
|||||||
del' _ (_, ListResult {..}) = do
|
del' _ (_, ListResult {..}) = do
|
||||||
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
AppState { ghcupInfo = GHCupInfo { _ghcupDownloads = dls }} <- ask
|
||||||
|
|
||||||
let run = runE @'[NotInstalled]
|
let run = runE @'[NotInstalled, UninstallFailed]
|
||||||
|
|
||||||
run (do
|
run (do
|
||||||
let vi = getVersionInfo lVer lTool dls
|
let vi = getVersionInfo lVer lTool dls
|
||||||
@@ -501,10 +557,11 @@ del' _ (_, ListResult {..}) = do
|
|||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
|
logGHCPostRm (mkTVer lVer)
|
||||||
forM_ (_viPostRemove =<< vi) $ \msg ->
|
forM_ (_viPostRemove =<< vi) $ \msg ->
|
||||||
logInfo msg
|
logInfo msg
|
||||||
pure $ Right ()
|
pure $ Right ()
|
||||||
VLeft e -> pure $ Left (prettyShow e)
|
VLeft e -> pure $ Left (prettyHFError e)
|
||||||
|
|
||||||
|
|
||||||
changelog' :: (MonadReader AppState m, MonadIO m)
|
changelog' :: (MonadReader AppState m, MonadIO m)
|
||||||
@@ -524,7 +581,7 @@ changelog' _ (_, ListResult {..}) = do
|
|||||||
Windows -> "start"
|
Windows -> "start"
|
||||||
exec cmd [T.unpack $ decUTF8Safe $ serializeURIRef' uri] Nothing Nothing >>= \case
|
exec cmd [T.unpack $ decUTF8Safe $ serializeURIRef' uri] Nothing Nothing >>= \case
|
||||||
Right _ -> pure $ Right ()
|
Right _ -> pure $ Right ()
|
||||||
Left e -> pure $ Left $ prettyShow e
|
Left e -> pure $ Left $ prettyHFError e
|
||||||
|
|
||||||
|
|
||||||
settings' :: IORef AppState
|
settings' :: IORef AppState
|
||||||
@@ -536,17 +593,7 @@ settings' = unsafePerformIO $ do
|
|||||||
, fileOutter = \_ -> pure ()
|
, fileOutter = \_ -> pure ()
|
||||||
, fancyColors = True
|
, fancyColors = True
|
||||||
}
|
}
|
||||||
newIORef $ AppState (Settings { cache = True
|
newIORef $ AppState defaultSettings
|
||||||
, noVerify = False
|
|
||||||
, keepDirs = Never
|
|
||||||
, downloader = Curl
|
|
||||||
, verbose = False
|
|
||||||
, urlSource = GHCupURL
|
|
||||||
, noNetwork = False
|
|
||||||
, gpgSetting = GPGNone
|
|
||||||
, noColor = False
|
|
||||||
, ..
|
|
||||||
})
|
|
||||||
dirs
|
dirs
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
(GHCupInfo mempty mempty mempty)
|
(GHCupInfo mempty mempty mempty)
|
||||||
@@ -587,12 +634,12 @@ getGHCupInfo = do
|
|||||||
|
|
||||||
r <-
|
r <-
|
||||||
flip runReaderT settings
|
flip runReaderT settings
|
||||||
. runE @'[DigestError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError]
|
. runE @'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed , FileDoesNotExistError]
|
||||||
$ liftE getDownloadsF
|
$ liftE getDownloadsF
|
||||||
|
|
||||||
case r of
|
case r of
|
||||||
VRight a -> pure $ Right a
|
VRight a -> pure $ Right a
|
||||||
VLeft e -> pure $ Left (prettyShow e)
|
VLeft e -> pure $ Left (prettyHFError e)
|
||||||
|
|
||||||
|
|
||||||
getAppData :: Maybe GHCupInfo
|
getAppData :: Maybe GHCupInfo
|
||||||
@@ -605,4 +652,3 @@ getAppData mgi = runExceptT $ do
|
|||||||
flip runReaderT settings $ do
|
flip runReaderT settings $ do
|
||||||
lV <- listVersions Nothing Nothing
|
lV <- listVersions Nothing Nothing
|
||||||
pure $ BrickData (reverse lV)
|
pure $ BrickData (reverse lV)
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
module GHCup.OptParse (
|
module GHCup.OptParse (
|
||||||
module GHCup.OptParse.Common
|
module GHCup.OptParse.Common
|
||||||
, module GHCup.OptParse.Install
|
, module GHCup.OptParse.Install
|
||||||
|
, module GHCup.OptParse.Test
|
||||||
, module GHCup.OptParse.Set
|
, module GHCup.OptParse.Set
|
||||||
, module GHCup.OptParse.UnSet
|
, module GHCup.OptParse.UnSet
|
||||||
, module GHCup.OptParse.Rm
|
, module GHCup.OptParse.Rm
|
||||||
@@ -15,27 +16,34 @@ module GHCup.OptParse (
|
|||||||
, module GHCup.OptParse.Config
|
, module GHCup.OptParse.Config
|
||||||
, module GHCup.OptParse.Whereis
|
, module GHCup.OptParse.Whereis
|
||||||
, module GHCup.OptParse.List
|
, module GHCup.OptParse.List
|
||||||
|
#ifndef DISABLE_UPGRADE
|
||||||
, module GHCup.OptParse.Upgrade
|
, module GHCup.OptParse.Upgrade
|
||||||
|
#endif
|
||||||
, module GHCup.OptParse.ChangeLog
|
, module GHCup.OptParse.ChangeLog
|
||||||
, module GHCup.OptParse.Prefetch
|
, module GHCup.OptParse.Prefetch
|
||||||
, module GHCup.OptParse.GC
|
, module GHCup.OptParse.GC
|
||||||
, module GHCup.OptParse.DInfo
|
, module GHCup.OptParse.DInfo
|
||||||
, module GHCup.OptParse.Nuke
|
, module GHCup.OptParse.Nuke
|
||||||
, module GHCup.OptParse.ToolRequirements
|
, module GHCup.OptParse.ToolRequirements
|
||||||
|
, module GHCup.OptParse.Run
|
||||||
, module GHCup.OptParse
|
, module GHCup.OptParse
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.OptParse.Install
|
import GHCup.OptParse.Install
|
||||||
|
import GHCup.OptParse.Test
|
||||||
import GHCup.OptParse.Set
|
import GHCup.OptParse.Set
|
||||||
import GHCup.OptParse.UnSet
|
import GHCup.OptParse.UnSet
|
||||||
import GHCup.OptParse.Rm
|
import GHCup.OptParse.Rm
|
||||||
|
import GHCup.OptParse.Run
|
||||||
import GHCup.OptParse.Compile
|
import GHCup.OptParse.Compile
|
||||||
import GHCup.OptParse.Config
|
import GHCup.OptParse.Config
|
||||||
import GHCup.OptParse.Whereis
|
import GHCup.OptParse.Whereis
|
||||||
import GHCup.OptParse.List
|
import GHCup.OptParse.List
|
||||||
|
#ifndef DISABLE_UPGRADE
|
||||||
import GHCup.OptParse.Upgrade
|
import GHCup.OptParse.Upgrade
|
||||||
|
#endif
|
||||||
import GHCup.OptParse.ChangeLog
|
import GHCup.OptParse.ChangeLog
|
||||||
import GHCup.OptParse.Prefetch
|
import GHCup.OptParse.Prefetch
|
||||||
import GHCup.OptParse.GC
|
import GHCup.OptParse.GC
|
||||||
@@ -61,12 +69,14 @@ import URI.ByteString
|
|||||||
import qualified Data.ByteString.UTF8 as UTF8
|
import qualified Data.ByteString.UTF8 as UTF8
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data Options = Options
|
data Options = Options
|
||||||
{
|
{
|
||||||
-- global options
|
-- global options
|
||||||
optVerbose :: Maybe Bool
|
optVerbose :: Maybe Bool
|
||||||
, optCache :: Maybe Bool
|
, optCache :: Maybe Bool
|
||||||
|
, optMetaCache :: Maybe Integer
|
||||||
|
, optMetaMode :: Maybe MetaMode
|
||||||
|
, optPlatform :: Maybe PlatformRequest
|
||||||
, optUrlSource :: Maybe URI
|
, optUrlSource :: Maybe URI
|
||||||
, optNoVerify :: Maybe Bool
|
, optNoVerify :: Maybe Bool
|
||||||
, optKeepDirs :: Maybe KeepDirs
|
, optKeepDirs :: Maybe KeepDirs
|
||||||
@@ -79,6 +89,7 @@ data Options = Options
|
|||||||
|
|
||||||
data Command
|
data Command
|
||||||
= Install (Either InstallCommand InstallOptions)
|
= Install (Either InstallCommand InstallOptions)
|
||||||
|
| Test TestCommand
|
||||||
| InstallCabalLegacy InstallOptions
|
| InstallCabalLegacy InstallOptions
|
||||||
| Set (Either SetCommand SetOptions)
|
| Set (Either SetCommand SetOptions)
|
||||||
| UnSet UnsetCommand
|
| UnSet UnsetCommand
|
||||||
@@ -88,8 +99,10 @@ data Command
|
|||||||
| Compile CompileCommand
|
| Compile CompileCommand
|
||||||
| Config ConfigCommand
|
| Config ConfigCommand
|
||||||
| Whereis WhereisOptions WhereisCommand
|
| Whereis WhereisOptions WhereisCommand
|
||||||
| Upgrade UpgradeOpts Bool
|
#ifndef DISABLE_UPGRADE
|
||||||
| ToolRequirements
|
| Upgrade UpgradeOpts Bool Bool
|
||||||
|
#endif
|
||||||
|
| ToolRequirements ToolReqOpts
|
||||||
| ChangeLog ChangeLogOptions
|
| ChangeLog ChangeLogOptions
|
||||||
| Nuke
|
| Nuke
|
||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
@@ -97,14 +110,28 @@ data Command
|
|||||||
#endif
|
#endif
|
||||||
| Prefetch PrefetchCommand
|
| Prefetch PrefetchCommand
|
||||||
| GC GCOptions
|
| GC GCOptions
|
||||||
|
| Run RunOptions
|
||||||
|
| PrintAppErrors
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
opts :: Parser Options
|
opts :: Parser Options
|
||||||
opts =
|
opts =
|
||||||
Options
|
Options
|
||||||
<$> invertableSwitch "verbose" 'v' False (help "Enable verbosity (default: disabled)")
|
<$> invertableSwitch "verbose" (Just 'v') False (help "Enable verbosity (default: disabled)")
|
||||||
<*> invertableSwitch "cache" 'c' False (help "Cache downloads in ~/.ghcup/cache (default: disabled)")
|
<*> invertableSwitch "cache" (Just 'c') False (help "Cache downloads in ~/.ghcup/cache (default: disabled)")
|
||||||
|
<*> optional (option auto (long "metadata-caching" <> metavar "SEC" <> help "How long the yaml metadata caching interval is (in seconds), 0 to disable"))
|
||||||
|
<*> optional (option auto (long "metadata-fetching-mode" <> metavar "<Strict|Lax>" <> help "Whether to fail on metadata download failure (Strict) or fall back to cached version (Lax (default))"))
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader platformParser)
|
||||||
|
( short 'p'
|
||||||
|
<> long "platform"
|
||||||
|
<> metavar "PLATFORM"
|
||||||
|
<> help
|
||||||
|
"Override for platform (triple matching ghc tarball names), e.g. x86_64-fedora27-linux"
|
||||||
|
)
|
||||||
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader parseUri)
|
(eitherReader parseUri)
|
||||||
@@ -113,9 +140,10 @@ opts =
|
|||||||
<> metavar "URL"
|
<> metavar "URL"
|
||||||
<> help "Alternative ghcup download info url"
|
<> help "Alternative ghcup download info url"
|
||||||
<> internal
|
<> internal
|
||||||
|
<> completer fileUri
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> (fmap . fmap) not (invertableSwitch "verify" 'n' True (help "Disable tarball checksum verification (default: enabled)"))
|
<*> (fmap . fmap) not (invertableSwitch "verify" (Just 'n') True (help "Disable tarball checksum verification (default: enabled)"))
|
||||||
<*> optional (option
|
<*> optional (option
|
||||||
(eitherReader keepOnParser)
|
(eitherReader keepOnParser)
|
||||||
( long "keep"
|
( long "keep"
|
||||||
@@ -123,6 +151,7 @@ opts =
|
|||||||
<> help
|
<> help
|
||||||
"Keep build directories? (default: errors)"
|
"Keep build directories? (default: errors)"
|
||||||
<> hidden
|
<> hidden
|
||||||
|
<> completer (listCompleter ["always", "errors", "never"])
|
||||||
))
|
))
|
||||||
<*> optional (option
|
<*> optional (option
|
||||||
(eitherReader downloaderParser)
|
(eitherReader downloaderParser)
|
||||||
@@ -131,20 +160,23 @@ opts =
|
|||||||
<> metavar "<internal|curl|wget>"
|
<> metavar "<internal|curl|wget>"
|
||||||
<> help
|
<> help
|
||||||
"Downloader to use (default: internal)"
|
"Downloader to use (default: internal)"
|
||||||
|
<> completer (listCompleter ["internal", "curl", "wget"])
|
||||||
#else
|
#else
|
||||||
<> metavar "<curl|wget>"
|
<> metavar "<curl|wget>"
|
||||||
<> help
|
<> help
|
||||||
"Downloader to use (default: curl)"
|
"Downloader to use (default: curl)"
|
||||||
|
<> completer (listCompleter ["curl", "wget"])
|
||||||
#endif
|
#endif
|
||||||
<> hidden
|
<> hidden
|
||||||
))
|
))
|
||||||
<*> invertableSwitch "offline" 'o' False (help "Don't do any network calls, trying cached assets and failing if missing.")
|
<*> invertableSwitch "offline" (Just 'o') False (help "Don't do any network calls, trying cached assets and failing if missing.")
|
||||||
<*> optional (option
|
<*> optional (option
|
||||||
(eitherReader gpgParser)
|
(eitherReader gpgParser)
|
||||||
( long "gpg"
|
( long "gpg"
|
||||||
<> metavar "<strict|lax|none>"
|
<> metavar "<strict|lax|none>"
|
||||||
<> help
|
<> help
|
||||||
"GPG verification (default: none)"
|
"GPG verification (default: none)"
|
||||||
|
<> completer (listCompleter ["strict", "lax", "none"])
|
||||||
))
|
))
|
||||||
<*> com
|
<*> com
|
||||||
where
|
where
|
||||||
@@ -176,6 +208,14 @@ com =
|
|||||||
<> footerDoc (Just $ text installToolFooter)
|
<> footerDoc (Just $ text installToolFooter)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
<> command
|
||||||
|
"test"
|
||||||
|
(info
|
||||||
|
(Test <$> testParser <**> helper)
|
||||||
|
( progDesc "Run tests for a tool (if any) [EXPERIMENTAL!]"
|
||||||
|
<> footerDoc (Just $ text testFooter)
|
||||||
|
)
|
||||||
|
)
|
||||||
<> command
|
<> command
|
||||||
"set"
|
"set"
|
||||||
(info
|
(info
|
||||||
@@ -211,6 +251,8 @@ com =
|
|||||||
(info
|
(info
|
||||||
( (Upgrade <$> upgradeOptsP <*> switch
|
( (Upgrade <$> upgradeOptsP <*> switch
|
||||||
(short 'f' <> long "force" <> help "Force update")
|
(short 'f' <> long "force" <> help "Force update")
|
||||||
|
<*> switch
|
||||||
|
(long "fail-if-shadowed" <> help "Fails after upgrading if the upgraded ghcup binary is shadowed by something else in PATH (useful for CI)")
|
||||||
)
|
)
|
||||||
<**> helper
|
<**> helper
|
||||||
)
|
)
|
||||||
@@ -253,6 +295,16 @@ com =
|
|||||||
(progDesc "Garbage collection"
|
(progDesc "Garbage collection"
|
||||||
<> footerDoc ( Just $ text gcFooter ))
|
<> footerDoc ( Just $ text gcFooter ))
|
||||||
)
|
)
|
||||||
|
<> command
|
||||||
|
"run"
|
||||||
|
(Run
|
||||||
|
<$>
|
||||||
|
info
|
||||||
|
(runOpts <**> helper)
|
||||||
|
(progDesc "Run a command with the given tool in PATH"
|
||||||
|
<> footerDoc ( Just $ text runFooter )
|
||||||
|
)
|
||||||
|
)
|
||||||
<> commandGroup "Main commands:"
|
<> commandGroup "Main commands:"
|
||||||
)
|
)
|
||||||
<|> subparser
|
<|> subparser
|
||||||
@@ -261,8 +313,8 @@ com =
|
|||||||
((\_ -> DInfo) <$> info helper (progDesc "Show debug info"))
|
((\_ -> DInfo) <$> info helper (progDesc "Show debug info"))
|
||||||
<> command
|
<> command
|
||||||
"tool-requirements"
|
"tool-requirements"
|
||||||
( (\_ -> ToolRequirements)
|
( ToolRequirements
|
||||||
<$> info helper
|
<$> info (toolReqP <**> helper)
|
||||||
(progDesc "Show the requirements for ghc/cabal")
|
(progDesc "Show the requirements for ghc/cabal")
|
||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
@@ -301,3 +353,10 @@ com =
|
|||||||
<> commandGroup "Nuclear Commands:"
|
<> commandGroup "Nuclear Commands:"
|
||||||
<> hidden
|
<> hidden
|
||||||
)
|
)
|
||||||
|
<|> subparser
|
||||||
|
(command
|
||||||
|
"print-app-errors"
|
||||||
|
(info (pure PrintAppErrors <**> helper)
|
||||||
|
(progDesc ""))
|
||||||
|
<> internal
|
||||||
|
)
|
||||||
|
|||||||
@@ -12,9 +12,12 @@ module GHCup.OptParse.ChangeLog where
|
|||||||
|
|
||||||
|
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Errors
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Prelude
|
||||||
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
|
import GHCup.Prelude.Process (exec)
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -34,8 +37,6 @@ import GHCup.Types.Optics
|
|||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import Data.Versions
|
import Data.Versions
|
||||||
import URI.ByteString (serializeURIRef')
|
import URI.ByteString (serializeURIRef')
|
||||||
import GHCup.Utils.Prelude
|
|
||||||
import GHCup.Utils.File (exec)
|
|
||||||
import Data.Char (toLower)
|
import Data.Char (toLower)
|
||||||
|
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ data ChangeLogOptions = ChangeLogOptions
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
changelogP :: Parser ChangeLogOptions
|
changelogP :: Parser ChangeLogOptions
|
||||||
changelogP =
|
changelogP =
|
||||||
(\x y -> ChangeLogOptions x y)
|
(\x y -> ChangeLogOptions x y)
|
||||||
@@ -71,14 +72,16 @@ changelogP =
|
|||||||
"cabal" -> Right Cabal
|
"cabal" -> Right Cabal
|
||||||
"ghcup" -> Right GHCup
|
"ghcup" -> Right GHCup
|
||||||
"stack" -> Right Stack
|
"stack" -> Right Stack
|
||||||
|
"hls" -> Right HLS
|
||||||
e -> Left e
|
e -> Left e
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(short 't' <> long "tool" <> metavar "<ghc|cabal|ghcup>" <> help
|
(short 't' <> long "tool" <> metavar "<ghc|cabal|hls|ghcup>" <> help
|
||||||
"Open changelog for given tool (default: ghc)"
|
"Open changelog for given tool (default: ghc)"
|
||||||
|
<> completer toolCompleter
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional (toolVersionArgument Nothing Nothing)
|
<*> optional (toolVersionTagArgument Nothing Nothing)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -115,7 +118,8 @@ changelog ChangeLogOptions{..} runAppState runLogger = do
|
|||||||
ver' = maybe
|
ver' = maybe
|
||||||
(Right Latest)
|
(Right Latest)
|
||||||
(\case
|
(\case
|
||||||
ToolVersion tv -> Left (_tvVersion tv) -- FIXME: ugly sharing of ToolVersion
|
GHCVersion tv -> Left (_tvVersion tv)
|
||||||
|
ToolVersion tv -> Left tv
|
||||||
ToolTag t -> Right t
|
ToolTag t -> Right t
|
||||||
)
|
)
|
||||||
clToolVer
|
clToolVer
|
||||||
@@ -145,6 +149,6 @@ changelog ChangeLogOptions{..} runAppState runLogger = do
|
|||||||
Nothing
|
Nothing
|
||||||
>>= \case
|
>>= \case
|
||||||
Right _ -> pure ExitSuccess
|
Right _ -> pure ExitSuccess
|
||||||
Left e -> logError (T.pack $ prettyShow e)
|
Left e -> logError (T.pack $ prettyHFError e)
|
||||||
>> pure (ExitFailure 13)
|
>> pure (ExitFailure 13)
|
||||||
else liftIO $ putStrLn uri' >> pure ExitSuccess
|
else liftIO $ putStrLn uri' >> pure ExitSuccess
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
{-# LANGUAGE NumericUnderscores #-}
|
||||||
|
|
||||||
module GHCup.OptParse.Common where
|
module GHCup.OptParse.Common where
|
||||||
|
|
||||||
@@ -14,56 +16,80 @@ import GHCup.Platform
|
|||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude
|
||||||
import GHCup.Utils.MegaParsec
|
import GHCup.Prelude.Process
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.MegaParsec
|
||||||
|
|
||||||
|
import Control.DeepSeq
|
||||||
|
import Control.Concurrent
|
||||||
|
import Control.Concurrent.Async
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
|
import Control.Monad.Identity (Identity(..))
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
#endif
|
#endif
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
|
import Data.Aeson
|
||||||
|
#if MIN_VERSION_aeson(2,0,0)
|
||||||
|
import qualified Data.Aeson.Key as KM
|
||||||
|
import qualified Data.Aeson.KeyMap as KM
|
||||||
|
#else
|
||||||
|
import qualified Data.HashMap.Strict as KM
|
||||||
|
#endif
|
||||||
|
import Data.ByteString.Lazy ( ByteString )
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.Char
|
import Data.Char
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.List ( nub, sort, sortBy )
|
import Data.List ( nub, sort, sortBy, isPrefixOf, stripPrefix )
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Versions hiding ( str )
|
import Data.Versions hiding ( str )
|
||||||
import Data.Void
|
import Data.Void
|
||||||
|
import qualified Data.Vector as V
|
||||||
|
import GHC.IO.Exception
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import Safe
|
import Safe
|
||||||
|
import System.Process ( readProcess )
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
|
import Text.HTML.TagSoup hiding ( Tag )
|
||||||
import URI.ByteString
|
import URI.ByteString
|
||||||
|
|
||||||
import qualified Data.ByteString.UTF8 as UTF8
|
import qualified Data.ByteString.UTF8 as UTF8
|
||||||
import qualified Data.Map.Strict as M
|
import qualified Data.Map.Strict as M
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Text.Megaparsec as MP
|
import qualified Text.Megaparsec as MP
|
||||||
|
import qualified System.FilePath.Posix as FP
|
||||||
import GHCup.Version
|
import GHCup.Version
|
||||||
|
import Control.Exception (evaluate)
|
||||||
|
import qualified Cabal.Config as CC
|
||||||
|
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
--[ Types ]--
|
--[ Types ]--
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
data ToolVersion = ToolVersion GHCTargetVersion -- target is ignored for cabal
|
data ToolVersion = GHCVersion GHCTargetVersion
|
||||||
|
| ToolVersion Version
|
||||||
| ToolTag Tag
|
| ToolTag Tag
|
||||||
|
|
||||||
-- a superset of ToolVersion
|
-- a superset of ToolVersion
|
||||||
data SetToolVersion = SetToolVersion GHCTargetVersion
|
data SetToolVersion = SetGHCVersion GHCTargetVersion
|
||||||
|
| SetToolVersion Version
|
||||||
| SetToolTag Tag
|
| SetToolTag Tag
|
||||||
| SetRecommended
|
| SetRecommended
|
||||||
| SetNext
|
| SetNext
|
||||||
|
|
||||||
prettyToolVer :: ToolVersion -> String
|
prettyToolVer :: ToolVersion -> String
|
||||||
prettyToolVer (ToolVersion v') = T.unpack $ tVerToText v'
|
prettyToolVer (GHCVersion v') = T.unpack $ tVerToText v'
|
||||||
|
prettyToolVer (ToolVersion v') = T.unpack $ prettyVer v'
|
||||||
prettyToolVer (ToolTag t) = show t
|
prettyToolVer (ToolTag t) = show t
|
||||||
|
|
||||||
toSetToolVer :: Maybe ToolVersion -> SetToolVersion
|
toSetToolVer :: Maybe ToolVersion -> SetToolVersion
|
||||||
|
toSetToolVer (Just (GHCVersion v')) = SetGHCVersion v'
|
||||||
toSetToolVer (Just (ToolVersion v')) = SetToolVersion v'
|
toSetToolVer (Just (ToolVersion v')) = SetToolVersion v'
|
||||||
toSetToolVer (Just (ToolTag t')) = SetToolTag t'
|
toSetToolVer (Just (ToolTag t')) = SetToolTag t'
|
||||||
toSetToolVer Nothing = SetRecommended
|
toSetToolVer Nothing = SetRecommended
|
||||||
@@ -76,10 +102,9 @@ toSetToolVer Nothing = SetRecommended
|
|||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
||||||
-- | same as toolVersionParser, except as an argument.
|
toolVersionTagArgument :: Maybe ListCriteria -> Maybe Tool -> Parser ToolVersion
|
||||||
toolVersionArgument :: Maybe ListCriteria -> Maybe Tool -> Parser ToolVersion
|
toolVersionTagArgument criteria tool =
|
||||||
toolVersionArgument criteria tool =
|
argument (eitherReader (parser tool))
|
||||||
argument (eitherReader toolVersionEither)
|
|
||||||
(metavar (mv tool)
|
(metavar (mv tool)
|
||||||
<> completer (tagCompleter (fromMaybe GHC tool) [])
|
<> completer (tagCompleter (fromMaybe GHC tool) [])
|
||||||
<> foldMap (completer . versionCompleter criteria) tool)
|
<> foldMap (completer . versionCompleter criteria) tool)
|
||||||
@@ -88,20 +113,19 @@ toolVersionArgument criteria tool =
|
|||||||
mv (Just HLS) = "HLS_VERSION|TAG"
|
mv (Just HLS) = "HLS_VERSION|TAG"
|
||||||
mv _ = "VERSION|TAG"
|
mv _ = "VERSION|TAG"
|
||||||
|
|
||||||
|
parser (Just GHC) = ghcVersionTagEither
|
||||||
|
parser Nothing = ghcVersionTagEither
|
||||||
|
parser _ = toolVersionTagEither
|
||||||
|
|
||||||
versionParser :: Parser GHCTargetVersion
|
|
||||||
versionParser = option
|
|
||||||
(eitherReader tVersionEither)
|
|
||||||
(short 'v' <> long "version" <> metavar "VERSION" <> help "The target version"
|
|
||||||
)
|
|
||||||
|
|
||||||
versionParser' :: Maybe ListCriteria -> Maybe Tool -> Parser Version
|
versionParser' :: Maybe ListCriteria -> Maybe Tool -> Parser Version
|
||||||
versionParser' criteria tool = argument
|
versionParser' criteria tool = argument
|
||||||
(eitherReader (first show . version . T.pack))
|
(eitherReader (first show . version . T.pack))
|
||||||
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
||||||
|
|
||||||
versionArgument :: Maybe ListCriteria -> Maybe Tool -> Parser GHCTargetVersion
|
ghcVersionArgument :: Maybe ListCriteria -> Maybe Tool -> Parser GHCTargetVersion
|
||||||
versionArgument criteria tool = argument (eitherReader tVersionEither) (metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
ghcVersionArgument criteria tool = argument (eitherReader ghcVersionEither)
|
||||||
|
(metavar "VERSION" <> foldMap (completer . versionCompleter criteria) tool)
|
||||||
|
|
||||||
|
|
||||||
-- https://github.com/pcapriotti/optparse-applicative/issues/148
|
-- https://github.com/pcapriotti/optparse-applicative/issues/148
|
||||||
@@ -117,7 +141,7 @@ versionArgument criteria tool = argument (eitherReader tVersionEither) (metavar
|
|||||||
-- the help is shown only for --no-recursive.
|
-- the help is shown only for --no-recursive.
|
||||||
invertableSwitch
|
invertableSwitch
|
||||||
:: String -- ^ long option
|
:: String -- ^ long option
|
||||||
-> Char -- ^ short option for the non-default option
|
-> Maybe Char -- ^ short option for the non-default option
|
||||||
-> Bool -- ^ is switch enabled by default?
|
-> Bool -- ^ is switch enabled by default?
|
||||||
-> Mod FlagFields Bool -- ^ option modifier
|
-> Mod FlagFields Bool -- ^ option modifier
|
||||||
-> Parser (Maybe Bool)
|
-> Parser (Maybe Bool)
|
||||||
@@ -128,14 +152,14 @@ invertableSwitch longopt shortopt defv optmod = invertableSwitch' longopt shorto
|
|||||||
-- | Allows providing option modifiers for both --foo and --no-foo.
|
-- | Allows providing option modifiers for both --foo and --no-foo.
|
||||||
invertableSwitch'
|
invertableSwitch'
|
||||||
:: String -- ^ long option (eg "foo")
|
:: String -- ^ long option (eg "foo")
|
||||||
-> Char -- ^ short option for the non-default option
|
-> Maybe Char -- ^ short option for the non-default option
|
||||||
-> Bool -- ^ is switch enabled by default?
|
-> Bool -- ^ is switch enabled by default?
|
||||||
-> Mod FlagFields Bool -- ^ option modifier for --foo
|
-> Mod FlagFields Bool -- ^ option modifier for --foo
|
||||||
-> Mod FlagFields Bool -- ^ option modifier for --no-foo
|
-> Mod FlagFields Bool -- ^ option modifier for --no-foo
|
||||||
-> Parser (Maybe Bool)
|
-> Parser (Maybe Bool)
|
||||||
invertableSwitch' longopt shortopt defv enmod dismod = optional
|
invertableSwitch' longopt shortopt defv enmod dismod = optional
|
||||||
( flag' True ( enmod <> long longopt <> if defv then mempty else short shortopt)
|
( flag' True ( enmod <> long longopt <> if defv then mempty else maybe mempty short shortopt)
|
||||||
<|> flag' False (dismod <> long nolongopt <> if defv then short shortopt else mempty)
|
<|> flag' False (dismod <> long nolongopt <> if defv then maybe mempty short shortopt else mempty)
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
nolongopt = "no-" ++ longopt
|
nolongopt = "no-" ++ longopt
|
||||||
@@ -196,8 +220,8 @@ platformParser s' = case MP.parse (platformP <* MP.eof) "" (T.pack s') of
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
bindistParser :: String -> Either String URI
|
uriParser :: String -> Either String URI
|
||||||
bindistParser = first show . parseURI strictURIParserOptions . UTF8.fromString
|
uriParser = first show . parseURI strictURIParserOptions . UTF8.fromString
|
||||||
|
|
||||||
|
|
||||||
absolutePathParser :: FilePath -> Either String FilePath
|
absolutePathParser :: FilePath -> Either String FilePath
|
||||||
@@ -206,13 +230,19 @@ absolutePathParser f = case isValid f && isAbsolute f of
|
|||||||
False -> Left "Please enter a valid absolute filepath."
|
False -> Left "Please enter a valid absolute filepath."
|
||||||
|
|
||||||
isolateParser :: FilePath -> Either String FilePath
|
isolateParser :: FilePath -> Either String FilePath
|
||||||
isolateParser f = case isValid f of
|
isolateParser f = case isValid f && isAbsolute f of
|
||||||
True -> Right $ normalise f
|
True -> Right $ normalise f
|
||||||
False -> Left "Please enter a valid filepath for isolate dir."
|
False -> Left "Please enter a valid filepath for isolate dir."
|
||||||
|
|
||||||
toolVersionEither :: String -> Either String ToolVersion
|
-- this accepts cross prefix
|
||||||
toolVersionEither s' =
|
ghcVersionTagEither :: String -> Either String ToolVersion
|
||||||
second ToolTag (tagEither s') <|> second ToolVersion (tVersionEither s')
|
ghcVersionTagEither s' =
|
||||||
|
second ToolTag (tagEither s') <|> second GHCVersion (ghcVersionEither s')
|
||||||
|
|
||||||
|
-- this ignores cross prefix
|
||||||
|
toolVersionTagEither :: String -> Either String ToolVersion
|
||||||
|
toolVersionTagEither s' =
|
||||||
|
second ToolTag (tagEither s') <|> second ToolVersion (toolVersionEither s')
|
||||||
|
|
||||||
tagEither :: String -> Either String Tag
|
tagEither :: String -> Either String Tag
|
||||||
tagEither s' = case fmap toLower s' of
|
tagEither s' = case fmap toLower s' of
|
||||||
@@ -224,10 +254,14 @@ tagEither s' = case fmap toLower s' of
|
|||||||
other -> Left $ "Unknown tag " <> other
|
other -> Left $ "Unknown tag " <> other
|
||||||
|
|
||||||
|
|
||||||
tVersionEither :: String -> Either String GHCTargetVersion
|
ghcVersionEither :: String -> Either String GHCTargetVersion
|
||||||
tVersionEither =
|
ghcVersionEither =
|
||||||
first (const "Not a valid version") . MP.parse ghcTargetVerP "" . T.pack
|
first (const "Not a valid version") . MP.parse ghcTargetVerP "" . T.pack
|
||||||
|
|
||||||
|
toolVersionEither :: String -> Either String Version
|
||||||
|
toolVersionEither =
|
||||||
|
first (const "Not a valid version") . MP.parse version' "" . T.pack
|
||||||
|
|
||||||
|
|
||||||
toolParser :: String -> Either String Tool
|
toolParser :: String -> Either String Tool
|
||||||
toolParser s' | t == T.pack "ghc" = Right GHC
|
toolParser s' | t == T.pack "ghc" = Right GHC
|
||||||
@@ -246,18 +280,6 @@ criteriaParser s' | t == T.pack "installed" = Right ListInstalled
|
|||||||
where t = T.toLower (T.pack s')
|
where t = T.toLower (T.pack s')
|
||||||
|
|
||||||
|
|
||||||
toolVersionParser :: Parser ToolVersion
|
|
||||||
toolVersionParser = verP' <|> toolP
|
|
||||||
where
|
|
||||||
verP' = ToolVersion <$> versionParser
|
|
||||||
toolP =
|
|
||||||
ToolTag
|
|
||||||
<$> option
|
|
||||||
(eitherReader tagEither)
|
|
||||||
(short 't' <> long "tag" <> metavar "TAG" <> help "The target tag")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
keepOnParser :: String -> Either String KeepDirs
|
keepOnParser :: String -> Either String KeepDirs
|
||||||
keepOnParser s' | t == T.pack "always" = Right Always
|
keepOnParser s' | t == T.pack "always" = Right Always
|
||||||
@@ -289,6 +311,126 @@ gpgParser s' | t == T.pack "strict" = Right GPGStrict
|
|||||||
--[ Completers ]--
|
--[ Completers ]--
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
||||||
|
toolCompleter :: Completer
|
||||||
|
toolCompleter = listCompleter ["ghc", "cabal", "hls", "stack"]
|
||||||
|
|
||||||
|
gitFileUri :: [String] -> Completer
|
||||||
|
gitFileUri add = mkCompleter $ fileUri' (["git://"] <> add)
|
||||||
|
|
||||||
|
fileUri :: Completer
|
||||||
|
fileUri = mkCompleter $ fileUri' []
|
||||||
|
|
||||||
|
fileUri' :: [String] -> String -> IO [String]
|
||||||
|
fileUri' add = \case
|
||||||
|
"" -> do
|
||||||
|
pwd <- getCurrentDirectory
|
||||||
|
pure $ ["https://", "http://", "file:///", "file://" <> pwd <> "/"] <> add
|
||||||
|
xs
|
||||||
|
| "file:///" `isPrefixOf` xs -> fmap ("file://" <>) <$>
|
||||||
|
case stripPrefix "file://" xs of
|
||||||
|
Nothing -> pure []
|
||||||
|
Just r -> do
|
||||||
|
pwd <- getCurrentDirectory
|
||||||
|
dirs <- compgen "directory" r ["-S", "/"]
|
||||||
|
files <- filter (\f -> (f <> "/") `notElem` dirs) <$> compgen "file" r []
|
||||||
|
pure (dirs <> files <> if r `isPrefixOf` pwd then [pwd <> "/"] else [])
|
||||||
|
| xs `isPrefixOf` "file:///" -> pure ["file:///"]
|
||||||
|
| xs `isPrefixOf` "https://" -> pure ["https://"]
|
||||||
|
| xs `isPrefixOf` "http://" -> pure ["http://"]
|
||||||
|
| otherwise -> pure []
|
||||||
|
where
|
||||||
|
compgen :: String -> String -> [String] -> IO [String]
|
||||||
|
compgen action' r opts = do
|
||||||
|
let cmd = unwords $ ["compgen", "-A", action'] <> opts <> ["--", requote r]
|
||||||
|
result <- tryIO $ readProcess "bash" ["-c", cmd] ""
|
||||||
|
return . lines . either (const []) id $ result
|
||||||
|
|
||||||
|
-- | Strongly quote the string we pass to compgen.
|
||||||
|
--
|
||||||
|
-- We need to do this so bash doesn't expand out any ~ or other
|
||||||
|
-- chars we want to complete on, or emit an end of line error
|
||||||
|
-- when seeking the close to the quote.
|
||||||
|
--
|
||||||
|
-- NOTE: copied from https://hackage.haskell.org/package/optparse-applicative-0.17.0.0/docs/src/Options.Applicative.Builder.Completer.html#requote
|
||||||
|
requote :: String -> String
|
||||||
|
requote s =
|
||||||
|
let
|
||||||
|
-- Bash doesn't appear to allow "mixed" escaping
|
||||||
|
-- in bash completions. So we don't have to really
|
||||||
|
-- worry about people swapping between strong and
|
||||||
|
-- weak quotes.
|
||||||
|
unescaped =
|
||||||
|
case s of
|
||||||
|
-- It's already strongly quoted, so we
|
||||||
|
-- can use it mostly as is, but we must
|
||||||
|
-- ensure it's closed off at the end and
|
||||||
|
-- there's no single quotes in the
|
||||||
|
-- middle which might confuse bash.
|
||||||
|
('\'': rs) -> unescapeN rs
|
||||||
|
|
||||||
|
-- We're weakly quoted.
|
||||||
|
('"': rs) -> unescapeD rs
|
||||||
|
|
||||||
|
-- We're not quoted at all.
|
||||||
|
-- We need to unescape some characters like
|
||||||
|
-- spaces and quotation marks.
|
||||||
|
elsewise -> unescapeU elsewise
|
||||||
|
in
|
||||||
|
strong unescaped
|
||||||
|
|
||||||
|
where
|
||||||
|
strong ss = '\'' : foldr go "'" ss
|
||||||
|
where
|
||||||
|
-- If there's a single quote inside the
|
||||||
|
-- command: exit from the strong quote and
|
||||||
|
-- emit it the quote escaped, then resume.
|
||||||
|
go '\'' t = "'\\''" ++ t
|
||||||
|
go h t = h : t
|
||||||
|
|
||||||
|
-- Unescape a strongly quoted string
|
||||||
|
-- We have two recursive functions, as we
|
||||||
|
-- can enter and exit the strong escaping.
|
||||||
|
unescapeN = goX
|
||||||
|
where
|
||||||
|
goX ('\'' : xs) = goN xs
|
||||||
|
goX (x : xs) = x : goX xs
|
||||||
|
goX [] = []
|
||||||
|
|
||||||
|
goN ('\\' : '\'' : xs) = '\'' : goN xs
|
||||||
|
goN ('\'' : xs) = goX xs
|
||||||
|
goN (x : xs) = x : goN xs
|
||||||
|
goN [] = []
|
||||||
|
|
||||||
|
-- Unescape an unquoted string
|
||||||
|
unescapeU = goX
|
||||||
|
where
|
||||||
|
goX [] = []
|
||||||
|
goX ('\\' : x : xs) = x : goX xs
|
||||||
|
goX (x : xs) = x : goX xs
|
||||||
|
|
||||||
|
-- Unescape a weakly quoted string
|
||||||
|
unescapeD = goX
|
||||||
|
where
|
||||||
|
-- Reached an escape character
|
||||||
|
goX ('\\' : x : xs)
|
||||||
|
-- If it's true escapable, strip the
|
||||||
|
-- slashes, as we're going to strong
|
||||||
|
-- escape instead.
|
||||||
|
| x `elem` ("$`\"\\\n" :: String) = x : goX xs
|
||||||
|
| otherwise = '\\' : x : goX xs
|
||||||
|
-- We've ended quoted section, so we
|
||||||
|
-- don't recurse on goX, it's done.
|
||||||
|
goX ('"' : xs)
|
||||||
|
= xs
|
||||||
|
-- Not done, but not a special character
|
||||||
|
-- just continue the fold.
|
||||||
|
goX (x : xs)
|
||||||
|
= x : goX xs
|
||||||
|
goX []
|
||||||
|
= []
|
||||||
|
|
||||||
|
|
||||||
tagCompleter :: Tool -> [String] -> Completer
|
tagCompleter :: Tool -> [String] -> Completer
|
||||||
tagCompleter tool add = listIOCompleter $ do
|
tagCompleter tool add = listIOCompleter $ do
|
||||||
dirs' <- liftIO getAllDirs
|
dirs' <- liftIO getAllDirs
|
||||||
@@ -299,7 +441,7 @@ tagCompleter tool add = listIOCompleter $ do
|
|||||||
, fancyColors = False
|
, fancyColors = False
|
||||||
}
|
}
|
||||||
let appState = LeanAppState
|
let appState = LeanAppState
|
||||||
(Settings True False Never Curl False GHCupURL True GPGNone False)
|
(defaultSettings { noNetwork = True })
|
||||||
dirs'
|
dirs'
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
loggerConfig
|
loggerConfig
|
||||||
@@ -312,9 +454,11 @@ tagCompleter tool add = listIOCompleter $ do
|
|||||||
pure $ nub $ (add ++) $ fmap tagToString allTags
|
pure $ nub $ (add ++) $ fmap tagToString allTags
|
||||||
VLeft _ -> pure (nub $ ["recommended", "latest"] ++ add)
|
VLeft _ -> pure (nub $ ["recommended", "latest"] ++ add)
|
||||||
|
|
||||||
|
|
||||||
versionCompleter :: Maybe ListCriteria -> Tool -> Completer
|
versionCompleter :: Maybe ListCriteria -> Tool -> Completer
|
||||||
versionCompleter criteria tool = listIOCompleter $ do
|
versionCompleter criteria tool = versionCompleter' criteria tool (const True)
|
||||||
|
|
||||||
|
versionCompleter' :: Maybe ListCriteria -> Tool -> (Version -> Bool) -> Completer
|
||||||
|
versionCompleter' criteria tool filter' = listIOCompleter $ do
|
||||||
dirs' <- liftIO getAllDirs
|
dirs' <- liftIO getAllDirs
|
||||||
let loggerConfig = LoggerConfig
|
let loggerConfig = LoggerConfig
|
||||||
{ lcPrintDebug = False
|
{ lcPrintDebug = False
|
||||||
@@ -322,7 +466,7 @@ versionCompleter criteria tool = listIOCompleter $ do
|
|||||||
, fileOutter = mempty
|
, fileOutter = mempty
|
||||||
, fancyColors = False
|
, fancyColors = False
|
||||||
}
|
}
|
||||||
let settings = Settings True False Never Curl False GHCupURL True GPGNone False
|
let settings = defaultSettings { noNetwork = True }
|
||||||
let leanAppState = LeanAppState
|
let leanAppState = LeanAppState
|
||||||
settings
|
settings
|
||||||
dirs'
|
dirs'
|
||||||
@@ -343,7 +487,151 @@ versionCompleter criteria tool = listIOCompleter $ do
|
|||||||
runEnv = flip runReaderT appState
|
runEnv = flip runReaderT appState
|
||||||
|
|
||||||
installedVersions <- runEnv $ listVersions (Just tool) criteria
|
installedVersions <- runEnv $ listVersions (Just tool) criteria
|
||||||
return $ T.unpack . prettyVer . lVer <$> installedVersions
|
return $ fmap (T.unpack . prettyVer) . filter filter' . fmap lVer $ installedVersions
|
||||||
|
|
||||||
|
|
||||||
|
toolDlCompleter :: Tool -> Completer
|
||||||
|
toolDlCompleter tool = mkCompleter $ \case
|
||||||
|
"" -> pure (initUrl tool <> ["https://", "http://", "file:///"])
|
||||||
|
word
|
||||||
|
| "file://" `isPrefixOf` word -> fileUri' [] word
|
||||||
|
-- downloads.haskell.org
|
||||||
|
| "https://downloads.haskell.org/" `isPrefixOf` word ->
|
||||||
|
fmap (completePrefix word) . prefixMatch (FP.takeFileName word) <$> fromHRef word
|
||||||
|
|
||||||
|
-- github releases
|
||||||
|
| "https://github.com/haskell/haskell-language-server/releases/download/" `isPrefixOf` word
|
||||||
|
, let xs = splitPath word
|
||||||
|
, (length xs == 6 && last word == '/') || (length xs == 7 && last word /= '/') ->
|
||||||
|
fmap (\x -> completePrefix word x <> "/") . prefixMatch (FP.takeFileName word) <$> getGithubReleases "haskell" "haskell-language-server"
|
||||||
|
| "https://github.com/commercialhaskell/stack/releases/download/" == word
|
||||||
|
, let xs = splitPath word
|
||||||
|
, (length xs == 6 && last word == '/') || (length xs == 7 && last word /= '/') ->
|
||||||
|
fmap (\x -> completePrefix word x <> "/") . prefixMatch (FP.takeFileName word) <$> getGithubReleases "commercialhaskell" "stack"
|
||||||
|
|
||||||
|
-- github release assets
|
||||||
|
| "https://github.com/haskell/haskell-language-server/releases/download/" `isPrefixOf` word
|
||||||
|
, let xs = splitPath word
|
||||||
|
, (length xs == 7 && last word == '/') || length xs == 8
|
||||||
|
, let rel = xs !! 6
|
||||||
|
, length rel > 1 -> do
|
||||||
|
fmap (completePrefix word) . prefixMatch (FP.takeFileName word) <$> getGithubAssets "haskell" "haskell-language-server" (init rel)
|
||||||
|
| "https://github.com/commercialhaskell/stack/releases/download/" `isPrefixOf` word
|
||||||
|
, let xs = splitPath word
|
||||||
|
, (length xs == 7 && last word == '/') || length xs == 8
|
||||||
|
, let rel = xs !! 6
|
||||||
|
, length rel > 1 -> do
|
||||||
|
fmap (completePrefix word) . prefixMatch (FP.takeFileName word) <$> getGithubAssets "commercialhaskell" "stack" (init rel)
|
||||||
|
|
||||||
|
-- github
|
||||||
|
| "https://github.com/c" `isPrefixOf` word -> pure ["https://github.com/commercialhaskell/stack/releases/download/"]
|
||||||
|
| "https://github.com/h" `isPrefixOf` word -> pure ["https://github.com/haskell/haskell-language-server/releases/download/"]
|
||||||
|
| "https://g" `isPrefixOf` word
|
||||||
|
, tool == Stack -> pure ["https://github.com/commercialhaskell/stack/releases/download/"]
|
||||||
|
| "https://g" `isPrefixOf` word
|
||||||
|
, tool == HLS -> pure ["https://github.com/haskell/haskell-language-server/releases/download/"]
|
||||||
|
|
||||||
|
| "https://d" `isPrefixOf` word -> pure $ filter ("https://downloads.haskell.org/" `isPrefixOf`) $ initUrl tool
|
||||||
|
|
||||||
|
| "h" `isPrefixOf` word -> pure $ initUrl tool
|
||||||
|
|
||||||
|
| word `isPrefixOf` "file:///" -> pure ["file:///"]
|
||||||
|
| word `isPrefixOf` "https://" -> pure ["https://"]
|
||||||
|
| word `isPrefixOf` "http://" -> pure ["http://"]
|
||||||
|
|
||||||
|
| otherwise -> pure []
|
||||||
|
where
|
||||||
|
initUrl :: Tool -> [String]
|
||||||
|
initUrl GHC = [ "https://downloads.haskell.org/~ghc/"
|
||||||
|
, "https://downloads.haskell.org/~ghcup/unofficial-bindists/ghc/"
|
||||||
|
]
|
||||||
|
initUrl Cabal = [ "https://downloads.haskell.org/~cabal/"
|
||||||
|
, "https://downloads.haskell.org/~ghcup/unofficial-bindists/cabal/"
|
||||||
|
]
|
||||||
|
initUrl GHCup = [ "https://downloads.haskell.org/~ghcup/" ]
|
||||||
|
initUrl HLS = [ "https://github.com/haskell/haskell-language-server/releases/download/"
|
||||||
|
, "https://downloads.haskell.org/~ghcup/unofficial-bindists/haskell-language-server/"
|
||||||
|
]
|
||||||
|
initUrl Stack = [ "https://github.com/commercialhaskell/stack/releases/download/"
|
||||||
|
, "https://downloads.haskell.org/~ghcup/unofficial-bindists/stack/"
|
||||||
|
]
|
||||||
|
|
||||||
|
completePrefix :: String -- ^ url, e.g. 'https://github.com/haskell/haskell-languag'
|
||||||
|
-> String -- ^ match, e.g. 'haskell-language-server'
|
||||||
|
-> String -- ^ result, e.g. 'https://github.com/haskell/haskell-language-server'
|
||||||
|
completePrefix url match =
|
||||||
|
let base = FP.takeDirectory url
|
||||||
|
fn = FP.takeFileName url
|
||||||
|
in if fn `isPrefixOf` match then base <> "/" <> match else url
|
||||||
|
|
||||||
|
prefixMatch :: String -> [String] -> [String]
|
||||||
|
prefixMatch pref = filter (pref `isPrefixOf`)
|
||||||
|
|
||||||
|
fromHRef :: String -> IO [String]
|
||||||
|
fromHRef url = withCurl (FP.takeDirectory url) 2_000_000 $ \stdout ->
|
||||||
|
pure
|
||||||
|
. fmap (T.unpack . decUTF8Safe' . fromAttrib "href")
|
||||||
|
. filter isTagOpen
|
||||||
|
. filter (~== ("<a href>" :: String))
|
||||||
|
. parseTags
|
||||||
|
$ stdout
|
||||||
|
|
||||||
|
withCurl :: String -- ^ url
|
||||||
|
-> Int -- ^ delay
|
||||||
|
-> (ByteString -> IO [String]) -- ^ callback
|
||||||
|
-> IO [String]
|
||||||
|
withCurl url delay cb = do
|
||||||
|
let limit = threadDelay delay
|
||||||
|
race limit (executeOut "curl" ["-fL", url] Nothing) >>= \case
|
||||||
|
Right (CapturedProcess {_exitCode, _stdOut}) -> do
|
||||||
|
case _exitCode of
|
||||||
|
ExitSuccess ->
|
||||||
|
(try @_ @SomeException . cb $ _stdOut) >>= \case
|
||||||
|
Left _ -> pure []
|
||||||
|
Right r' -> do
|
||||||
|
r <- try @_ @SomeException
|
||||||
|
. evaluate
|
||||||
|
. force
|
||||||
|
$ r'
|
||||||
|
either (\_ -> pure []) pure r
|
||||||
|
ExitFailure _ -> pure []
|
||||||
|
Left _ -> pure []
|
||||||
|
|
||||||
|
getGithubReleases :: String
|
||||||
|
-> String
|
||||||
|
-> IO [String]
|
||||||
|
getGithubReleases owner repo = withCurl url 3_000_000 $ \stdout -> do
|
||||||
|
Just xs <- pure $ decode' @Array stdout
|
||||||
|
fmap V.toList $ forM xs $ \x -> do
|
||||||
|
(Object r) <- pure x
|
||||||
|
Just (String name) <- pure $ KM.lookup (mkval "tag_name") r
|
||||||
|
pure $ T.unpack name
|
||||||
|
where
|
||||||
|
url = "https://api.github.com/repos/" <> owner <> "/" <> repo <> "/releases"
|
||||||
|
|
||||||
|
getGithubAssets :: String
|
||||||
|
-> String
|
||||||
|
-> String
|
||||||
|
-> IO [String]
|
||||||
|
getGithubAssets owner repo tag = withCurl url 3_000_000 $ \stdout -> do
|
||||||
|
Just xs <- pure $ decode' @Object stdout
|
||||||
|
Just (Array assets) <- pure $ KM.lookup (mkval "assets") xs
|
||||||
|
as <- fmap V.toList $ forM assets $ \val -> do
|
||||||
|
(Object asset) <- pure val
|
||||||
|
Just (String name) <- pure $ KM.lookup (mkval "name") asset
|
||||||
|
pure $ T.unpack name
|
||||||
|
pure as
|
||||||
|
where
|
||||||
|
url = "https://api.github.com/repos/" <> owner <> "/" <> repo <> "/releases/tags/" <> tag
|
||||||
|
|
||||||
|
|
||||||
|
#if MIN_VERSION_aeson(2,0,0)
|
||||||
|
mkval = KM.fromString
|
||||||
|
#else
|
||||||
|
mkval = id
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -391,7 +679,7 @@ fromVersion' SetRecommended tool = do
|
|||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
bimap mkTVer Just <$> getRecommended dls tool
|
bimap mkTVer Just <$> getRecommended dls tool
|
||||||
?? TagNotFound Recommended tool
|
?? TagNotFound Recommended tool
|
||||||
fromVersion' (SetToolVersion v) tool = do
|
fromVersion' (SetGHCVersion v) tool = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo (_tvVersion v) tool dls
|
let vi = getVersionInfo (_tvVersion v) tool dls
|
||||||
case pvp $ prettyVer (_tvVersion v) of -- need to be strict here
|
case pvp $ prettyVer (_tvVersion v) of -- need to be strict here
|
||||||
@@ -399,10 +687,22 @@ fromVersion' (SetToolVersion v) tool = do
|
|||||||
Right pvpIn ->
|
Right pvpIn ->
|
||||||
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
||||||
Just (pvp_, vi') -> do
|
Just (pvp_, vi') -> do
|
||||||
v' <- lift $ pvpToVersion pvp_
|
v' <- lift $ pvpToVersion pvp_ ""
|
||||||
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
||||||
pure (GHCTargetVersion (_tvTarget v) v', Just vi')
|
pure (GHCTargetVersion (_tvTarget v) v', Just vi')
|
||||||
Nothing -> pure (v, vi)
|
Nothing -> pure (v, vi)
|
||||||
|
fromVersion' (SetToolVersion v) tool = do
|
||||||
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
|
let vi = getVersionInfo v tool dls
|
||||||
|
case pvp $ prettyVer v of -- need to be strict here
|
||||||
|
Left _ -> pure (mkTVer v, vi)
|
||||||
|
Right pvpIn ->
|
||||||
|
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
||||||
|
Just (pvp_, vi') -> do
|
||||||
|
v' <- lift $ pvpToVersion pvp_ ""
|
||||||
|
when (v' /= v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
||||||
|
pure (GHCTargetVersion mempty v', Just vi')
|
||||||
|
Nothing -> pure (mkTVer v, vi)
|
||||||
fromVersion' (SetToolTag Latest) tool = do
|
fromVersion' (SetToolTag Latest) tool = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
bimap mkTVer Just <$> getLatest dls tool ?? TagNotFound Latest tool
|
bimap mkTVer Just <$> getLatest dls tool ?? TagNotFound Latest tool
|
||||||
@@ -472,42 +772,31 @@ checkForUpdates :: ( MonadReader env m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> m ()
|
=> m [(Tool, Version)]
|
||||||
checkForUpdates = do
|
checkForUpdates = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
||||||
lInstalled <- listVersions Nothing (Just ListInstalled)
|
lInstalled <- listVersions Nothing (Just ListInstalled)
|
||||||
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
||||||
|
|
||||||
forM_ (getLatest dls GHCup) $ \(l, _) -> do
|
ghcup <- forMM (getLatest dls GHCup) $ \(l, _) -> do
|
||||||
(Right ghc_ver) <- pure $ version $ prettyPVP ghcUpVer
|
(Right ghcup_ver) <- pure $ version $ prettyPVP ghcUpVer
|
||||||
when (l > ghc_ver)
|
if (l > ghcup_ver) then pure $ Just (GHCup, l) else pure Nothing
|
||||||
$ logWarn $
|
|
||||||
"New GHCup version available: " <> prettyVer l <> ". To upgrade, run 'ghcup upgrade'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls GHC) $ \(l, _) -> do
|
otherTools <- forM [GHC, Cabal, HLS, Stack] $ \t ->
|
||||||
let mghc_ver = latestInstalled GHC
|
forMM (getLatest dls t) $ \(l, _) -> do
|
||||||
forM mghc_ver $ \ghc_ver ->
|
let mver = latestInstalled t
|
||||||
when (l > ghc_ver)
|
forMM mver $ \ver ->
|
||||||
$ logWarn $
|
if (l > ver) then pure $ Just (t, l) else pure Nothing
|
||||||
"New GHC version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install ghc " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls Cabal) $ \(l, _) -> do
|
pure $ catMaybes (ghcup:otherTools)
|
||||||
let mcabal_ver = latestInstalled Cabal
|
where
|
||||||
forM mcabal_ver $ \cabal_ver ->
|
forMM a f = fmap join $ forM a f
|
||||||
when (l > cabal_ver)
|
|
||||||
$ logWarn $
|
|
||||||
"New Cabal version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install cabal " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls HLS) $ \(l, _) -> do
|
|
||||||
let mhls_ver = latestInstalled HLS
|
|
||||||
forM mhls_ver $ \hls_ver ->
|
|
||||||
when (l > hls_ver)
|
|
||||||
$ logWarn $
|
|
||||||
"New HLS version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install hls " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls Stack) $ \(l, _) -> do
|
logGHCPostRm :: (MonadReader env m, HasLog env, MonadIO m) => GHCTargetVersion -> m ()
|
||||||
let mstack_ver = latestInstalled Stack
|
logGHCPostRm ghcVer = do
|
||||||
forM mstack_ver $ \stack_ver ->
|
cabalStore <- liftIO $ handleIO (\_ -> if isWindows then pure "C:\\cabal\\store" else pure "~/.cabal/store")
|
||||||
when (l > stack_ver)
|
(runIdentity . CC.cfgStoreDir <$> CC.readConfig)
|
||||||
$ logWarn $
|
let storeGhcDir = cabalStore </> ("ghc-" <> T.unpack (prettyVer $ _tvVersion ghcVer))
|
||||||
"New Stack version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install stack " <> prettyVer l <> "'"
|
logInfo $ T.pack $ "After removing GHC you might also want to clean up your cabal store at: " <> storeGhcDir
|
||||||
|
|
||||||
|
|||||||
@@ -12,14 +12,15 @@ module GHCup.OptParse.Compile where
|
|||||||
|
|
||||||
|
|
||||||
import GHCup
|
import GHCup
|
||||||
|
import qualified GHCup.GHC as GHC
|
||||||
|
import qualified GHCup.HLS as HLS
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Utils.File
|
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.Utils.String.QQ
|
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -31,17 +32,18 @@ import Control.Monad.Trans.Resource
|
|||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Versions ( Version, prettyVer, version )
|
import Data.Versions ( Version, prettyVer, version, pvp )
|
||||||
|
import qualified Data.Versions as V
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Options.Applicative.Help.Pretty ( text )
|
import Options.Applicative.Help.Pretty ( text )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
|
import URI.ByteString hiding ( uriParser )
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask, displayException)
|
||||||
import System.FilePath (isPathSeparator)
|
import System.FilePath (isPathSeparator)
|
||||||
import Text.Read (readEither)
|
import Text.Read (readEither)
|
||||||
|
|
||||||
@@ -64,11 +66,11 @@ data CompileCommand = CompileGHC GHCCompileOptions
|
|||||||
|
|
||||||
|
|
||||||
data GHCCompileOptions = GHCCompileOptions
|
data GHCCompileOptions = GHCCompileOptions
|
||||||
{ targetGhc :: Either Version GitBranch
|
{ targetGhc :: GHC.GHCVer Version
|
||||||
, bootstrapGhc :: Either Version FilePath
|
, bootstrapGhc :: Either Version FilePath
|
||||||
, jobs :: Maybe Int
|
, jobs :: Maybe Int
|
||||||
, buildConfig :: Maybe FilePath
|
, buildConfig :: Maybe FilePath
|
||||||
, patchDir :: Maybe FilePath
|
, patches :: Maybe (Either FilePath [URI])
|
||||||
, crossTarget :: Maybe Text
|
, crossTarget :: Maybe Text
|
||||||
, addConfArgs :: [Text]
|
, addConfArgs :: [Text]
|
||||||
, setCompile :: Bool
|
, setCompile :: Bool
|
||||||
@@ -78,16 +80,19 @@ data GHCCompileOptions = GHCCompileOptions
|
|||||||
, isolateDir :: Maybe FilePath
|
, isolateDir :: Maybe FilePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
data HLSCompileOptions = HLSCompileOptions
|
data HLSCompileOptions = HLSCompileOptions
|
||||||
{ targetHLS :: Either Version GitBranch
|
{ targetHLS :: HLS.HLSVer
|
||||||
, jobs :: Maybe Int
|
, jobs :: Maybe Int
|
||||||
, setCompile :: Bool
|
, setCompile :: Bool
|
||||||
, ovewrwiteVer :: Maybe Version
|
, updateCabal :: Bool
|
||||||
|
, ovewrwiteVer :: Either Bool Version
|
||||||
, isolateDir :: Maybe FilePath
|
, isolateDir :: Maybe FilePath
|
||||||
, cabalProject :: Maybe FilePath
|
, cabalProject :: Maybe (Either FilePath URI)
|
||||||
, cabalProjectLocal :: Maybe FilePath
|
, cabalProjectLocal :: Maybe URI
|
||||||
, patchDir :: Maybe FilePath
|
, patches :: Maybe (Either FilePath [URI])
|
||||||
, targetGHCs :: [ToolVersion]
|
, targetGHCs :: [ToolVersion]
|
||||||
|
, cabalArgs :: [Text]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -97,7 +102,7 @@ data HLSCompileOptions = HLSCompileOptions
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
compileP :: Parser CompileCommand
|
compileP :: Parser CompileCommand
|
||||||
compileP = subparser
|
compileP = subparser
|
||||||
( command
|
( command
|
||||||
@@ -144,31 +149,51 @@ Examples:
|
|||||||
|
|
||||||
compileHLSFooter = [s|Discussion:
|
compileHLSFooter = [s|Discussion:
|
||||||
Compiles and installs the specified HLS version.
|
Compiles and installs the specified HLS version.
|
||||||
The last argument is a list of GHC versions to compile for.
|
The --ghc arguments are necessary to specify which GHC version to build for/against.
|
||||||
These need to be available in PATH prior to compilation.
|
These need to be available in PATH prior to compilation.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
ghcup compile hls -v 1.4.0 -j 12 8.10.5 8.10.7 9.0.1|]
|
# compile 1.7.0.0 from hackage for 8.10.7, running 'cabal update' before the build
|
||||||
|
ghcup compile hls --version 1.7.0.0 --ghc 8.10.7 --cabal-update
|
||||||
|
# compile from master for ghc 9.2.3 using 'git describe' to name the binary and ignore the pinned index state
|
||||||
|
ghcup compile hls -g master --git-describe-version --ghc 9.2.3 -- --index-state=@(date '+%s')
|
||||||
|
# compile a specific commit for ghc 9.2.3 and set a specifc version for the binary name
|
||||||
|
ghcup compile hls -g a32db0b -o 1.7.0.0-p1 --ghc 9.2.3|]
|
||||||
|
|
||||||
|
|
||||||
ghcCompileOpts :: Parser GHCCompileOptions
|
ghcCompileOpts :: Parser GHCCompileOptions
|
||||||
ghcCompileOpts =
|
ghcCompileOpts =
|
||||||
GHCCompileOptions
|
GHCCompileOptions
|
||||||
<$> ((Left <$> option
|
<$> ((GHC.SourceDist <$> option
|
||||||
(eitherReader
|
(eitherReader
|
||||||
(first (const "Not a valid version") . version . T.pack)
|
(first (const "Not a valid version") . version . T.pack)
|
||||||
)
|
)
|
||||||
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
||||||
"The tool version to compile"
|
"The tool version to compile"
|
||||||
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
)
|
)
|
||||||
) <|>
|
) <|>
|
||||||
(Right <$> (GitBranch <$> option
|
(GHC.GitDist <$> (GitBranch <$> option
|
||||||
str
|
str
|
||||||
(short 'g' <> long "git-ref" <> metavar "GIT_REFERENCE" <> help
|
(short 'g' <> long "git-ref" <> metavar "GIT_REFERENCE" <> help
|
||||||
"The git commit/branch/ref to build from"
|
"The git commit/branch/ref to build from"
|
||||||
) <*>
|
) <*>
|
||||||
optional (option str (short 'r' <> long "repository" <> metavar "GIT_REPOSITORY" <> help "The git repository to build from (defaults to GHC upstream)"))
|
optional (option str (
|
||||||
)))
|
short 'r' <> long "repository" <> metavar "GIT_REPOSITORY" <> help "The git repository to build from (defaults to GHC upstream)"
|
||||||
|
<> completer (gitFileUri ["https://gitlab.haskell.org/ghc/ghc.git"])
|
||||||
|
))
|
||||||
|
))
|
||||||
|
<|>
|
||||||
|
(
|
||||||
|
GHC.RemoteDist <$> (option
|
||||||
|
(eitherReader uriParser)
|
||||||
|
(long "remote-source-dist" <> metavar "URI" <> help
|
||||||
|
"URI (https/http/file) to a GHC source distribution"
|
||||||
|
<> completer fileUri
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
<*> option
|
<*> option
|
||||||
(eitherReader
|
(eitherReader
|
||||||
(\x ->
|
(\x ->
|
||||||
@@ -180,12 +205,14 @@ ghcCompileOpts =
|
|||||||
<> metavar "BOOTSTRAP_GHC"
|
<> metavar "BOOTSTRAP_GHC"
|
||||||
<> help
|
<> help
|
||||||
"The GHC version (or full path) to bootstrap with (must be installed)"
|
"The GHC version (or full path) to bootstrap with (must be installed)"
|
||||||
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader (readEither @Int))
|
(eitherReader (readEither @Int))
|
||||||
(short 'j' <> long "jobs" <> metavar "JOBS" <> help
|
(short 'j' <> long "jobs" <> metavar "JOBS" <> help
|
||||||
"How many jobs to use for make"
|
"How many jobs to use for make"
|
||||||
|
<> (completer $ listCompleter $ fmap show ([1..12] :: [Int]))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -193,15 +220,28 @@ ghcCompileOpts =
|
|||||||
str
|
str
|
||||||
(short 'c' <> long "config" <> metavar "CONFIG" <> help
|
(short 'c' <> long "config" <> metavar "CONFIG" <> help
|
||||||
"Absolute path to build config file"
|
"Absolute path to build config file"
|
||||||
|
<> completer (bashCompleter "file")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> (optional
|
||||||
(option
|
(
|
||||||
str
|
(fmap Right $ many $ option
|
||||||
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
(eitherReader uriParser)
|
||||||
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
(long "patch" <> metavar "PATCH_URI" <> help
|
||||||
|
"URI to a patch (https/http/file)"
|
||||||
|
<> completer fileUri
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|>
|
||||||
|
(fmap Left $ option
|
||||||
|
str
|
||||||
|
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
||||||
|
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1. This order is determined by a quilt series file if it exists, or the patches are lexicographically ordered)"
|
||||||
|
<> completer (bashCompleter "directory")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
str
|
str
|
||||||
@@ -209,13 +249,8 @@ ghcCompileOpts =
|
|||||||
"Build cross-compiler for this platform"
|
"Build cross-compiler for this platform"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> many (argument str (metavar "CONFIGURE_ARGS" <> help "Additional arguments to configure, prefix with '-- ' (longopts)"))
|
<*> many (argument str (metavar "CONFIGURE_ARGS" <> help "Additional arguments to compile configure, prefix with '-- ' (longopts)"))
|
||||||
<*> flag
|
<*> fmap (fromMaybe False) (invertableSwitch "set" Nothing False (help "Set as active version after install"))
|
||||||
False
|
|
||||||
True
|
|
||||||
(long "set" <> help
|
|
||||||
"Set as active version after install"
|
|
||||||
)
|
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader
|
(eitherReader
|
||||||
@@ -223,6 +258,7 @@ ghcCompileOpts =
|
|||||||
)
|
)
|
||||||
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
||||||
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
||||||
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -242,49 +278,82 @@ ghcCompileOpts =
|
|||||||
<> long "isolate"
|
<> long "isolate"
|
||||||
<> metavar "DIR"
|
<> metavar "DIR"
|
||||||
<> help "install in an isolated directory instead of the default one, no symlinks to this installation will be made"
|
<> help "install in an isolated directory instead of the default one, no symlinks to this installation will be made"
|
||||||
|
<> completer (bashCompleter "directory")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
hlsCompileOpts :: Parser HLSCompileOptions
|
hlsCompileOpts :: Parser HLSCompileOptions
|
||||||
hlsCompileOpts =
|
hlsCompileOpts =
|
||||||
HLSCompileOptions
|
HLSCompileOptions
|
||||||
<$> ((Left <$> option
|
<$> ((HLS.HackageDist <$> option
|
||||||
(eitherReader
|
(eitherReader
|
||||||
(first (const "Not a valid version") . version . T.pack)
|
((>>= first displayException . V.version . V.prettyPVP) . first (const "Not a valid PVP version") . pvp . T.pack)
|
||||||
)
|
)
|
||||||
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
(short 'v' <> long "version" <> metavar "VERSION" <> help
|
||||||
"The tool version to compile"
|
"The version to compile (pulled from hackage)"
|
||||||
|
<> (completer $ versionCompleter' Nothing HLS (either (const False) (const True) . V.pvp . V.prettyVer))
|
||||||
)
|
)
|
||||||
) <|>
|
)
|
||||||
(Right <$> (GitBranch <$> option
|
<|>
|
||||||
|
(HLS.GitDist <$> (GitBranch <$> option
|
||||||
str
|
str
|
||||||
(short 'g' <> long "git-ref" <> metavar "GIT_REFERENCE" <> help
|
(short 'g' <> long "git-ref" <> metavar "GIT_REFERENCE" <> help
|
||||||
"The git commit/branch/ref to build from"
|
"The git commit/branch/ref to build from (accepts anything 'git checkout' accepts)"
|
||||||
) <*>
|
) <*>
|
||||||
optional (option str (short 'r' <> long "repository" <> metavar "GIT_REPOSITORY" <> help "The git repository to build from (defaults to GHC upstream)"))
|
optional (option str (short 'r' <> long "repository" <> metavar "GIT_REPOSITORY" <> help "The git repository to build from (defaults to HLS upstream)"
|
||||||
)))
|
<> completer (gitFileUri ["https://github.com/haskell/haskell-language-server.git"])
|
||||||
|
))
|
||||||
|
))
|
||||||
|
<|>
|
||||||
|
(HLS.SourceDist <$> (option
|
||||||
|
(eitherReader
|
||||||
|
(first (const "Not a valid version") . version . T.pack)
|
||||||
|
)
|
||||||
|
(long "source-dist" <> metavar "VERSION" <> help
|
||||||
|
"The version to compile (pulled from packaged git sources)"
|
||||||
|
<> (completer $ versionCompleter Nothing HLS)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
<|>
|
||||||
|
(
|
||||||
|
HLS.RemoteDist <$> (option
|
||||||
|
(eitherReader uriParser)
|
||||||
|
(long "remote-source-dist" <> metavar "URI" <> help
|
||||||
|
"URI (https/http/file) to a HLS source distribution"
|
||||||
|
<> completer fileUri
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader (readEither @Int))
|
(eitherReader (readEither @Int))
|
||||||
(short 'j' <> long "jobs" <> metavar "JOBS" <> help
|
(short 'j' <> long "jobs" <> metavar "JOBS" <> help
|
||||||
"How many jobs to use for make"
|
"How many jobs to use for make"
|
||||||
|
<> (completer $ listCompleter $ fmap show ([1..12] :: [Int]))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> flag
|
<*> fmap (fromMaybe True) (invertableSwitch "set" Nothing True (help "Don't set as active version after install"))
|
||||||
False
|
<*> switch (long "cabal-update" <> help "Run 'cabal update' before the build")
|
||||||
True
|
<*>
|
||||||
(long "set" <> help
|
(
|
||||||
"Set as active version after install"
|
(Right <$> option
|
||||||
)
|
|
||||||
<*> optional
|
|
||||||
(option
|
|
||||||
(eitherReader
|
(eitherReader
|
||||||
(first (const "Not a valid version") . version . T.pack)
|
(first (const "Not a valid version") . version . T.pack)
|
||||||
)
|
)
|
||||||
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
(short 'o' <> long "overwrite-version" <> metavar "OVERWRITE_VERSION" <> help
|
||||||
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
"Allows to overwrite the finally installed VERSION with a different one, e.g. when you build 8.10.4 with your own patches, you might want to set this to '8.10.4-p1'"
|
||||||
|
<> (completer $ versionCompleter Nothing HLS)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
<|>
|
||||||
|
(Left <$> (switch
|
||||||
|
(long "git-describe-version"
|
||||||
|
<> help "Use the output of 'git describe' (if building from git) as the VERSION component of the installed binary."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader isolateParser)
|
(eitherReader isolateParser)
|
||||||
@@ -292,30 +361,51 @@ hlsCompileOpts =
|
|||||||
<> long "isolate"
|
<> long "isolate"
|
||||||
<> metavar "DIR"
|
<> metavar "DIR"
|
||||||
<> help "install in an isolated directory instead of the default one, no symlinks to this installation will be made"
|
<> help "install in an isolated directory instead of the default one, no symlinks to this installation will be made"
|
||||||
|
<> completer (bashCompleter "directory")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
str
|
((fmap Right $ eitherReader uriParser) <|> (fmap Left str))
|
||||||
(long "cabal-project" <> metavar "CABAL_PROJECT" <> help
|
(long "cabal-project" <> metavar "CABAL_PROJECT" <> help
|
||||||
"If relative, specifies the path to cabal.project inside the unpacked HLS tarball/checkout. If absolute, will copy the file over."
|
"If relative filepath, specifies the path to cabal.project inside the unpacked HLS tarball/checkout. Otherwise expects a full URI with https/http/file scheme."
|
||||||
|
<> completer fileUri
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader absolutePathParser)
|
(eitherReader uriParser)
|
||||||
(long "cabal-project-local" <> metavar "CABAL_PROJECT_LOCAL" <> help
|
(long "cabal-project-local" <> metavar "CABAL_PROJECT_LOCAL" <> help
|
||||||
"Absolute path to a cabal.project.local to be used for the build. Will be copied over."
|
"URI (https/http/file) to a cabal.project.local to be used for the build. Will be copied over."
|
||||||
|
<> completer fileUri
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> (optional
|
||||||
(option
|
(
|
||||||
(eitherReader absolutePathParser)
|
(fmap Right $ many $ option
|
||||||
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
(eitherReader uriParser)
|
||||||
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
(long "patch" <> metavar "PATCH_URI" <> help
|
||||||
|
"URI to a patch (https/http/file)"
|
||||||
|
<> completer fileUri
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|>
|
||||||
|
(fmap Left $ option
|
||||||
|
str
|
||||||
|
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
||||||
|
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
||||||
|
<> completer (bashCompleter "directory")
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> some (toolVersionArgument Nothing (Just GHC))
|
)
|
||||||
|
<*> some (
|
||||||
|
option (eitherReader ghcVersionTagEither)
|
||||||
|
( long "ghc" <> metavar "GHC_VERSION|TAG" <> help "For which GHC version to compile for (can be specified multiple times)"
|
||||||
|
<> completer (tagCompleter GHC [])
|
||||||
|
<> completer (versionCompleter Nothing GHC))
|
||||||
|
)
|
||||||
|
<*> many (argument str (metavar "CABAL_ARGS" <> help "Additional arguments to cabal install, prefix with '-- ' (longopts)"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -329,6 +419,7 @@ hlsCompileOpts =
|
|||||||
type GHCEffects = '[ AlreadyInstalled
|
type GHCEffects = '[ AlreadyInstalled
|
||||||
, BuildFailed
|
, BuildFailed
|
||||||
, DigestError
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
, GPGError
|
, GPGError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, GHCupSetError
|
, GHCupSetError
|
||||||
@@ -346,10 +437,13 @@ type GHCEffects = '[ AlreadyInstalled
|
|||||||
, ProcessError
|
, ProcessError
|
||||||
, CopyError
|
, CopyError
|
||||||
, BuildFailed
|
, BuildFailed
|
||||||
|
, UninstallFailed
|
||||||
|
, MergeFileTreeError
|
||||||
]
|
]
|
||||||
type HLSEffects = '[ AlreadyInstalled
|
type HLSEffects = '[ AlreadyInstalled
|
||||||
, BuildFailed
|
, BuildFailed
|
||||||
, DigestError
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
, GPGError
|
, GPGError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, GHCupSetError
|
, GHCupSetError
|
||||||
@@ -364,6 +458,8 @@ type HLSEffects = '[ AlreadyInstalled
|
|||||||
, NotInstalled
|
, NotInstalled
|
||||||
, DirNotEmpty
|
, DirNotEmpty
|
||||||
, ArchiveResult
|
, ArchiveResult
|
||||||
|
, UninstallFailed
|
||||||
|
, MergeFileTreeError
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -403,16 +499,16 @@ compile :: ( Monad m
|
|||||||
)
|
)
|
||||||
=> CompileCommand
|
=> CompileCommand
|
||||||
-> Settings
|
-> Settings
|
||||||
|
-> Dirs
|
||||||
-> (forall eff a . ReaderT AppState m (VEither eff a) -> m (VEither eff a))
|
-> (forall eff a . ReaderT AppState m (VEither eff a) -> m (VEither eff a))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
compile compileCommand settings runAppState runLogger = do
|
compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||||
VRight Dirs{ .. } <- runAppState (VRight <$> getDirs)
|
|
||||||
case compileCommand of
|
case compileCommand of
|
||||||
(CompileHLS HLSCompileOptions { .. }) -> do
|
(CompileHLS HLSCompileOptions { .. }) -> do
|
||||||
runCompileHLS runAppState (do
|
runCompileHLS runAppState (do
|
||||||
case targetHLS of
|
case targetHLS of
|
||||||
Left targetVer -> do
|
HLS.SourceDist targetVer -> do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo targetVer HLS dls
|
let vi = getVersionInfo targetVer HLS dls
|
||||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||||
@@ -420,21 +516,23 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
lift $ logInfo
|
lift $ logInfo
|
||||||
"...waiting for 5 seconds, you can still abort..."
|
"...waiting for 5 seconds, you can still abort..."
|
||||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||||
Right _ -> pure ()
|
_ -> pure ()
|
||||||
ghcs <- liftE $ forM targetGHCs (\ghc -> fmap (_tvVersion . fst) . fromVersion (Just ghc) $ GHC)
|
ghcs <- liftE $ forM targetGHCs (\ghc -> fmap (_tvVersion . fst) . fromVersion (Just ghc) $ GHC)
|
||||||
targetVer <- liftE $ compileHLS
|
targetVer <- liftE $ compileHLS
|
||||||
targetHLS
|
targetHLS
|
||||||
ghcs
|
ghcs
|
||||||
jobs
|
jobs
|
||||||
ovewrwiteVer
|
ovewrwiteVer
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
cabalProject
|
cabalProject
|
||||||
cabalProjectLocal
|
cabalProjectLocal
|
||||||
patchDir
|
updateCabal
|
||||||
|
patches
|
||||||
|
cabalArgs
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo targetVer HLS dls
|
let vi = getVersionInfo targetVer HLS dls
|
||||||
when setCompile $ void $ liftE $
|
when setCompile $ void $ liftE $
|
||||||
setHLS targetVer
|
setHLS targetVer SetHLSOnly Nothing
|
||||||
pure (vi, targetVer)
|
pure (vi, targetVer)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -447,14 +545,14 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||||
case keepDirs settings of
|
case keepDirs settings of
|
||||||
Never -> runLogger $ logError $ T.pack $ prettyShow err
|
Never -> runLogger $ logError $ T.pack $ prettyHFError err
|
||||||
_ -> runLogger (logError $ T.pack (prettyShow err) <> "\n" <>
|
_ -> runLogger (logError $ T.pack (prettyHFError err) <> "\n" <>
|
||||||
"Check the logs at " <> T.pack logsDir <> " and the build directory "
|
"Check the logs at " <> T.pack (fromGHCupPath logsDir) <> " and the build directory "
|
||||||
<> T.pack tmpdir <> " for more clues." <> "\n" <>
|
<> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||||
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||||
pure $ ExitFailure 9
|
pure $ ExitFailure 9
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 9
|
pure $ ExitFailure 9
|
||||||
(CompileGHC GHCCompileOptions { hadrian = True, crossTarget = Just _ }) -> do
|
(CompileGHC GHCCompileOptions { hadrian = True, crossTarget = Just _ }) -> do
|
||||||
runLogger $ logError "Hadrian cross compile support is not yet implemented!"
|
runLogger $ logError "Hadrian cross compile support is not yet implemented!"
|
||||||
@@ -462,7 +560,7 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
(CompileGHC GHCCompileOptions {..}) ->
|
(CompileGHC GHCCompileOptions {..}) ->
|
||||||
runCompileGHC runAppState (do
|
runCompileGHC runAppState (do
|
||||||
case targetGhc of
|
case targetGhc of
|
||||||
Left targetVer -> do
|
GHC.SourceDist targetVer -> do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo targetVer GHC dls
|
let vi = getVersionInfo targetVer GHC dls
|
||||||
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
forM_ (_viPreCompile =<< vi) $ \msg -> do
|
||||||
@@ -470,22 +568,25 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
lift $ logInfo
|
lift $ logInfo
|
||||||
"...waiting for 5 seconds, you can still abort..."
|
"...waiting for 5 seconds, you can still abort..."
|
||||||
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
liftIO $ threadDelay 5000000 -- for compilation, give the user a sec to intervene
|
||||||
Right _ -> pure ()
|
_ -> pure ()
|
||||||
targetVer <- liftE $ compileGHC
|
targetVer <- liftE $ compileGHC
|
||||||
(first (GHCTargetVersion crossTarget) targetGhc)
|
((\case
|
||||||
|
GHC.SourceDist v -> GHC.SourceDist $ GHCTargetVersion crossTarget v
|
||||||
|
GHC.GitDist g -> GHC.GitDist g
|
||||||
|
GHC.RemoteDist r -> GHC.RemoteDist r) targetGhc)
|
||||||
ovewrwiteVer
|
ovewrwiteVer
|
||||||
bootstrapGhc
|
bootstrapGhc
|
||||||
jobs
|
jobs
|
||||||
buildConfig
|
buildConfig
|
||||||
patchDir
|
patches
|
||||||
addConfArgs
|
addConfArgs
|
||||||
buildFlavour
|
buildFlavour
|
||||||
hadrian
|
hadrian
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo (_tvVersion targetVer) GHC dls
|
let vi = getVersionInfo (_tvVersion targetVer) GHC dls
|
||||||
when setCompile $ void $ liftE $
|
when setCompile $ void $ liftE $
|
||||||
setGHC targetVer SetGHCOnly
|
setGHC targetVer SetGHCOnly Nothing
|
||||||
pure (vi, targetVer)
|
pure (vi, targetVer)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -498,20 +599,20 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
VLeft (V (AlreadyInstalled _ v)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
"GHC ver " <> prettyVer v <> " already installed; if you really want to reinstall it, you may want to run 'ghcup install ghc --force " <> prettyVer v <> "'"
|
"GHC ver " <> prettyVer v <> " already installed, remove it first to reinstall"
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (DirNotEmpty fp)) -> do
|
VLeft (V (DirNotEmpty fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logError $
|
||||||
"Install directory " <> T.pack fp <> " is not empty. Use 'ghcup install ghc --isolate " <> T.pack fp <> " --force ..." <> "' to install regardless."
|
"Install directory " <> T.pack fp <> " is not empty."
|
||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||||
case keepDirs settings of
|
case keepDirs settings of
|
||||||
Never -> runLogger $ logError $ T.pack $ prettyShow err
|
Never -> runLogger $ logError $ T.pack $ prettyHFError err
|
||||||
_ -> runLogger (logError $ T.pack (prettyShow err) <> "\n" <>
|
_ -> runLogger (logError $ T.pack (prettyHFError err) <> "\n" <>
|
||||||
"Check the logs at " <> T.pack logsDir <> " and the build directory "
|
"Check the logs at " <> T.pack (fromGHCupPath logsDir) <> " and the build directory "
|
||||||
<> T.pack tmpdir <> " for more clues." <> "\n" <>
|
<> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||||
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||||
pure $ ExitFailure 9
|
pure $ ExitFailure 9
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 9
|
pure $ ExitFailure 9
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ module GHCup.OptParse.Config where
|
|||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Prelude
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.Logger
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Prelude.String.QQ
|
||||||
|
import GHCup.OptParse.Common
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -27,10 +28,11 @@ import Control.Monad.Trans.Resource
|
|||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style, ParseError )
|
||||||
import Options.Applicative.Help.Pretty ( text )
|
import Options.Applicative.Help.Pretty ( text )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
|
import URI.ByteString hiding ( uriParser )
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.ByteString.UTF8 as UTF8
|
import qualified Data.ByteString.UTF8 as UTF8
|
||||||
@@ -49,6 +51,7 @@ data ConfigCommand
|
|||||||
= ShowConfig
|
= ShowConfig
|
||||||
| SetConfig String (Maybe String)
|
| SetConfig String (Maybe String)
|
||||||
| InitConfig
|
| InitConfig
|
||||||
|
| AddReleaseChannel Bool URI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -56,12 +59,13 @@ data ConfigCommand
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
configP :: Parser ConfigCommand
|
configP :: Parser ConfigCommand
|
||||||
configP = subparser
|
configP = subparser
|
||||||
( command "init" initP
|
( command "init" initP
|
||||||
<> command "set" setP -- [set] KEY VALUE at help lhs
|
<> command "set" setP -- [set] KEY VALUE at help lhs
|
||||||
<> command "show" showP
|
<> command "show" showP
|
||||||
|
<> command "add-release-channel" addP
|
||||||
)
|
)
|
||||||
<|> argsP -- add show for a single option
|
<|> argsP -- add show for a single option
|
||||||
<|> pure ShowConfig
|
<|> pure ShowConfig
|
||||||
@@ -70,6 +74,8 @@ configP = subparser
|
|||||||
showP = info (pure ShowConfig) (progDesc "Show current config (default)")
|
showP = info (pure ShowConfig) (progDesc "Show current config (default)")
|
||||||
setP = info argsP (progDesc "Set config KEY to VALUE (or specify as single json value)" <> footerDoc (Just $ text configSetFooter))
|
setP = info argsP (progDesc "Set config KEY to VALUE (or specify as single json value)" <> footerDoc (Just $ text configSetFooter))
|
||||||
argsP = SetConfig <$> argument str (metavar "<JSON_VALUE | YAML_KEY>") <*> optional (argument str (metavar "YAML_VALUE"))
|
argsP = SetConfig <$> argument str (metavar "<JSON_VALUE | YAML_KEY>") <*> optional (argument str (metavar "YAML_VALUE"))
|
||||||
|
addP = info (AddReleaseChannel <$> switch (long "force" <> help "Delete existing entry (if any) and append instead of failing") <*> argument (eitherReader uriParser) (metavar "URI" <> completer fileUri))
|
||||||
|
(progDesc "Add a release channel from a URI")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -114,22 +120,38 @@ formatConfig :: UserSettings -> String
|
|||||||
formatConfig = UTF8.toString . Y.encode
|
formatConfig = UTF8.toString . Y.encode
|
||||||
|
|
||||||
|
|
||||||
updateSettings :: Monad m => UTF8.ByteString -> Settings -> Excepts '[JSONError] m Settings
|
updateSettings :: UserSettings -> UserSettings -> UserSettings
|
||||||
updateSettings config' settings = do
|
updateSettings usl usr =
|
||||||
settings' <- lE' (JSONDecodeError . displayException) . Y.decodeEither' $ config'
|
let cache' = uCache usl <|> uCache usr
|
||||||
pure $ mergeConf settings' settings
|
metaCache' = uMetaCache usl <|> uMetaCache usr
|
||||||
where
|
metaMode' = uMetaMode usl <|> uMetaMode usr
|
||||||
mergeConf :: UserSettings -> Settings -> Settings
|
noVerify' = uNoVerify usl <|> uNoVerify usr
|
||||||
mergeConf UserSettings{..} Settings{..} =
|
verbose' = uVerbose usl <|> uVerbose usr
|
||||||
let cache' = fromMaybe cache uCache
|
keepDirs' = uKeepDirs usl <|> uKeepDirs usr
|
||||||
noVerify' = fromMaybe noVerify uNoVerify
|
downloader' = uDownloader usl <|> uDownloader usr
|
||||||
keepDirs' = fromMaybe keepDirs uKeepDirs
|
urlSource' = uUrlSource usl <|> uUrlSource usr
|
||||||
downloader' = fromMaybe downloader uDownloader
|
noNetwork' = uNoNetwork usl <|> uNoNetwork usr
|
||||||
verbose' = fromMaybe verbose uVerbose
|
gpgSetting' = uGPGSetting usl <|> uGPGSetting usr
|
||||||
urlSource' = fromMaybe urlSource uUrlSource
|
platformOverride' = uPlatformOverride usl <|> uPlatformOverride usr
|
||||||
noNetwork' = fromMaybe noNetwork uNoNetwork
|
mirrors' = uMirrors usl <|> uMirrors usr
|
||||||
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
in UserSettings cache' metaCache' metaMode' noVerify' verbose' keepDirs' downloader' (updateKeyBindings (uKeyBindings usl) (uKeyBindings usr)) urlSource' noNetwork' gpgSetting' platformOverride' mirrors'
|
||||||
in Settings cache' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor
|
where
|
||||||
|
updateKeyBindings :: Maybe UserKeyBindings -> Maybe UserKeyBindings -> Maybe UserKeyBindings
|
||||||
|
updateKeyBindings Nothing Nothing = Nothing
|
||||||
|
updateKeyBindings (Just kbl) Nothing = Just kbl
|
||||||
|
updateKeyBindings Nothing (Just kbr) = Just kbr
|
||||||
|
updateKeyBindings (Just kbl) (Just kbr) =
|
||||||
|
Just $ UserKeyBindings {
|
||||||
|
kUp = kUp kbl <|> kUp kbr
|
||||||
|
, kDown = kDown kbl <|> kDown kbr
|
||||||
|
, kQuit = kQuit kbl <|> kQuit kbr
|
||||||
|
, kInstall = kInstall kbl <|> kInstall kbr
|
||||||
|
, kUninstall = kUninstall kbl <|> kUninstall kbr
|
||||||
|
, kSet = kSet kbl <|> kSet kbr
|
||||||
|
, kChangelog = kChangelog kbl <|> kChangelog kbr
|
||||||
|
, kShowAll = kShowAll kbl <|> kShowAll kbr
|
||||||
|
, kShowAllTools = kShowAllTools kbl <|> kShowAllTools kbr
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -137,19 +159,23 @@ updateSettings config' settings = do
|
|||||||
--[ Entrypoint ]--
|
--[ Entrypoint ]--
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
data Duplicate = Duplicate -- ^ there is a duplicate somewhere in the middle
|
||||||
|
| NoDuplicate -- ^ there is no duplicate
|
||||||
|
| DuplicateLast -- ^ there's a duplicate, but it's the last element
|
||||||
|
|
||||||
|
|
||||||
config :: ( Monad m
|
config :: forall m. ( Monad m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> ConfigCommand
|
=> ConfigCommand
|
||||||
-> Settings
|
-> Settings
|
||||||
|
-> UserSettings
|
||||||
-> KeyBindings
|
-> KeyBindings
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
config configCommand settings keybindings runLogger = case configCommand of
|
config configCommand settings userConf keybindings runLogger = case configCommand of
|
||||||
InitConfig -> do
|
InitConfig -> do
|
||||||
path <- getConfigFilePath
|
path <- getConfigFilePath
|
||||||
liftIO $ writeFile path $ formatConfig $ fromSettings settings (Just keybindings)
|
liftIO $ writeFile path $ formatConfig $ fromSettings settings (Just keybindings)
|
||||||
@@ -160,27 +186,76 @@ config configCommand settings keybindings runLogger = case configCommand of
|
|||||||
liftIO $ putStrLn $ formatConfig $ fromSettings settings (Just keybindings)
|
liftIO $ putStrLn $ formatConfig $ fromSettings settings (Just keybindings)
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
(SetConfig k (Just v)) ->
|
(SetConfig k mv) -> do
|
||||||
case v of
|
r <- runE @'[JSONError, ParseError] $ do
|
||||||
"" -> do
|
case mv of
|
||||||
runLogger $ logError "Empty values are not allowed"
|
Just "" ->
|
||||||
pure $ ExitFailure 55
|
throwE $ ParseError "Empty values are not allowed"
|
||||||
_ -> doConfig (k <> ": " <> v <> "\n")
|
Nothing -> do
|
||||||
|
usersettings <- decodeSettings k
|
||||||
|
lift $ doConfig usersettings
|
||||||
|
pure ()
|
||||||
|
Just v -> do
|
||||||
|
usersettings <- decodeSettings (k <> ": " <> v <> "\n")
|
||||||
|
lift $ doConfig usersettings
|
||||||
|
pure ()
|
||||||
|
case r of
|
||||||
|
VRight _ -> pure ExitSuccess
|
||||||
|
VLeft (V (JSONDecodeError e)) -> do
|
||||||
|
runLogger $ logError $ "Error decoding config: " <> T.pack e
|
||||||
|
pure $ ExitFailure 65
|
||||||
|
VLeft _ -> pure $ ExitFailure 65
|
||||||
|
|
||||||
(SetConfig json Nothing) -> doConfig json
|
AddReleaseChannel force uri -> do
|
||||||
|
r <- runE @'[DuplicateReleaseChannel] $ do
|
||||||
|
case urlSource settings of
|
||||||
|
AddSource xs -> do
|
||||||
|
case checkDuplicate xs (Right uri) of
|
||||||
|
Duplicate
|
||||||
|
| not force -> throwE (DuplicateReleaseChannel uri)
|
||||||
|
DuplicateLast -> pure ()
|
||||||
|
_ -> lift $ doConfig (defaultUserSettings { uUrlSource = Just $ AddSource (appendUnique xs (Right uri)) })
|
||||||
|
GHCupURL -> do
|
||||||
|
lift $ doConfig (defaultUserSettings { uUrlSource = Just $ AddSource [Right uri] })
|
||||||
|
pure ()
|
||||||
|
OwnSource xs -> do
|
||||||
|
case checkDuplicate xs (Right uri) of
|
||||||
|
Duplicate
|
||||||
|
| not force -> throwE (DuplicateReleaseChannel uri)
|
||||||
|
DuplicateLast -> pure ()
|
||||||
|
_ -> lift $ doConfig (defaultUserSettings { uUrlSource = Just $ OwnSource (appendUnique xs (Right uri)) })
|
||||||
|
OwnSpec spec -> do
|
||||||
|
lift $ doConfig (defaultUserSettings { uUrlSource = Just $ OwnSource [Left spec, Right uri] })
|
||||||
|
pure ()
|
||||||
|
case r of
|
||||||
|
VRight _ -> do
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
|
pure $ ExitFailure 15
|
||||||
|
|
||||||
where
|
where
|
||||||
doConfig val = do
|
checkDuplicate :: Eq a => [a] -> a -> Duplicate
|
||||||
r <- runE @'[JSONError] $ do
|
checkDuplicate xs a
|
||||||
settings' <- updateSettings (UTF8.fromString val) settings
|
| last xs == a = DuplicateLast
|
||||||
path <- liftIO getConfigFilePath
|
| a `elem` xs = Duplicate
|
||||||
liftIO $ writeFile path $ formatConfig $ fromSettings settings' (Just keybindings)
|
| otherwise = NoDuplicate
|
||||||
lift $ runLogger $ logDebug $ T.pack $ show settings'
|
|
||||||
pure ()
|
|
||||||
|
|
||||||
case r of
|
-- appends the element to the end of the list, but also removes it from the existing list
|
||||||
VRight _ -> pure ExitSuccess
|
appendUnique :: Eq a => [a] -> a -> [a]
|
||||||
VLeft (V (JSONDecodeError e)) -> do
|
appendUnique xs' e = go xs'
|
||||||
runLogger $ logError $ "Error decoding config: " <> T.pack e
|
where
|
||||||
pure $ ExitFailure 65
|
go [] = [e]
|
||||||
VLeft _ -> pure $ ExitFailure 65
|
go (x:xs)
|
||||||
|
| x == e = go xs -- skip
|
||||||
|
| otherwise = x : go xs
|
||||||
|
|
||||||
|
doConfig :: MonadIO m => UserSettings -> m ()
|
||||||
|
doConfig usersettings = do
|
||||||
|
let settings' = updateSettings usersettings userConf
|
||||||
|
path <- liftIO getConfigFilePath
|
||||||
|
liftIO $ writeFile path $ formatConfig $ settings'
|
||||||
|
runLogger $ logDebug $ T.pack $ show settings'
|
||||||
|
pure ()
|
||||||
|
|
||||||
|
decodeSettings = lE' (JSONDecodeError . displayException) . Y.decodeEither' . UTF8.fromString
|
||||||
|
|||||||
@@ -17,9 +17,10 @@ import GHCup
|
|||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Version
|
import GHCup.Version
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Prelude
|
|
||||||
import GHCup.Utils.Dirs
|
import GHCup.Utils.Dirs
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude
|
||||||
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.Process
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -36,7 +37,6 @@ import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
import GHCup.Utils.File
|
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ describe_result = $( LitE . StringL <$>
|
|||||||
runIO (do
|
runIO (do
|
||||||
CapturedProcess{..} <- do
|
CapturedProcess{..} <- do
|
||||||
dirs <- liftIO getAllDirs
|
dirs <- liftIO getAllDirs
|
||||||
let settings = AppState (Settings True False Never Curl False GHCupURL False GPGNone False)
|
let settings = AppState (defaultSettings { noNetwork = True })
|
||||||
dirs
|
dirs
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
flip runReaderT settings $ executeOut "git" ["describe"] Nothing
|
flip runReaderT settings $ executeOut "git" ["describe"] Nothing
|
||||||
@@ -115,5 +115,5 @@ dinfo runAppState runLogger = do
|
|||||||
liftIO $ putStrLn $ prettyDebugInfo di
|
liftIO $ putStrLn $ prettyDebugInfo di
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 8
|
pure $ ExitFailure 8
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ module GHCup.OptParse.GC where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.Logger
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Prelude.String.QQ
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -27,7 +27,6 @@ import Haskus.Utils.Variant.Excepts
|
|||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
@@ -56,26 +55,26 @@ data GCOptions = GCOptions
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
gcP :: Parser GCOptions
|
gcP :: Parser GCOptions
|
||||||
gcP =
|
gcP =
|
||||||
GCOptions
|
GCOptions
|
||||||
<$>
|
<$>
|
||||||
switch
|
switch
|
||||||
(short 'o' <> long "ghc-old" <> help "Remove GHC versions marked as 'old'")
|
(short 'o' <> long "ghc-old" <> help "Remove GHC versions marked as 'old'")
|
||||||
<*>
|
<*>
|
||||||
switch
|
switch
|
||||||
(short 'p' <> long "profiling-libs" <> help "Remove profiling libs of GHC versions")
|
(short 'p' <> long "profiling-libs" <> help "Remove profiling libs of GHC versions")
|
||||||
<*>
|
<*>
|
||||||
switch
|
switch
|
||||||
(short 's' <> long "share-dir" <> help "Remove GHC share directories (documentation)")
|
(short 's' <> long "share-dir" <> help "Remove GHC share directories (documentation)")
|
||||||
<*>
|
<*>
|
||||||
switch
|
switch
|
||||||
(short 'h' <> long "hls-no-ghc" <> help "Remove HLS versions that don't have a corresponding installed GHC version")
|
(short 'h' <> long "hls-no-ghc" <> help "Remove HLS versions that don't have a corresponding installed GHC version")
|
||||||
<*>
|
<*>
|
||||||
switch
|
switch
|
||||||
(short 'c' <> long "cache" <> help "GC the GHCup cache")
|
(short 'c' <> long "cache" <> help "GC the GHCup cache")
|
||||||
<*>
|
<*>
|
||||||
switch
|
switch
|
||||||
(short 't' <> long "tmpdirs" <> help "Remove tmpdir leftovers")
|
(short 't' <> long "tmpdirs" <> help "Remove tmpdir leftovers")
|
||||||
|
|
||||||
@@ -98,7 +97,7 @@ gcFooter = [s|Discussion:
|
|||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
||||||
type GCEffects = '[ NotInstalled ]
|
type GCEffects = '[ NotInstalled, UninstallFailed ]
|
||||||
|
|
||||||
|
|
||||||
runGC :: MonadUnliftIO m
|
runGC :: MonadUnliftIO m
|
||||||
@@ -129,15 +128,15 @@ gc :: ( Monad m
|
|||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
gc GCOptions{..} runAppState runLogger = runGC runAppState (do
|
gc GCOptions{..} runAppState runLogger = runGC runAppState (do
|
||||||
when gcOldGHC rmOldGHC
|
when gcOldGHC (liftE rmOldGHC)
|
||||||
lift $ when gcProfilingLibs rmProfilingLibs
|
lift $ when gcProfilingLibs rmProfilingLibs
|
||||||
lift $ when gcShareDir rmShareDir
|
lift $ when gcShareDir rmShareDir
|
||||||
lift $ when gcHLSNoGHC rmHLSNoGHC
|
liftE $ when gcHLSNoGHC rmHLSNoGHC
|
||||||
lift $ when gcCache rmCache
|
lift $ when gcCache rmCache
|
||||||
lift $ when gcTmp rmTmp
|
lift $ when gcTmp rmTmp
|
||||||
) >>= \case
|
) >>= \case
|
||||||
VRight _ -> do
|
VRight _ -> do
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 27
|
pure $ ExitFailure 27
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
|
{-# LANGUAGE TypeOperators #-}
|
||||||
|
|
||||||
module GHCup.OptParse.Install where
|
module GHCup.OptParse.Install where
|
||||||
|
|
||||||
@@ -17,9 +19,10 @@ import GHCup.OptParse.Common
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.File
|
import GHCup.Utils.Dirs
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
|
|
||||||
import Codec.Archive
|
import Codec.Archive
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
@@ -30,14 +33,12 @@ import Control.Monad.Trans.Resource
|
|||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Versions hiding ( str )
|
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Options.Applicative.Help.Pretty ( text )
|
import Options.Applicative.Help.Pretty ( text )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import URI.ByteString hiding ( uriParser )
|
||||||
import URI.ByteString
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
|
||||||
@@ -64,11 +65,11 @@ data InstallCommand = InstallGHC InstallOptions
|
|||||||
|
|
||||||
data InstallOptions = InstallOptions
|
data InstallOptions = InstallOptions
|
||||||
{ instVer :: Maybe ToolVersion
|
{ instVer :: Maybe ToolVersion
|
||||||
, instPlatform :: Maybe PlatformRequest
|
|
||||||
, instBindist :: Maybe URI
|
, instBindist :: Maybe URI
|
||||||
, instSet :: Bool
|
, instSet :: Bool
|
||||||
, isolateDir :: Maybe FilePath
|
, isolateDir :: Maybe FilePath
|
||||||
, forceInstall :: Bool
|
, forceInstall :: Bool
|
||||||
|
, addConfArgs :: [T.Text]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -168,40 +169,27 @@ Examples:
|
|||||||
ghcup install ghc 8.10.2
|
ghcup install ghc 8.10.2
|
||||||
|
|
||||||
# install GHC head fedora bindist
|
# install GHC head fedora bindist
|
||||||
ghcup install ghc -u https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27 head|]
|
ghcup install ghc -u 'https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-fedora33-release.tar.xz?job=x86_64-linux-fedora33-release' head|]
|
||||||
|
|
||||||
|
|
||||||
installOpts :: Maybe Tool -> Parser InstallOptions
|
installOpts :: Maybe Tool -> Parser InstallOptions
|
||||||
installOpts tool =
|
installOpts tool =
|
||||||
(\p (u, v) b is f -> InstallOptions v p u b is f)
|
(\(u, v) b is f -> InstallOptions v u b is f)
|
||||||
<$> optional
|
<$> ( ( (,)
|
||||||
(option
|
|
||||||
(eitherReader platformParser)
|
|
||||||
( short 'p'
|
|
||||||
<> long "platform"
|
|
||||||
<> metavar "PLATFORM"
|
|
||||||
<> help
|
|
||||||
"Override for platform (triple matching ghc tarball names), e.g. x86_64-fedora27-linux"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<*> ( ( (,)
|
|
||||||
<$> optional
|
<$> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader bindistParser)
|
(eitherReader uriParser)
|
||||||
(short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
|
(short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
|
||||||
"Install the specified version from this bindist"
|
"Install the specified version from this bindist"
|
||||||
|
<> completer (toolDlCompleter (fromMaybe GHC tool))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> (Just <$> toolVersionArgument Nothing tool)
|
<*> (Just <$> toolVersionTagArgument Nothing tool)
|
||||||
)
|
)
|
||||||
<|> pure (Nothing, Nothing)
|
<|> pure (Nothing, Nothing)
|
||||||
)
|
)
|
||||||
<*> flag
|
<*> fmap (fromMaybe setDefault) (invertableSwitch "set" Nothing setDefault
|
||||||
False
|
(help $ if not setDefault then "Set as active version after install" else "Don't set as active version after install"))
|
||||||
True
|
|
||||||
(long "set" <> help
|
|
||||||
"Set as active version after install"
|
|
||||||
)
|
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader isolateParser)
|
(eitherReader isolateParser)
|
||||||
@@ -209,11 +197,18 @@ installOpts tool =
|
|||||||
<> long "isolate"
|
<> long "isolate"
|
||||||
<> metavar "DIR"
|
<> metavar "DIR"
|
||||||
<> help "install in an isolated dir instead of the default one"
|
<> help "install in an isolated dir instead of the default one"
|
||||||
|
<> completer (bashCompleter "directory")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> switch
|
<*> switch
|
||||||
(short 'f' <> long "force" <> help "Force install")
|
(short 'f' <> long "force" <> help "Force install (THIS IS UNSAFE, only use it in Dockerfiles or CI)")
|
||||||
|
<*> many (argument str (metavar "CONFIGURE_ARGS" <> help "Additional arguments to bindist configure, prefix with '-- ' (longopts)"))
|
||||||
|
where
|
||||||
|
setDefault = case tool of
|
||||||
|
Nothing -> False
|
||||||
|
Just GHC -> False
|
||||||
|
Just _ -> True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -247,6 +242,7 @@ type InstallEffects = '[ AlreadyInstalled
|
|||||||
, BuildFailed
|
, BuildFailed
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
, DigestError
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
, GPGError
|
, GPGError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, TarDirDoesNotExist
|
, TarDirDoesNotExist
|
||||||
@@ -254,20 +250,55 @@ type InstallEffects = '[ AlreadyInstalled
|
|||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
, FileAlreadyExistsError
|
, FileAlreadyExistsError
|
||||||
, ProcessError
|
, ProcessError
|
||||||
|
, UninstallFailed
|
||||||
|
, MergeFileTreeError
|
||||||
|
, InstallSetError
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
runInstTool :: AppState
|
runInstTool :: AppState
|
||||||
-> Maybe PlatformRequest
|
|
||||||
-> Excepts InstallEffects (ResourceT (ReaderT AppState IO)) a
|
-> Excepts InstallEffects (ResourceT (ReaderT AppState IO)) a
|
||||||
-> IO (VEither InstallEffects a)
|
-> IO (VEither InstallEffects a)
|
||||||
runInstTool appstate' mInstPlatform =
|
runInstTool appstate' =
|
||||||
flip runReaderT (maybe appstate' (\x -> appstate'{ pfreq = x } :: AppState) mInstPlatform)
|
flip runReaderT appstate'
|
||||||
. runResourceT
|
. runResourceT
|
||||||
. runE
|
. runE
|
||||||
@InstallEffects
|
@InstallEffects
|
||||||
|
|
||||||
|
|
||||||
|
type InstallGHCEffects = '[ AlreadyInstalled
|
||||||
|
, ArchiveResult
|
||||||
|
, BuildFailed
|
||||||
|
, CopyError
|
||||||
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
|
, DirNotEmpty
|
||||||
|
, DownloadFailed
|
||||||
|
, FileAlreadyExistsError
|
||||||
|
, FileDoesNotExistError
|
||||||
|
, GPGError
|
||||||
|
, MergeFileTreeError
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoDownload
|
||||||
|
, NoToolVersionSet
|
||||||
|
, NotInstalled
|
||||||
|
, ProcessError
|
||||||
|
, TagNotFound
|
||||||
|
, TarDirDoesNotExist
|
||||||
|
, UninstallFailed
|
||||||
|
, UnknownArchive
|
||||||
|
, InstallSetError
|
||||||
|
]
|
||||||
|
|
||||||
|
runInstGHC :: AppState
|
||||||
|
-> Excepts InstallGHCEffects (ResourceT (ReaderT AppState IO)) a
|
||||||
|
-> IO (VEither InstallGHCEffects a)
|
||||||
|
runInstGHC appstate' =
|
||||||
|
flip runReaderT appstate'
|
||||||
|
. runResourceT
|
||||||
|
. runE
|
||||||
|
@InstallGHCEffects
|
||||||
|
|
||||||
|
|
||||||
-------------------
|
-------------------
|
||||||
--[ Entrypoints ]--
|
--[ Entrypoints ]--
|
||||||
@@ -288,23 +319,27 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
installGHC InstallOptions{..} = do
|
installGHC InstallOptions{..} = do
|
||||||
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
||||||
(case instBindist of
|
(case instBindist of
|
||||||
Nothing -> runInstTool s' instPlatform $ do
|
Nothing -> runInstGHC s' $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||||
liftE $ installGHCBin
|
liftE $ runBothE' (installGHCBin
|
||||||
(_tvVersion v)
|
(_tvVersion v)
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
when instSet $ void $ liftE $ setGHC v SetGHCOnly
|
addConfArgs
|
||||||
|
)
|
||||||
|
$ when instSet $ when (isNothing isolateDir) $ liftE $ void $ setGHC v SetGHCOnly Nothing
|
||||||
pure vi
|
pure vi
|
||||||
Just uri -> do
|
Just uri -> do
|
||||||
runInstTool s'{ settings = settings {noVerify = True}} instPlatform $ do
|
runInstGHC s'{ settings = settings {noVerify = True}} $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer GHC
|
(v, vi) <- liftE $ fromVersion instVer GHC
|
||||||
liftE $ installGHCBindist
|
liftE $ runBothE' (installGHCBindist
|
||||||
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "")
|
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing)
|
||||||
(_tvVersion v)
|
(_tvVersion v)
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
when instSet $ void $ liftE $ setGHC v SetGHCOnly
|
addConfArgs
|
||||||
|
)
|
||||||
|
$ when instSet $ when (isNothing isolateDir) $ liftE $ void $ setGHC v SetGHCOnly Nothing
|
||||||
pure vi
|
pure vi
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -313,25 +348,42 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg ->
|
||||||
runLogger $ logInfo msg
|
runLogger $ logInfo msg
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
|
||||||
runLogger $ logWarn $
|
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||||
"GHC ver " <> prettyVer v <> " already installed; if you really want to reinstall it, you may want to run 'ghcup install ghc --force " <> prettyVer v <> "'"
|
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||||
|
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||||
|
pure ExitSuccess
|
||||||
|
|
||||||
VLeft (V (DirNotEmpty fp)) -> do
|
VLeft (V (DirNotEmpty fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logError $
|
||||||
"Install directory " <> T.pack fp <> " is not empty. Use 'ghcup install ghc --isolate " <> T.pack fp <> " --force ..." <> "' to install regardless."
|
"Install directory " <> T.pack fp <> " is not empty."
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
VLeft (V (DirNotEmpty fp)) -> do
|
||||||
|
runLogger $ logError $
|
||||||
|
"Install directory " <> T.pack fp <> " is not empty."
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
|
||||||
|
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||||
|
case keepDirs settings of
|
||||||
|
Never -> runLogger (logError $ T.pack $ prettyHFError err)
|
||||||
|
_ -> runLogger (logError $ T.pack (prettyHFError err) <> "\n" <>
|
||||||
|
"Check the logs at " <> T.pack (fromGHCupPath logsDir) <> " and the build directory " <> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||||
|
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
VLeft err@(V (BuildFailed tmpdir _)) -> do
|
||||||
case keepDirs settings of
|
case keepDirs settings of
|
||||||
Never -> runLogger (logError $ T.pack $ prettyShow err)
|
Never -> runLogger (logError $ T.pack $ prettyHFError err)
|
||||||
_ -> runLogger (logError $ T.pack (prettyShow err) <> "\n" <>
|
_ -> runLogger (logError $ T.pack (prettyHFError err) <> "\n" <>
|
||||||
"Check the logs at " <> T.pack logsDir <> " and the build directory " <> T.pack tmpdir <> " for more clues." <> "\n" <>
|
"Check the logs at " <> T.pack (fromGHCupPath logsDir) <> " and the build directory " <> T.pack tmpdir <> " for more clues." <> "\n" <>
|
||||||
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
"Make sure to clean up " <> T.pack tmpdir <> " afterwards.")
|
||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
|
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ do
|
runLogger $ do
|
||||||
logError $ T.pack $ prettyShow e
|
logError $ T.pack $ prettyHFError e
|
||||||
logError $ "Also check the logs in " <> T.pack logsDir
|
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
|
|
||||||
|
|
||||||
@@ -339,21 +391,23 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
installCabal InstallOptions{..} = do
|
installCabal InstallOptions{..} = do
|
||||||
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
||||||
(case instBindist of
|
(case instBindist of
|
||||||
Nothing -> runInstTool s' instPlatform $ do
|
Nothing -> runInstTool s' $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer Cabal
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Cabal
|
||||||
liftE $ installCabalBin
|
liftE $ runBothE' (installCabalBin
|
||||||
(_tvVersion v)
|
v
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
|
) $ when instSet $ when (isNothing isolateDir) $ liftE $ setCabal v
|
||||||
pure vi
|
pure vi
|
||||||
Just uri -> do
|
Just uri -> do
|
||||||
runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do
|
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer Cabal
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Cabal
|
||||||
liftE $ installCabalBindist
|
liftE $ runBothE' (installCabalBindist
|
||||||
(DownloadInfo uri Nothing "")
|
(DownloadInfo uri Nothing "" Nothing)
|
||||||
(_tvVersion v)
|
v
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
|
) $ when instSet $ when (isNothing isolateDir) $ liftE $ setCabal v
|
||||||
pure vi
|
pure vi
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -362,9 +416,15 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg ->
|
||||||
runLogger $ logInfo msg
|
runLogger $ logInfo msg
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||||
|
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
"Cabal ver " <> prettyVer v <> " already installed; if you really want to reinstall it, you may want to run 'ghcup install cabal --force " <> prettyVer v <> "'"
|
"File " <> T.pack fp <> " already exists. Use 'ghcup install cabal --isolate " <> T.pack fp <> " --force ..." <> "' if you want to overwrite."
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||||
|
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
@@ -372,29 +432,32 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ do
|
runLogger $ do
|
||||||
logError $ T.pack $ prettyShow e
|
logError $ T.pack $ prettyHFError e
|
||||||
logError $ "Also check the logs in " <> T.pack logsDir
|
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||||
pure $ ExitFailure 4
|
pure $ ExitFailure 4
|
||||||
|
|
||||||
installHLS :: InstallOptions -> IO ExitCode
|
installHLS :: InstallOptions -> IO ExitCode
|
||||||
installHLS InstallOptions{..} = do
|
installHLS InstallOptions{..} = do
|
||||||
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
||||||
(case instBindist of
|
(case instBindist of
|
||||||
Nothing -> runInstTool s' instPlatform $ do
|
Nothing -> runInstTool s' $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer HLS
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer HLS
|
||||||
liftE $ installHLSBin
|
liftE $ runBothE' (installHLSBin
|
||||||
(_tvVersion v)
|
v
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
|
) $ when instSet $ when (isNothing isolateDir) $ liftE $ setHLS v SetHLSOnly Nothing
|
||||||
pure vi
|
pure vi
|
||||||
Just uri -> do
|
Just uri -> do
|
||||||
runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do
|
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer HLS
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer HLS
|
||||||
liftE $ installHLSBindist
|
-- TODO: support legacy
|
||||||
(DownloadInfo uri Nothing "")
|
liftE $ runBothE' (installHLSBindist
|
||||||
(_tvVersion v)
|
(DownloadInfo uri (if isWindows then Nothing else Just (RegexDir "haskell-language-server-*")) "" Nothing)
|
||||||
isolateDir
|
v
|
||||||
forceInstall
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
|
forceInstall
|
||||||
|
) $ when instSet $ when (isNothing isolateDir) $ liftE $ setHLS v SetHLSOnly Nothing
|
||||||
pure vi
|
pure vi
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -403,13 +466,15 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg ->
|
||||||
runLogger $ logInfo msg
|
runLogger $ logInfo msg
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||||
|
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
"HLS ver "
|
"File " <> T.pack fp <> " already exists. Use 'ghcup install hls --isolate " <> T.pack fp <> " --force ..." <> "' if you want to overwrite."
|
||||||
<> prettyVer v
|
pure $ ExitFailure 3
|
||||||
<> " already installed; if you really want to reinstall it, you may want to run 'ghcup install hls --force "
|
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||||
<> prettyVer v
|
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||||
<> "'"
|
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
@@ -417,29 +482,31 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ do
|
runLogger $ do
|
||||||
logError $ T.pack $ prettyShow e
|
logError $ T.pack $ prettyHFError e
|
||||||
logError $ "Also check the logs in " <> T.pack logsDir
|
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||||
pure $ ExitFailure 4
|
pure $ ExitFailure 4
|
||||||
|
|
||||||
installStack :: InstallOptions -> IO ExitCode
|
installStack :: InstallOptions -> IO ExitCode
|
||||||
installStack InstallOptions{..} = do
|
installStack InstallOptions{..} = do
|
||||||
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
||||||
(case instBindist of
|
(case instBindist of
|
||||||
Nothing -> runInstTool s' instPlatform $ do
|
Nothing -> runInstTool s' $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer Stack
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Stack
|
||||||
liftE $ installStackBin
|
liftE $ runBothE' (installStackBin
|
||||||
(_tvVersion v)
|
v
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
|
) $ when instSet $ when (isNothing isolateDir) $ liftE $ setStack v
|
||||||
pure vi
|
pure vi
|
||||||
Just uri -> do
|
Just uri -> do
|
||||||
runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do
|
runInstTool s'{ settings = settings { noVerify = True}} $ do
|
||||||
(v, vi) <- liftE $ fromVersion instVer Stack
|
(_tvVersion -> v, vi) <- liftE $ fromVersion instVer Stack
|
||||||
liftE $ installStackBindist
|
liftE $ runBothE' (installStackBindist
|
||||||
(DownloadInfo uri Nothing "")
|
(DownloadInfo uri Nothing "" Nothing)
|
||||||
(_tvVersion v)
|
v
|
||||||
isolateDir
|
(maybe GHCupInternal IsolateDir isolateDir)
|
||||||
forceInstall
|
forceInstall
|
||||||
|
) $ when instSet $ when (isNothing isolateDir) $ liftE $ setStack v
|
||||||
pure vi
|
pure vi
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -448,9 +515,15 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg ->
|
||||||
runLogger $ logInfo msg
|
runLogger $ logInfo msg
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||||
|
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
"Stack ver " <> prettyVer v <> " already installed; if you really want to reinstall it, you may want to run 'ghcup install stack --force " <> prettyVer v <> "'"
|
"File " <> T.pack fp <> " already exists. Use 'ghcup install stack --isolate " <> T.pack fp <> " --force ..." <> "' if you want to overwrite."
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
VLeft e@(V (AlreadyInstalled _ _)) -> do
|
||||||
|
runLogger $ logWarn $ T.pack $ prettyHFError e
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft (V (FileAlreadyExistsError fp)) -> do
|
VLeft (V (FileAlreadyExistsError fp)) -> do
|
||||||
runLogger $ logWarn $
|
runLogger $ logWarn $
|
||||||
@@ -458,7 +531,6 @@ install installCommand settings getAppState' runLogger = case installCommand of
|
|||||||
pure $ ExitFailure 3
|
pure $ ExitFailure 3
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ do
|
runLogger $ do
|
||||||
logError $ T.pack $ prettyShow e
|
logError $ T.pack $ prettyHFError e
|
||||||
logError $ "Also check the logs in " <> T.pack logsDir
|
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||||
pure $ ExitFailure 4
|
pure $ ExitFailure 4
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ module GHCup.OptParse.List where
|
|||||||
|
|
||||||
|
|
||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Prelude
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
|
|
||||||
@@ -69,6 +69,7 @@ listOpts =
|
|||||||
(eitherReader toolParser)
|
(eitherReader toolParser)
|
||||||
(short 't' <> long "tool" <> metavar "<ghc|cabal|hls|stack>" <> help
|
(short 't' <> long "tool" <> metavar "<ghc|cabal|hls|stack>" <> help
|
||||||
"Tool to list versions for. Default is all"
|
"Tool to list versions for. Default is all"
|
||||||
|
<> completer (toolCompleter)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
@@ -78,6 +79,7 @@ listOpts =
|
|||||||
<> long "show-criteria"
|
<> long "show-criteria"
|
||||||
<> metavar "<installed|set|available>"
|
<> metavar "<installed|set|available>"
|
||||||
<> help "Show only installed/set/available tool versions"
|
<> help "Show only installed/set/available tool versions"
|
||||||
|
<> completer (listCompleter ["installed", "set", "available"])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> switch
|
<*> switch
|
||||||
@@ -141,11 +143,11 @@ printListResult no_color raw lr = do
|
|||||||
)
|
)
|
||||||
$ lr
|
$ lr
|
||||||
let cols =
|
let cols =
|
||||||
foldr (\xs ys -> zipWith (:) xs ys) (replicate (length rows) []) rows
|
foldr (\xs ys -> zipWith (:) xs ys) (repeat []) rows
|
||||||
lengths = fmap (maximum . fmap strWidth) cols
|
lengths = fmap (maximum . fmap strWidth) cols
|
||||||
padded = fmap (\xs -> zipWith padTo xs lengths) rows
|
padded = fmap (\xs -> zipWith padTo xs lengths) rows
|
||||||
|
|
||||||
forM_ padded $ \row -> putStrLn $ unwords row
|
forM_ (if raw then rows else padded) $ \row -> putStrLn $ unwords row
|
||||||
where
|
where
|
||||||
|
|
||||||
padTo str' x =
|
padTo str' x =
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ module GHCup.OptParse.Nuke where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.Logger
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -26,7 +26,6 @@ import Haskus.Utils.Variant.Excepts
|
|||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
@@ -42,7 +41,7 @@ import Control.Concurrent (threadDelay)
|
|||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
||||||
type NukeEffects = '[ NotInstalled ]
|
type NukeEffects = '[ NotInstalled, UninstallFailed ]
|
||||||
|
|
||||||
|
|
||||||
runNuke :: AppState
|
runNuke :: AppState
|
||||||
@@ -95,5 +94,5 @@ nuke appState runLogger = do
|
|||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 15
|
pure $ ExitFailure 15
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ module GHCup.OptParse.Prefetch where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.File
|
||||||
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.Utils.String.QQ
|
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -29,11 +30,9 @@ import Haskus.Utils.Variant.Excepts
|
|||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
import GHCup.Utils.Prelude
|
|
||||||
import GHCup.Download (getDownloadsF)
|
import GHCup.Download (getDownloadsF)
|
||||||
|
|
||||||
|
|
||||||
@@ -74,44 +73,44 @@ data PrefetchGHCOptions = PrefetchGHCOptions {
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
prefetchP :: Parser PrefetchCommand
|
prefetchP :: Parser PrefetchCommand
|
||||||
prefetchP = subparser
|
prefetchP = subparser
|
||||||
( command
|
( command
|
||||||
"ghc"
|
"ghc"
|
||||||
(info
|
(info
|
||||||
(PrefetchGHC
|
(PrefetchGHC
|
||||||
<$> (PrefetchGHCOptions
|
<$> (PrefetchGHCOptions
|
||||||
<$> ( switch (short 's' <> long "source" <> help "Download source tarball instead of bindist") <**> helper )
|
<$> ( switch (short 's' <> long "source" <> help "Download source tarball instead of bindist") <**> helper )
|
||||||
<*> optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)")))
|
<*> optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||||
<*> optional (toolVersionArgument Nothing (Just GHC)) )
|
<*> optional (toolVersionTagArgument Nothing (Just GHC)) )
|
||||||
( progDesc "Download GHC assets for installation")
|
( progDesc "Download GHC assets for installation")
|
||||||
)
|
)
|
||||||
<>
|
<>
|
||||||
command
|
command
|
||||||
"cabal"
|
"cabal"
|
||||||
(info
|
(info
|
||||||
(PrefetchCabal
|
(PrefetchCabal
|
||||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)")))
|
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||||
<*> ( optional (toolVersionArgument Nothing (Just Cabal)) <**> helper ))
|
<*> ( optional (toolVersionTagArgument Nothing (Just Cabal)) <**> helper ))
|
||||||
( progDesc "Download cabal assets for installation")
|
( progDesc "Download cabal assets for installation")
|
||||||
)
|
)
|
||||||
<>
|
<>
|
||||||
command
|
command
|
||||||
"hls"
|
"hls"
|
||||||
(info
|
(info
|
||||||
(PrefetchHLS
|
(PrefetchHLS
|
||||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)")))
|
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||||
<*> ( optional (toolVersionArgument Nothing (Just HLS)) <**> helper ))
|
<*> ( optional (toolVersionTagArgument Nothing (Just HLS)) <**> helper ))
|
||||||
( progDesc "Download HLS assets for installation")
|
( progDesc "Download HLS assets for installation")
|
||||||
)
|
)
|
||||||
<>
|
<>
|
||||||
command
|
command
|
||||||
"stack"
|
"stack"
|
||||||
(info
|
(info
|
||||||
(PrefetchStack
|
(PrefetchStack
|
||||||
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)")))
|
<$> fmap PrefetchOptions (optional (option str (short 'd' <> long "directory" <> help "directory to download into (default: ~/.ghcup/cache/)" <> completer (bashCompleter "directory"))))
|
||||||
<*> ( optional (toolVersionArgument Nothing (Just Stack)) <**> helper ))
|
<*> ( optional (toolVersionTagArgument Nothing (Just Stack)) <**> helper ))
|
||||||
( progDesc "Download stack assets for installation")
|
( progDesc "Download stack assets for installation")
|
||||||
)
|
)
|
||||||
<>
|
<>
|
||||||
@@ -153,6 +152,7 @@ type PrefetchEffects = '[ TagNotFound
|
|||||||
, NoToolVersionSet
|
, NoToolVersionSet
|
||||||
, NoDownload
|
, NoDownload
|
||||||
, DigestError
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
, GPGError
|
, GPGError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, JSONError
|
, JSONError
|
||||||
@@ -215,5 +215,5 @@ prefetch prefetchCommand runAppState runLogger =
|
|||||||
VRight _ -> do
|
VRight _ -> do
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 15
|
pure $ ExitFailure 15
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ import GHCup.Errors
|
|||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.Utils.String.QQ
|
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -34,7 +34,6 @@ import Haskus.Utils.Variant.Excepts
|
|||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
@@ -71,7 +70,7 @@ data RmOptions = RmOptions
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
rmParser :: Parser (Either RmCommand RmOptions)
|
rmParser :: Parser (Either RmCommand RmOptions)
|
||||||
rmParser =
|
rmParser =
|
||||||
(Left <$> subparser
|
(Left <$> subparser
|
||||||
@@ -103,7 +102,7 @@ rmParser =
|
|||||||
|
|
||||||
|
|
||||||
rmOpts :: Maybe Tool -> Parser RmOptions
|
rmOpts :: Maybe Tool -> Parser RmOptions
|
||||||
rmOpts tool = RmOptions <$> versionArgument (Just ListInstalled) tool
|
rmOpts tool = RmOptions <$> ghcVersionArgument (Just ListInstalled) tool
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -127,7 +126,7 @@ rmFooter = [s|Discussion:
|
|||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
||||||
type RmEffects = '[ NotInstalled ]
|
type RmEffects = '[ NotInstalled, UninstallFailed ]
|
||||||
|
|
||||||
|
|
||||||
runRm :: (ReaderT env m (VEither RmEffects a) -> m (VEither RmEffects a))
|
runRm :: (ReaderT env m (VEither RmEffects a) -> m (VEither RmEffects a))
|
||||||
@@ -175,11 +174,11 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
|||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
forM_ (_viPostRemove =<< vi) $ \msg ->
|
runLogger $ logGHCPostRm ghcVer
|
||||||
runLogger $ logInfo msg
|
postRmLog vi
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 7
|
pure $ ExitFailure 7
|
||||||
|
|
||||||
rmCabal' tv =
|
rmCabal' tv =
|
||||||
@@ -191,11 +190,10 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
|||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
forM_ (_viPostRemove =<< vi) $ \msg ->
|
postRmLog vi
|
||||||
runLogger $ logInfo msg
|
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 15
|
pure $ ExitFailure 15
|
||||||
|
|
||||||
rmHLS' tv =
|
rmHLS' tv =
|
||||||
@@ -207,11 +205,10 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
|||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
forM_ (_viPostRemove =<< vi) $ \msg ->
|
postRmLog vi
|
||||||
runLogger $ logInfo msg
|
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 15
|
pure $ ExitFailure 15
|
||||||
|
|
||||||
rmStack' tv =
|
rmStack' tv =
|
||||||
@@ -223,10 +220,12 @@ rm rmCommand runAppState runLogger = case rmCommand of
|
|||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight vi -> do
|
||||||
forM_ (_viPostRemove =<< vi) $ \msg ->
|
postRmLog vi
|
||||||
runLogger $ logInfo msg
|
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 15
|
pure $ ExitFailure 15
|
||||||
|
|
||||||
|
postRmLog vi =
|
||||||
|
forM_ (_viPostRemove =<< vi) $ \msg ->
|
||||||
|
runLogger $ logInfo msg
|
||||||
|
|||||||
492
app/ghcup/GHCup/OptParse/Run.hs
Normal file
492
app/ghcup/GHCup/OptParse/Run.hs
Normal file
@@ -0,0 +1,492 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
|
module GHCup.OptParse.Run where
|
||||||
|
|
||||||
|
|
||||||
|
import GHCup
|
||||||
|
import GHCup.Utils
|
||||||
|
import GHCup.OptParse.Common
|
||||||
|
import GHCup.Errors
|
||||||
|
import GHCup.Types
|
||||||
|
import GHCup.Types.Optics
|
||||||
|
import GHCup.Prelude
|
||||||
|
import GHCup.Prelude.File
|
||||||
|
#ifdef IS_WINDOWS
|
||||||
|
import GHCup.Prelude.Process
|
||||||
|
import GHCup.Prelude.Process.Windows ( execNoMinGW )
|
||||||
|
#endif
|
||||||
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
|
|
||||||
|
import Control.Exception.Safe ( MonadMask, MonadCatch )
|
||||||
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
|
import Control.Monad.Fail ( MonadFail )
|
||||||
|
#endif
|
||||||
|
import Codec.Archive
|
||||||
|
import Control.Monad.Reader
|
||||||
|
import Control.Monad.Trans.Resource
|
||||||
|
import Data.Functor
|
||||||
|
import Data.Maybe (isNothing)
|
||||||
|
import Data.List ( intercalate )
|
||||||
|
import Haskus.Utils.Variant.Excepts
|
||||||
|
import Options.Applicative hiding ( style )
|
||||||
|
import Prelude hiding ( appendFile )
|
||||||
|
import System.FilePath
|
||||||
|
import System.Environment
|
||||||
|
import System.Exit
|
||||||
|
|
||||||
|
import qualified Data.Map.Strict as Map
|
||||||
|
import qualified Data.Text as T
|
||||||
|
#ifndef IS_WINDOWS
|
||||||
|
import qualified System.Posix.Process as SPP
|
||||||
|
#endif
|
||||||
|
import Data.Versions ( prettyVer, Version )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Options ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
data RunOptions = RunOptions
|
||||||
|
{ runAppendPATH :: Bool
|
||||||
|
, runInstTool' :: Bool
|
||||||
|
, runMinGWPath :: Bool
|
||||||
|
, runGHCVer :: Maybe ToolVersion
|
||||||
|
, runCabalVer :: Maybe ToolVersion
|
||||||
|
, runHLSVer :: Maybe ToolVersion
|
||||||
|
, runStackVer :: Maybe ToolVersion
|
||||||
|
, runBinDir :: Maybe FilePath
|
||||||
|
, runQuick :: Bool
|
||||||
|
, runCOMMAND :: [String]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Parsers ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
runOpts :: Parser RunOptions
|
||||||
|
runOpts =
|
||||||
|
RunOptions
|
||||||
|
<$> switch
|
||||||
|
(short 'a' <> long "append" <> help "Append bin/ dir to PATH instead of prepending (this means that e.g. a system installation may take precedence)")
|
||||||
|
<*> switch
|
||||||
|
(short 'i' <> long "install" <> help "Install the tool, if missing")
|
||||||
|
<*> switch
|
||||||
|
(short 'm' <> long "mingw-path" <> help "On windows, add mingw64 PATHs to environment (does nothing on unix)")
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader ghcVersionTagEither)
|
||||||
|
(metavar "GHC_VERSION" <> long "ghc" <> help "The ghc version"
|
||||||
|
<> completer (tagCompleter GHC [])
|
||||||
|
<> (completer $ versionCompleter Nothing GHC)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader toolVersionTagEither)
|
||||||
|
(metavar "CABAL_VERSION" <> long "cabal" <> help "The cabal version"
|
||||||
|
<> completer (tagCompleter Cabal [])
|
||||||
|
<> (completer $ versionCompleter Nothing Cabal)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader toolVersionTagEither)
|
||||||
|
(metavar "HLS_VERSION" <> long "hls" <> help "The HLS version"
|
||||||
|
<> completer (tagCompleter HLS [])
|
||||||
|
<> (completer $ versionCompleter Nothing HLS)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader toolVersionTagEither)
|
||||||
|
(metavar "STACK_VERSION" <> long "stack" <> help "The stack version"
|
||||||
|
<> completer (tagCompleter Stack [])
|
||||||
|
<> (completer $ versionCompleter Nothing Stack)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<*> optional
|
||||||
|
(option
|
||||||
|
(eitherReader isolateParser)
|
||||||
|
( short 'b'
|
||||||
|
<> long "bindir"
|
||||||
|
<> metavar "DIR"
|
||||||
|
<> help "directory where to create the tool symlinks (default: newly created system temp dir)"
|
||||||
|
<> completer (bashCompleter "directory")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<*> switch
|
||||||
|
(short 'q' <> long "quick" <> help "Avoid any expensive work (such as downloads, version/tag resolution etc.). Disables --install.")
|
||||||
|
<*> many (argument str (metavar "COMMAND" <> help "The command to run, with arguments (use longopts --). If omitted, just prints the created bin/ dir to stdout and exits."))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------
|
||||||
|
--[ Footer ]--
|
||||||
|
--------------
|
||||||
|
|
||||||
|
|
||||||
|
runFooter :: String
|
||||||
|
runFooter = [s|Discussion:
|
||||||
|
Adds the given tools to a dedicated bin/ directory and adds them to PATH, exposing
|
||||||
|
the relevant binaries, then executes a command.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# run VSCode with all latest toolchain exposed, installing missing versions if necessary
|
||||||
|
ghcup run --ghc latest --cabal latest --hls latest --stack latest --install -- code Setup.hs
|
||||||
|
|
||||||
|
# create a custom toolchain bin/ dir with GHC and cabal that can be manually added to PATH
|
||||||
|
ghcup run --ghc 8.10.7 --cabal 3.2.0.0 --bindir $HOME/toolchain/bin
|
||||||
|
|
||||||
|
# run a specific ghc version
|
||||||
|
ghcup run --ghc 8.10.7 -- ghc --version|]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
--[ Effect interpreters ]--
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
type RunEffects = '[ AlreadyInstalled
|
||||||
|
, UnknownArchive
|
||||||
|
, ArchiveResult
|
||||||
|
, FileDoesNotExistError
|
||||||
|
, CopyError
|
||||||
|
, NotInstalled
|
||||||
|
, DirNotEmpty
|
||||||
|
, NoDownload
|
||||||
|
, NotInstalled
|
||||||
|
, BuildFailed
|
||||||
|
, TagNotFound
|
||||||
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
|
, GPGError
|
||||||
|
, DownloadFailed
|
||||||
|
, TarDirDoesNotExist
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
, FileAlreadyExistsError
|
||||||
|
, ProcessError
|
||||||
|
, UninstallFailed
|
||||||
|
, MergeFileTreeError
|
||||||
|
]
|
||||||
|
|
||||||
|
runLeanRUN :: (MonadUnliftIO m, MonadIO m)
|
||||||
|
=> LeanAppState
|
||||||
|
-> Excepts RunEffects (ReaderT LeanAppState m) a
|
||||||
|
-> m (VEither RunEffects a)
|
||||||
|
runLeanRUN leanAppstate =
|
||||||
|
-- Don't use runLeanAppState here, which is disabled on windows.
|
||||||
|
-- This is the only command on all platforms that doesn't need full appstate.
|
||||||
|
flip runReaderT leanAppstate
|
||||||
|
. runE
|
||||||
|
@RunEffects
|
||||||
|
|
||||||
|
runRUN :: MonadUnliftIO m
|
||||||
|
=> IO AppState
|
||||||
|
-> Excepts RunEffects (ResourceT (ReaderT AppState m)) a
|
||||||
|
-> m (VEither RunEffects a)
|
||||||
|
runRUN appState action' = do
|
||||||
|
s' <- liftIO appState
|
||||||
|
flip runReaderT s'
|
||||||
|
. runResourceT
|
||||||
|
. runE
|
||||||
|
@RunEffects
|
||||||
|
$ action'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------
|
||||||
|
--[ Entrypoint ]--
|
||||||
|
------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
run :: forall m .
|
||||||
|
( MonadFail m
|
||||||
|
, MonadMask m
|
||||||
|
, MonadCatch m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadUnliftIO m
|
||||||
|
)
|
||||||
|
=> RunOptions
|
||||||
|
-> IO AppState
|
||||||
|
-> LeanAppState
|
||||||
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
|
-> m ExitCode
|
||||||
|
run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||||
|
r <- if not runQuick
|
||||||
|
then runRUN runAppState $ do
|
||||||
|
toolchain <- liftE resolveToolchainFull
|
||||||
|
|
||||||
|
-- oh dear
|
||||||
|
r <- lift ask
|
||||||
|
tmp <- lift . lift . lift . flip runReaderT (fromAppState r) $ createTmpDir toolchain
|
||||||
|
|
||||||
|
liftE $ installToolChainFull toolchain tmp
|
||||||
|
pure tmp
|
||||||
|
else runLeanRUN leanAppstate $ do
|
||||||
|
toolchain <- resolveToolchain
|
||||||
|
tmp <- lift $ createTmpDir toolchain
|
||||||
|
liftE $ installToolChain toolchain tmp
|
||||||
|
pure tmp
|
||||||
|
case r of
|
||||||
|
VRight tmp -> do
|
||||||
|
case runCOMMAND of
|
||||||
|
[] -> do
|
||||||
|
liftIO $ putStr tmp
|
||||||
|
pure ExitSuccess
|
||||||
|
(cmd:args) -> do
|
||||||
|
newEnv <- liftIO $ addToPath tmp runAppendPATH
|
||||||
|
#ifndef IS_WINDOWS
|
||||||
|
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
||||||
|
pure ExitSuccess
|
||||||
|
#else
|
||||||
|
r' <- if runMinGWPath
|
||||||
|
then runLeanRUN leanAppstate $ liftE $ lEM @_ @'[ProcessError] $ exec cmd args Nothing (Just newEnv)
|
||||||
|
else runLeanRUN leanAppstate $ liftE $ lEM @_ @'[ProcessError] $ execNoMinGW cmd args Nothing (Just newEnv)
|
||||||
|
case r' of
|
||||||
|
VRight _ -> pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
|
pure $ ExitFailure 28
|
||||||
|
#endif
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
|
pure $ ExitFailure 27
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
-- TODO: doesn't work for cross
|
||||||
|
resolveToolchainFull :: ( MonadFail m
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
] (ResourceT (ReaderT AppState m)) Toolchain
|
||||||
|
resolveToolchainFull = do
|
||||||
|
ghcVer <- forM runGHCVer $ \ver -> do
|
||||||
|
(v, _) <- liftE $ fromVersion (Just ver) GHC
|
||||||
|
pure v
|
||||||
|
cabalVer <- forM runCabalVer $ \ver -> do
|
||||||
|
(v, _) <- liftE $ fromVersion (Just ver) Cabal
|
||||||
|
pure (_tvVersion v)
|
||||||
|
hlsVer <- forM runHLSVer $ \ver -> do
|
||||||
|
(v, _) <- liftE $ fromVersion (Just ver) HLS
|
||||||
|
pure (_tvVersion v)
|
||||||
|
stackVer <- forM runStackVer $ \ver -> do
|
||||||
|
(v, _) <- liftE $ fromVersion (Just ver) Stack
|
||||||
|
pure (_tvVersion v)
|
||||||
|
pure Toolchain{..}
|
||||||
|
|
||||||
|
resolveToolchain = do
|
||||||
|
ghcVer <- case runGHCVer of
|
||||||
|
Just (GHCVersion v) -> pure $ Just v
|
||||||
|
Just (ToolVersion v) -> pure $ Just (mkTVer v)
|
||||||
|
Nothing -> pure Nothing
|
||||||
|
_ -> fail "Internal error"
|
||||||
|
cabalVer <- case runCabalVer of
|
||||||
|
Just (GHCVersion v) -> pure $ Just (_tvVersion v)
|
||||||
|
Just (ToolVersion v) -> pure $ Just v
|
||||||
|
Nothing -> pure Nothing
|
||||||
|
_ -> fail "Internal error"
|
||||||
|
hlsVer <- case runHLSVer of
|
||||||
|
Just (GHCVersion v) -> pure $ Just (_tvVersion v)
|
||||||
|
Just (ToolVersion v) -> pure $ Just v
|
||||||
|
Nothing -> pure Nothing
|
||||||
|
_ -> fail "Internal error"
|
||||||
|
stackVer <- case runStackVer of
|
||||||
|
Just (GHCVersion v) -> pure $ Just (_tvVersion v)
|
||||||
|
Just (ToolVersion v) -> pure $ Just v
|
||||||
|
Nothing -> pure Nothing
|
||||||
|
_ -> fail "Internal error"
|
||||||
|
pure Toolchain{..}
|
||||||
|
|
||||||
|
installToolChainFull :: ( MonadFail m
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Toolchain
|
||||||
|
-> FilePath
|
||||||
|
-> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
, UnknownArchive
|
||||||
|
, TarDirDoesNotExist
|
||||||
|
, ProcessError
|
||||||
|
, NotInstalled
|
||||||
|
, NoDownload
|
||||||
|
, GPGError
|
||||||
|
, DownloadFailed
|
||||||
|
, DirNotEmpty
|
||||||
|
, DigestError
|
||||||
|
, ContentLengthError
|
||||||
|
, BuildFailed
|
||||||
|
, ArchiveResult
|
||||||
|
, AlreadyInstalled
|
||||||
|
, FileAlreadyExistsError
|
||||||
|
, CopyError
|
||||||
|
, UninstallFailed
|
||||||
|
, MergeFileTreeError
|
||||||
|
] (ResourceT (ReaderT AppState m)) ()
|
||||||
|
installToolChainFull Toolchain{..} tmp = do
|
||||||
|
case ghcVer of
|
||||||
|
Just v -> do
|
||||||
|
isInstalled <- lift $ checkIfToolInstalled' GHC v
|
||||||
|
unless isInstalled $ when (runInstTool' && isNothing (_tvTarget v)) $ void $ liftE $ installGHCBin
|
||||||
|
(_tvVersion v)
|
||||||
|
GHCupInternal
|
||||||
|
False
|
||||||
|
[]
|
||||||
|
setGHC' v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
case cabalVer of
|
||||||
|
Just v -> do
|
||||||
|
isInstalled <- lift $ checkIfToolInstalled' Cabal (mkTVer v)
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installCabalBin
|
||||||
|
v
|
||||||
|
GHCupInternal
|
||||||
|
False
|
||||||
|
setCabal' v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
case stackVer of
|
||||||
|
Just v -> do
|
||||||
|
isInstalled <- lift $ checkIfToolInstalled' Stack (mkTVer v)
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installStackBin
|
||||||
|
v
|
||||||
|
GHCupInternal
|
||||||
|
False
|
||||||
|
setStack' v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
case hlsVer of
|
||||||
|
Just v -> do
|
||||||
|
isInstalled <- lift $ checkIfToolInstalled' HLS (mkTVer v)
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installHLSBin
|
||||||
|
v
|
||||||
|
GHCupInternal
|
||||||
|
False
|
||||||
|
setHLS' v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
|
||||||
|
installToolChain :: ( MonadFail m
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Toolchain
|
||||||
|
-> FilePath
|
||||||
|
-> Excepts '[NotInstalled] (ReaderT LeanAppState m) ()
|
||||||
|
installToolChain Toolchain{..} tmp = do
|
||||||
|
case ghcVer of
|
||||||
|
Just v -> setGHC' v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
case cabalVer of
|
||||||
|
Just v -> setCabal' v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
case stackVer of
|
||||||
|
Just v -> setStack' v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
case hlsVer of
|
||||||
|
Just v -> setHLS' v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
|
||||||
|
setGHC' v tmp = do
|
||||||
|
void $ liftE $ setGHC v SetGHC_XYZ (Just tmp)
|
||||||
|
void $ liftE $ setGHC v SetGHCOnly (Just tmp)
|
||||||
|
setCabal' v tmp = do
|
||||||
|
bin <- liftE $ whereIsTool Cabal (mkTVer v)
|
||||||
|
cbin <- liftIO $ canonicalizePath bin
|
||||||
|
lift $ createLink (relativeSymlink tmp cbin) (tmp </> ("cabal" <.> exeExt))
|
||||||
|
setStack' v tmp = do
|
||||||
|
bin <- liftE $ whereIsTool Stack (mkTVer v)
|
||||||
|
cbin <- liftIO $ canonicalizePath bin
|
||||||
|
lift $ createLink (relativeSymlink tmp cbin) (tmp </> ("stack" <.> exeExt))
|
||||||
|
setHLS' v tmp = do
|
||||||
|
Dirs {..} <- getDirs
|
||||||
|
legacy <- isLegacyHLS v
|
||||||
|
if legacy
|
||||||
|
then do
|
||||||
|
-- TODO: factor this out
|
||||||
|
hlsWrapper <- liftE @_ @'[NotInstalled] $ hlsWrapperBinary v !? (NotInstalled HLS (mkTVer v))
|
||||||
|
cw <- liftIO $ canonicalizePath (binDir </> hlsWrapper)
|
||||||
|
lift $ createLink (relativeSymlink tmp cw) (tmp </> takeFileName cw)
|
||||||
|
hlsBins <- hlsServerBinaries v Nothing >>= liftIO . traverse (canonicalizePath . (binDir </>))
|
||||||
|
forM_ hlsBins $ \bin ->
|
||||||
|
lift $ createLink (relativeSymlink tmp bin) (tmp </> takeFileName bin)
|
||||||
|
liftE $ setHLS v SetHLSOnly (Just tmp)
|
||||||
|
else do
|
||||||
|
liftE $ setHLS v SetHLS_XYZ (Just tmp)
|
||||||
|
liftE $ setHLS v SetHLSOnly (Just tmp)
|
||||||
|
|
||||||
|
createTmpDir :: ( MonadUnliftIO m
|
||||||
|
, MonadCatch m
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadMask m
|
||||||
|
, MonadIO m
|
||||||
|
)
|
||||||
|
=> Toolchain
|
||||||
|
-> ReaderT LeanAppState m FilePath
|
||||||
|
createTmpDir toolchain =
|
||||||
|
case runBinDir of
|
||||||
|
Just bindir -> do
|
||||||
|
liftIO $ createDirRecursive' bindir
|
||||||
|
liftIO $ canonicalizePath bindir
|
||||||
|
Nothing -> do
|
||||||
|
d <- predictableTmpDir toolchain
|
||||||
|
liftIO $ createDirRecursive' d
|
||||||
|
liftIO $ canonicalizePath d
|
||||||
|
|
||||||
|
predictableTmpDir :: Monad m
|
||||||
|
=> Toolchain
|
||||||
|
-> ReaderT LeanAppState m FilePath
|
||||||
|
predictableTmpDir (Toolchain Nothing Nothing Nothing Nothing) = do
|
||||||
|
Dirs { tmpDir } <- getDirs
|
||||||
|
pure (fromGHCupPath tmpDir </> "ghcup-none")
|
||||||
|
predictableTmpDir Toolchain{..} = do
|
||||||
|
Dirs { tmpDir } <- getDirs
|
||||||
|
pure $ fromGHCupPath tmpDir
|
||||||
|
</> ("ghcup-" <> intercalate "_"
|
||||||
|
( maybe [] ( (:[]) . ("ghc-" <>) . T.unpack . tVerToText) ghcVer
|
||||||
|
<> maybe [] ( (:[]) . ("cabal-" <>) . T.unpack . prettyVer) cabalVer
|
||||||
|
<> maybe [] ( (:[]) . ("hls-" <>) . T.unpack . prettyVer) hlsVer
|
||||||
|
<> maybe [] ( (:[]) . ("stack-" <>) . T.unpack . prettyVer) stackVer
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
--[ Other local types ]--
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data Toolchain = Toolchain
|
||||||
|
{ ghcVer :: Maybe GHCTargetVersion
|
||||||
|
, cabalVer :: Maybe Version
|
||||||
|
, hlsVer :: Maybe Version
|
||||||
|
, stackVer :: Maybe Version
|
||||||
|
} deriving Show
|
||||||
@@ -17,8 +17,8 @@ import GHCup.OptParse.Common
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.Logger
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Prelude.String.QQ
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -35,7 +35,6 @@ import Options.Applicative hiding ( style )
|
|||||||
import Options.Applicative.Help.Pretty ( text )
|
import Options.Applicative.Help.Pretty ( text )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Data.Bifunctor (second)
|
import Data.Bifunctor (second)
|
||||||
@@ -74,7 +73,7 @@ data SetOptions = SetOptions
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
setParser :: Parser (Either SetCommand SetOptions)
|
setParser :: Parser (Either SetCommand SetOptions)
|
||||||
setParser =
|
setParser =
|
||||||
(Left <$> subparser
|
(Left <$> subparser
|
||||||
@@ -82,7 +81,7 @@ setParser =
|
|||||||
"ghc"
|
"ghc"
|
||||||
( SetGHC
|
( SetGHC
|
||||||
<$> info
|
<$> info
|
||||||
(setOpts (Just GHC) <**> helper)
|
(setOpts GHC <**> helper)
|
||||||
( progDesc "Set GHC version"
|
( progDesc "Set GHC version"
|
||||||
<> footerDoc (Just $ text setGHCFooter)
|
<> footerDoc (Just $ text setGHCFooter)
|
||||||
)
|
)
|
||||||
@@ -91,7 +90,7 @@ setParser =
|
|||||||
"cabal"
|
"cabal"
|
||||||
( SetCabal
|
( SetCabal
|
||||||
<$> info
|
<$> info
|
||||||
(setOpts (Just Cabal) <**> helper)
|
(setOpts Cabal <**> helper)
|
||||||
( progDesc "Set Cabal version"
|
( progDesc "Set Cabal version"
|
||||||
<> footerDoc (Just $ text setCabalFooter)
|
<> footerDoc (Just $ text setCabalFooter)
|
||||||
)
|
)
|
||||||
@@ -100,7 +99,7 @@ setParser =
|
|||||||
"hls"
|
"hls"
|
||||||
( SetHLS
|
( SetHLS
|
||||||
<$> info
|
<$> info
|
||||||
(setOpts (Just HLS) <**> helper)
|
(setOpts HLS <**> helper)
|
||||||
( progDesc "Set haskell-language-server version"
|
( progDesc "Set haskell-language-server version"
|
||||||
<> footerDoc (Just $ text setHLSFooter)
|
<> footerDoc (Just $ text setHLSFooter)
|
||||||
)
|
)
|
||||||
@@ -109,14 +108,14 @@ setParser =
|
|||||||
"stack"
|
"stack"
|
||||||
( SetStack
|
( SetStack
|
||||||
<$> info
|
<$> info
|
||||||
(setOpts (Just Stack) <**> helper)
|
(setOpts Stack <**> helper)
|
||||||
( progDesc "Set stack version"
|
( progDesc "Set stack version"
|
||||||
<> footerDoc (Just $ text setStackFooter)
|
<> footerDoc (Just $ text setStackFooter)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<|> (Right <$> setOpts Nothing)
|
<|> (Right <$> setOpts GHC)
|
||||||
where
|
where
|
||||||
setGHCFooter :: String
|
setGHCFooter :: String
|
||||||
setGHCFooter = [s|Discussion:
|
setGHCFooter = [s|Discussion:
|
||||||
@@ -137,22 +136,25 @@ setParser =
|
|||||||
Sets the the current haskell-language-server version.|]
|
Sets the the current haskell-language-server version.|]
|
||||||
|
|
||||||
|
|
||||||
setOpts :: Maybe Tool -> Parser SetOptions
|
setOpts :: Tool -> Parser SetOptions
|
||||||
setOpts tool = SetOptions <$>
|
setOpts tool = SetOptions <$>
|
||||||
(fromMaybe SetRecommended <$>
|
(fromMaybe SetRecommended <$>
|
||||||
optional (setVersionArgument (Just ListInstalled) tool))
|
optional (setVersionArgument (Just ListInstalled) tool))
|
||||||
|
|
||||||
setVersionArgument :: Maybe ListCriteria -> Maybe Tool -> Parser SetToolVersion
|
setVersionArgument :: Maybe ListCriteria -> Tool -> Parser SetToolVersion
|
||||||
setVersionArgument criteria tool =
|
setVersionArgument criteria tool =
|
||||||
argument (eitherReader setEither)
|
argument (eitherReader setEither)
|
||||||
(metavar "VERSION|TAG|next"
|
(metavar "VERSION|TAG|next"
|
||||||
<> completer (tagCompleter (fromMaybe GHC tool) ["next"])
|
<> completer (tagCompleter tool ["next"])
|
||||||
<> foldMap (completer . versionCompleter criteria) tool)
|
<> (completer . versionCompleter criteria) tool)
|
||||||
where
|
where
|
||||||
setEither s' =
|
setEither s' =
|
||||||
parseSet s'
|
parseSet s'
|
||||||
<|> second SetToolTag (tagEither s')
|
<|> second SetToolTag (tagEither s')
|
||||||
<|> second SetToolVersion (tVersionEither s')
|
<|> se s'
|
||||||
|
se s' = case tool of
|
||||||
|
GHC -> second SetGHCVersion (ghcVersionEither s')
|
||||||
|
_ -> second SetToolVersion (toolVersionEither s')
|
||||||
parseSet s' = case fmap toLower s' of
|
parseSet s' = case fmap toLower s' of
|
||||||
"next" -> Right SetNext
|
"next" -> Right SetNext
|
||||||
other -> Left $ "Unknown tag/version " <> other
|
other -> Left $ "Unknown tag/version " <> other
|
||||||
@@ -257,24 +259,21 @@ set :: forall m env.
|
|||||||
-> m (VEither eff GHCTargetVersion))
|
-> m (VEither eff GHCTargetVersion))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
set setCommand runAppState _ runLogger = case setCommand of
|
||||||
(Right sopts) -> do
|
(Right sopts) -> do
|
||||||
runLogger (logWarn "This is an old-style command for setting GHC. Use 'ghcup set ghc' instead.")
|
runLogger (logWarn "This is an old-style command for setting GHC. Use 'ghcup set ghc' instead.")
|
||||||
setGHC' sopts
|
setGHC' sopts
|
||||||
(Left (SetGHC sopts)) -> setGHC' sopts
|
(Left (SetGHC sopts)) -> setGHC' sopts
|
||||||
(Left (SetCabal sopts)) -> setCabal' sopts
|
(Left (SetCabal sopts)) -> setCabal' sopts
|
||||||
(Left (SetHLS sopts)) -> setHLS' sopts
|
(Left (SetHLS sopts)) -> setHLS' sopts
|
||||||
(Left (SetStack sopts)) -> setStack' sopts
|
(Left (SetStack sopts)) -> setStack' sopts
|
||||||
|
|
||||||
where
|
where
|
||||||
setGHC' :: SetOptions
|
setGHC' :: SetOptions
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setGHC' SetOptions{ sToolVer } =
|
setGHC' SetOptions{ sToolVer } = runSetGHC runAppState (do
|
||||||
case sToolVer of
|
|
||||||
(SetToolVersion v) -> runSetGHC runLeanAppState (liftE $ setGHC v SetGHCOnly >> pure v)
|
|
||||||
_ -> runSetGHC runAppState (do
|
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer GHC
|
v <- liftE $ fst <$> fromVersion' sToolVer GHC
|
||||||
liftE $ setGHC v SetGHCOnly
|
liftE $ setGHC v SetGHCOnly Nothing
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight GHCTargetVersion{..} -> do
|
VRight GHCTargetVersion{..} -> do
|
||||||
@@ -283,67 +282,58 @@ set setCommand runAppState runLeanAppState runLogger = case setCommand of
|
|||||||
"GHC " <> prettyVer _tvVersion <> " successfully set as default version" <> maybe "" (" for cross target " <>) _tvTarget
|
"GHC " <> prettyVer _tvVersion <> " successfully set as default version" <> maybe "" (" for cross target " <>) _tvTarget
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 5
|
pure $ ExitFailure 5
|
||||||
|
|
||||||
|
|
||||||
setCabal' :: SetOptions
|
setCabal' :: SetOptions
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setCabal' SetOptions{ sToolVer } =
|
setCabal' SetOptions{ sToolVer } = runSetCabal runAppState (do
|
||||||
case sToolVer of
|
|
||||||
(SetToolVersion v) -> runSetCabal runLeanAppState (liftE $ setCabal (_tvVersion v) >> pure v)
|
|
||||||
_ -> runSetCabal runAppState (do
|
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer Cabal
|
v <- liftE $ fst <$> fromVersion' sToolVer Cabal
|
||||||
liftE $ setCabal (_tvVersion v)
|
liftE $ setCabal (_tvVersion v)
|
||||||
pure v
|
pure v
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight GHCTargetVersion{..} -> do
|
VRight v -> do
|
||||||
runLogger
|
runLogger
|
||||||
$ logInfo $
|
$ logInfo $
|
||||||
"Cabal " <> prettyVer _tvVersion <> " successfully set as default version"
|
"Cabal " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 14
|
pure $ ExitFailure 14
|
||||||
|
|
||||||
setHLS' :: SetOptions
|
setHLS' :: SetOptions
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setHLS' SetOptions{ sToolVer } =
|
setHLS' SetOptions{ sToolVer } = runSetHLS runAppState (do
|
||||||
case sToolVer of
|
|
||||||
(SetToolVersion v) -> runSetHLS runLeanAppState (liftE $ setHLS (_tvVersion v) >> pure v)
|
|
||||||
_ -> runSetHLS runAppState (do
|
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer HLS
|
v <- liftE $ fst <$> fromVersion' sToolVer HLS
|
||||||
liftE $ setHLS (_tvVersion v)
|
liftE $ setHLS (_tvVersion v) SetHLSOnly Nothing
|
||||||
pure v
|
pure v
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight GHCTargetVersion{..} -> do
|
VRight v -> do
|
||||||
runLogger
|
runLogger
|
||||||
$ logInfo $
|
$ logInfo $
|
||||||
"HLS " <> prettyVer _tvVersion <> " successfully set as default version"
|
"HLS " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 14
|
pure $ ExitFailure 14
|
||||||
|
|
||||||
|
|
||||||
setStack' :: SetOptions
|
setStack' :: SetOptions
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
setStack' SetOptions{ sToolVer } =
|
setStack' SetOptions{ sToolVer } = runSetStack runAppState (do
|
||||||
case sToolVer of
|
|
||||||
(SetToolVersion v) -> runSetStack runLeanAppState (liftE $ setStack (_tvVersion v) >> pure v)
|
|
||||||
_ -> runSetStack runAppState (do
|
|
||||||
v <- liftE $ fst <$> fromVersion' sToolVer Stack
|
v <- liftE $ fst <$> fromVersion' sToolVer Stack
|
||||||
liftE $ setStack (_tvVersion v)
|
liftE $ setStack (_tvVersion v)
|
||||||
pure v
|
pure v
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight GHCTargetVersion{..} -> do
|
VRight v -> do
|
||||||
runLogger
|
runLogger
|
||||||
$ logInfo $
|
$ logInfo $
|
||||||
"Stack " <> prettyVer _tvVersion <> " successfully set as default version"
|
"Stack " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 14
|
pure $ ExitFailure 14
|
||||||
|
|||||||
188
app/ghcup/GHCup/OptParse/Test.hs
Normal file
188
app/ghcup/GHCup/OptParse/Test.hs
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
|
{-# LANGUAGE TypeOperators #-}
|
||||||
|
|
||||||
|
module GHCup.OptParse.Test where
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import GHCup.OptParse.Common
|
||||||
|
|
||||||
|
import GHCup
|
||||||
|
import GHCup.Errors
|
||||||
|
import GHCup.Types
|
||||||
|
import GHCup.Utils.Dirs
|
||||||
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
|
|
||||||
|
import Codec.Archive
|
||||||
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
|
import Control.Monad.Fail ( MonadFail )
|
||||||
|
#endif
|
||||||
|
import Control.Monad.Reader
|
||||||
|
import Control.Monad.Trans.Resource
|
||||||
|
import Data.Functor
|
||||||
|
import Data.Maybe
|
||||||
|
import Haskus.Utils.Variant.Excepts
|
||||||
|
import Options.Applicative hiding ( style )
|
||||||
|
import Options.Applicative.Help.Pretty ( text )
|
||||||
|
import Prelude hiding ( appendFile )
|
||||||
|
import System.Exit
|
||||||
|
import URI.ByteString hiding ( uriParser )
|
||||||
|
|
||||||
|
import qualified Data.Text as T
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------
|
||||||
|
--[ Commands ]--
|
||||||
|
----------------
|
||||||
|
|
||||||
|
|
||||||
|
data TestCommand = TestGHC TestOptions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Options ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
data TestOptions = TestOptions
|
||||||
|
{ testVer :: Maybe ToolVersion
|
||||||
|
, testBindist :: Maybe URI
|
||||||
|
, addMakeArgs :: [T.Text]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Footers ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
testFooter :: String
|
||||||
|
testFooter = [s|Discussion:
|
||||||
|
Runs test suites from the test bindist.|]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Parsers ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
testParser :: Parser TestCommand
|
||||||
|
testParser =
|
||||||
|
subparser
|
||||||
|
( command
|
||||||
|
"ghc"
|
||||||
|
( TestGHC
|
||||||
|
<$> info
|
||||||
|
(testOpts (Just GHC) <**> helper)
|
||||||
|
( progDesc "Test GHC"
|
||||||
|
<> footerDoc (Just $ text testGHCFooter)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
where
|
||||||
|
testGHCFooter :: String
|
||||||
|
testGHCFooter = [s|Discussion:
|
||||||
|
Runs the GHC test suite from the test bindist.|]
|
||||||
|
|
||||||
|
|
||||||
|
testOpts :: Maybe Tool -> Parser TestOptions
|
||||||
|
testOpts tool =
|
||||||
|
(\(u, v) args -> TestOptions v u args)
|
||||||
|
<$> ( ( (,)
|
||||||
|
<$> optional
|
||||||
|
(option
|
||||||
|
(eitherReader uriParser)
|
||||||
|
(short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
|
||||||
|
"Install the specified version from this bindist"
|
||||||
|
<> completer (toolDlCompleter (fromMaybe GHC tool))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<*> (Just <$> toolVersionTagArgument Nothing tool)
|
||||||
|
)
|
||||||
|
<|> pure (Nothing, Nothing)
|
||||||
|
)
|
||||||
|
<*> many (argument str (metavar "MAKE_ARGS" <> help "Additional arguments to 'make', prefix with '-- ' (longopts)"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
--[ Effect interpreters ]--
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
type TestGHCEffects = [ DigestError
|
||||||
|
, ContentLengthError
|
||||||
|
, GPGError
|
||||||
|
, DownloadFailed
|
||||||
|
, NoDownload
|
||||||
|
, ArchiveResult
|
||||||
|
, TarDirDoesNotExist
|
||||||
|
, UnknownArchive
|
||||||
|
, TestFailed
|
||||||
|
, NextVerNotFound
|
||||||
|
, TagNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
]
|
||||||
|
|
||||||
|
runTestGHC :: AppState
|
||||||
|
-> Excepts TestGHCEffects (ResourceT (ReaderT AppState IO)) a
|
||||||
|
-> IO (VEither TestGHCEffects a)
|
||||||
|
runTestGHC appstate' =
|
||||||
|
flip runReaderT appstate'
|
||||||
|
. runResourceT
|
||||||
|
. runE
|
||||||
|
@TestGHCEffects
|
||||||
|
|
||||||
|
|
||||||
|
-------------------
|
||||||
|
--[ Entrypoints ]--
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
|
||||||
|
test :: TestCommand -> Settings -> IO AppState -> (ReaderT LeanAppState IO () -> IO ()) -> IO ExitCode
|
||||||
|
test testCommand settings getAppState' runLogger = case testCommand of
|
||||||
|
(TestGHC iopts) -> go iopts
|
||||||
|
where
|
||||||
|
go :: TestOptions -> IO ExitCode
|
||||||
|
go TestOptions{..} = do
|
||||||
|
s'@AppState{ dirs = Dirs{ .. } } <- liftIO getAppState'
|
||||||
|
(case testBindist of
|
||||||
|
Nothing -> runTestGHC s' $ do
|
||||||
|
(v, vi) <- liftE $ fromVersion testVer GHC
|
||||||
|
liftE $ testGHCVer (_tvVersion v) addMakeArgs
|
||||||
|
pure vi
|
||||||
|
Just uri -> do
|
||||||
|
runTestGHC s'{ settings = settings {noVerify = True}} $ do
|
||||||
|
(v, vi) <- liftE $ fromVersion testVer GHC
|
||||||
|
liftE $ testGHCBindist (DownloadInfo uri (Just $ RegexDir ".*/.*") "" Nothing) (_tvVersion v) addMakeArgs
|
||||||
|
pure vi
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight _ -> do
|
||||||
|
runLogger $ logInfo "GHC test successful"
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ do
|
||||||
|
logError $ T.pack $ prettyHFError e
|
||||||
|
logError $ "Also check the logs in " <> T.pack (fromGHCupPath logsDir)
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
|
||||||
@@ -4,13 +4,15 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
{-# LANGUAGE RankNTypes #-}
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
|
||||||
module GHCup.OptParse.ToolRequirements where
|
module GHCup.OptParse.ToolRequirements where
|
||||||
|
|
||||||
|
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -21,19 +23,53 @@ import Haskus.Utils.Variant.Excepts
|
|||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.IO as T
|
import qualified Data.Text.IO as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
import GHCup.Platform
|
import GHCup.Platform
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Prelude
|
||||||
import GHCup.Requirements
|
import GHCup.Requirements
|
||||||
import System.IO
|
import System.IO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Options ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
data ToolReqOpts = ToolReqOpts
|
||||||
|
{ tlrRaw :: Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Parsers ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
toolReqP :: Parser ToolReqOpts
|
||||||
|
toolReqP =
|
||||||
|
ToolReqOpts
|
||||||
|
<$> switch (short 'r' <> long "raw-format" <> help "machine-parsable format")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------
|
||||||
|
--[ Footer ]--
|
||||||
|
--------------
|
||||||
|
|
||||||
|
|
||||||
|
toolReqFooter :: String
|
||||||
|
toolReqFooter = [s|Discussion:
|
||||||
|
Print tool requirements on the current platform.
|
||||||
|
If you want to pass this to your package manage, use '--raw-format'.|]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
@@ -66,17 +102,20 @@ toolRequirements :: ( Monad m
|
|||||||
, MonadFail m
|
, MonadFail m
|
||||||
, Alternative m
|
, Alternative m
|
||||||
)
|
)
|
||||||
=> (ReaderT AppState m (VEither ToolRequirementsEffects ()) -> m (VEither ToolRequirementsEffects ()))
|
=> ToolReqOpts
|
||||||
|
-> (ReaderT AppState m (VEither ToolRequirementsEffects ()) -> m (VEither ToolRequirementsEffects ()))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
toolRequirements runAppState runLogger = runToolRequirements runAppState (do
|
toolRequirements ToolReqOpts{..} runAppState runLogger = runToolRequirements runAppState (do
|
||||||
GHCupInfo { .. } <- lift getGHCupInfo
|
GHCupInfo { .. } <- lift getGHCupInfo
|
||||||
platform' <- liftE getPlatform
|
platform' <- liftE getPlatform
|
||||||
req <- getCommonRequirements platform' _toolRequirements ?? NoToolRequirements
|
req <- getCommonRequirements platform' _toolRequirements ?? NoToolRequirements
|
||||||
liftIO $ T.hPutStr stdout (prettyRequirements req)
|
if tlrRaw
|
||||||
|
then liftIO $ T.hPutStr stdout (rawRequirements req)
|
||||||
|
else liftIO $ T.hPutStr stdout (prettyRequirements req)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight _ -> pure ExitSuccess
|
VRight _ -> pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 12
|
pure $ ExitFailure 12
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ module GHCup.OptParse.UnSet where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.Logger
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Prelude.String.QQ
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -31,7 +31,6 @@ import Options.Applicative hiding ( style )
|
|||||||
import Options.Applicative.Help.Pretty ( text )
|
import Options.Applicative.Help.Pretty ( text )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
@@ -189,7 +188,7 @@ unset unsetCommand runLeanAppState runLogger = case unsetCommand of
|
|||||||
runLogger $ logInfo "GHC successfully unset"
|
runLogger $ logInfo "GHC successfully unset"
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 14
|
pure $ ExitFailure 14
|
||||||
(UnsetCabal (UnsetOptions _)) -> do
|
(UnsetCabal (UnsetOptions _)) -> do
|
||||||
void $ runLeanAppState (VRight <$> unsetCabal)
|
void $ runLeanAppState (VRight <$> unsetCabal)
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ module GHCup.OptParse.Upgrade where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude.File
|
||||||
|
import GHCup.Prelude.Logger
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -27,7 +28,6 @@ import Haskus.Utils.Variant.Excepts
|
|||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
@@ -59,19 +59,21 @@ data UpgradeOpts = UpgradeInplace
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
upgradeOptsP :: Parser UpgradeOpts
|
upgradeOptsP :: Parser UpgradeOpts
|
||||||
upgradeOptsP =
|
upgradeOptsP =
|
||||||
flag'
|
flag'
|
||||||
UpgradeInplace
|
UpgradeInplace
|
||||||
(short 'i' <> long "inplace" <> help
|
(short 'i' <> long "inplace" <> help
|
||||||
"Upgrade ghcup in-place (wherever it's at)"
|
"Upgrade ghcup in-place"
|
||||||
)
|
)
|
||||||
<|> ( UpgradeAt
|
<|>
|
||||||
|
( UpgradeAt
|
||||||
<$> option
|
<$> option
|
||||||
str
|
str
|
||||||
(short 't' <> long "target" <> metavar "TARGET_DIR" <> help
|
(short 't' <> long "target" <> metavar "TARGET_DIR" <> help
|
||||||
"Absolute filepath to write ghcup into"
|
"Absolute filepath to write ghcup into"
|
||||||
|
<> completer (bashCompleter "file")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<|> pure UpgradeGHCupDir
|
<|> pure UpgradeGHCupDir
|
||||||
@@ -85,12 +87,14 @@ upgradeOptsP =
|
|||||||
|
|
||||||
|
|
||||||
type UpgradeEffects = '[ DigestError
|
type UpgradeEffects = '[ DigestError
|
||||||
|
, ContentLengthError
|
||||||
, GPGError
|
, GPGError
|
||||||
, NoDownload
|
, NoDownload
|
||||||
, NoUpdate
|
, NoUpdate
|
||||||
, FileDoesNotExistError
|
, FileDoesNotExistError
|
||||||
, CopyError
|
, CopyError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
|
, ToolShadowed
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -113,24 +117,25 @@ runUpgrade runAppState =
|
|||||||
|
|
||||||
|
|
||||||
upgrade :: ( Monad m
|
upgrade :: ( Monad m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> UpgradeOpts
|
=> UpgradeOpts
|
||||||
-> Bool
|
-> Bool
|
||||||
|
-> Bool
|
||||||
|
-> Dirs
|
||||||
-> (forall a. ReaderT AppState m (VEither UpgradeEffects a) -> m (VEither UpgradeEffects a))
|
-> (forall a. ReaderT AppState m (VEither UpgradeEffects a) -> m (VEither UpgradeEffects a))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
upgrade uOpts force' runAppState runLogger = do
|
upgrade uOpts force' fatal Dirs{..} runAppState runLogger = do
|
||||||
VRight Dirs{ .. } <- runAppState (VRight <$> getDirs)
|
|
||||||
target <- case uOpts of
|
target <- case uOpts of
|
||||||
UpgradeInplace -> Just <$> liftIO getExecutablePath
|
UpgradeInplace -> Just <$> liftIO getExecutablePath
|
||||||
(UpgradeAt p) -> pure $ Just p
|
(UpgradeAt p) -> pure $ Just p
|
||||||
UpgradeGHCupDir -> pure (Just (binDir </> "ghcup" <> exeExt))
|
UpgradeGHCupDir -> pure (Just (binDir </> "ghcup" <> exeExt))
|
||||||
|
|
||||||
runUpgrade runAppState (do
|
runUpgrade runAppState (do
|
||||||
v' <- liftE $ upgradeGHCup target force'
|
v' <- liftE $ upgradeGHCup target force' fatal
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
pure (v', dls)
|
pure (v', dls)
|
||||||
) >>= \case
|
) >>= \case
|
||||||
@@ -146,5 +151,5 @@ upgrade uOpts force' runAppState runLogger = do
|
|||||||
runLogger $ logWarn "No GHCup update available"
|
runLogger $ logWarn "No GHCup update available"
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 11
|
pure $ ExitFailure 11
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ import GHCup
|
|||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Prelude.Logger
|
||||||
|
import GHCup.Prelude.String.QQ
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -31,8 +32,8 @@ import Haskus.Utils.Variant.Excepts
|
|||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style )
|
||||||
import Options.Applicative.Help.Pretty ( text )
|
import Options.Applicative.Help.Pretty ( text )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
|
import System.Environment
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
@@ -74,14 +75,14 @@ data WhereisOptions = WhereisOptions {
|
|||||||
--[ Parsers ]--
|
--[ Parsers ]--
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
||||||
whereisP :: Parser WhereisCommand
|
whereisP :: Parser WhereisCommand
|
||||||
whereisP = subparser
|
whereisP = subparser
|
||||||
(commandGroup "Tools locations:" <>
|
(commandGroup "Tools locations:" <>
|
||||||
command
|
command
|
||||||
"ghc"
|
"ghc"
|
||||||
(WhereisTool GHC <$> info
|
(WhereisTool GHC <$> info
|
||||||
( optional (toolVersionArgument Nothing (Just GHC)) <**> helper )
|
( optional (toolVersionTagArgument Nothing (Just GHC)) <**> helper )
|
||||||
( progDesc "Get GHC location"
|
( progDesc "Get GHC location"
|
||||||
<> footerDoc (Just $ text whereisGHCFooter ))
|
<> footerDoc (Just $ text whereisGHCFooter ))
|
||||||
)
|
)
|
||||||
@@ -89,7 +90,7 @@ whereisP = subparser
|
|||||||
command
|
command
|
||||||
"cabal"
|
"cabal"
|
||||||
(WhereisTool Cabal <$> info
|
(WhereisTool Cabal <$> info
|
||||||
( optional (toolVersionArgument Nothing (Just Cabal)) <**> helper )
|
( optional (toolVersionTagArgument Nothing (Just Cabal)) <**> helper )
|
||||||
( progDesc "Get cabal location"
|
( progDesc "Get cabal location"
|
||||||
<> footerDoc (Just $ text whereisCabalFooter ))
|
<> footerDoc (Just $ text whereisCabalFooter ))
|
||||||
)
|
)
|
||||||
@@ -97,7 +98,7 @@ whereisP = subparser
|
|||||||
command
|
command
|
||||||
"hls"
|
"hls"
|
||||||
(WhereisTool HLS <$> info
|
(WhereisTool HLS <$> info
|
||||||
( optional (toolVersionArgument Nothing (Just HLS)) <**> helper )
|
( optional (toolVersionTagArgument Nothing (Just HLS)) <**> helper )
|
||||||
( progDesc "Get HLS location"
|
( progDesc "Get HLS location"
|
||||||
<> footerDoc (Just $ text whereisHLSFooter ))
|
<> footerDoc (Just $ text whereisHLSFooter ))
|
||||||
)
|
)
|
||||||
@@ -105,7 +106,7 @@ whereisP = subparser
|
|||||||
command
|
command
|
||||||
"stack"
|
"stack"
|
||||||
(WhereisTool Stack <$> info
|
(WhereisTool Stack <$> info
|
||||||
( optional (toolVersionArgument Nothing (Just Stack)) <**> helper )
|
( optional (toolVersionTagArgument Nothing (Just Stack)) <**> helper )
|
||||||
( progDesc "Get stack location"
|
( progDesc "Get stack location"
|
||||||
<> footerDoc (Just $ text whereisStackFooter ))
|
<> footerDoc (Just $ text whereisStackFooter ))
|
||||||
)
|
)
|
||||||
@@ -267,7 +268,14 @@ whereis :: ( Monad m
|
|||||||
whereis whereisCommand whereisOptions runAppState leanAppstate runLogger = do
|
whereis whereisCommand whereisOptions runAppState leanAppstate runLogger = do
|
||||||
Dirs{ .. } <- runReaderT getDirs leanAppstate
|
Dirs{ .. } <- runReaderT getDirs leanAppstate
|
||||||
case (whereisCommand, whereisOptions) of
|
case (whereisCommand, whereisOptions) of
|
||||||
(WhereisTool tool (Just (ToolVersion v)), WhereisOptions{..}) ->
|
(WhereisTool GHCup _, WhereisOptions{..}) -> do
|
||||||
|
loc <- liftIO (getExecutablePath >>= canonicalizePath )
|
||||||
|
if directory
|
||||||
|
then liftIO $ putStr $ takeDirectory loc
|
||||||
|
else liftIO $ putStr loc
|
||||||
|
pure ExitSuccess
|
||||||
|
|
||||||
|
(WhereisTool tool (Just (GHCVersion v)), WhereisOptions{..}) ->
|
||||||
runLeanWhereIs leanAppstate (do
|
runLeanWhereIs leanAppstate (do
|
||||||
loc <- liftE $ whereIsTool tool v
|
loc <- liftE $ whereIsTool tool v
|
||||||
if directory
|
if directory
|
||||||
@@ -279,7 +287,21 @@ whereis whereisCommand whereisOptions runAppState leanAppstate runLogger = do
|
|||||||
liftIO $ putStr r
|
liftIO $ putStr r
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
|
pure $ ExitFailure 30
|
||||||
|
(WhereisTool tool (Just (ToolVersion v)), WhereisOptions{..}) ->
|
||||||
|
runLeanWhereIs leanAppstate (do
|
||||||
|
loc <- liftE $ whereIsTool tool (mkTVer v)
|
||||||
|
if directory
|
||||||
|
then pure $ takeDirectory loc
|
||||||
|
else pure loc
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight r -> do
|
||||||
|
liftIO $ putStr r
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 30
|
pure $ ExitFailure 30
|
||||||
|
|
||||||
(WhereisTool tool whereVer, WhereisOptions{..}) -> do
|
(WhereisTool tool whereVer, WhereisOptions{..}) -> do
|
||||||
@@ -295,11 +317,11 @@ whereis whereisCommand whereisOptions runAppState leanAppstate runLogger = do
|
|||||||
liftIO $ putStr r
|
liftIO $ putStr r
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyHFError e
|
||||||
pure $ ExitFailure 30
|
pure $ ExitFailure 30
|
||||||
|
|
||||||
(WhereisBaseDir, _) -> do
|
(WhereisBaseDir, _) -> do
|
||||||
liftIO $ putStr baseDir
|
liftIO $ putStr $ fromGHCupPath baseDir
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
(WhereisBinDir, _) -> do
|
(WhereisBinDir, _) -> do
|
||||||
@@ -307,13 +329,13 @@ whereis whereisCommand whereisOptions runAppState leanAppstate runLogger = do
|
|||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
(WhereisCacheDir, _) -> do
|
(WhereisCacheDir, _) -> do
|
||||||
liftIO $ putStr cacheDir
|
liftIO $ putStr $ fromGHCupPath cacheDir
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
(WhereisLogsDir, _) -> do
|
(WhereisLogsDir, _) -> do
|
||||||
liftIO $ putStr logsDir
|
liftIO $ putStr $ fromGHCupPath logsDir
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
(WhereisConfDir, _) -> do
|
(WhereisConfDir, _) -> do
|
||||||
liftIO $ putStr confDir
|
liftIO $ putStr $ fromGHCupPath confDir
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|||||||
@@ -14,16 +14,19 @@ module Main where
|
|||||||
import BrickMain ( brickMain )
|
import BrickMain ( brickMain )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
import qualified GHCup.GHC as GHC
|
||||||
|
import qualified GHCup.HLS as HLS
|
||||||
import GHCup.OptParse
|
import GHCup.OptParse
|
||||||
|
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Platform
|
import GHCup.Platform
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
|
import GHCup.Types.Optics hiding ( toolRequirements )
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Prelude
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Prelude.Logger
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Prelude.String.QQ
|
||||||
import GHCup.Version
|
import GHCup.Version
|
||||||
|
|
||||||
import Cabal.Plan ( findPlanJson, SearchPlanJson(..) )
|
import Cabal.Plan ( findPlanJson, SearchPlanJson(..) )
|
||||||
@@ -39,6 +42,7 @@ import Data.Aeson.Encode.Pretty ( encodePretty )
|
|||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
import Data.Versions
|
||||||
import GHC.IO.Encoding
|
import GHC.IO.Encoding
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
@@ -55,10 +59,11 @@ import qualified Data.ByteString as B
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.IO as T
|
import qualified Data.Text.IO as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
|
import qualified GHCup.Types as Types
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
toSettings :: Options -> IO (Settings, KeyBindings)
|
toSettings :: Options -> IO (Settings, KeyBindings, UserSettings)
|
||||||
toSettings options = do
|
toSettings options = do
|
||||||
noColor <- isJust <$> lookupEnv "NO_COLOR"
|
noColor <- isJust <$> lookupEnv "NO_COLOR"
|
||||||
userConf <- runE @'[ JSONError ] ghcupConfigFile >>= \case
|
userConf <- runE @'[ JSONError ] ghcupConfigFile >>= \case
|
||||||
@@ -68,19 +73,23 @@ toSettings options = do
|
|||||||
pure defaultUserSettings
|
pure defaultUserSettings
|
||||||
_ -> do
|
_ -> do
|
||||||
die "Unexpected error!"
|
die "Unexpected error!"
|
||||||
pure $ mergeConf options userConf noColor
|
pure $ (\(s', k) -> (s', k, userConf)) $ mergeConf options userConf noColor
|
||||||
where
|
where
|
||||||
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
||||||
mergeConf Options{..} UserSettings{..} noColor =
|
mergeConf Options{..} UserSettings{..} noColor =
|
||||||
let cache = fromMaybe (fromMaybe False uCache) optCache
|
let cache = fromMaybe (fromMaybe (Types.cache defaultSettings) uCache) optCache
|
||||||
noVerify = fromMaybe (fromMaybe False uNoVerify) optNoVerify
|
metaCache = fromMaybe (fromMaybe (Types.metaCache defaultSettings) uMetaCache) optMetaCache
|
||||||
verbose = fromMaybe (fromMaybe False uVerbose) optVerbose
|
metaMode = fromMaybe (fromMaybe (Types.metaMode defaultSettings) uMetaMode) optMetaMode
|
||||||
keepDirs = fromMaybe (fromMaybe Errors uKeepDirs) optKeepDirs
|
noVerify = fromMaybe (fromMaybe (Types.noVerify defaultSettings) uNoVerify) optNoVerify
|
||||||
|
verbose = fromMaybe (fromMaybe (Types.verbose defaultSettings) uVerbose) optVerbose
|
||||||
|
keepDirs = fromMaybe (fromMaybe (Types.keepDirs defaultSettings) uKeepDirs) optKeepDirs
|
||||||
downloader = fromMaybe (fromMaybe defaultDownloader uDownloader) optsDownloader
|
downloader = fromMaybe (fromMaybe defaultDownloader uDownloader) optsDownloader
|
||||||
keyBindings = maybe defaultKeyBindings mergeKeys uKeyBindings
|
keyBindings = maybe defaultKeyBindings mergeKeys uKeyBindings
|
||||||
urlSource = maybe (fromMaybe GHCupURL uUrlSource) OwnSource optUrlSource
|
urlSource = maybe (fromMaybe (Types.urlSource defaultSettings) uUrlSource) (OwnSource . (:[]) . Right) optUrlSource
|
||||||
noNetwork = fromMaybe (fromMaybe False uNoNetwork) optNoNetwork
|
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
|
||||||
gpgSetting = fromMaybe (fromMaybe GPGNone uGPGSetting) optGpg
|
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
|
||||||
|
platformOverride = optPlatform <|> (uPlatformOverride <|> Types.platformOverride defaultSettings)
|
||||||
|
mirrors = fromMaybe (Types.mirrors defaultSettings) uMirrors
|
||||||
in (Settings {..}, keyBindings)
|
in (Settings {..}, keyBindings)
|
||||||
#if defined(INTERNAL_DOWNLOADER)
|
#if defined(INTERNAL_DOWNLOADER)
|
||||||
defaultDownloader = Internal
|
defaultDownloader = Internal
|
||||||
@@ -136,7 +145,10 @@ main = do
|
|||||||
<> hidden
|
<> hidden
|
||||||
)
|
)
|
||||||
let listCommands = infoOption
|
let listCommands = infoOption
|
||||||
"install set rm install-cabal list upgrade compile debug-info tool-requirements changelog"
|
("install set rm install-cabal list"
|
||||||
|
<> " upgrade"
|
||||||
|
<> " compile debug-info tool-requirements changelog"
|
||||||
|
)
|
||||||
( long "list-commands"
|
( long "list-commands"
|
||||||
<> help "List available commands for shell completion"
|
<> help "List available commands for shell completion"
|
||||||
<> internal
|
<> internal
|
||||||
@@ -148,11 +160,10 @@ main = do
|
|||||||
versions. It maintains a self-contained ~/.ghcup directory.
|
versions. It maintains a self-contained ~/.ghcup directory.
|
||||||
|
|
||||||
ENV variables:
|
ENV variables:
|
||||||
* TMPDIR: where ghcup does the work (unpacking, building, ...)
|
|
||||||
* GHCUP_INSTALL_BASE_PREFIX: the base of ghcup (default: $HOME)
|
* GHCUP_INSTALL_BASE_PREFIX: the base of ghcup (default: $HOME)
|
||||||
* GHCUP_USE_XDG_DIRS: set to anything to use XDG style directories
|
* GHCUP_USE_XDG_DIRS: set to anything to use XDG style directories
|
||||||
|
|
||||||
Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
Report bugs at <https://github.com/haskell/ghcup-hs/issues>|]
|
||||||
|
|
||||||
customExecParser
|
customExecParser
|
||||||
(prefs showHelpOnError)
|
(prefs showHelpOnError)
|
||||||
@@ -165,7 +176,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
-- create ~/.ghcup dir
|
-- create ~/.ghcup dir
|
||||||
ensureDirectories dirs
|
ensureDirectories dirs
|
||||||
|
|
||||||
(settings, keybindings) <- toSettings opt
|
(settings, keybindings, userConf) <- toSettings opt
|
||||||
|
|
||||||
-- logger interpreter
|
-- logger interpreter
|
||||||
logfile <- runReaderT initGHCupFileLogging dirs
|
logfile <- runReaderT initGHCupFileLogging dirs
|
||||||
@@ -189,44 +200,66 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
||||||
appState = do
|
let appState = do
|
||||||
pfreq <- (
|
pfreq <- case platformOverride settings of
|
||||||
runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest
|
Just pfreq' -> return pfreq'
|
||||||
) >>= \case
|
Nothing -> (runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest) >>= \case
|
||||||
VRight r -> pure r
|
VRight r -> pure r
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger
|
runLogger
|
||||||
(logError $ T.pack $ prettyShow e)
|
(logError $ T.pack $ prettyHFError e)
|
||||||
exitWith (ExitFailure 2)
|
exitWith (ExitFailure 2)
|
||||||
|
|
||||||
ghcupInfo <-
|
ghcupInfo <-
|
||||||
( flip runReaderT leanAppstate
|
( flip runReaderT leanAppstate
|
||||||
. runE @'[DigestError, GPGError, JSONError , DownloadFailed, FileDoesNotExistError]
|
. runE @'[DigestError, ContentLengthError, GPGError, JSONError , DownloadFailed, FileDoesNotExistError]
|
||||||
$ liftE getDownloadsF
|
$ liftE getDownloadsF
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight r -> pure r
|
VRight r -> pure r
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger
|
runLogger
|
||||||
(logError $ T.pack $ prettyShow e)
|
(logError $ T.pack $ prettyHFError e)
|
||||||
exitWith (ExitFailure 2)
|
exitWith (ExitFailure 2)
|
||||||
let s' = AppState settings dirs keybindings ghcupInfo pfreq loggerConfig
|
let s' = AppState settings dirs keybindings ghcupInfo pfreq loggerConfig
|
||||||
|
|
||||||
race_ (liftIO $ runReaderT cleanupTrash s')
|
race_ (liftIO $ runReaderT cleanupTrash s')
|
||||||
(threadDelay 5000000 >> runLogger (logWarn $ "Killing cleanup thread (exceeded 5s timeout)... please remove leftover files in " <> T.pack recycleDir <> " manually"))
|
(threadDelay 5000000 >> runLogger (logWarn $ "Killing cleanup thread (exceeded 5s timeout)... please remove leftover files in " <> T.pack (fromGHCupPath recycleDir) <> " manually"))
|
||||||
|
|
||||||
case optCommand of
|
case optCommand of
|
||||||
Nuke -> pure ()
|
Nuke -> pure ()
|
||||||
Whereis _ _ -> pure ()
|
Whereis _ _ -> pure ()
|
||||||
DInfo -> pure ()
|
DInfo -> pure ()
|
||||||
ToolRequirements -> pure ()
|
ToolRequirements _ -> pure ()
|
||||||
ChangeLog _ -> pure ()
|
ChangeLog _ -> pure ()
|
||||||
UnSet _ -> pure ()
|
UnSet _ -> pure ()
|
||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
Interactive -> pure ()
|
Interactive -> pure ()
|
||||||
#endif
|
#endif
|
||||||
_ -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
-- check for new tools
|
||||||
Nothing -> runReaderT checkForUpdates s'
|
_
|
||||||
|
| Just False <- optVerbose -> pure ()
|
||||||
|
| otherwise -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
||||||
|
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
||||||
|
newTools <- lift checkForUpdates
|
||||||
|
forM_ newTools $ \newTool@(t, l) -> do
|
||||||
|
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/283
|
||||||
|
alreadyInstalling' <- alreadyInstalling optCommand newTool
|
||||||
|
when (not alreadyInstalling') $
|
||||||
|
case t of
|
||||||
|
GHCup -> runLogger $
|
||||||
|
logWarn ("New GHCup version available: "
|
||||||
|
<> prettyVer l
|
||||||
|
<> ". To upgrade, run 'ghcup upgrade'")
|
||||||
|
_ -> runLogger $
|
||||||
|
logWarn ("New "
|
||||||
|
<> T.pack (prettyShow t)
|
||||||
|
<> " version available. "
|
||||||
|
<> "If you want to install this latest version, run 'ghcup install "
|
||||||
|
<> T.pack (prettyShow t)
|
||||||
|
<> " "
|
||||||
|
<> prettyVer l
|
||||||
|
<> "'")
|
||||||
Just _ -> pure ()
|
Just _ -> pure ()
|
||||||
|
|
||||||
-- TODO: always run for windows
|
-- TODO: always run for windows
|
||||||
@@ -234,7 +267,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
VRight _ -> pure ()
|
VRight _ -> pure ()
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger
|
runLogger
|
||||||
(logError $ T.pack $ prettyShow e)
|
(logError $ T.pack $ prettyHFError e)
|
||||||
exitWith (ExitFailure 30)
|
exitWith (ExitFailure 30)
|
||||||
pure s'
|
pure s'
|
||||||
|
|
||||||
@@ -249,7 +282,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
runAppState action' = do
|
runAppState action' = do
|
||||||
s' <- liftIO appState
|
s' <- liftIO appState
|
||||||
runReaderT action' s'
|
runReaderT action' s'
|
||||||
|
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
-- Run command --
|
-- Run command --
|
||||||
@@ -261,23 +294,26 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
s' <- appState
|
s' <- appState
|
||||||
liftIO $ brickMain s' >> pure ExitSuccess
|
liftIO $ brickMain s' >> pure ExitSuccess
|
||||||
#endif
|
#endif
|
||||||
Install installCommand -> install installCommand settings appState runLogger
|
Install installCommand -> install installCommand settings appState runLogger
|
||||||
InstallCabalLegacy iopts -> install (Left (InstallCabal iopts)) settings appState runLogger
|
InstallCabalLegacy iopts -> install (Left (InstallCabal iopts)) settings appState runLogger
|
||||||
Set setCommand -> set setCommand runAppState runLeanAppState runLogger
|
Test testCommand -> test testCommand settings appState runLogger
|
||||||
UnSet unsetCommand -> unset unsetCommand runLeanAppState runLogger
|
Set setCommand -> set setCommand runAppState runLeanAppState runLogger
|
||||||
List lo -> list lo no_color runAppState
|
UnSet unsetCommand -> unset unsetCommand runLeanAppState runLogger
|
||||||
Rm rmCommand -> rm rmCommand runAppState runLogger
|
List lo -> list lo no_color runAppState
|
||||||
DInfo -> dinfo runAppState runLogger
|
Rm rmCommand -> rm rmCommand runAppState runLogger
|
||||||
Compile compileCommand -> compile compileCommand settings runAppState runLogger
|
DInfo -> dinfo runAppState runLogger
|
||||||
Config configCommand -> config configCommand settings keybindings runLogger
|
Compile compileCommand -> compile compileCommand settings dirs runAppState runLogger
|
||||||
|
Config configCommand -> config configCommand settings userConf keybindings runLogger
|
||||||
Whereis whereisOptions
|
Whereis whereisOptions
|
||||||
whereisCommand -> whereis whereisCommand whereisOptions runAppState leanAppstate runLogger
|
whereisCommand -> whereis whereisCommand whereisOptions runAppState leanAppstate runLogger
|
||||||
Upgrade uOpts force' -> upgrade uOpts force' runAppState runLogger
|
Upgrade uOpts force' fatal -> upgrade uOpts force' fatal dirs runAppState runLogger
|
||||||
ToolRequirements -> toolRequirements runAppState runLogger
|
ToolRequirements topts -> toolRequirements topts runAppState runLogger
|
||||||
ChangeLog changelogOpts -> changelog changelogOpts runAppState runLogger
|
ChangeLog changelogOpts -> changelog changelogOpts runAppState runLogger
|
||||||
Nuke -> nuke appState runLogger
|
Nuke -> nuke appState runLogger
|
||||||
Prefetch pfCom -> prefetch pfCom runAppState runLogger
|
Prefetch pfCom -> prefetch pfCom runAppState runLogger
|
||||||
GC gcOpts -> gc gcOpts runAppState runLogger
|
GC gcOpts -> gc gcOpts runAppState runLogger
|
||||||
|
Run runCommand -> run runCommand appState leanAppstate runLogger
|
||||||
|
PrintAppErrors -> putStrLn allHFError >> pure ExitSuccess
|
||||||
|
|
||||||
case res of
|
case res of
|
||||||
ExitSuccess -> pure ()
|
ExitSuccess -> pure ()
|
||||||
@@ -285,4 +321,58 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
|
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
|
where
|
||||||
|
alreadyInstalling :: ( HasLog env
|
||||||
|
, MonadFail m
|
||||||
|
, MonadReader env m
|
||||||
|
, HasGHCupInfo env
|
||||||
|
, HasDirs env
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Command
|
||||||
|
-> (Tool, Version)
|
||||||
|
-> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
] m Bool
|
||||||
|
alreadyInstalling (Install (Right InstallOptions{..})) (GHC, ver) = cmp' GHC instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallGHC InstallOptions{..}))) (GHC, ver) = cmp' GHC instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallCabal InstallOptions{..}))) (Cabal, ver) = cmp' Cabal instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallHLS InstallOptions{..}))) (HLS, ver) = cmp' HLS instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallStack InstallOptions{..}))) (Stack, ver) = cmp' Stack instVer ver
|
||||||
|
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ ovewrwiteVer = Just over }))
|
||||||
|
(GHC, ver) = cmp' GHC (Just $ GHCVersion (mkTVer over)) ver
|
||||||
|
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ targetGhc = GHC.SourceDist tver }))
|
||||||
|
(GHC, ver) = cmp' GHC (Just $ ToolVersion tver) ver
|
||||||
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ ovewrwiteVer = Right over }))
|
||||||
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion over) ver
|
||||||
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ targetHLS = HLS.SourceDist tver }))
|
||||||
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion tver) ver
|
||||||
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ targetHLS = HLS.HackageDist tver }))
|
||||||
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion tver) ver
|
||||||
|
alreadyInstalling (Upgrade {}) (GHCup, _) = pure True
|
||||||
|
alreadyInstalling _ _ = pure False
|
||||||
|
|
||||||
|
cmp' :: ( HasLog env
|
||||||
|
, MonadFail m
|
||||||
|
, MonadReader env m
|
||||||
|
, HasGHCupInfo env
|
||||||
|
, HasDirs env
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Tool
|
||||||
|
-> Maybe ToolVersion
|
||||||
|
-> Version
|
||||||
|
-> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
] m Bool
|
||||||
|
cmp' tool instVer ver = do
|
||||||
|
(v, _) <- liftE $ fromVersion instVer tool
|
||||||
|
pure (v == mkTVer ver)
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ optional-packages: ./vendored/*/*.cabal
|
|||||||
optimization: 2
|
optimization: 2
|
||||||
|
|
||||||
package ghcup
|
package ghcup
|
||||||
tests: True
|
|
||||||
flags: +tui
|
flags: +tui
|
||||||
|
|
||||||
constraints: http-io-streams -brotli
|
constraints: http-io-streams -brotli,
|
||||||
|
any.aeson >= 2.0.1.0
|
||||||
|
|
||||||
package libarchive
|
package libarchive
|
||||||
flags: -system-libarchive
|
flags: -system-libarchive
|
||||||
@@ -19,6 +19,11 @@ package aeson-pretty
|
|||||||
package cabal-plan
|
package cabal-plan
|
||||||
flags: -exe
|
flags: -exe
|
||||||
|
|
||||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
package aeson
|
||||||
|
flags: +ordered-keymap
|
||||||
|
|
||||||
|
package streamly
|
||||||
|
flags: +use-unliftio
|
||||||
|
|
||||||
|
|
||||||
with-compiler: ghc-8.10.7
|
with-compiler: ghc-8.10.7
|
||||||
|
|||||||
@@ -1,49 +1,55 @@
|
|||||||
active-repositories: hackage.haskell.org:merge
|
active-repositories: hackage.haskell.org:merge
|
||||||
constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
constraints: any.Cabal ==3.6.3.0,
|
||||||
Cabal -bundled-binary-generic,
|
Cabal -bundled-binary-generic,
|
||||||
|
any.Cabal-syntax ==3.8.1.0,
|
||||||
any.HUnit ==1.6.2.0,
|
any.HUnit ==1.6.2.0,
|
||||||
any.HsOpenSSL ==0.11.7.2,
|
any.HsOpenSSL ==0.11.7.4,
|
||||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||||
any.HsYAML ==0.2.1.0,
|
any.OneTuple ==0.3.1,
|
||||||
HsYAML -exe,
|
|
||||||
any.HsYAML-aeson ==0.2.0.0,
|
|
||||||
any.QuickCheck ==2.14.2,
|
any.QuickCheck ==2.14.2,
|
||||||
QuickCheck -old-random +templatehaskell,
|
QuickCheck -old-random +templatehaskell,
|
||||||
any.StateVar ==1.2.2,
|
any.StateVar ==1.2.2,
|
||||||
any.aeson ==1.5.6.0,
|
any.abstract-deque ==0.3,
|
||||||
aeson -bytestring-builder -cffi -developer -fast,
|
abstract-deque -usecas,
|
||||||
any.aeson-pretty ==0.8.8,
|
any.aeson ==2.1.1.0,
|
||||||
|
aeson -cffi +ordered-keymap,
|
||||||
|
any.aeson-pretty ==0.8.9,
|
||||||
aeson-pretty +lib-only,
|
aeson-pretty +lib-only,
|
||||||
any.alex ==3.2.6,
|
any.alex ==3.2.7.1,
|
||||||
alex +small_base,
|
any.ansi-terminal ==0.11.4,
|
||||||
any.ansi-terminal ==0.11,
|
ansi-terminal -example +win32-2-13-1,
|
||||||
ansi-terminal -example,
|
|
||||||
any.ansi-wl-pprint ==0.6.9,
|
any.ansi-wl-pprint ==0.6.9,
|
||||||
ansi-wl-pprint -example,
|
ansi-wl-pprint -example,
|
||||||
any.array ==0.5.4.0,
|
any.array ==0.5.4.0,
|
||||||
any.assoc ==1.0.2,
|
any.assoc ==1.0.2,
|
||||||
any.async ==2.2.3,
|
any.async ==2.2.4,
|
||||||
async -bench,
|
async -bench,
|
||||||
any.attoparsec ==0.13.2.5,
|
any.atomic-primops ==0.8.4,
|
||||||
|
atomic-primops -debug,
|
||||||
|
any.attoparsec ==0.14.4,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.base ==4.14.3.0,
|
any.base ==4.14.3.0,
|
||||||
any.base-compat ==0.12.0,
|
any.base-compat ==0.12.2,
|
||||||
any.base-compat-batteries ==0.12.0,
|
any.base-compat-batteries ==0.12.2,
|
||||||
any.base-orphans ==0.8.5,
|
any.base-orphans ==0.8.7,
|
||||||
any.base16-bytestring ==1.0.1.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base64-bytestring ==1.1.0.0,
|
any.base64-bytestring ==1.2.1.0,
|
||||||
any.bifunctors ==5.5.11,
|
any.bifunctors ==5.5.14,
|
||||||
bifunctors +semigroups +tagged,
|
bifunctors +semigroups +tagged,
|
||||||
|
any.bimap ==0.5.0,
|
||||||
any.binary ==0.8.8.0,
|
any.binary ==0.8.8.0,
|
||||||
any.blaze-builder ==0.4.2.1,
|
any.binary-instances ==1.0.3,
|
||||||
any.brick ==0.64.1,
|
any.binary-orphans ==1.0.3,
|
||||||
|
any.blaze-builder ==0.4.2.2,
|
||||||
|
any.brick ==1.5,
|
||||||
brick -demos,
|
brick -demos,
|
||||||
any.bytestring ==0.10.12.0,
|
any.bytestring ==0.10.12.0,
|
||||||
any.bz2 ==1.0.1.0,
|
any.bz2 ==1.0.1.0,
|
||||||
bz2 -cross +with-bzlib,
|
bz2 -cross +with-bzlib,
|
||||||
any.c2hs ==0.28.8,
|
any.c2hs ==0.28.8,
|
||||||
c2hs +base3 -regression,
|
c2hs +base3 -regression,
|
||||||
any.cabal-plan ==0.7.2.0,
|
any.cabal-install-parsers ==0.5,
|
||||||
|
any.cabal-plan ==0.7.2.3,
|
||||||
cabal-plan -_ -exe -license-report,
|
cabal-plan -_ -exe -license-report,
|
||||||
any.call-stack ==0.4.0,
|
any.call-stack ==0.4.0,
|
||||||
any.case-insensitive ==1.2.1.0,
|
any.case-insensitive ==1.2.1.0,
|
||||||
@@ -51,24 +57,23 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.chs-cabal ==0.1.1.1,
|
any.chs-cabal ==0.1.1.1,
|
||||||
any.chs-deps ==0.1.0.0,
|
any.chs-deps ==0.1.0.0,
|
||||||
chs-deps -cross,
|
chs-deps -cross,
|
||||||
any.clock ==0.8.2,
|
|
||||||
clock -llvm,
|
|
||||||
any.colour ==2.3.6,
|
any.colour ==2.3.6,
|
||||||
any.comonad ==5.0.8,
|
any.comonad ==5.0.8,
|
||||||
comonad +containers +distributive +indexed-traversable,
|
comonad +containers +distributive +indexed-traversable,
|
||||||
any.composition-prelude ==3.0.0.2,
|
any.composition-prelude ==3.0.0.2,
|
||||||
composition-prelude -development,
|
composition-prelude -development,
|
||||||
any.config-ini ==0.2.4.0,
|
any.config-ini ==0.2.5.0,
|
||||||
config-ini -enable-doctests,
|
config-ini -enable-doctests,
|
||||||
any.containers ==0.6.5.1,
|
any.containers ==0.6.5.1,
|
||||||
any.contravariant ==1.5.5,
|
any.contravariant ==1.5.5,
|
||||||
contravariant +semigroups +statevar +tagged,
|
contravariant +semigroups +statevar +tagged,
|
||||||
any.cpphs ==1.20.9.1,
|
any.cpphs ==1.20.9.1,
|
||||||
cpphs -old-locale,
|
cpphs -old-locale,
|
||||||
any.cryptohash-sha1 ==0.11.100.1,
|
any.cryptohash-sha1 ==0.11.101.0,
|
||||||
any.cryptohash-sha256 ==0.11.102.0,
|
any.cryptohash-sha256 ==0.11.102.1,
|
||||||
cryptohash-sha256 -exe +use-cbits,
|
cryptohash-sha256 -exe +use-cbits,
|
||||||
any.data-clist ==0.1.2.3,
|
any.data-array-byte ==0.1.0.1,
|
||||||
|
any.data-clist ==0.2,
|
||||||
any.data-fix ==0.3.2,
|
any.data-fix ==0.3.2,
|
||||||
any.deepseq ==1.4.4.0,
|
any.deepseq ==1.4.4.0,
|
||||||
any.directory ==1.3.6.0,
|
any.directory ==1.3.6.0,
|
||||||
@@ -79,106 +84,128 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
dlist -werror,
|
dlist -werror,
|
||||||
any.exceptions ==0.10.4,
|
any.exceptions ==0.10.4,
|
||||||
any.filepath ==1.4.2.1,
|
any.filepath ==1.4.2.1,
|
||||||
any.free ==5.1.7,
|
any.free ==5.1.10,
|
||||||
any.generic-arbitrary ==0.1.0,
|
any.fusion-plugin-types ==0.1.0,
|
||||||
|
any.generic-arbitrary ==0.2.2,
|
||||||
|
any.generically ==0.1,
|
||||||
any.ghc-boot-th ==8.10.7,
|
any.ghc-boot-th ==8.10.7,
|
||||||
any.ghc-byteorder ==4.11.0.0.10,
|
any.ghc-byteorder ==4.11.0.0.10,
|
||||||
any.ghc-prim ==0.6.1,
|
any.ghc-prim ==0.6.1,
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.3.3.0,
|
any.hashable ==1.4.2.0,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable +integer-gmp -random-initial-seed,
|
||||||
|
any.haskell-lexer ==1.1.1,
|
||||||
any.haskus-utils-data ==1.4,
|
any.haskus-utils-data ==1.4,
|
||||||
any.haskus-utils-types ==1.5.1,
|
any.haskus-utils-types ==1.5.1,
|
||||||
any.haskus-utils-variant ==3.1,
|
any.haskus-utils-variant ==3.2.1,
|
||||||
any.hsc2hs ==0.68.7,
|
any.heaps ==0.4,
|
||||||
|
any.hsc2hs ==0.68.8,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.7.10,
|
any.hspec ==2.10.8,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.10.8,
|
||||||
any.hspec-discover ==2.7.10,
|
any.hspec-discover ==2.10.8,
|
||||||
any.hspec-expectations ==0.8.2,
|
any.hspec-expectations ==0.8.2,
|
||||||
any.hspec-golden-aeson ==0.9.0.0,
|
any.hspec-golden-aeson ==0.9.0.0,
|
||||||
any.http-io-streams ==0.1.6.0,
|
any.http-io-streams ==0.1.6.1,
|
||||||
http-io-streams -brotli +fast-xor,
|
http-io-streams -brotli +fast-xor,
|
||||||
any.indexed-profunctors ==0.1.1,
|
any.indexed-profunctors ==0.1.1,
|
||||||
any.indexed-traversable ==0.1.1,
|
any.indexed-traversable ==0.1.2,
|
||||||
any.indexed-traversable-instances ==0.1,
|
any.indexed-traversable-instances ==0.1.1.1,
|
||||||
any.integer-gmp ==1.0.3.0,
|
any.integer-gmp ==1.0.3.0,
|
||||||
any.integer-logarithms ==1.0.3.1,
|
any.integer-logarithms ==1.0.3.1,
|
||||||
integer-logarithms -check-bounds +integer-gmp,
|
integer-logarithms -check-bounds +integer-gmp,
|
||||||
any.io-streams ==1.5.2.1,
|
any.io-streams ==1.5.2.2,
|
||||||
io-streams +network -nointeractivetests +zlib,
|
io-streams +network -nointeractivetests +zlib,
|
||||||
any.language-c ==0.9.0.1,
|
any.language-c ==0.9.2,
|
||||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||||
any.libarchive ==3.0.3.0,
|
any.libarchive ==3.0.3.2,
|
||||||
libarchive -cross -low-memory -system-libarchive,
|
libarchive -cross -low-memory +no-exe -system-libarchive,
|
||||||
any.lzma-static ==5.2.5.4,
|
any.libyaml-streamly ==0.2.1,
|
||||||
any.megaparsec ==9.0.1,
|
libyaml-streamly -no-unicode -system-libyaml,
|
||||||
|
any.lockfree-queue ==0.2.4,
|
||||||
|
any.lukko ==0.1.1.3,
|
||||||
|
lukko +ofd-locking,
|
||||||
|
any.lzma-static ==5.2.5.5,
|
||||||
|
any.megaparsec ==9.2.1,
|
||||||
megaparsec -dev,
|
megaparsec -dev,
|
||||||
any.microlens ==0.4.12.0,
|
any.microlens ==0.4.13.1,
|
||||||
any.microlens-mtl ==0.2.0.1,
|
any.microlens-mtl ==0.2.0.3,
|
||||||
any.microlens-th ==0.4.3.10,
|
any.microlens-th ==0.4.3.11,
|
||||||
any.mtl ==2.2.2,
|
any.mtl ==2.2.2,
|
||||||
any.network ==3.1.2.2,
|
any.network ==3.1.2.7,
|
||||||
network -devel,
|
network -devel,
|
||||||
any.network-uri ==2.6.4.1,
|
any.network-uri ==2.6.4.2,
|
||||||
any.openssl-streams ==1.2.3.0,
|
any.openssl-streams ==1.2.3.0,
|
||||||
any.optics ==0.4,
|
any.optics ==0.4.2,
|
||||||
any.optics-core ==0.4,
|
any.optics-core ==0.4.1,
|
||||||
optics-core -explicit-generic-labels,
|
optics-core -explicit-generic-labels,
|
||||||
any.optics-extra ==0.4,
|
any.optics-extra ==0.4.2.1,
|
||||||
any.optics-th ==0.4,
|
any.optics-th ==0.4.1,
|
||||||
any.optparse-applicative ==0.16.1.0,
|
any.optparse-applicative ==0.17.0.0,
|
||||||
optparse-applicative +process,
|
optparse-applicative +process,
|
||||||
any.os-release ==1.0.2,
|
any.os-release ==1.0.2.1,
|
||||||
os-release -devel,
|
os-release -devel,
|
||||||
any.parallel ==3.2.2.0,
|
any.parallel ==3.2.2.0,
|
||||||
any.parsec ==3.1.14.0,
|
any.parsec ==3.1.16.1,
|
||||||
any.parser-combinators ==1.3.0,
|
any.parser-combinators ==1.3.0,
|
||||||
parser-combinators -dev,
|
parser-combinators -dev,
|
||||||
any.polyparse ==1.13,
|
any.polyparse ==1.13,
|
||||||
any.pretty ==1.1.3.6,
|
any.pretty ==1.1.3.6,
|
||||||
any.pretty-terminal ==0.1.0.0,
|
any.pretty-terminal ==0.1.0.0,
|
||||||
any.primitive ==0.7.2.0,
|
any.primitive ==0.7.4.0,
|
||||||
any.process ==1.6.13.2,
|
any.process ==1.6.13.2,
|
||||||
any.profunctors ==5.6.2,
|
any.profunctors ==5.6.2,
|
||||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||||
any.quickcheck-io ==0.2.0,
|
any.quickcheck-io ==0.2.0,
|
||||||
any.random ==1.2.1,
|
any.random ==1.2.1.1,
|
||||||
any.recursion-schemes ==5.2.2.1,
|
any.recursion-schemes ==5.2.2.3,
|
||||||
recursion-schemes +template-haskell,
|
recursion-schemes +template-haskell,
|
||||||
any.regex-base ==0.94.0.1,
|
any.regex-base ==0.94.0.2,
|
||||||
any.regex-posix ==0.96.0.1,
|
any.regex-posix ==0.96.0.1,
|
||||||
regex-posix -_regex-posix-clib,
|
regex-posix -_regex-posix-clib,
|
||||||
any.resourcet ==1.2.4.3,
|
any.resourcet ==1.2.6,
|
||||||
|
any.retry ==0.8.1.2,
|
||||||
|
retry -lib-werror,
|
||||||
any.rts ==1.0.1,
|
any.rts ==1.0.1,
|
||||||
any.safe ==0.3.19,
|
any.safe ==0.3.19,
|
||||||
any.safe-exceptions ==0.1.7.2,
|
any.safe-exceptions ==0.1.7.3,
|
||||||
any.scientific ==0.3.7.0,
|
any.scientific ==0.3.7.0,
|
||||||
scientific -bytestring-builder -integer-simple,
|
scientific -bytestring-builder -integer-simple,
|
||||||
any.semigroupoids ==5.3.5,
|
any.semialign ==1.2.0.1,
|
||||||
|
semialign +semigroupoids,
|
||||||
|
any.semigroupoids ==5.3.7,
|
||||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||||
any.setenv ==0.1.1.3,
|
any.setenv ==0.1.1.3,
|
||||||
any.split ==0.2.3.4,
|
any.split ==0.2.3.5,
|
||||||
any.splitmix ==0.1.0.3,
|
any.splitmix ==0.1.0.4,
|
||||||
splitmix -optimised-mixer,
|
splitmix -optimised-mixer,
|
||||||
any.stm ==2.5.0.1,
|
any.stm ==2.5.0.1,
|
||||||
|
any.streamly ==0.8.3,
|
||||||
|
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -streamly-core -use-c-malloc +use-unliftio,
|
||||||
any.strict ==0.4.0.1,
|
any.strict ==0.4.0.1,
|
||||||
strict +assoc,
|
strict +assoc,
|
||||||
any.strict-base ==0.4.0.0,
|
any.strict-base ==0.4.0.0,
|
||||||
any.tagged ==0.8.6.1,
|
any.tagged ==0.8.6.1,
|
||||||
tagged +deepseq +transformers,
|
tagged +deepseq +transformers,
|
||||||
|
any.tagsoup ==0.14.8,
|
||||||
|
any.tar ==0.5.1.1,
|
||||||
|
tar -old-bytestring -old-time,
|
||||||
any.template-haskell ==2.16.0.0,
|
any.template-haskell ==2.16.0.0,
|
||||||
any.temporary ==1.3,
|
any.temporary ==1.3,
|
||||||
any.terminal-progress-bar ==0.4.1,
|
any.terminal-progress-bar ==0.4.1,
|
||||||
any.terminal-size ==0.3.2.1,
|
any.terminal-size ==0.3.3,
|
||||||
any.terminfo ==0.4.1.4,
|
any.terminfo ==0.4.1.4,
|
||||||
any.text ==1.2.4.1,
|
any.text ==2.0.1,
|
||||||
any.text-zipper ==0.11,
|
text -developer +simdutf,
|
||||||
|
any.text-binary ==0.2.1.1,
|
||||||
|
any.text-short ==0.1.5,
|
||||||
|
text-short -asserts,
|
||||||
|
any.text-zipper ==0.12,
|
||||||
any.tf-random ==0.5,
|
any.tf-random ==0.5,
|
||||||
any.th-abstraction ==0.4.3.0,
|
any.th-abstraction ==0.4.5.0,
|
||||||
any.th-compat ==0.1.3,
|
any.th-compat ==0.1.4,
|
||||||
any.th-lift ==0.8.2,
|
any.th-lift ==0.8.2,
|
||||||
any.th-lift-instances ==0.1.18,
|
any.th-lift-instances ==0.1.20,
|
||||||
any.these ==1.1.1.1,
|
any.these ==1.1.1.1,
|
||||||
these +assoc,
|
these +assoc,
|
||||||
any.time ==1.9.3,
|
any.time ==1.9.3,
|
||||||
@@ -187,14 +214,16 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.transformers ==0.5.6.2,
|
any.transformers ==0.5.6.2,
|
||||||
any.transformers-base ==0.4.6,
|
any.transformers-base ==0.4.6,
|
||||||
transformers-base +orphaninstances,
|
transformers-base +orphaninstances,
|
||||||
any.transformers-compat ==0.7,
|
any.transformers-compat ==0.7.2,
|
||||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||||
|
any.unicode-data ==0.3.1,
|
||||||
|
unicode-data -ucd2haskell,
|
||||||
any.unix ==2.7.2.2,
|
any.unix ==2.7.2.2,
|
||||||
any.unix-bytestring ==0.3.7.3,
|
any.unix-bytestring ==0.3.7.8,
|
||||||
any.unix-compat ==0.5.3,
|
any.unix-compat ==0.6,
|
||||||
unix-compat -old-time,
|
unix-compat -old-time,
|
||||||
any.unliftio-core ==0.2.0.1,
|
any.unliftio-core ==0.2.0.1,
|
||||||
any.unordered-containers ==0.2.14.0,
|
any.unordered-containers ==0.2.19.1,
|
||||||
unordered-containers -debug,
|
unordered-containers -debug,
|
||||||
any.uri-bytestring ==0.3.3.1,
|
any.uri-bytestring ==0.3.3.1,
|
||||||
uri-bytestring -lib-werror,
|
uri-bytestring -lib-werror,
|
||||||
@@ -202,12 +231,16 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.uuid-types ==1.0.5,
|
any.uuid-types ==1.0.5,
|
||||||
any.vector ==0.12.3.1,
|
any.vector ==0.12.3.1,
|
||||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||||
any.versions ==5.0.0,
|
any.vector-binary-instances ==0.2.5.2,
|
||||||
any.vty ==5.33,
|
any.versions ==5.0.4,
|
||||||
|
any.vty ==5.37,
|
||||||
|
any.witherable ==0.4.2,
|
||||||
any.word-wrap ==0.5,
|
any.word-wrap ==0.5,
|
||||||
any.word8 ==0.1.3,
|
any.word8 ==0.1.3,
|
||||||
any.xor ==0.0.1.0,
|
any.xor ==0.0.1.1,
|
||||||
any.zlib ==0.6.2.3,
|
any.yaml-streamly ==0.12.1,
|
||||||
|
yaml-streamly +no-examples +no-exe,
|
||||||
|
any.zlib ==0.6.3.0,
|
||||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||||
any.zlib-bindings ==0.1.1.5
|
any.zlib-bindings ==0.1.1.5
|
||||||
index-state: hackage.haskell.org 2021-10-01T15:16:26Z
|
index-state: hackage.haskell.org 2023-01-12T04:22:48Z
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
packages: ./ghcup.cabal
|
|
||||||
|
|
||||||
optional-packages: ./vendored/*/*.cabal
|
|
||||||
|
|
||||||
optimization: 2
|
|
||||||
|
|
||||||
package ghcup
|
|
||||||
tests: True
|
|
||||||
flags: +tui
|
|
||||||
|
|
||||||
constraints: http-io-streams -brotli
|
|
||||||
|
|
||||||
package libarchive
|
|
||||||
flags: -system-libarchive
|
|
||||||
|
|
||||||
package aeson-pretty
|
|
||||||
flags: +lib-only
|
|
||||||
|
|
||||||
package cabal-plan
|
|
||||||
flags: -exe
|
|
||||||
|
|
||||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
|
||||||
|
|
||||||
with-compiler: ghc-9.0.1
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
active-repositories: hackage.haskell.org:merge
|
|
||||||
constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|
||||||
Cabal -bundled-binary-generic,
|
|
||||||
any.HUnit ==1.6.2.0,
|
|
||||||
any.HsOpenSSL ==0.11.7.2,
|
|
||||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
|
||||||
any.HsYAML ==0.2.1.0,
|
|
||||||
HsYAML -exe,
|
|
||||||
any.HsYAML-aeson ==0.2.0.0,
|
|
||||||
any.QuickCheck ==2.14.2,
|
|
||||||
QuickCheck -old-random +templatehaskell,
|
|
||||||
any.StateVar ==1.2.2,
|
|
||||||
any.aeson ==1.5.6.0,
|
|
||||||
aeson -bytestring-builder -cffi -developer -fast,
|
|
||||||
any.aeson-pretty ==0.8.8,
|
|
||||||
aeson-pretty +lib-only,
|
|
||||||
any.alex ==3.2.6,
|
|
||||||
alex +small_base,
|
|
||||||
any.ansi-terminal ==0.11,
|
|
||||||
ansi-terminal -example,
|
|
||||||
any.ansi-wl-pprint ==0.6.9,
|
|
||||||
ansi-wl-pprint -example,
|
|
||||||
any.array ==0.5.4.0,
|
|
||||||
any.assoc ==1.0.2,
|
|
||||||
any.async ==2.2.3,
|
|
||||||
async -bench,
|
|
||||||
any.attoparsec ==0.13.2.5,
|
|
||||||
attoparsec -developer,
|
|
||||||
any.base ==4.15.0.0,
|
|
||||||
any.base-compat ==0.12.0,
|
|
||||||
any.base-compat-batteries ==0.12.0,
|
|
||||||
any.base-orphans ==0.8.5,
|
|
||||||
any.base16-bytestring ==1.0.1.0,
|
|
||||||
any.base64-bytestring ==1.1.0.0,
|
|
||||||
any.bifunctors ==5.5.11,
|
|
||||||
bifunctors +semigroups +tagged,
|
|
||||||
any.binary ==0.8.8.0,
|
|
||||||
any.blaze-builder ==0.4.2.1,
|
|
||||||
any.brick ==0.64.1,
|
|
||||||
brick -demos,
|
|
||||||
any.bytestring ==0.10.12.1,
|
|
||||||
any.bz2 ==1.0.1.0,
|
|
||||||
bz2 -cross +with-bzlib,
|
|
||||||
any.c2hs ==0.28.8,
|
|
||||||
c2hs +base3 -regression,
|
|
||||||
any.cabal-plan ==0.7.2.0,
|
|
||||||
cabal-plan -_ -exe -license-report,
|
|
||||||
any.call-stack ==0.4.0,
|
|
||||||
any.case-insensitive ==1.2.1.0,
|
|
||||||
any.casing ==0.1.4.1,
|
|
||||||
any.chs-cabal ==0.1.1.1,
|
|
||||||
any.chs-deps ==0.1.0.0,
|
|
||||||
chs-deps -cross,
|
|
||||||
any.clock ==0.8.2,
|
|
||||||
clock -llvm,
|
|
||||||
any.colour ==2.3.6,
|
|
||||||
any.comonad ==5.0.8,
|
|
||||||
comonad +containers +distributive +indexed-traversable,
|
|
||||||
any.composition-prelude ==3.0.0.2,
|
|
||||||
composition-prelude -development,
|
|
||||||
any.config-ini ==0.2.4.0,
|
|
||||||
config-ini -enable-doctests,
|
|
||||||
any.containers ==0.6.4.1,
|
|
||||||
any.contravariant ==1.5.5,
|
|
||||||
contravariant +semigroups +statevar +tagged,
|
|
||||||
any.cpphs ==1.20.9.1,
|
|
||||||
cpphs -old-locale,
|
|
||||||
any.cryptohash-sha1 ==0.11.100.1,
|
|
||||||
any.cryptohash-sha256 ==0.11.102.0,
|
|
||||||
cryptohash-sha256 -exe +use-cbits,
|
|
||||||
any.data-clist ==0.1.2.3,
|
|
||||||
any.data-fix ==0.3.2,
|
|
||||||
any.deepseq ==1.4.5.0,
|
|
||||||
any.directory ==1.3.6.1,
|
|
||||||
any.disk-free-space ==0.1.0.1,
|
|
||||||
any.distributive ==0.6.2.1,
|
|
||||||
distributive +semigroups +tagged,
|
|
||||||
any.dlist ==1.0,
|
|
||||||
dlist -werror,
|
|
||||||
any.exceptions ==0.10.4,
|
|
||||||
any.filepath ==1.4.2.1,
|
|
||||||
any.free ==5.1.7,
|
|
||||||
any.generic-arbitrary ==0.1.0,
|
|
||||||
any.ghc-bignum ==1.0,
|
|
||||||
any.ghc-boot-th ==9.0.1,
|
|
||||||
any.ghc-byteorder ==4.11.0.0.10,
|
|
||||||
any.ghc-prim ==0.7.0,
|
|
||||||
any.happy ==1.20.0,
|
|
||||||
any.hashable ==1.3.3.0,
|
|
||||||
hashable +integer-gmp -random-initial-seed,
|
|
||||||
any.haskus-utils-data ==1.4,
|
|
||||||
any.haskus-utils-types ==1.5.1,
|
|
||||||
any.haskus-utils-variant ==3.1,
|
|
||||||
any.hsc2hs ==0.68.7,
|
|
||||||
hsc2hs -in-ghc-tree,
|
|
||||||
any.hspec ==2.7.10,
|
|
||||||
any.hspec-core ==2.7.10,
|
|
||||||
any.hspec-discover ==2.7.10,
|
|
||||||
any.hspec-expectations ==0.8.2,
|
|
||||||
any.hspec-golden-aeson ==0.9.0.0,
|
|
||||||
any.http-io-streams ==0.1.6.0,
|
|
||||||
http-io-streams -brotli +fast-xor,
|
|
||||||
any.indexed-profunctors ==0.1.1,
|
|
||||||
any.indexed-traversable ==0.1.1,
|
|
||||||
any.indexed-traversable-instances ==0.1,
|
|
||||||
any.integer-logarithms ==1.0.3.1,
|
|
||||||
integer-logarithms -check-bounds +integer-gmp,
|
|
||||||
any.io-streams ==1.5.2.1,
|
|
||||||
io-streams +network -nointeractivetests +zlib,
|
|
||||||
any.language-c ==0.9.0.1,
|
|
||||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
|
||||||
any.libarchive ==3.0.3.0,
|
|
||||||
libarchive -cross -low-memory -system-libarchive,
|
|
||||||
any.lzma-static ==5.2.5.4,
|
|
||||||
any.megaparsec ==9.0.1,
|
|
||||||
megaparsec -dev,
|
|
||||||
any.microlens ==0.4.12.0,
|
|
||||||
any.microlens-mtl ==0.2.0.1,
|
|
||||||
any.microlens-th ==0.4.3.10,
|
|
||||||
any.mtl ==2.2.2,
|
|
||||||
any.network ==3.1.2.2,
|
|
||||||
network -devel,
|
|
||||||
any.network-uri ==2.6.4.1,
|
|
||||||
any.openssl-streams ==1.2.3.0,
|
|
||||||
any.optics ==0.4,
|
|
||||||
any.optics-core ==0.4,
|
|
||||||
optics-core -explicit-generic-labels,
|
|
||||||
any.optics-extra ==0.4,
|
|
||||||
any.optics-th ==0.4,
|
|
||||||
any.optparse-applicative ==0.16.1.0,
|
|
||||||
optparse-applicative +process,
|
|
||||||
any.os-release ==1.0.2,
|
|
||||||
os-release -devel,
|
|
||||||
any.parallel ==3.2.2.0,
|
|
||||||
any.parsec ==3.1.14.0,
|
|
||||||
any.parser-combinators ==1.3.0,
|
|
||||||
parser-combinators -dev,
|
|
||||||
any.polyparse ==1.13,
|
|
||||||
any.pretty ==1.1.3.6,
|
|
||||||
any.pretty-terminal ==0.1.0.0,
|
|
||||||
any.primitive ==0.7.2.0,
|
|
||||||
any.process ==1.6.11.0,
|
|
||||||
any.profunctors ==5.6.2,
|
|
||||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
|
||||||
any.quickcheck-io ==0.2.0,
|
|
||||||
any.random ==1.2.1,
|
|
||||||
any.recursion-schemes ==5.2.2.1,
|
|
||||||
recursion-schemes +template-haskell,
|
|
||||||
any.regex-base ==0.94.0.1,
|
|
||||||
any.regex-posix ==0.96.0.1,
|
|
||||||
regex-posix -_regex-posix-clib,
|
|
||||||
any.resourcet ==1.2.4.3,
|
|
||||||
any.rts ==1.0,
|
|
||||||
any.safe ==0.3.19,
|
|
||||||
any.safe-exceptions ==0.1.7.2,
|
|
||||||
any.scientific ==0.3.7.0,
|
|
||||||
scientific -bytestring-builder -integer-simple,
|
|
||||||
any.semigroupoids ==5.3.5,
|
|
||||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
|
||||||
any.setenv ==0.1.1.3,
|
|
||||||
any.split ==0.2.3.4,
|
|
||||||
any.splitmix ==0.1.0.3,
|
|
||||||
splitmix -optimised-mixer,
|
|
||||||
any.stm ==2.5.0.0,
|
|
||||||
any.strict ==0.4.0.1,
|
|
||||||
strict +assoc,
|
|
||||||
any.strict-base ==0.4.0.0,
|
|
||||||
any.tagged ==0.8.6.1,
|
|
||||||
tagged +deepseq +transformers,
|
|
||||||
any.template-haskell ==2.17.0.0,
|
|
||||||
any.temporary ==1.3,
|
|
||||||
any.terminal-progress-bar ==0.4.1,
|
|
||||||
any.terminal-size ==0.3.2.1,
|
|
||||||
any.terminfo ==0.4.1.4,
|
|
||||||
any.text ==1.2.4.1,
|
|
||||||
any.text-zipper ==0.11,
|
|
||||||
any.tf-random ==0.5,
|
|
||||||
any.th-abstraction ==0.4.3.0,
|
|
||||||
any.th-compat ==0.1.3,
|
|
||||||
any.th-lift ==0.8.2,
|
|
||||||
any.th-lift-instances ==0.1.18,
|
|
||||||
any.these ==1.1.1.1,
|
|
||||||
these +assoc,
|
|
||||||
any.time ==1.9.3,
|
|
||||||
any.time-compat ==1.9.6.1,
|
|
||||||
time-compat -old-locale,
|
|
||||||
any.transformers ==0.5.6.2,
|
|
||||||
any.transformers-base ==0.4.6,
|
|
||||||
transformers-base +orphaninstances,
|
|
||||||
any.transformers-compat ==0.7,
|
|
||||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
|
||||||
any.unix ==2.7.2.2,
|
|
||||||
any.unix-bytestring ==0.3.7.3,
|
|
||||||
any.unix-compat ==0.5.3,
|
|
||||||
unix-compat -old-time,
|
|
||||||
any.unliftio-core ==0.2.0.1,
|
|
||||||
any.unordered-containers ==0.2.14.0,
|
|
||||||
unordered-containers -debug,
|
|
||||||
any.uri-bytestring ==0.3.3.1,
|
|
||||||
uri-bytestring -lib-werror,
|
|
||||||
any.utf8-string ==1.0.2,
|
|
||||||
any.uuid-types ==1.0.5,
|
|
||||||
any.vector ==0.12.3.1,
|
|
||||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
|
||||||
any.versions ==5.0.0,
|
|
||||||
any.vty ==5.33,
|
|
||||||
any.word-wrap ==0.5,
|
|
||||||
any.word8 ==0.1.3,
|
|
||||||
any.xor ==0.0.1.0,
|
|
||||||
any.zlib ==0.6.2.3,
|
|
||||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
|
||||||
any.zlib-bindings ==0.1.1.5
|
|
||||||
index-state: hackage.haskell.org 2021-10-01T15:16:26Z
|
|
||||||
@@ -2,21 +2,12 @@ packages: ./ghcup.cabal
|
|||||||
|
|
||||||
optional-packages: ./vendored/*/*.cabal
|
optional-packages: ./vendored/*/*.cabal
|
||||||
|
|
||||||
optimization: 2
|
|
||||||
|
|
||||||
package ghcup
|
package ghcup
|
||||||
tests: True
|
|
||||||
flags: +tui
|
flags: +tui
|
||||||
|
|
||||||
constraints: http-io-streams -brotli,
|
constraints: http-io-streams -brotli,
|
||||||
any.Cabal ==3.4.0.0 || ==3.6.2.0,
|
|
||||||
any.aeson >= 2.0.1.0
|
any.aeson >= 2.0.1.0
|
||||||
|
|
||||||
source-repository-package
|
|
||||||
type: git
|
|
||||||
location: https://github.com/hasufell/aeson-pretty.git
|
|
||||||
tag: e902ab866bb41d990b66af3644aeb352ff7aaf6f
|
|
||||||
|
|
||||||
package libarchive
|
package libarchive
|
||||||
flags: -system-libarchive
|
flags: -system-libarchive
|
||||||
|
|
||||||
@@ -29,4 +20,6 @@ package cabal-plan
|
|||||||
package aeson
|
package aeson
|
||||||
flags: +ordered-keymap
|
flags: +ordered-keymap
|
||||||
|
|
||||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
package streamly
|
||||||
|
flags: +use-unliftio
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
-- windows picks weird version
|
-- windows picks weird version
|
||||||
constraints: any.hsc2hs ==0.68.7
|
constraints: any.hsc2hs ==0.68.8
|
||||||
|
|||||||
50
cabal.project.release
Normal file
50
cabal.project.release
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
packages: ./ghcup.cabal
|
||||||
|
|
||||||
|
optional-packages: ./vendored/*/*.cabal
|
||||||
|
|
||||||
|
optimization: 2
|
||||||
|
|
||||||
|
if os(linux)
|
||||||
|
package ghcup
|
||||||
|
flags: +tui
|
||||||
|
if arch(x86_64) || arch(i386)
|
||||||
|
package *
|
||||||
|
ghc-options: -split-sections -optl-static
|
||||||
|
elif os(darwin)
|
||||||
|
constraints: zlib +bundled-c-zlib,
|
||||||
|
lzma +static
|
||||||
|
package ghcup
|
||||||
|
flags: +tui
|
||||||
|
elif os(mingw32)
|
||||||
|
constraints: zlib +bundled-c-zlib,
|
||||||
|
lzma +static,
|
||||||
|
text -simdutf
|
||||||
|
package ghcup
|
||||||
|
flags: -tui
|
||||||
|
elif os(freebsd)
|
||||||
|
constraints: zlib +bundled-c-zlib,
|
||||||
|
zip +disable-zstd
|
||||||
|
package *
|
||||||
|
ghc-options: -split-sections -pgmc clang++14
|
||||||
|
package ghcup
|
||||||
|
flags: +tui
|
||||||
|
|
||||||
|
constraints: http-io-streams -brotli,
|
||||||
|
any.aeson >= 2.0.1.0,
|
||||||
|
any.hsc2hs ==0.68.8
|
||||||
|
|
||||||
|
package libarchive
|
||||||
|
flags: -system-libarchive
|
||||||
|
|
||||||
|
package aeson-pretty
|
||||||
|
flags: +lib-only
|
||||||
|
|
||||||
|
package cabal-plan
|
||||||
|
flags: -exe
|
||||||
|
|
||||||
|
package aeson
|
||||||
|
flags: +ordered-keymap
|
||||||
|
|
||||||
|
package streamly
|
||||||
|
flags: +use-unliftio
|
||||||
|
|
||||||
7
cbits/dirutils.c
Normal file
7
cbits/dirutils.c
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include "dirutils.h"
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
__posixdir_d_type(struct dirent* d)
|
||||||
|
{
|
||||||
|
return(d -> d_type);
|
||||||
|
}
|
||||||
16
cbits/dirutils.h
Normal file
16
cbits/dirutils.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef POSIXPATHS_CBITS_DIRUTILS_H
|
||||||
|
#define POSIXPATHS_CBITS_DIRUTILS_H
|
||||||
|
|
||||||
|
#include <HsFFI.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern unsigned int
|
||||||
|
__posixdir_d_type(struct dirent* d)
|
||||||
|
;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -36,6 +36,16 @@ key-bindings:
|
|||||||
show-all-tools:
|
show-all-tools:
|
||||||
KChar: 't'
|
KChar: 't'
|
||||||
|
|
||||||
|
# The caching for the metadata files containing download info, depending on last access time
|
||||||
|
# of the file. These usually are in '~/.ghcup/cache/ghcup-<ver>.yaml'.
|
||||||
|
meta-cache: 300 # in seconds
|
||||||
|
|
||||||
|
# When trying to download ghcup metadata, this option decides what to do
|
||||||
|
# when the download fails:
|
||||||
|
# 1. Lax: use existing ~/.ghcup/cache/ghcup-<ver>.yaml as fallback (default)
|
||||||
|
# 2. Strict: fail hard
|
||||||
|
meta-mode: Lax # Strict | Lax
|
||||||
|
|
||||||
# Where to get GHC/cabal/hls download info/versions from. For more detailed explanation
|
# Where to get GHC/cabal/hls download info/versions from. For more detailed explanation
|
||||||
# check the 'URLSource' type in the code.
|
# check the 'URLSource' type in the code.
|
||||||
url-source:
|
url-source:
|
||||||
@@ -44,12 +54,16 @@ url-source:
|
|||||||
|
|
||||||
## Example 1: Read download info from this location instead
|
## Example 1: Read download info from this location instead
|
||||||
## Accepts file/http/https scheme
|
## Accepts file/http/https scheme
|
||||||
|
## Can also be an array of URLs or an array of 'Either GHCupInfo URL', in
|
||||||
|
## which case they are merged right-biased (overwriting duplicate versions).
|
||||||
# OwnSource: "file:///home/jule/git/ghcup-hs/ghcup-0.0.3.yaml"
|
# OwnSource: "file:///home/jule/git/ghcup-hs/ghcup-0.0.3.yaml"
|
||||||
|
|
||||||
## Example 2: Add custom tarballs to the default downloads, overwriting duplicate versions
|
## Example 2: Add custom tarballs to the default downloads, overwriting duplicate versions.
|
||||||
|
## Can also be an array of 'Either GHCupInfo URL', also see Example 3.
|
||||||
# AddSource:
|
# AddSource:
|
||||||
# Left:
|
# Left:
|
||||||
# toolRequirements: {} # this is ignored
|
# globalTools: {}
|
||||||
|
# toolRequirements: {}
|
||||||
# ghcupDownloads:
|
# ghcupDownloads:
|
||||||
# GHC:
|
# GHC:
|
||||||
# 9.10.2:
|
# 9.10.2:
|
||||||
@@ -62,6 +76,46 @@ url-source:
|
|||||||
# dlSubdir: ghc-7.10.3
|
# dlSubdir: ghc-7.10.3
|
||||||
# dlHash: 01cfbad8dff1e8b34a5fdca8caeaf843b56e36af919e29cd68870d2588563db5
|
# dlHash: 01cfbad8dff1e8b34a5fdca8caeaf843b56e36af919e29cd68870d2588563db5
|
||||||
|
|
||||||
## Example 3: Add a custom download file to the default downloads, overwriting duplicate versions
|
## Example 3: Add multiple custom download files to the default downloads via right-biased merge (overwriting duplicate
|
||||||
|
## versions).
|
||||||
# AddSource:
|
# AddSource:
|
||||||
# Right: "file:///home/jule/git/ghcup-hs/ghcup-custom.yaml"
|
# - Right: "file:///home/jule/git/ghcup-hs/ghcup-prereleases.yaml"
|
||||||
|
# - Right: "file:///home/jule/git/ghcup-hs/ghcup-custom.yaml"
|
||||||
|
|
||||||
|
# This is a way to override platform detection, e.g. when you're running
|
||||||
|
# a Ubuntu derivate based on 18.04, you could do:
|
||||||
|
#
|
||||||
|
# platform-override:
|
||||||
|
# arch: A_64
|
||||||
|
# platform:
|
||||||
|
# contents: Ubuntu
|
||||||
|
# tag: Linux
|
||||||
|
# version: '18.04'
|
||||||
|
platform-override: null
|
||||||
|
|
||||||
|
# Support for mirrors. Currently there are 3 hosts you can mirror:
|
||||||
|
# - github.com (for stack and some older HLS versions)
|
||||||
|
# - raw.githubusercontent.com (for the yaml metadata)
|
||||||
|
# - downloads.haskell.org (for everything else)
|
||||||
|
#
|
||||||
|
# E.g. when we have 'https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml'
|
||||||
|
# and the following mirror config
|
||||||
|
#
|
||||||
|
# "raw.githubusercontent.com":
|
||||||
|
# authority:
|
||||||
|
# host: "mirror.sjtu.edu.cn"
|
||||||
|
# pathPrefix: "ghcup/yaml"
|
||||||
|
#
|
||||||
|
# Then the resulting url will be 'https://mirror.sjtu.edu.cn/ghcup/yaml/haskell/ghcup-metadata/master/ghcup-0.0.7.yaml'
|
||||||
|
mirrors:
|
||||||
|
"github.com":
|
||||||
|
authority:
|
||||||
|
host: "mirror.sjtu.edu.cn"
|
||||||
|
"raw.githubusercontent.com":
|
||||||
|
authority:
|
||||||
|
host: "mirror.sjtu.edu.cn"
|
||||||
|
pathPrefix: "ghcup/yaml"
|
||||||
|
"downloads.haskell.org":
|
||||||
|
authority:
|
||||||
|
host: "mirror.sjtu.edu.cn"
|
||||||
|
|
||||||
|
|||||||
1
data/metadata
Submodule
1
data/metadata
Submodule
Submodule data/metadata added at ea9b67d5d0
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
71
docker/alpine32/Dockerfile
Normal file
71
docker/alpine32/Dockerfile
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
FROM --platform=linux/i386 i386/alpine:3.12
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
curl \
|
||||||
|
gcc \
|
||||||
|
g++ \
|
||||||
|
binutils \
|
||||||
|
binutils-gold \
|
||||||
|
coreutils \
|
||||||
|
bsd-compat-headers \
|
||||||
|
gmp-dev \
|
||||||
|
ncurses-dev \
|
||||||
|
libffi-dev \
|
||||||
|
make \
|
||||||
|
xz \
|
||||||
|
tar \
|
||||||
|
perl \
|
||||||
|
bash \
|
||||||
|
diffutils \
|
||||||
|
git \
|
||||||
|
gzip \
|
||||||
|
gnupg && \
|
||||||
|
apk add --no-cache \
|
||||||
|
zlib \
|
||||||
|
zlib-dev \
|
||||||
|
zlib-static \
|
||||||
|
bzip2 \
|
||||||
|
bzip2-dev \
|
||||||
|
bzip2-static \
|
||||||
|
gmp \
|
||||||
|
gmp-dev \
|
||||||
|
openssl-dev \
|
||||||
|
openssl-libs-static \
|
||||||
|
xz \
|
||||||
|
xz-dev \
|
||||||
|
ncurses-static
|
||||||
|
|
||||||
|
ARG GHCUP_VERSION=0.1.18.0
|
||||||
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
|
# install ghcup
|
||||||
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/i386-linux-ghcup-$GHCUP_VERSION && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS.sig && \
|
||||||
|
gpg --verify SHA256SUMS.sig SHA256SUMS && \
|
||||||
|
sha256sum -c --ignore-missing SHA256SUMS && \
|
||||||
|
mv i386-linux-ghcup-$GHCUP_VERSION /usr/bin/ghcup && \
|
||||||
|
chmod +x /usr/bin/ghcup && \
|
||||||
|
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||||
|
|
||||||
|
ARG GHC=8.10.7
|
||||||
|
ARG CABAL_INSTALL=3.6.2.0
|
||||||
|
ARG STACK=2.9.1
|
||||||
|
|
||||||
|
ENV GHCUP_CURL_OPTS="--silent"
|
||||||
|
ENV NO_COLOR=1
|
||||||
|
|
||||||
|
# install haskell toolchain
|
||||||
|
RUN ghcup config set gpg-setting GPGStrict && \
|
||||||
|
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||||
|
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||||
|
find "/usr/lib/ghc-${GHC}/" \( -name "*_p.a" -o -name "*.p_hi" \) -type f -delete && \
|
||||||
|
rm -r "/usr/share/doc/ghc-${GHC}" && \
|
||||||
|
rm -rf /tmp/ghcup* && \
|
||||||
|
ghcup gc -p -s -c -t
|
||||||
|
|
||||||
|
ENV PATH /root/.cabal/bin:/root/.ghcup:/root/.local/bin:$PATH
|
||||||
|
|
||||||
71
docker/alpine64/Dockerfile
Normal file
71
docker/alpine64/Dockerfile
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
FROM alpine:3.12
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
curl \
|
||||||
|
gcc \
|
||||||
|
g++ \
|
||||||
|
binutils \
|
||||||
|
binutils-gold \
|
||||||
|
coreutils \
|
||||||
|
bsd-compat-headers \
|
||||||
|
gmp-dev \
|
||||||
|
ncurses-dev \
|
||||||
|
libffi-dev \
|
||||||
|
make \
|
||||||
|
xz \
|
||||||
|
tar \
|
||||||
|
perl \
|
||||||
|
bash \
|
||||||
|
diffutils \
|
||||||
|
git \
|
||||||
|
gzip \
|
||||||
|
gnupg && \
|
||||||
|
apk add --no-cache \
|
||||||
|
zlib \
|
||||||
|
zlib-dev \
|
||||||
|
zlib-static \
|
||||||
|
bzip2 \
|
||||||
|
bzip2-dev \
|
||||||
|
bzip2-static \
|
||||||
|
gmp \
|
||||||
|
gmp-dev \
|
||||||
|
openssl-dev \
|
||||||
|
openssl-libs-static \
|
||||||
|
xz \
|
||||||
|
xz-dev \
|
||||||
|
ncurses-static
|
||||||
|
|
||||||
|
ARG GHCUP_VERSION=0.1.18.0
|
||||||
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
|
# install ghcup
|
||||||
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/x86_64-linux-ghcup-$GHCUP_VERSION && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS.sig && \
|
||||||
|
gpg --verify SHA256SUMS.sig SHA256SUMS && \
|
||||||
|
sha256sum -c --ignore-missing SHA256SUMS && \
|
||||||
|
mv x86_64-linux-ghcup-$GHCUP_VERSION /usr/bin/ghcup && \
|
||||||
|
chmod +x /usr/bin/ghcup && \
|
||||||
|
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||||
|
|
||||||
|
ARG GHC=8.10.7
|
||||||
|
ARG CABAL_INSTALL=3.6.2.0
|
||||||
|
ARG STACK=2.9.1
|
||||||
|
|
||||||
|
ENV GHCUP_CURL_OPTS="--silent"
|
||||||
|
ENV NO_COLOR=1
|
||||||
|
|
||||||
|
# install haskell toolchain
|
||||||
|
RUN ghcup config set gpg-setting GPGStrict && \
|
||||||
|
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||||
|
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||||
|
find "/usr/lib/ghc-${GHC}/" \( -name "*_p.a" -o -name "*.p_hi" \) -type f -delete && \
|
||||||
|
rm -r "/usr/share/doc/ghc-${GHC}" && \
|
||||||
|
rm -rf /tmp/ghcup* && \
|
||||||
|
ghcup gc -p -s -c -t
|
||||||
|
|
||||||
|
ENV PATH /root/.cabal/bin:/root/.ghcup:/root/.local/bin:$PATH
|
||||||
|
|
||||||
61
docker/arm32v7/buster/Dockerfile
Normal file
61
docker/arm32v7/buster/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
FROM arm32v7/debian:10
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
ENV TZ=Asia/Singapore
|
||||||
|
|
||||||
|
COPY update_opt.sh /usr/bin/update_opt.sh
|
||||||
|
RUN chmod +x /usr/bin/update_opt.sh
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
dirmngr \
|
||||||
|
g++ \
|
||||||
|
git \
|
||||||
|
gnupg \
|
||||||
|
libsqlite3-dev \
|
||||||
|
libtinfo-dev \
|
||||||
|
libgmp-dev \
|
||||||
|
make \
|
||||||
|
netbase \
|
||||||
|
openssh-client \
|
||||||
|
xz-utils \
|
||||||
|
zlib1g-dev \
|
||||||
|
libnuma-dev libgmp10 libssl-dev liblzma-dev libbz2-dev wget lsb-release software-properties-common apt-transport-https gcc autoconf automake build-essential gzip patchelf tree \
|
||||||
|
llvm-11 clang-11 && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN update_opt.sh 11 1
|
||||||
|
|
||||||
|
ARG GHCUP_VERSION=0.1.17.8
|
||||||
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
|
# install ghcup
|
||||||
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/armv7-linux-ghcup-$GHCUP_VERSION && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS.sig && \
|
||||||
|
gpg --verify SHA256SUMS.sig SHA256SUMS && \
|
||||||
|
sha256sum -c --ignore-missing SHA256SUMS && \
|
||||||
|
mv armv7-linux-ghcup-$GHCUP_VERSION /usr/bin/ghcup && \
|
||||||
|
chmod +x /usr/bin/ghcup && \
|
||||||
|
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||||
|
|
||||||
|
ARG GHC=8.10.7
|
||||||
|
ARG CABAL_INSTALL=3.6.2.0
|
||||||
|
ARG STACK=2.9.1
|
||||||
|
|
||||||
|
ENV GHCUP_CURL_OPTS="--silent"
|
||||||
|
ENV NO_COLOR=1
|
||||||
|
|
||||||
|
# install haskell toolchain
|
||||||
|
RUN ghcup config set gpg-setting GPGStrict && \
|
||||||
|
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||||
|
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||||
|
ghcup gc -s -c -t
|
||||||
|
|
||||||
|
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||||
|
|
||||||
|
CMD ["ghci"]
|
||||||
36
docker/arm32v7/buster/update_opt.sh
Executable file
36
docker/arm32v7/buster/update_opt.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# update_alternatives.sh
|
||||||
|
|
||||||
|
update_alternatives() {
|
||||||
|
local version=${1}
|
||||||
|
local priority=${2}
|
||||||
|
local master=${3}
|
||||||
|
local slaves=${4}
|
||||||
|
local path=${5}
|
||||||
|
local cmdln
|
||||||
|
|
||||||
|
cmdln="--verbose --install ${path}${master} ${master} ${path}${master}-${version} ${priority}"
|
||||||
|
for slave in ${slaves}; do
|
||||||
|
cmdln="${cmdln} --slave ${path}${slave} ${slave} ${path}${slave}-${version}"
|
||||||
|
done
|
||||||
|
update-alternatives ${cmdln}
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ${#} -ne 2 ]]; then
|
||||||
|
echo usage: "${0}" clang_version priority
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
version=${1}
|
||||||
|
priority=${2}
|
||||||
|
path="/usr/bin/"
|
||||||
|
|
||||||
|
master="llvm-config"
|
||||||
|
slaves="llvm-addr2line llvm-ar llvm-as llvm-bcanalyzer llvm-bitcode-strip llvm-cat llvm-cfi-verify llvm-cov llvm-c-test llvm-cvtres llvm-cxxdump llvm-cxxfilt llvm-cxxmap llvm-debuginfod llvm-debuginfod-find llvm-diff llvm-dis llvm-dlltool llvm-dwarfdump llvm-dwarfutil llvm-dwp llvm-exegesis llvm-extract llvm-gsymutil llvm-ifs llvm-install-name-tool llvm-jitlink llvm-jitlink-executor llvm-lib llvm-libtool-darwin llvm-link llvm-lipo llvm-lto llvm-lto2 llvm-mc llvm-mca llvm-ml llvm-modextract llvm-mt llvm-nm llvm-objcopy llvm-objdump llvm-omp-device-info llvm-opt-report llvm-otool llvm-pdbutil llvm-PerfectShuffle llvm-profdata llvm-profgen llvm-ranlib llvm-rc llvm-readelf llvm-readobj llvm-reduce llvm-remark-size-diff llvm-rtdyld llvm-sim llvm-size llvm-split llvm-stress llvm-strings llvm-strip llvm-symbolizer llvm-tapi-diff llvm-tblgen llvm-tli-checker llvm-undname llvm-windres llvm-xray"
|
||||||
|
|
||||||
|
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||||
|
|
||||||
|
master="clang"
|
||||||
|
slaves="analyze-build asan_symbolize bugpoint c-index-test clang++ clang-apply-replacements clang-change-namespace clang-check clang-cl clang-cpp clangd clang-doc clang-extdef-mapping clang-format clang-format-diff clang-include-fixer clang-linker-wrapper clang-move clang-nvlink-wrapper clang-offload-bundler clang-offload-packager clang-offload-wrapper clang-pseudo clang-query clang-refactor clang-rename clang-reorder-fields clang-repl clang-scan-deps clang-tidy count diagtool dsymutil FileCheck find-all-symbols git-clang-format hmaptool hwasan_symbolize intercept-build ld64.lld ld.lld llc lld lldb lldb-argdumper lldb-instr lldb-server lldb-vscode lld-link lli lli-child-target modularize not obj2yaml opt pp-trace run-clang-tidy sancov sanstats scan-build scan-build-py scan-view split-file UnicodeNameMappingGenerator verify-uselistorder wasm-ld yaml2obj yaml-bench"
|
||||||
|
|
||||||
|
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||||
61
docker/arm32v7/focal/Dockerfile
Normal file
61
docker/arm32v7/focal/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
FROM arm32v7/ubuntu:focal
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
ENV TZ=Asia/Singapore
|
||||||
|
|
||||||
|
COPY update_opt.sh /usr/bin/update_opt.sh
|
||||||
|
RUN chmod +x /usr/bin/update_opt.sh
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
dirmngr \
|
||||||
|
g++ \
|
||||||
|
git \
|
||||||
|
gnupg \
|
||||||
|
libsqlite3-dev \
|
||||||
|
libtinfo-dev \
|
||||||
|
libgmp-dev \
|
||||||
|
make \
|
||||||
|
netbase \
|
||||||
|
openssh-client \
|
||||||
|
xz-utils \
|
||||||
|
zlib1g-dev \
|
||||||
|
libnuma-dev libgmp10 libssl-dev liblzma-dev libbz2-dev wget lsb-release software-properties-common apt-transport-https gcc autoconf automake build-essential gzip patchelf tree \
|
||||||
|
llvm-9 clang-9 && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN update_opt.sh 9 1
|
||||||
|
|
||||||
|
ARG GHCUP_VERSION=0.1.17.8
|
||||||
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
|
# install ghcup
|
||||||
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/armv7-linux-ghcup-$GHCUP_VERSION && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS.sig && \
|
||||||
|
gpg --verify SHA256SUMS.sig SHA256SUMS && \
|
||||||
|
sha256sum -c --ignore-missing SHA256SUMS && \
|
||||||
|
mv armv7-linux-ghcup-$GHCUP_VERSION /usr/bin/ghcup && \
|
||||||
|
chmod +x /usr/bin/ghcup && \
|
||||||
|
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||||
|
|
||||||
|
ARG GHC=8.10.7
|
||||||
|
ARG CABAL_INSTALL=3.6.2.0
|
||||||
|
ARG STACK=2.9.1
|
||||||
|
|
||||||
|
ENV GHCUP_CURL_OPTS="--silent"
|
||||||
|
ENV NO_COLOR=1
|
||||||
|
|
||||||
|
# install haskell toolchain
|
||||||
|
RUN ghcup config set gpg-setting GPGStrict && \
|
||||||
|
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||||
|
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||||
|
ghcup gc -s -c -t
|
||||||
|
|
||||||
|
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||||
|
|
||||||
|
CMD ["ghci"]
|
||||||
36
docker/arm32v7/focal/update_opt.sh
Executable file
36
docker/arm32v7/focal/update_opt.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# update_alternatives.sh
|
||||||
|
|
||||||
|
update_alternatives() {
|
||||||
|
local version=${1}
|
||||||
|
local priority=${2}
|
||||||
|
local master=${3}
|
||||||
|
local slaves=${4}
|
||||||
|
local path=${5}
|
||||||
|
local cmdln
|
||||||
|
|
||||||
|
cmdln="--verbose --install ${path}${master} ${master} ${path}${master}-${version} ${priority}"
|
||||||
|
for slave in ${slaves}; do
|
||||||
|
cmdln="${cmdln} --slave ${path}${slave} ${slave} ${path}${slave}-${version}"
|
||||||
|
done
|
||||||
|
update-alternatives ${cmdln}
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ${#} -ne 2 ]]; then
|
||||||
|
echo usage: "${0}" clang_version priority
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
version=${1}
|
||||||
|
priority=${2}
|
||||||
|
path="/usr/bin/"
|
||||||
|
|
||||||
|
master="llvm-config"
|
||||||
|
slaves="llvm-addr2line llvm-ar llvm-as llvm-bcanalyzer llvm-bitcode-strip llvm-cat llvm-cfi-verify llvm-cov llvm-c-test llvm-cvtres llvm-cxxdump llvm-cxxfilt llvm-cxxmap llvm-debuginfod llvm-debuginfod-find llvm-diff llvm-dis llvm-dlltool llvm-dwarfdump llvm-dwarfutil llvm-dwp llvm-exegesis llvm-extract llvm-gsymutil llvm-ifs llvm-install-name-tool llvm-jitlink llvm-jitlink-executor llvm-lib llvm-libtool-darwin llvm-link llvm-lipo llvm-lto llvm-lto2 llvm-mc llvm-mca llvm-ml llvm-modextract llvm-mt llvm-nm llvm-objcopy llvm-objdump llvm-omp-device-info llvm-opt-report llvm-otool llvm-pdbutil llvm-PerfectShuffle llvm-profdata llvm-profgen llvm-ranlib llvm-rc llvm-readelf llvm-readobj llvm-reduce llvm-remark-size-diff llvm-rtdyld llvm-sim llvm-size llvm-split llvm-stress llvm-strings llvm-strip llvm-symbolizer llvm-tapi-diff llvm-tblgen llvm-tli-checker llvm-undname llvm-windres llvm-xray"
|
||||||
|
|
||||||
|
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||||
|
|
||||||
|
master="clang"
|
||||||
|
slaves="analyze-build asan_symbolize bugpoint c-index-test clang++ clang-apply-replacements clang-change-namespace clang-check clang-cl clang-cpp clangd clang-doc clang-extdef-mapping clang-format clang-format-diff clang-include-fixer clang-linker-wrapper clang-move clang-nvlink-wrapper clang-offload-bundler clang-offload-packager clang-offload-wrapper clang-pseudo clang-query clang-refactor clang-rename clang-reorder-fields clang-repl clang-scan-deps clang-tidy count diagtool dsymutil FileCheck find-all-symbols git-clang-format hmaptool hwasan_symbolize intercept-build ld64.lld ld.lld llc lld lldb lldb-argdumper lldb-instr lldb-server lldb-vscode lld-link lli lli-child-target modularize not obj2yaml opt pp-trace run-clang-tidy sancov sanstats scan-build scan-build-py scan-view split-file UnicodeNameMappingGenerator verify-uselistorder wasm-ld yaml2obj yaml-bench"
|
||||||
|
|
||||||
|
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||||
61
docker/arm64v8/buster/Dockerfile
Normal file
61
docker/arm64v8/buster/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
FROM arm64v8/debian:10
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
ENV TZ=Asia/Singapore
|
||||||
|
|
||||||
|
COPY update_opt.sh /usr/bin/update_opt.sh
|
||||||
|
RUN chmod +x /usr/bin/update_opt.sh
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
dirmngr \
|
||||||
|
g++ \
|
||||||
|
git \
|
||||||
|
gnupg \
|
||||||
|
libsqlite3-dev \
|
||||||
|
libtinfo-dev \
|
||||||
|
libgmp-dev \
|
||||||
|
make \
|
||||||
|
netbase \
|
||||||
|
openssh-client \
|
||||||
|
xz-utils \
|
||||||
|
zlib1g-dev \
|
||||||
|
libnuma-dev libgmp10 libssl-dev liblzma-dev libbz2-dev wget lsb-release software-properties-common apt-transport-https gcc autoconf automake build-essential gzip patchelf tree \
|
||||||
|
llvm-11 clang-11 && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN update_opt.sh 11 1
|
||||||
|
|
||||||
|
ARG GHCUP_VERSION=0.1.18.0
|
||||||
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
|
# install ghcup
|
||||||
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/aarch64-linux-ghcup-$GHCUP_VERSION && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS.sig && \
|
||||||
|
gpg --verify SHA256SUMS.sig SHA256SUMS && \
|
||||||
|
sha256sum -c --ignore-missing SHA256SUMS && \
|
||||||
|
mv aarch64-linux-ghcup-$GHCUP_VERSION /usr/bin/ghcup && \
|
||||||
|
chmod +x /usr/bin/ghcup && \
|
||||||
|
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||||
|
|
||||||
|
ARG GHC=8.10.7
|
||||||
|
ARG CABAL_INSTALL=3.6.2.0
|
||||||
|
ARG STACK=2.9.1
|
||||||
|
|
||||||
|
ENV GHCUP_CURL_OPTS="--silent"
|
||||||
|
ENV NO_COLOR=1
|
||||||
|
|
||||||
|
# install haskell toolchain
|
||||||
|
RUN ghcup config set gpg-setting GPGStrict && \
|
||||||
|
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||||
|
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||||
|
ghcup gc -s -c -t
|
||||||
|
|
||||||
|
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||||
|
|
||||||
|
CMD ["ghci"]
|
||||||
36
docker/arm64v8/buster/update_opt.sh
Executable file
36
docker/arm64v8/buster/update_opt.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# update_alternatives.sh
|
||||||
|
|
||||||
|
update_alternatives() {
|
||||||
|
local version=${1}
|
||||||
|
local priority=${2}
|
||||||
|
local master=${3}
|
||||||
|
local slaves=${4}
|
||||||
|
local path=${5}
|
||||||
|
local cmdln
|
||||||
|
|
||||||
|
cmdln="--verbose --install ${path}${master} ${master} ${path}${master}-${version} ${priority}"
|
||||||
|
for slave in ${slaves}; do
|
||||||
|
cmdln="${cmdln} --slave ${path}${slave} ${slave} ${path}${slave}-${version}"
|
||||||
|
done
|
||||||
|
update-alternatives ${cmdln}
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ${#} -ne 2 ]]; then
|
||||||
|
echo usage: "${0}" clang_version priority
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
version=${1}
|
||||||
|
priority=${2}
|
||||||
|
path="/usr/bin/"
|
||||||
|
|
||||||
|
master="llvm-config"
|
||||||
|
slaves="llvm-addr2line llvm-ar llvm-as llvm-bcanalyzer llvm-bitcode-strip llvm-cat llvm-cfi-verify llvm-cov llvm-c-test llvm-cvtres llvm-cxxdump llvm-cxxfilt llvm-cxxmap llvm-debuginfod llvm-debuginfod-find llvm-diff llvm-dis llvm-dlltool llvm-dwarfdump llvm-dwarfutil llvm-dwp llvm-exegesis llvm-extract llvm-gsymutil llvm-ifs llvm-install-name-tool llvm-jitlink llvm-jitlink-executor llvm-lib llvm-libtool-darwin llvm-link llvm-lipo llvm-lto llvm-lto2 llvm-mc llvm-mca llvm-ml llvm-modextract llvm-mt llvm-nm llvm-objcopy llvm-objdump llvm-omp-device-info llvm-opt-report llvm-otool llvm-pdbutil llvm-PerfectShuffle llvm-profdata llvm-profgen llvm-ranlib llvm-rc llvm-readelf llvm-readobj llvm-reduce llvm-remark-size-diff llvm-rtdyld llvm-sim llvm-size llvm-split llvm-stress llvm-strings llvm-strip llvm-symbolizer llvm-tapi-diff llvm-tblgen llvm-tli-checker llvm-undname llvm-windres llvm-xray"
|
||||||
|
|
||||||
|
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||||
|
|
||||||
|
master="clang"
|
||||||
|
slaves="analyze-build asan_symbolize bugpoint c-index-test clang++ clang-apply-replacements clang-change-namespace clang-check clang-cl clang-cpp clangd clang-doc clang-extdef-mapping clang-format clang-format-diff clang-include-fixer clang-linker-wrapper clang-move clang-nvlink-wrapper clang-offload-bundler clang-offload-packager clang-offload-wrapper clang-pseudo clang-query clang-refactor clang-rename clang-reorder-fields clang-repl clang-scan-deps clang-tidy count diagtool dsymutil FileCheck find-all-symbols git-clang-format hmaptool hwasan_symbolize intercept-build ld64.lld ld.lld llc lld lldb lldb-argdumper lldb-instr lldb-server lldb-vscode lld-link lli lli-child-target modularize not obj2yaml opt pp-trace run-clang-tidy sancov sanstats scan-build scan-build-py scan-view split-file UnicodeNameMappingGenerator verify-uselistorder wasm-ld yaml2obj yaml-bench"
|
||||||
|
|
||||||
|
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||||
61
docker/arm64v8/focal/Dockerfile
Normal file
61
docker/arm64v8/focal/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
FROM arm64v8/ubuntu:focal
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
ENV TZ=Asia/Singapore
|
||||||
|
|
||||||
|
COPY update_opt.sh /usr/bin/update_opt.sh
|
||||||
|
RUN chmod +x /usr/bin/update_opt.sh
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
dirmngr \
|
||||||
|
g++ \
|
||||||
|
git \
|
||||||
|
gnupg \
|
||||||
|
libsqlite3-dev \
|
||||||
|
libtinfo-dev \
|
||||||
|
libgmp-dev \
|
||||||
|
make \
|
||||||
|
netbase \
|
||||||
|
openssh-client \
|
||||||
|
xz-utils \
|
||||||
|
zlib1g-dev \
|
||||||
|
libnuma-dev libgmp10 libssl-dev liblzma-dev libbz2-dev wget lsb-release software-properties-common apt-transport-https gcc autoconf automake build-essential gzip patchelf tree \
|
||||||
|
llvm-9 clang-9 && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN update_opt.sh 9 1
|
||||||
|
|
||||||
|
ARG GHCUP_VERSION=0.1.18.0
|
||||||
|
ARG GPG_KEY=7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
|
||||||
|
# install ghcup
|
||||||
|
RUN gpg --batch --keyserver keys.openpgp.org --recv-keys $GPG_KEY && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/aarch64-linux-ghcup-$GHCUP_VERSION && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS && \
|
||||||
|
curl -sSfL -O https://downloads.haskell.org/~ghcup/$GHCUP_VERSION/SHA256SUMS.sig && \
|
||||||
|
gpg --verify SHA256SUMS.sig SHA256SUMS && \
|
||||||
|
sha256sum -c --ignore-missing SHA256SUMS && \
|
||||||
|
mv aarch64-linux-ghcup-$GHCUP_VERSION /usr/bin/ghcup && \
|
||||||
|
chmod +x /usr/bin/ghcup && \
|
||||||
|
rm -rf SHA256SUMS SHA256SUMS.sig
|
||||||
|
|
||||||
|
ARG GHC=8.10.7
|
||||||
|
ARG CABAL_INSTALL=3.6.2.0
|
||||||
|
ARG STACK=2.9.1
|
||||||
|
|
||||||
|
ENV GHCUP_CURL_OPTS="--silent"
|
||||||
|
ENV NO_COLOR=1
|
||||||
|
|
||||||
|
# install haskell toolchain
|
||||||
|
RUN ghcup config set gpg-setting GPGStrict && \
|
||||||
|
ghcup --verbose install ghc --isolate=/usr --force ${GHC} && \
|
||||||
|
ghcup --verbose install cabal --isolate=/usr/bin --force ${CABAL_INSTALL} && \
|
||||||
|
ghcup gc -s -c -t
|
||||||
|
|
||||||
|
ENV PATH /root/.cabal/bin:/root/.ghcup/bin:/root/.local/bin:$PATH
|
||||||
|
|
||||||
|
CMD ["ghci"]
|
||||||
36
docker/arm64v8/focal/update_opt.sh
Executable file
36
docker/arm64v8/focal/update_opt.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# update_alternatives.sh
|
||||||
|
|
||||||
|
update_alternatives() {
|
||||||
|
local version=${1}
|
||||||
|
local priority=${2}
|
||||||
|
local master=${3}
|
||||||
|
local slaves=${4}
|
||||||
|
local path=${5}
|
||||||
|
local cmdln
|
||||||
|
|
||||||
|
cmdln="--verbose --install ${path}${master} ${master} ${path}${master}-${version} ${priority}"
|
||||||
|
for slave in ${slaves}; do
|
||||||
|
cmdln="${cmdln} --slave ${path}${slave} ${slave} ${path}${slave}-${version}"
|
||||||
|
done
|
||||||
|
update-alternatives ${cmdln}
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ${#} -ne 2 ]]; then
|
||||||
|
echo usage: "${0}" clang_version priority
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
version=${1}
|
||||||
|
priority=${2}
|
||||||
|
path="/usr/bin/"
|
||||||
|
|
||||||
|
master="llvm-config"
|
||||||
|
slaves="llvm-addr2line llvm-ar llvm-as llvm-bcanalyzer llvm-bitcode-strip llvm-cat llvm-cfi-verify llvm-cov llvm-c-test llvm-cvtres llvm-cxxdump llvm-cxxfilt llvm-cxxmap llvm-debuginfod llvm-debuginfod-find llvm-diff llvm-dis llvm-dlltool llvm-dwarfdump llvm-dwarfutil llvm-dwp llvm-exegesis llvm-extract llvm-gsymutil llvm-ifs llvm-install-name-tool llvm-jitlink llvm-jitlink-executor llvm-lib llvm-libtool-darwin llvm-link llvm-lipo llvm-lto llvm-lto2 llvm-mc llvm-mca llvm-ml llvm-modextract llvm-mt llvm-nm llvm-objcopy llvm-objdump llvm-omp-device-info llvm-opt-report llvm-otool llvm-pdbutil llvm-PerfectShuffle llvm-profdata llvm-profgen llvm-ranlib llvm-rc llvm-readelf llvm-readobj llvm-reduce llvm-remark-size-diff llvm-rtdyld llvm-sim llvm-size llvm-split llvm-stress llvm-strings llvm-strip llvm-symbolizer llvm-tapi-diff llvm-tblgen llvm-tli-checker llvm-undname llvm-windres llvm-xray"
|
||||||
|
|
||||||
|
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||||
|
|
||||||
|
master="clang"
|
||||||
|
slaves="analyze-build asan_symbolize bugpoint c-index-test clang++ clang-apply-replacements clang-change-namespace clang-check clang-cl clang-cpp clangd clang-doc clang-extdef-mapping clang-format clang-format-diff clang-include-fixer clang-linker-wrapper clang-move clang-nvlink-wrapper clang-offload-bundler clang-offload-packager clang-offload-wrapper clang-pseudo clang-query clang-refactor clang-rename clang-reorder-fields clang-repl clang-scan-deps clang-tidy count diagtool dsymutil FileCheck find-all-symbols git-clang-format hmaptool hwasan_symbolize intercept-build ld64.lld ld.lld llc lld lldb lldb-argdumper lldb-instr lldb-server lldb-vscode lld-link lli lli-child-target modularize not obj2yaml opt pp-trace run-clang-tidy sancov sanstats scan-build scan-build-py scan-view split-file UnicodeNameMappingGenerator verify-uselistorder wasm-ld yaml2obj yaml-bench"
|
||||||
|
|
||||||
|
update_alternatives "${version}" "${priority}" "${master}" "${slaves}" "${path}"
|
||||||
@@ -42,8 +42,8 @@ All you wanted to know about GHCup.
|
|||||||
|
|
||||||
## How to help
|
## How to help
|
||||||
|
|
||||||
* if you want to contribute code or documentation, check out the [issue tracker](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues) and the [Development guide](./dev.md)
|
* if you want to contribute code or documentation, check out the [issue tracker](https://github.com/haskell/ghcup-hs/issues) and the [Development guide](./dev.md)
|
||||||
* if you want to propose features or write user feedback, feel free to [open a ticket](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/new?issue)
|
* if you want to propose features or write user feedback, feel free to [open a ticket](https://github.com/haskell/ghcup-hs/issues/new)
|
||||||
* if you want to donate to the project, visit our [opencollective](https://opencollective.com/ghcup#category-CONTRIBUTE) page
|
* if you want to donate to the project, visit our [opencollective](https://opencollective.com/ghcup#category-CONTRIBUTE) page
|
||||||
|
|
||||||
## Design goals
|
## Design goals
|
||||||
@@ -60,6 +60,29 @@ All you wanted to know about GHCup.
|
|||||||
3. handling cabal projects
|
3. handling cabal projects
|
||||||
4. being a stack alternative
|
4. being a stack alternative
|
||||||
|
|
||||||
|
## Distribution policies
|
||||||
|
|
||||||
|
Like most Linux distros and other distribution channels, GHCup also
|
||||||
|
follows certain policies. These are as follows:
|
||||||
|
|
||||||
|
1. The end-user experience is our primary concern
|
||||||
|
- ghcup in CI systems as a use case is a first class citizen
|
||||||
|
2. We strive to collaborate with all maintainers of all the tools we support and maintain a good relationship
|
||||||
|
3. We may fix build system or other distribution bugs in upstream bindists
|
||||||
|
- these are always communicated upstream
|
||||||
|
4. We may even patch source code of supported tools in very rare cases if that is required to ensure that the end-user experience does not break
|
||||||
|
- we'll first try to upstream any such required patch and request a new release to avoid downstream patching
|
||||||
|
- patches will be communicated to the maintainers either way and we'll strive to get their review
|
||||||
|
- they will also be communicated to the end-user
|
||||||
|
- they will be uploaded along with the bindist
|
||||||
|
- we will avoid maintaining long-running downstream patches (currently zero)
|
||||||
|
5. We may add bindists for platforms that upstream does not support
|
||||||
|
- this is currently the case for GHC for e.g. Alpine and possibly FreeBSD in the future
|
||||||
|
- this is currently also the case for stack on darwin M1
|
||||||
|
- we don't guarantee for unofficial bindists that the test suite passes at the moment (this may change in the future)
|
||||||
|
6. We GPG sign all the GHCup metadata as well as the unofficial bindists
|
||||||
|
- any trust issues relating to missing checksums or GPG signatures is a bug and given high priority
|
||||||
|
|
||||||
## How
|
## How
|
||||||
|
|
||||||
Installs a specified GHC version into `~/.ghcup/ghc/<ver>`, and places `ghc-<ver>` symlinks in `~/.ghcup/bin/`.
|
Installs a specified GHC version into `~/.ghcup/ghc/<ver>`, and places `ghc-<ver>` symlinks in `~/.ghcup/bin/`.
|
||||||
@@ -74,13 +97,16 @@ cabal-install/HLS/stack are installed in `~/.ghcup/bin/<tool>-<ver>` and have un
|
|||||||
|
|
||||||
## Known users
|
## Known users
|
||||||
|
|
||||||
* Github actions:
|
* CI:
|
||||||
- [actions/virtual-environments](https://github.com/actions/virtual-environments)
|
- [Github actions/virtual-environments](https://github.com/actions/virtual-environments)
|
||||||
- [haskell/actions/setup](https://github.com/haskell/actions/tree/main/setup)
|
- [Github haskell/actions/setup](https://github.com/haskell/actions/tree/main/setup)
|
||||||
|
- [haskell-ci](https://github.com/haskell-CI/haskell-ci)
|
||||||
* mirrors:
|
* mirrors:
|
||||||
- [sjtug](https://mirror.sjtu.edu.cn/docs/ghcup)
|
- [sjtug](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||||
* tools:
|
* tools:
|
||||||
- [vabal](https://github.com/Franciman/vabal)
|
- [vscode-haskell](https://github.com/haskell/vscode-haskell)
|
||||||
|
- [nvim-lsp-installer](https://github.com/williamboman/nvim-lsp-installer)
|
||||||
|
- [vabal](https://github.com/Franciman/vabal)
|
||||||
|
|
||||||
## Known problems
|
## Known problems
|
||||||
|
|
||||||
@@ -152,6 +178,11 @@ Windows 7 and Powershell 2.0 aren't well supported at the moment, also see:
|
|||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
### Is ghcup really the main installer?
|
||||||
|
|
||||||
|
This is based on the Haskell survey results from 2022, which show that more
|
||||||
|
than half of survey participants use GHCup: https://taylor.fausak.me/2022/11/18/haskell-survey-results/
|
||||||
|
|
||||||
### Why reimplement stack?
|
### Why reimplement stack?
|
||||||
|
|
||||||
GHCup is not a reimplementation of stack. The only common part is automatic installation of GHC,
|
GHCup is not a reimplementation of stack. The only common part is automatic installation of GHC,
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
:root {
|
:root {
|
||||||
--theme-purple: #5E5184;
|
--theme-purple: #5E5184;
|
||||||
|
--theme-purple-dark: rgba(69, 59, 97, 0.5);
|
||||||
|
--ukraine-top: #0057B8;
|
||||||
|
--ukraine-bottom: #FFD700;
|
||||||
--link-pink: #9E358F;
|
--link-pink: #9E358F;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,12 +111,12 @@ body.homepage>div.container div.col-md-9 {
|
|||||||
|
|
||||||
.bg-primary {
|
.bg-primary {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
background-color: var(--theme-purple) !important;
|
background-color: var(--ukraine-top) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body .bg-primary {
|
body .bg-primary {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
background-color: var(--theme-purple);
|
background-color: var(--ukraine-top);
|
||||||
border: 0px;
|
border: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +128,8 @@ body .btn-primary {
|
|||||||
|
|
||||||
.navbar.fixed-top {
|
.navbar.fixed-top {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
background-color: var(--theme-purple);
|
background-color: var(--ukraine-top);
|
||||||
border-bottom: 5px solid rgba(69, 59, 97, 0.5);
|
border-bottom: 40px solid var(--ukraine-bottom);
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
38
docs/dev.md
38
docs/dev.md
@@ -12,8 +12,7 @@ organised tree-ish in `GHCup.Utils` and `GHCup.Utils.*`.
|
|||||||
Anything dealing with ghcup specific directories is in
|
Anything dealing with ghcup specific directories is in
|
||||||
`GHCup.Utils.Dirs`.
|
`GHCup.Utils.Dirs`.
|
||||||
|
|
||||||
Download information on where to fetch bindists from is in the appropriate
|
Download information on where to fetch bindists from is in the [ghcup-metadata](https://github.com/haskell/ghcup-metadata) repository.
|
||||||
yaml files: `data/metadata/ghcup-<yaml-ver>.yaml`.
|
|
||||||
|
|
||||||
## Design decisions
|
## Design decisions
|
||||||
|
|
||||||
@@ -66,17 +65,13 @@ Some light suggestions:
|
|||||||
|
|
||||||
### Adding a new GHC version
|
### Adding a new GHC version
|
||||||
|
|
||||||
1. open the latest `data/metadata/ghcup-<yaml-ver>.yaml`
|
Head over to: [https://github.com/haskell/ghcup-metadata#adding-a-new-ghc-version](https://github.com/haskell/ghcup-metadata#adding-a-new-ghc-version)
|
||||||
2. find the latest ghc version (in yaml tree e.g. `ghcupDownloads -> GHC -> 8.10.7`)
|
|
||||||
3. copy-paste it
|
|
||||||
4. adjust the version, tags, changelog, source url
|
|
||||||
5. adjust the various bindist urls (make sure to also change the yaml anchors)
|
|
||||||
6. run `cabal run exe:ghcup-gen -- check -f data/metadata/ghcup-<yaml-ver>.yaml`
|
|
||||||
7. run `cabal run exe:ghcup-gen -- check-tarballs -f data/metadata/ghcup-<yaml-ver>.yaml -u 'ghc-8\.10\.8'`
|
|
||||||
|
|
||||||
### Adding a new CLI command
|
### Adding a new CLI command
|
||||||
|
|
||||||
An example illustration on how to deal with [optparse-applicative](https://hackage.haskell.org/package/optparse-applicative) can be seen here: [https://gitlab.haskell.org/haskell/ghcup-hs/-/commit/c19dd5ee8b2edbaf0336af143f1c75b6f4843e26](https://gitlab.haskell.org/haskell/ghcup-hs/-/commit/c19dd5ee8b2edbaf0336af143f1c75b6f4843e26)
|
An example illustration on how to deal with [optparse-applicative](https://hackage.haskell.org/package/optparse-applicative) can be seen here: [https://github.com/haskell/ghcup-hs/commit/c19dd5ee8b2edbaf0336af143f1c75b6f4843e26](https://github.com/haskell/ghcup-hs/commit/c19dd5ee8b2edbaf0336af143f1c75b6f4843e26)
|
||||||
|
|
||||||
|
Every subcommand now lives in its own module under [GHCup.OptParse.MyCommand](https://github.com/haskell/ghcup-hs/tree/master/app/ghcup/GHCup/OptParse).
|
||||||
|
|
||||||
## Major refactors
|
## Major refactors
|
||||||
|
|
||||||
@@ -89,30 +84,37 @@ An example illustration on how to deal with [optparse-applicative](https://hacka
|
|||||||
The major changes here were switching `hpath` library out for `filepath`/`directory` (sadly) and
|
The major changes here were switching `hpath` library out for `filepath`/`directory` (sadly) and
|
||||||
introducing a non-unix way of handling processes via the `process` library. It also introduced considerable
|
introducing a non-unix way of handling processes via the `process` library. It also introduced considerable
|
||||||
amounts of CPP wrt file handling, installation etc.
|
amounts of CPP wrt file handling, installation etc.
|
||||||
|
3. This refactor split up the huge `Main.hs` and put every subcommand in its own module: [#212](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/212)
|
||||||
|
|
||||||
# Releasing
|
# Releasing
|
||||||
|
|
||||||
1. Update version in `ghcup.cabal` and `boostrap-haskell` (`ghver` variable at the top of the script)
|
1. Update version in `ghcup.cabal`
|
||||||
|
|
||||||
2. Update `GHCup.Version` module. `ghcupURL` must only be updated if we change the `GHCupInfo` type or the YAML representation of it. The version of the YAML represents the change increments. `ghcUpVer` is the current application version, read from `ghcup.cabal`.
|
2. Update `GHCup.Version` module. `ghcupURL` must only be updated if we change the `GHCupInfo` type or the YAML representation of it. The version of the YAML represents the change increments. `ghcUpVer` is the current application version, read from `ghcup.cabal`.
|
||||||
|
|
||||||
3. Add ChangeLog entry
|
3. Add ChangeLog entry
|
||||||
|
|
||||||
4. Add/fix downloads in `ghcup-<ver>.yaml` (under `data/metadata`), then verify with `ghcup-gen check -f data/metadata/ghcup-<ver>.yaml` and possibly (example only) `ghcup-gen check-tarballs -f data/metadata/ghcup-<ver>.yaml -u 'ghc-8.10.7'`. Generally, new GHC/cabal/stack/hls versions are only added to the latest yaml file. New GHCup versions are added to all (great care must be taken here to not break the parser... e.g. ARM platforms don't parse in all older formats).
|
4. If a new ghcup yaml version is needed, create one at [ghcup-metadata repo](https://github.com/haskell/ghcup-metadata) and push to a temporary release branch, then update the `data/metadata` submodule in ghcup-hs repo to that branch, so CI can pass
|
||||||
|
|
||||||
5. Commit and git push with tag. Wait for tests to succeed and release artifacts to build.
|
5. Commit and git push with tag. Wait for tests to succeed and release artifacts to build.
|
||||||
|
|
||||||
6. Download release artifacts and upload them `downloads.haskell.org/~ghcup` along with checksum files (`sha256sum --tag * > SHA256SUMS && gpg --detach-sign -u <your-email> SHA256SUMS`)
|
6. Download release artifacts and upload them `downloads.haskell.org/~ghcup` along with checksum files (also check `scripts/releasing/pull_release_artifacts.sh` and `scripts/releasing/sftp-upload-artifacts.sh`)
|
||||||
|
|
||||||
7. Add ghcup release artifacts to ALL yaml files (see point 4.)
|
7. Add ghcup release artifacts to ALL yaml files, see [ghcup-metadata repo](https://github.com/haskell/ghcup-metadata)
|
||||||
|
|
||||||
8. Upload the final `data/metadata/ghcup-<ver>.yaml` (and a detached GPG sig of it) to `webhost.haskell.org/ghcup/data/`.
|
8. Upload the final `ghcup-<ver>.yaml` (and a detached GPG sig of it) to `webhost.haskell.org/ghcup/data/` (for yaml versions <= 0.0.6) as well as [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata) (for all versions).
|
||||||
|
|
||||||
9. Update `bootstrap-haskell` and `bootstrap-haskell.ps1` to `webhost.haskell.org/ghcup/sh/`
|
9. Update version in `scripts/bootstrap/bootstrap-haskell` (`ghver` variable at the top of the script)
|
||||||
|
|
||||||
10. Update the top-level ghcup symlinks at `downloads.haskell.org/~ghcup`
|
10. Upload `scripts/bootstrap/bootstrap-haskell` and `scripts/bootstrap/bootstrap-haskell.ps1` to `webhost.haskell.org/ghcup/sh/`
|
||||||
|
|
||||||
11. Post on reddit/discourse/etc. and collect rewards
|
11. Update the top-level ghcup symlinks at `downloads.haskell.org/~ghcup` (see `scripts/releasing/sftp-symlink-artifacts.sh`)
|
||||||
|
|
||||||
|
12. Update the `data/metadata` submodule in ghcup-hs repo to master
|
||||||
|
|
||||||
|
13. Do hackage release
|
||||||
|
|
||||||
|
14. Post on reddit/discourse/etc. and collect rewards
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
|
|||||||
519
docs/guide.md
519
docs/guide.md
@@ -1,10 +1,10 @@
|
|||||||
# User Guide
|
# User Guide
|
||||||
|
|
||||||
`ghcup --help` is your friend.
|
This is a more in-depth guide specific to GHCup. `ghcup --help` is your friend.
|
||||||
|
|
||||||
## Basic usage
|
## Basic usage
|
||||||
|
|
||||||
For the simple interactive TUI (not available on windows), run:
|
For the simple, interactive, text-based user interface (TUI) (not available on windows), run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ghcup tui
|
ghcup tui
|
||||||
@@ -32,12 +32,16 @@ ghcup install cabal
|
|||||||
ghcup upgrade
|
ghcup upgrade
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
### Tags and shortcuts
|
||||||
|
|
||||||
A configuration file can be put in `~/.ghcup/config.yaml`. The default config file
|
GHCup has a number of tags and version shortcuts, that can be used as arguments to **install**/**set** etc.
|
||||||
explaining all possible configurations can be found in this repo: [config.yaml](https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/data/config.yaml).
|
All of the following are valid arguments to `ghcup install ghc`:
|
||||||
|
|
||||||
Partial configuration is fine. Command line options always override the config file settings.
|
* `latest`, `recommended`
|
||||||
|
* `base-4.15.1.0`
|
||||||
|
* `9.0.2`, `9.0`, `9`
|
||||||
|
|
||||||
|
If the argument is omitted, the default is `recommended`.
|
||||||
|
|
||||||
## Manpages
|
## Manpages
|
||||||
|
|
||||||
@@ -46,37 +50,58 @@ For man pages to work you need [man-db](http://man-db.nongnu.org/) as your `man`
|
|||||||
|
|
||||||
## Shell-completion
|
## Shell-completion
|
||||||
|
|
||||||
Shell completions are in [scripts/shell-completions](https://gitlab.haskell.org/haskell/ghcup-hs/-/tree/master/scripts/shell-completions) directory of this repository.
|
Shell completions are in [scripts/shell-completions](https://github.com/haskell/ghcup-hs/tree/master/scripts/shell-completions) directory of this repository.
|
||||||
|
|
||||||
For bash: install `shell-completions/bash`
|
For bash: install `shell-completions/bash`
|
||||||
as e.g. `/etc/bash_completion.d/ghcup` (depending on distro)
|
as e.g. `/etc/bash_completion.d/ghcup` (depending on distro)
|
||||||
and make sure your bashrc sources the startup script
|
and make sure your bashrc sources the startup script
|
||||||
(`/usr/share/bash-completion/bash_completion` on some distros).
|
(`/usr/share/bash-completion/bash_completion` on some distros).
|
||||||
|
|
||||||
## Compiling GHC from source
|
## Portability
|
||||||
|
|
||||||
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
|
`ghcup` is very portable. There are a few exceptions though:
|
||||||
for a list of all available options.
|
|
||||||
|
|
||||||
If you need to overwrite the existing `build.mk`, check the default files
|
1. `ghcup tui` is only available on non-windows platforms
|
||||||
in [data/build_mk](https://gitlab.haskell.org/haskell/ghcup-hs/-/tree/master/data/build_mk), copy them somewhere, adjust them and
|
2. legacy subcommands `ghcup install` (without a tool identifier) and `ghcup install-cabal` may be removed in the future
|
||||||
pass `--config path/to/build.mk` to `ghcup compile ghc`.
|
|
||||||
Common `build.mk` options are explained [here](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/using#build-configuration).
|
|
||||||
|
|
||||||
Make sure your system meets all the [prerequisites](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/preparation).
|
# Configuration
|
||||||
|
|
||||||
### Cross support
|
A configuration file can be put in `~/.ghcup/config.yaml`. The default config file
|
||||||
|
explaining all possible configurations can be found in this repo: [config.yaml](https://github.com/haskell/ghcup-hs/blob/master/data/config.yaml).
|
||||||
|
|
||||||
ghcup can compile and install a cross GHC for any target. However, this
|
Partial configuration is fine. Command line options always override the config file settings.
|
||||||
requires that the build host has a complete cross toolchain and various
|
|
||||||
libraries installed for the target platform.
|
|
||||||
|
|
||||||
Consult the GHC documentation on the [prerequisites](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/cross-compiling#tools-to-install).
|
## Overriding distro detection
|
||||||
For distributions with non-standard locations of cross toolchain and
|
|
||||||
libraries, this may need some tweaking of `build.mk` or configure args.
|
|
||||||
See `ghcup compile ghc --help` for further information.
|
|
||||||
|
|
||||||
## XDG support
|
If you're running e.g. an Ubuntu derivate based on 18.04 and ghcup is picking bindists that
|
||||||
|
don't work well, you could do this in `config.yaml`:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
platform-override:
|
||||||
|
arch: A_64
|
||||||
|
platform:
|
||||||
|
contents: Ubuntu
|
||||||
|
tag: Linux
|
||||||
|
version: '18.04'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Env variables
|
||||||
|
|
||||||
|
This is the complete list of env variables that change GHCup behavior:
|
||||||
|
|
||||||
|
* `GHCUP_USE_XDG_DIRS`: see [XDG support](#xdg-support) above
|
||||||
|
* `GHCUP_INSTALL_BASE_PREFIX`: the base of ghcup (default: `$HOME`)
|
||||||
|
* `GHCUP_CURL_OPTS`: additional options that can be passed to curl
|
||||||
|
* `GHCUP_WGET_OPTS`: additional options that can be passed to wget
|
||||||
|
* `GHCUP_GPG_OPTS`: additional options that can be passed to gpg
|
||||||
|
* `GHCUP_SKIP_UPDATE_CHECK`: Skip the (possibly annoying) update check when you run a command
|
||||||
|
* `CC`/`LD` etc.: full environment is passed to the build system when compiling GHC via GHCup
|
||||||
|
|
||||||
|
On windows, there's additionally:
|
||||||
|
|
||||||
|
* `GHCUP_MSYS2`: Has to point to the root of an existing MSYS2 installation (when installed by GHCup, that's e.g. `C:\ghcup\msys64`). GHCup bootstrap takes care of this usually.
|
||||||
|
|
||||||
|
### XDG support
|
||||||
|
|
||||||
To enable XDG style directories, set the environment variable `GHCUP_USE_XDG_DIRS` to anything.
|
To enable XDG style directories, set the environment variable `GHCUP_USE_XDG_DIRS` to anything.
|
||||||
|
|
||||||
@@ -90,18 +115,184 @@ Then you can control the locations via XDG environment variables as such:
|
|||||||
**Note that `ghcup` makes some assumptions about structure of files in `XDG_BIN_HOME`. So if you have other tools
|
**Note that `ghcup` makes some assumptions about structure of files in `XDG_BIN_HOME`. So if you have other tools
|
||||||
installing e.g. stack/cabal/ghc into it, this will likely clash. In that case consider disabling XDG support.**
|
installing e.g. stack/cabal/ghc into it, this will likely clash. In that case consider disabling XDG support.**
|
||||||
|
|
||||||
## Env variables
|
## Caching
|
||||||
|
|
||||||
This is the complete list of env variables that change GHCup behavior:
|
GHCup has a few caching mechanisms to avoid redownloads. All cached files end up in `~/.ghcup/cache` by default.
|
||||||
|
|
||||||
* `GHCUP_USE_XDG_DIRS`: see [XDG support](#xdg-support) above
|
### Downloads cache
|
||||||
* `TMPDIR`: where ghcup does the work (unpacking, building, ...)
|
|
||||||
* `GHCUP_INSTALL_BASE_PREFIX`: the base of ghcup (default: `$HOME`)
|
Downloaded tarballs (such as GHC, cabal, etc.) are not cached by default unless you pass `ghcup --cache` or set caching
|
||||||
* `GHCUP_CURL_OPTS`: additional options that can be passed to curl
|
in your [config](#configuration) via `ghcup config set cache true`.
|
||||||
* `GHCUP_WGET_OPTS`: additional options that can be passed to wget
|
|
||||||
* `GHCUP_GPG_OPTS`: additional options that can be passed to gpg
|
### Metadata cache
|
||||||
* `GHCUP_SKIP_UPDATE_CHECK`: Skip the (possibly annoying) update check when you run a command
|
|
||||||
* `CC`/`LD` etc.: full environment is passed to the build system when compiling GHC via GHCup
|
The metadata files (also see [github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata))
|
||||||
|
have a 5 minutes cache per default depending on the last access time of the file. That means if you run
|
||||||
|
`ghcup list` 10 times in a row, only the first time will trigger a download attempt.
|
||||||
|
|
||||||
|
### Clearing the cache
|
||||||
|
|
||||||
|
If you experience problems, consider clearing the cache via `ghcup gc --cache`.
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
The metadata are the files that describe tool versions, where to download them etc. and
|
||||||
|
can be viewed here: [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata)
|
||||||
|
|
||||||
|
### Mirrors
|
||||||
|
|
||||||
|
GHCup allows to use custom mirrors/download-info hosted by yourself or 3rd parties.
|
||||||
|
|
||||||
|
To use a mirror, set the following option in `~/.ghcup/config.yaml`:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
url-source:
|
||||||
|
# Accepts file/http/https scheme
|
||||||
|
OwnSource: "https://some-url/ghcup-0.0.6.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
See [config.yaml](https://github.com/haskell/ghcup-hs/blob/master/data/config.yaml)
|
||||||
|
for more options.
|
||||||
|
|
||||||
|
Alternatively you can do it via a cli switch:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup --url-source=https://some-url/ghcup-0.0.6.yaml list
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Known mirrors
|
||||||
|
|
||||||
|
1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||||
|
2. [https://mirrors.ustc.edu.cn/help/ghcup.html](https://mirrors.ustc.edu.cn/help/ghcup.html)
|
||||||
|
|
||||||
|
### (Pre-)Release channels
|
||||||
|
|
||||||
|
A release channel is basically just a metadata file location. You can add additional release
|
||||||
|
channels that complement the default one, such as the **prerelease channel** like so:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
This will result in `~/.ghcup/config.yaml` to contain this record:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
url-source:
|
||||||
|
AddSource:
|
||||||
|
- Right: https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
You can add as many channels as you like. They are combined under *Last*, so versions from the prerelease channel
|
||||||
|
here overwrite the default ones, if any.
|
||||||
|
|
||||||
|
To remove the channel, delete the entire `url-source` section or set it back to the default:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
url-source:
|
||||||
|
GHCupURL: []
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to combine your release channel with a mirror, you'd do it like so:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
url-source:
|
||||||
|
OwnSource:
|
||||||
|
# base metadata
|
||||||
|
- "https://mirror.sjtu.edu.cn/ghcup/yaml/ghcup/data/ghcup-0.0.6.yaml"
|
||||||
|
# prerelease channel
|
||||||
|
- "https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Stack integration
|
||||||
|
|
||||||
|
Stack manages GHC versions internally by default. In order to make it use ghcup installed
|
||||||
|
GHC versions there are two strategies.
|
||||||
|
|
||||||
|
### Strategy 1: System GHC (works on all stack versions)
|
||||||
|
|
||||||
|
You can instruct stack to use "system" GHC versions (whatever is in PATH). To do so,
|
||||||
|
run the following commands:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
stack config set install-ghc false --global
|
||||||
|
stack config set system-ghc true --global
|
||||||
|
```
|
||||||
|
|
||||||
|
### Strategy 2: Stack hooks (new, recommended)
|
||||||
|
|
||||||
|
Since stack 2.9.1 you can customize the installation logic of GHC completely, see [https://docs.haskellstack.org/en/stable/yaml_configuration/#ghc-installation-customisation](https://docs.haskellstack.org/en/stable/yaml_configuration/#ghc-installation-customisation).
|
||||||
|
|
||||||
|
We can use this to simply invoke ghcup whenever stack is trying to install/discover a GHC versions. This
|
||||||
|
is done via placing a shell script at `~/.stack/hooks/ghc-install.sh` and making it executable.
|
||||||
|
|
||||||
|
The ghcup bootstrap script asks you during installation whether you want to install this shell script. You can also
|
||||||
|
install/update it manually like so:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir -p ~/.stack/hooks/
|
||||||
|
curl https://raw.githubusercontent.com/haskell/ghcup-hs/master/scripts/hooks/stack/ghc-install.sh \
|
||||||
|
> ~/.stack/hooks/ghc-install.sh
|
||||||
|
chmod +x ~/.stack/hooks/ghc-install.sh
|
||||||
|
# hooks are only run when 'system-ghc: false'
|
||||||
|
stack config set system-ghc false --global
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, when the hook fails for whatever reason, stack will fall back to its own installation logic. To disable
|
||||||
|
this, run `stack config set install-ghc false --global`.
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
On windows, you may find the following config options useful too:
|
||||||
|
`skip-msys`, `extra-path`, `extra-include-dirs`, `extra-lib-dirs`.
|
||||||
|
|
||||||
|
Also check out: [https://docs.haskellstack.org/en/stable/yaml_configuration](https://docs.haskellstack.org/en/stable/yaml_configuration)
|
||||||
|
|
||||||
|
# More on installation
|
||||||
|
|
||||||
|
## Customisation of the installation scripts
|
||||||
|
|
||||||
|
The scripts offered to install GHCup are available here:
|
||||||
|
|
||||||
|
* [bootstrap-haskell](https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell#L7)
|
||||||
|
for Unix-like operating systems
|
||||||
|
* [bootstrap-haskell.ps1](https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell.ps1)
|
||||||
|
for Windows (PowerShell). This will, in turn, run the final bootstrap script
|
||||||
|
(by default, that for the Unix-like operating systems).
|
||||||
|
|
||||||
|
The effect of the scripts can be customised by setting one or more
|
||||||
|
`BOOTSTRAP_HASKELL_*` environment variables (as set out in the first script)
|
||||||
|
and, in the case of Windows, by specifying parameters (as set out in the
|
||||||
|
PowerShell script).
|
||||||
|
|
||||||
|
For example, you can toggle:
|
||||||
|
|
||||||
|
* non-interactive installation
|
||||||
|
* a more verbose installation
|
||||||
|
* whether to install only GHCup (and, on Windows, MSYS2)
|
||||||
|
* not to trigger the upgrade of GHCup
|
||||||
|
* whether to install the latest version of HLS
|
||||||
|
* whether to install the latest version of Stack
|
||||||
|
* whether to respect the XDG Base Directory Specification
|
||||||
|
* whether to adjust (prepend) the PATH in `bashrc`
|
||||||
|
* on Windows, whether to adjust MINGW paths in `cabal.config`
|
||||||
|
|
||||||
|
You can also specify:
|
||||||
|
|
||||||
|
* the GHC version to install
|
||||||
|
* the Cabal version to install
|
||||||
|
* which downloader to use (the default is `curl`)
|
||||||
|
* the base URL for the download of the GHCup binary distribution
|
||||||
|
|
||||||
|
On Windows, you can also use the parameters to:
|
||||||
|
|
||||||
|
* toggle whether to overwrite a previous installation
|
||||||
|
* specify the GHCup installation root directory
|
||||||
|
* specify the Cabal root directory
|
||||||
|
* specify the directory of an existing installation of MSYS2 (for example,
|
||||||
|
the one supplied by Stack)
|
||||||
|
* specify the URL of the final bootstrap script
|
||||||
|
* toggle whether to run the final bootstrap script via `bash` (instead of in a
|
||||||
|
new MSYS2 shell)
|
||||||
|
|
||||||
## Installing custom bindists
|
## Installing custom bindists
|
||||||
|
|
||||||
@@ -110,7 +301,8 @@ There are a couple of good use cases to install custom bindists:
|
|||||||
1. manually built bindists (e.g. with patches)
|
1. manually built bindists (e.g. with patches)
|
||||||
- example: `ghcup install ghc -u 'file:///home/mearwald/tmp/ghc-eff-patches/ghc-8.10.2-x86_64-deb10-linux.tar.xz' 8.10.2-eff`
|
- example: `ghcup install ghc -u 'file:///home/mearwald/tmp/ghc-eff-patches/ghc-8.10.2-x86_64-deb10-linux.tar.xz' 8.10.2-eff`
|
||||||
2. GHC head CI bindists
|
2. GHC head CI bindists
|
||||||
- example: `ghcup install ghc -u 'https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27' head`
|
- example specifying a branch (`master`): `ghcup install ghc -u 'https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-fedora33-release.tar.xz?job=x86_64-linux-fedora33-release' head`
|
||||||
|
- example specifying a job id (`1129565`): `ghcup install ghc -u ' https://gitlab.haskell.org/api/v4/projects/1/jobs/1129565/artifacts/ghc-x86_64-linux-alpine3_12-validate+fully_static.tar.xz' mr7847`
|
||||||
3. DWARF bindists
|
3. DWARF bindists
|
||||||
- example: `ghcup install ghc -u 'https://downloads.haskell.org/~ghc/8.10.2/ghc-8.10.2-x86_64-deb10-linux-dwarf.tar.xz' 8.10.2-dwarf`
|
- example: `ghcup install ghc -u 'https://downloads.haskell.org/~ghc/8.10.2/ghc-8.10.2-x86_64-deb10-linux-dwarf.tar.xz' 8.10.2-dwarf`
|
||||||
|
|
||||||
@@ -119,8 +311,93 @@ and produce the binaries `ghc-8.10.2-eff` and `ghc-head` respectively.
|
|||||||
GHCup always needs to know which version the bindist corresponds to (this is not automatically
|
GHCup always needs to know which version the bindist corresponds to (this is not automatically
|
||||||
detected).
|
detected).
|
||||||
|
|
||||||
|
## Compiling from source
|
||||||
|
|
||||||
|
### GHC
|
||||||
|
|
||||||
|
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
|
||||||
|
for a list of all available options.
|
||||||
|
|
||||||
|
If you need to overwrite the existing `build.mk`, check the default files
|
||||||
|
in [data/build_mk](https://github.com/haskell/ghcup-hs/tree/master/data/build_mk), copy them somewhere, adjust them and
|
||||||
|
pass `--config path/to/build.mk` to `ghcup compile ghc`.
|
||||||
|
Common `build.mk` options are explained [here](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/using#build-configuration).
|
||||||
|
|
||||||
|
Make sure your system meets all the [prerequisites](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/preparation).
|
||||||
|
|
||||||
|
### HLS
|
||||||
|
|
||||||
|
There are 3 main ways to compile HLS from source.
|
||||||
|
|
||||||
|
1. from hackage (should have up to date version bounds)
|
||||||
|
- `ghcup compile hls --version 1.7.0.0 --ghc 9.2.3`
|
||||||
|
2. from git (allows to build latest sources and PRs)
|
||||||
|
- `ghcup compile hls --git-ref master --ghc 9.2.3`
|
||||||
|
- `ghcup compile hls --git-ref a32db0b --ghc 9.2.3`
|
||||||
|
- `ghcup compile hls --git-ref 1.7.0.0 --ghc 9.2.3`
|
||||||
|
3. from source distribution that's packaged during release from the corresponding git sources
|
||||||
|
- `ghcup compile hls --source-dist 1.7.0.0 --ghc 9.2.3`
|
||||||
|
|
||||||
|
All these use `cabal v2-install` under the hood, so all build components are cached.
|
||||||
|
You can pass arbitrary arguments to cabal, e.g. set the index state like so:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup compile hls --git-ref master --ghc 9.2.3 -- --index-state=2022-06-12T00:00:00Z --allow-newer
|
||||||
|
```
|
||||||
|
|
||||||
|
You can pass `--ghc <ver>` multiple times to install for many GHCs at once.
|
||||||
|
|
||||||
|
When building from git sources, ghcup will auto-detect the HLS version that the git commit corresponds to
|
||||||
|
from the `haskell-language-server.cabal` file. This version might not have been updated since the last release.
|
||||||
|
If you want to avoid overwriting the existing installed HLS version, you can instruct ghcup to use `git describe`
|
||||||
|
to set the HLS version instead:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup compile hls --git-ref master --ghc 9.2.3 --git-describe-version
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also set the version explicitly:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup compile hls --git-ref master --ghc 9.2.3 --overwrite-version 1.7.0.0-p1
|
||||||
|
```
|
||||||
|
|
||||||
|
To instruct cabal to run `cabal update` before building, run `ghcup compile hls --version 1.7.0.0 --ghc 9.2.3 --cabal-update`
|
||||||
|
|
||||||
|
As always, check `ghcup compile hls --help`.
|
||||||
|
|
||||||
|
#### Updating HLS for a new GHC version
|
||||||
|
|
||||||
|
First try to build from hackage with some tricks:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ghcup compile hls --version 1.7.0.0 --ghc 9.2.4 --cabal-update -- --allow-newer --index-state=2022-06-12T00:00:00Z
|
||||||
|
```
|
||||||
|
|
||||||
|
This augments the currently installed 1.7.0.0 official bindists in ghcup with new GHC versions support.
|
||||||
|
|
||||||
|
If that fails (since `--allow-newer` is quite brutal), you can install from HLS master branch (which may contain new fixes) like so:
|
||||||
|
```
|
||||||
|
ghcup compile hls --git-ref master --git-describe-version --ghc 8.10.7 --ghc 9.2.4 --cabal-update
|
||||||
|
```
|
||||||
|
|
||||||
|
This however will create a new HLS version in ghcup, e.g. `1.7.0.0-105-gdc682ba1`, for both 8.10.7 and 9.2.4. If you want to switch back to the official bindists, run `ghcup set hls 1.7.0.0`.
|
||||||
|
|
||||||
|
### Cross support
|
||||||
|
|
||||||
|
ghcup can compile and install a cross GHC for any target. However, this
|
||||||
|
requires that the build host has a complete cross toolchain and various
|
||||||
|
libraries installed for the target platform.
|
||||||
|
|
||||||
|
Consult the GHC documentation on the [prerequisites](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/cross-compiling#tools-to-install).
|
||||||
|
For distributions with non-standard locations of cross toolchain and
|
||||||
|
libraries, this may need some tweaking of `build.mk` or configure args.
|
||||||
|
See `ghcup compile ghc --help` for further information.
|
||||||
|
|
||||||
## Isolated installs
|
## Isolated installs
|
||||||
|
|
||||||
|
**Before using isolated installs, make sure to have at least GHCup version 0.1.17.8!**
|
||||||
|
|
||||||
Ghcup also enables you to install a tool (GHC, Cabal, HLS, Stack) at an isolated location of your choosing.
|
Ghcup also enables you to install a tool (GHC, Cabal, HLS, Stack) at an isolated location of your choosing.
|
||||||
These installs, as the name suggests, are separate from your main installs and DO NOT conflict with them.
|
These installs, as the name suggests, are separate from your main installs and DO NOT conflict with them.
|
||||||
|
|
||||||
@@ -133,112 +410,59 @@ You need to use the `--isolate` or `-i` flag followed by the directory path.
|
|||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
1. install an isolated GHC version at location /home/user/isolated_dir/ghc/
|
1. install an isolated GHC version at location /home/user/isolated_dir/ghc/
|
||||||
- `ghcup install ghc 8.10.5 --isolate /home/user/isolated_dir/ghc`
|
- `ghcup install ghc 8.10.5 --isolate /home/user/isolated_dir/ghc`
|
||||||
|
|
||||||
2. isolated install Cabal at a location you desire
|
2. isolated install Cabal at a location you desire
|
||||||
- `ghcup install cabal --isolate /home/username/my_isolated_dir/`
|
- `ghcup install cabal --isolate /home/username/my_isolated_dir/`
|
||||||
|
|
||||||
3. do an isolated install with a custom bindist
|
3. do an isolated install with a custom bindist
|
||||||
- `ghcup install ghc --isolate /home/username/my_isolated_dir/ -u 'https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27' head`
|
- `ghcup install ghc --isolate /home/username/my_isolated_dir/ -u 'https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-fedora33-release.tar.xz?job=x86_64-linux-fedora33-release' head`
|
||||||
|
|
||||||
4. isolated install HLS
|
4. isolated install HLS
|
||||||
- `ghcup install hls --isolate /home/username/dir/hls/`
|
- `ghcup install hls --isolate /home/username/dir/hls/`
|
||||||
|
|
||||||
5. you can even compile ghc to an isolated location.
|
5. you can even compile ghc to an isolated location.
|
||||||
- `ghcup compile ghc -j 4 -v 9.0.1 -b 8.10.5 -i /home/username/my/dir/ghc`
|
- `ghcup compile ghc -j 4 -v 9.0.1 -b 8.10.5 -i /home/username/my/dir/ghc`
|
||||||
|
|
||||||
## Continuous integration
|
## Continuous integration
|
||||||
|
|
||||||
On windows, ghcup can be installed automatically on a CI runner non-interactively like so:
|
On Windows, GHCup can be installed automatically on a CI runner
|
||||||
|
non-interactively, as below. The paramaters to the PowerShell script are
|
||||||
|
specified positionally, after `-ArgumentList`:
|
||||||
|
|
||||||
```ps
|
```ps
|
||||||
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $false,$true,$true,$false,$false,$false,$false,"C:\"
|
$ErrorActionPreference = 'Stop';Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;try { Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $false,$true,$true,$false,$false,$false,$false,"C:\" } catch { Write-Error $_ }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`$ErrorActionPreference = 'Stop'` here acts like `set -e` and stops execution if ghcup installation fails.
|
||||||
|
|
||||||
On linux/darwin/freebsd, run the following on your runner:
|
On linux/darwin/freebsd, run the following on your runner:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
|
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
|
||||||
```
|
```
|
||||||
|
|
||||||
This will just install `ghcup` and on windows additionally `msys2`.
|
This will just install `ghcup` and on Windows additionally MSYS2.
|
||||||
|
|
||||||
For the full list of env variables and parameters to tweak the script behavior, see:
|
See the installation scripts referred to above for the full list of environment
|
||||||
|
variables and, in the case of Windows, parameters to tweak the script behavior.
|
||||||
|
|
||||||
* [bootstrap-haskell for linux/darwin/freebsd](https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell#L7)
|
### github workflows
|
||||||
* [bootstrap-haskell.ps1 for windows](https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell.ps1#L17)
|
|
||||||
|
|
||||||
### Example github workflow
|
On github workflows you can use [https://github.com/haskell/actions/](https://github.com/haskell/actions/).
|
||||||
|
GHCup itself is also pre-installed on all platforms, but may use non-standard install locations.
|
||||||
On github workflows you can use [https://github.com/haskell/actions/](https://github.com/haskell/actions/)
|
|
||||||
|
|
||||||
If you want to install ghcup manually though, here's an example config:
|
|
||||||
|
|
||||||
```yml
|
|
||||||
name: Haskell CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-cabal:
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
|
||||||
ghc: ['8.10.7', '9.0.1']
|
|
||||||
cabal: ['3.4.0.0']
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- if: matrix.os == 'windows-latest'
|
|
||||||
name: Install ghcup on windows
|
|
||||||
run: Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $false,$true,$true,$false,$false,$false,$false,"C:\"
|
|
||||||
|
|
||||||
- if: matrix.os == 'windows-latest'
|
|
||||||
name: Add ghcup to PATH
|
|
||||||
run: echo "/c/ghcup/bin" >> $GITHUB_PATH
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- if: matrix.os != 'windows-latest'
|
|
||||||
name: Install ghcup on non-windows
|
|
||||||
run: curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
|
|
||||||
|
|
||||||
- name: Install ghc/cabal
|
|
||||||
run: |
|
|
||||||
ghcup install ghc ${{ matrix.ghc }}
|
|
||||||
ghcup install cabal ${{ matrix.cabal }}
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Update cabal index
|
|
||||||
run: cabal update
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cabal build --enable-tests --enable-benchmarks
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: cabal test
|
|
||||||
shell: bash
|
|
||||||
```
|
|
||||||
|
|
||||||
## GPG verification
|
## GPG verification
|
||||||
|
|
||||||
GHCup supports verifying the GPG signature of the metadata file. The metadata file then contains SHA256 hashes of all downloads, so
|
GHCup supports verifying the GPG signature of the metadata file. The metadata file then contains SHA256 hashes of all downloads, so
|
||||||
this is cryptographically secure.
|
this is cryptographically secure.
|
||||||
|
|
||||||
First, obtain the gpg key:
|
First, obtain the gpg keys:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
gpg --batch --keyserver keys.openpgp.org --recv-keys 7784930957807690A66EBDBE3786C5262ECB4A3F
|
gpg --batch --keyserver keys.openpgp.org --recv-keys 7784930957807690A66EBDBE3786C5262ECB4A3F
|
||||||
|
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01
|
||||||
```
|
```
|
||||||
|
|
||||||
Then verify the gpg key in one of these ways:
|
Then verify the gpg key in one of these ways:
|
||||||
@@ -257,51 +481,48 @@ gpg-setting: GPGLax # GPGStrict | GPGLax | GPGNone
|
|||||||
|
|
||||||
In `GPGStrict` mode, ghcup will fail if verification fails. In `GPGLax` mode it will just print a warning.
|
In `GPGStrict` mode, ghcup will fail if verification fails. In `GPGLax` mode it will just print a warning.
|
||||||
You can also pass the mode via `ghcup --gpg <strict|lax|none>`.
|
You can also pass the mode via `ghcup --gpg <strict|lax|none>`.
|
||||||
|
|
||||||
## Tips and tricks
|
|
||||||
|
|
||||||
### with_ghc wrapper (e.g. for HLS)
|
# Tips and tricks
|
||||||
|
|
||||||
Due to some HLS [bugs](https://github.com/mpickering/hie-bios/issues/194) it's necessary that the `ghc` in PATH
|
## ghcup run
|
||||||
is the one defined in `cabal.project`. With some simple shell functions, we can start our editor with the appropriate
|
|
||||||
path prepended.
|
|
||||||
|
|
||||||
For bash, in e.g. `~/.bashrc` define:
|
If you don't want to explicitly switch the active GHC all the time and are using
|
||||||
|
tools that rely on the plain `ghc` binary, GHCup provides an easy way to execute
|
||||||
|
commands with a certain toolchain prepended to PATH, e.g.:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
with_ghc() {
|
ghcup run --ghc 8.10.7 --cabal latest --hls latest --stack latest --install -- code Setup.hs
|
||||||
local np=$(ghcup --offline whereis -d ghc $1 || { ghcup --cache install ghc $1 && ghcup whereis -d ghc $1 ;})
|
|
||||||
if [ -e "${np}" ] ; then
|
|
||||||
shift
|
|
||||||
PATH="$np:$PATH" "$@"
|
|
||||||
else
|
|
||||||
>&2 echo "Cannot find or install GHC version $1"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For fish shell, in e.g. `~/.config/fish/config.fish` define:
|
This will execute vscode with GHC set to 8.10.7 and all other tools to their latest version.
|
||||||
|
|
||||||
```fish
|
# Troubleshooting
|
||||||
function with_ghc
|
|
||||||
set --local np (ghcup --offline whereis -d ghc $argv[1] ; or begin ghcup --cache install ghc $argv[1] ; and ghcup whereis -d ghc $argv[1] ; end)
|
## Script immediately exits on windows
|
||||||
if test -e "$np"
|
|
||||||
PATH="$np:$PATH" $argv[2..-1]
|
There are two possible reasons:
|
||||||
else
|
|
||||||
echo "Cannot find or install GHC version $argv[1]" 1>&2
|
1. your company blocks the script (some have a whitelist)... ask your administrator
|
||||||
return 1
|
2. your Antivirus or Windows Defender interfere with the installation. Disable them temporarily.
|
||||||
end
|
|
||||||
end
|
## C compiler cannot create executables
|
||||||
|
|
||||||
|
### Darwin
|
||||||
|
|
||||||
|
You need to update your XCode command line tools, e.g. [like this](https://stackoverflow.com/questions/34617452/how-to-update-xcode-from-command-line).
|
||||||
|
|
||||||
|
## Certificate authority errors (curl)
|
||||||
|
|
||||||
|
If your certificates are outdated or improperly configured, curl may be unable
|
||||||
|
to download ghcup.
|
||||||
|
|
||||||
|
There are two known workarounds:
|
||||||
|
|
||||||
|
1. Tell curl to ignore certificate errors (dangerous): `curl -k https://raw.githubusercontent.com/haskell/ghcup-hs/master/scripts/bootstrap/bootstrap-haskell | GHCUP_CURL_OPTS="-k" sh`
|
||||||
|
2. Try to use wget instead: `wget -O /dev/stdout https://raw.githubusercontent.com/haskell/ghcup-hs/master/scripts/bootstrap/bootstrap-haskell | BOOTSTRAP_HASKELL_DOWNLOADER=wget sh`
|
||||||
|
|
||||||
|
On windows, you can disable curl like so:
|
||||||
|
|
||||||
|
```pwsh
|
||||||
|
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;try { Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $true,$false,$false,$false,$false,$false,$false,"","","","",$true } catch { Write-Error $_ }
|
||||||
```
|
```
|
||||||
|
|
||||||
Then start a new shell and issue:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# replace 'code' with your editor
|
|
||||||
with_ghc 8.10.5 code path/to/haskell/source
|
|
||||||
```
|
|
||||||
|
|
||||||
Cabal and HLS will now see `8.10.5` as the primary GHC, without the need to
|
|
||||||
run `ghcup set` all the time when switching between projects.
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,19 +4,16 @@ hide:
|
|||||||
- toc
|
- toc
|
||||||
---
|
---
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
||||||
<script src="javascripts/extra.js"></script>
|
|
||||||
|
|
||||||
|
|
||||||
<section class="index-ghcup-hero">
|
<section class="index-ghcup-hero">
|
||||||
<img alt="haskell logo" src="./haskell_logo.png" />
|
<img alt="haskell logo" src="./haskell_logo.png" />
|
||||||
<h1>GHCup</h1>
|
<h1>GHCup</h1>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<p class="ghcup-intro">GHCup is an installer for the general purpose language <a href="https://www.haskell.org">Haskell</a>.</p>
|
<p class="ghcup-intro">GHCup is the main installer for the general purpose language <a href="https://www.haskell.org">Haskell</a>.</p>
|
||||||
|
|
||||||
<div class="text-center main-buttons">
|
<div class="text-center main-buttons">
|
||||||
<a href="install/" class="btn btn-primary" role="button">Getting Started</a>
|
<a href="install/" class="btn btn-primary" role="button">Installation</a>
|
||||||
|
<a href="steps/" class="btn btn-primary" role="button">First steps</a>
|
||||||
<a href="guide/" class="btn btn-primary" role="button">User Guide</a>
|
<a href="guide/" class="btn btn-primary" role="button">User Guide</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -34,7 +31,7 @@ hide:
|
|||||||
<span>
|
<span>
|
||||||
</span>
|
</span>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-install">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-installation">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -44,19 +41,19 @@ hide:
|
|||||||
|
|
||||||
<div class="command-button">
|
<div class="command-button">
|
||||||
<pre>
|
<pre>
|
||||||
<span class="ghcup-command" id="ghcup-command-windows">Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $true
|
<span class="ghcup-command" id="ghcup-command-windows">Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; try { Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $true } catch { Write-Error $_ }
|
||||||
</span>
|
</span>
|
||||||
</pre>
|
</pre>
|
||||||
<button class="btn" onclick="copyToClipboardWin()" id="ghcup-windows-button"><i class="fa fa-copy"></i></button>
|
<button class="btn" onclick="copyToClipboardWin()" id="ghcup-windows-button"><i class="fa fa-copy"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell.ps1" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-install">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
<a href="https://github.com/haskell/ghcup-hs/blob/master/scripts/bootstrap/bootstrap-haskell.ps1" target="_blank">What does this do?</a> <b> · </b> <a href="https://www.haskell.org/ghcup/install/#manual-installation">I don't like curl | sh</a> <div class="show-all-platforms"><b> · </b> <a class="show-all-platforms-button" href="#">Show all platforms</a></div></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<p id="help" class="ghcup-help">
|
<p id="help" class="ghcup-help">
|
||||||
Need help? Ask on
|
Need help? Check the <a href="guide/#troubleshooting">Troubleshooting section</a> or ask on
|
||||||
<span>
|
<span>
|
||||||
<a href="https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup">
|
<a href="https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup">
|
||||||
<img src="irc.svg" alt="" />
|
<img src="irc.svg" alt="" />
|
||||||
@@ -76,16 +73,13 @@ hide:
|
|||||||
</span>
|
</span>
|
||||||
or
|
or
|
||||||
<span>
|
<span>
|
||||||
<a href="https://gitlab.haskell.org/haskell/ghcup-hs/issues">
|
<a href="https://github.com/haskell/ghcup-hs/issues">
|
||||||
report a bug
|
report a bug
|
||||||
<img src="Octicons-bug.svg" alt="" />
|
<img src="Octicons-bug.svg" alt="" />
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<script type="text/javascript" src="javascripts/ghcup.js"></script>
|
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
252
docs/install.md
252
docs/install.md
@@ -1,10 +1,10 @@
|
|||||||
# Getting started
|
# Installation
|
||||||
|
|
||||||
GHCup makes it easy to install specific versions of GHC on GNU/Linux,
|
GHCup makes it easy to install specific versions of GHC on GNU/Linux,
|
||||||
macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh [Haskell developer environment](./install/#supported-tools) from scratch.
|
macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh [Haskell developer environment](./#supported-tools) from scratch.
|
||||||
It follows the unix UNIX philosophy of [do one thing and do it well](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well). Similar in scope to [rustup](https://github.com/rust-lang-nursery/rustup.rs), [pyenv](https://github.com/pyenv/pyenv) and [jenv](http://www.jenv.be).
|
It follows the UNIX philosophy of [do one thing and do it well](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well). Similar in scope to [rustup](https://github.com/rust-lang-nursery/rustup.rs), [pyenv](https://github.com/pyenv/pyenv) and [jenv](http://www.jenv.be).
|
||||||
|
|
||||||
## Installation
|
## How to install
|
||||||
|
|
||||||
The following commands will download the `ghcup` binary into `~/.ghcup/bin` (or `C:\ghcup\bin` on windows) and then
|
The following commands will download the `ghcup` binary into `~/.ghcup/bin` (or `C:\ghcup\bin` on windows) and then
|
||||||
run it to interactively install the [Haskell Toolchain](#supported-tools). These commands should be run as **non-root/non-admin
|
run it to interactively install the [Haskell Toolchain](#supported-tools). These commands should be run as **non-root/non-admin
|
||||||
@@ -19,31 +19,172 @@ curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
|
|||||||
For Windows, run this in a PowerShell session:
|
For Windows, run this in a PowerShell session:
|
||||||
|
|
||||||
```psh
|
```psh
|
||||||
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $true
|
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; try { Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $true } catch { Write-Error $_ }
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to know what these scripts do, check out the [source code at the repository](https://gitlab.haskell.org/haskell/ghcup-hs/-/tree/master/scripts/bootstrap). Advanced users may want to perform a [manual installation](#manual-install) and GPG verify the binaries.
|
There's also a [youtube video](https://www.youtube.com/watch?v=bB4fmQiUYPw) explaining installation on windows.
|
||||||
|
|
||||||
## First steps
|
If you want to know what these scripts do, check out the [source code at the repository](https://github.com/haskell/ghcup-hs/tree/master/scripts/bootstrap). Advanced users may want to perform a [manual installation](#manual-installation) and GPG verify the binaries.
|
||||||
|
|
||||||
1. To get started with creating a Haskell project, follow the [Getting Started with Haskell and Cabal](https://cabal.readthedocs.io/en/latest/getting-started.html) guide
|
### Which versions get installed?
|
||||||
2. To properly learn Haskell, run through the [CIS 194 Haskell course](https://www.cis.upenn.edu/~cis194/spring13/) including exercises
|
|
||||||
3. To learn more about Haskell Toolchain management, check out the [ghcup user guide](./guide.md)
|
GHCup has two main channels for every tool: **recommended** and **latest**. By default, it installs *recommended*.
|
||||||
|
|
||||||
|
*latest* follows the latest release of every tool, while *recommended* is at the discretion of the GHCup maintainers and based on community adoption (hackage libraries, tools like HLS, stackage support, etc.) and known bugs.
|
||||||
|
|
||||||
|
Also see [tags and shortcuts](../guide/#tags-and-shortcuts) for more information.
|
||||||
|
|
||||||
|
## System requirements
|
||||||
|
|
||||||
|
### Linux Debian
|
||||||
|
|
||||||
|
The following distro packages are required: `build-essential curl libffi-dev libffi6 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5`
|
||||||
|
|
||||||
|
### Linux Ubuntu
|
||||||
|
|
||||||
|
The following distro packages are required: `build-essential curl libffi-dev libffi6 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5`
|
||||||
|
|
||||||
|
### Linux Fedora
|
||||||
|
|
||||||
|
The following distro packages are required: `gcc gcc-c++ gmp gmp-devel make ncurses ncurses-compat-libs xz perl`
|
||||||
|
|
||||||
|
### Linux Mageia
|
||||||
|
|
||||||
|
The following distro packages are required: `curl gcc gcc-c++ gmp libffi-devel libffi7 libgmp-devel libgmp10 make libncurses-devel libncurses5 xz perl`
|
||||||
|
|
||||||
|
### Linux CentOS
|
||||||
|
|
||||||
|
The following distro packages are required: `gcc gcc-c++ gmp gmp-devel make ncurses ncurses-compat-libs xz perl`
|
||||||
|
|
||||||
|
### Linux Alpine
|
||||||
|
|
||||||
|
The following distro packages are required: `binutils-gold curl gcc g++ gmp-dev libc-dev libffi-dev make musl-dev ncurses-dev perl tar xz`
|
||||||
|
|
||||||
|
### Linux VoidLinux
|
||||||
|
|
||||||
|
The following distro packages are required: `gcc gmp curl coreutils xz ncurses make ncurses-libtinfo-libs perl tar`
|
||||||
|
|
||||||
|
### Linux (generic)
|
||||||
|
|
||||||
|
You need the following packages: curl g++ gcc gmp make ncurses realpath xz-utils. Consult your distro documentation on the exact names of those packages.
|
||||||
|
|
||||||
|
### Darwin
|
||||||
|
|
||||||
|
On OS X, in the course of running ghcup you will be given a dialog box to install the command line tools. Accept and the requirements will be installed for you. You will then need to run the command again.
|
||||||
|
On Darwin M1 you might also need a working llvm installed (e.g. via brew) and have the toolchain exposed in PATH.
|
||||||
|
|
||||||
|
### FreeBSD
|
||||||
|
|
||||||
|
The following distro packages are required: `curl gcc gmp gmake ncurses perl5 libffi libiconv`
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
On Windows, msys2 should already have been set up during the installation, so most users should just proceed. If you are installing manually, make sure to have a working mingw64 toolchain and shell.
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
|
||||||
|
1. Follow the [First steps guide](../steps) on how to build a "Hello world" program, use `ghc`, run an interactive REPL and create a Haskell project
|
||||||
|
2. To understand the difference and overlap of `stack` and `cabal`, read on [here](https://gist.github.com/merijn/8152d561fb8b011f9313c48d876ceb07)
|
||||||
|
3. To learn Haskell proper check out the links at [How to learn Haskell proper](../steps#how-to-learn-haskell-proper)
|
||||||
|
4. To learn more about Haskell Toolchain management, check out the [ghcup user guide](./guide.md)
|
||||||
|
|
||||||
## Uninstallation
|
## Uninstallation
|
||||||
|
|
||||||
On linux, just run `ghcup nuke`, then make sure any ghcup added lines in your `~/.bashrc` (or similar) are removed.
|
On linux, just run `ghcup nuke`, then make sure any ghcup added lines in your `~/.bashrc` (or similar) are removed.
|
||||||
|
|
||||||
On windows, double-click on the `Uninstall Haskell.ps1` PowerShell script on your Desktop.
|
On windows, right click on the `Uninstall Haskell.ps1` PowerShell script on your Desktop and select *Run with PowerShell*.
|
||||||
|
|
||||||
## Supported tools
|
## Supported tools
|
||||||
|
|
||||||
GHCup supports the following tools, which are also known as the **Haskell Toolchain**:
|
GHCup supports the following tools, which are also known as the **Haskell Toolchain**:
|
||||||
|
|
||||||
1. [GHC](https://www.haskell.org/ghc/)
|
<details> <summary>Show all supported <a href='https://www.haskell.org/ghc/'>GHC</a> versions</summary>
|
||||||
2. [cabal-install](https://cabal.readthedocs.io/en/latest/)
|
<table>
|
||||||
3. [haskell-language-server](https://haskell-language-server.readthedocs.io/en/latest/)
|
<thead><tr><th>GHC Version</th><th>Tags</th></tr></thead>
|
||||||
4. [stack](https://docs.haskellstack.org/en/latest/README/)
|
<tbody>
|
||||||
|
<tr><td>9.4.3</td><td><span style="color:blue">latest</span>, base-4.17.0.0</td></tr>
|
||||||
|
<tr><td>9.4.2</td><td>base-4.17.0.0</td></tr>
|
||||||
|
<tr><td>9.4.1</td><td>base-4.17.0.0</td></tr>
|
||||||
|
<tr><td>9.2.5</td><td><span style="color:green">recommended</span>, base-4.16.4.0</td></tr>
|
||||||
|
<tr><td>9.2.4</td><td>base-4.16.3.0</td></tr>
|
||||||
|
<tr><td>9.2.3</td><td>base-4.16.2.0</td></tr>
|
||||||
|
<tr><td>9.2.2</td><td>base-4.16.1.0</td></tr>
|
||||||
|
<tr><td>9.2.1</td><td>base-4.16.0.0</td></tr>
|
||||||
|
<tr><td>9.0.2</td><td>base-4.15.1.0</td></tr>
|
||||||
|
<tr><td>9.0.1</td><td>base-4.15.0.0</td></tr>
|
||||||
|
<tr><td>8.10.7</td><td>base-4.14.3.0</td></tr>
|
||||||
|
<tr><td>8.10.6</td><td>base-4.14.3.0</td></tr>
|
||||||
|
<tr><td>8.10.5</td><td>base-4.14.2.0</td></tr>
|
||||||
|
<tr><td>8.10.4</td><td>base-4.14.1.0</td></tr>
|
||||||
|
<tr><td>8.10.3</td><td>base-4.14.1.0</td></tr>
|
||||||
|
<tr><td>8.10.2</td><td>base-4.14.1.0</td></tr>
|
||||||
|
<tr><td>8.10.1</td><td>base-4.14.0.0</td></tr>
|
||||||
|
<tr><td>8.8.4</td><td>base-4.13.0.0</td></tr>
|
||||||
|
<tr><td>8.8.3</td><td>base-4.13.0.0</td></tr>
|
||||||
|
<tr><td>8.8.2</td><td>base-4.13.0.0</td></tr>
|
||||||
|
<tr><td>8.8.1</td><td>base-4.13.0.0</td></tr>
|
||||||
|
<tr><td>8.6.5</td><td>base-4.12.0.0</td></tr>
|
||||||
|
<tr><td>8.6.4</td><td>base-4.12.0.0</td></tr>
|
||||||
|
<tr><td>8.6.3</td><td>base-4.12.0.0</td></tr>
|
||||||
|
<tr><td>8.6.2</td><td>base-4.12.0.0</td></tr>
|
||||||
|
<tr><td>8.6.1</td><td>base-4.12.0.0</td></tr>
|
||||||
|
<tr><td>8.4.4</td><td>base-4.11.1.0</td></tr>
|
||||||
|
<tr><td>8.4.3</td><td>base-4.11.1.0</td></tr>
|
||||||
|
<tr><td>8.4.2</td><td>base-4.11.1.0</td></tr>
|
||||||
|
<tr><td>8.4.1</td><td>base-4.11.0.0</td></tr>
|
||||||
|
<tr><td>8.2.2</td><td>base-4.10.1.0</td></tr>
|
||||||
|
<tr><td>8.0.2</td><td>base-4.9.1.0</td></tr>
|
||||||
|
<tr><td>7.10.3</td><td>base-4.8.2.0</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details> <summary>Show all supported <a href='https://cabal.readthedocs.io/en/stable/'>cabal-install</a> versions</summary>
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>Cabal Version</th><th>Tags</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td>3.8.1.0</td><td><span style="color:blue">latest</span></td></tr>
|
||||||
|
<tr><td>3.6.2.0</td><td><span style="color:green">recommended</span></td></tr>
|
||||||
|
<tr><td>3.6.0.0</td><td></td></tr>
|
||||||
|
<tr><td>3.4.1.0</td><td></td></tr>
|
||||||
|
<tr><td>3.4.0.0</td><td></td></tr>
|
||||||
|
<tr><td>3.2.0.0</td><td></td></tr>
|
||||||
|
<tr><td>3.0.0.0</td><td></td></tr>
|
||||||
|
<tr><td>2.4.1.0</td><td></td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details> <summary>Show all supported <a href='https://haskell-language-server.readthedocs.io/en/stable/'>HLS</a> versions</summary>
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>HLS Version</th><th>Tags</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td>1.8.0.0</td><td><span style="color:blue">latest</span>, <span style="color:green">recommended</span></td></tr>
|
||||||
|
<tr><td>1.7.0.0</td><td></td></tr>
|
||||||
|
<tr><td>1.6.1.0</td><td></td></tr>
|
||||||
|
<tr><td>1.6.0.0</td><td></td></tr>
|
||||||
|
<tr><td>1.5.1</td><td></td></tr>
|
||||||
|
<tr><td>1.5.0</td><td></td></tr>
|
||||||
|
<tr><td>1.4.0</td><td></td></tr>
|
||||||
|
<tr><td>1.3.0</td><td></td></tr>
|
||||||
|
<tr><td>1.2.0</td><td></td></tr>
|
||||||
|
<tr><td>1.1.0</td><td></td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details> <summary>Show all supported <a href='https://docs.haskellstack.org/en/stable/README/'>Stack</a> versions</summary>
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>Stack Version</th><th>Tags</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td>2.9.1</td><td><span style="color:blue">latest</span>, <span style="color:green">recommended</span></td></tr>
|
||||||
|
<tr><td>2.7.5</td><td></td></tr>
|
||||||
|
<tr><td>2.7.3</td><td></td></tr>
|
||||||
|
<tr><td>2.7.1</td><td></td></tr>
|
||||||
|
<tr><td>2.5.1</td><td></td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</details>
|
||||||
|
|
||||||
## Supported platforms
|
## Supported platforms
|
||||||
|
|
||||||
@@ -78,14 +219,15 @@ May or may not work, several issues:
|
|||||||
|
|
||||||
Unsupported. GHC may or may not work. Upgrade to WSL2.
|
Unsupported. GHC may or may not work. Upgrade to WSL2.
|
||||||
|
|
||||||
### MacOS <13
|
### MacOS <10.13
|
||||||
|
|
||||||
Not supported. Would require separate binaries, since >=13 binaries are incompatible.
|
Not supported. Would require separate binaries, since >=10.13 binaries are incompatible.
|
||||||
Please upgrade.
|
Please upgrade.
|
||||||
|
|
||||||
### MacOS aarch64
|
### MacOS aarch64
|
||||||
|
|
||||||
HLS bindists are still experimental. Stack is theoretically supported, but has no binaries yet.
|
HLS bindists are still experimental. Stack has only unofficial binaries for this platform.
|
||||||
|
There are various issues with GHC itself.
|
||||||
|
|
||||||
### FreeBSD
|
### FreeBSD
|
||||||
|
|
||||||
@@ -94,14 +236,16 @@ HLS bindists are experimental.
|
|||||||
|
|
||||||
### Linux ARMv7/AARCH64
|
### Linux ARMv7/AARCH64
|
||||||
|
|
||||||
Lower availability of bindists. HLS only has experimental ones. Stack not supported currently.
|
Lower availability of bindists. Stack and HLS binaries are experimental.
|
||||||
|
|
||||||
## Manual install
|
## Manual installation
|
||||||
|
|
||||||
|
### Unix
|
||||||
|
|
||||||
Download the binary for your platform at [https://downloads.haskell.org/~ghcup/](https://downloads.haskell.org/~ghcup/)
|
Download the binary for your platform at [https://downloads.haskell.org/~ghcup/](https://downloads.haskell.org/~ghcup/)
|
||||||
and place it into your `PATH` anywhere.
|
and place it into your `PATH` anywhere.
|
||||||
|
|
||||||
If you want to GPG verify the binaries, import the following key first: `7784930957807690A66EBDBE3786C5262ECB4A3F`.
|
If you want to GPG verify the binaries, import the following keys first: `7784930957807690A66EBDBE3786C5262ECB4A3F` and `FE5AB6C91FEA597C3B31180B73EDE9E8CFBAEF01`.
|
||||||
|
|
||||||
Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) like so:
|
Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) like so:
|
||||||
|
|
||||||
@@ -109,14 +253,78 @@ Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) lik
|
|||||||
export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
|
export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
1. Install ghcup binary
|
||||||
|
- choose a base directory for installation, e.g. `C:\` that has sufficient space
|
||||||
|
- then create the directory, e.g. `C:\ghcup\bin`
|
||||||
|
- download the binary: https://downloads.haskell.org/~ghcup/x86_64-mingw64-ghcup.exe
|
||||||
|
- place it as `ghcup.exe` into e.g. `C:\ghcup\bin`
|
||||||
|
2. Install MSYS2
|
||||||
|
- download https://repo.msys2.org/distrib/msys2-x86_64-latest.exe and execute it
|
||||||
|
- remember the installation destination you choose (default is `C:\msys64`)
|
||||||
|
- finish the installation
|
||||||
|
* Add environment variables and update `Path`
|
||||||
|
- open search bar and type in "Edit the system environment variables", then open it
|
||||||
|
- click on "Environment Variables..." at the near bottom
|
||||||
|
- in the upper half, select `Path` variable and double click on it
|
||||||
|
- in the new window, click "New", type in `C:\ghcup\bin` (depending on step 1.) and press enter
|
||||||
|
- click "OK" at the bottom
|
||||||
|
- in the upper half, click on "New..."
|
||||||
|
- enter `GHCUP_MSYS2` under "Variable name" and the installation destination from step 2. under "Variable value"
|
||||||
|
- click "OK" at the bottom
|
||||||
|
- in the upper half, click on "New..."
|
||||||
|
- enter `GHCUP_INSTALL_BASE_PREFIX` under "Variable name" and based on the installation destination from step 1. enter the device directory (default `C:\`)
|
||||||
|
- click "OK" at the bottom
|
||||||
|
- in the upper half, click on "New..."
|
||||||
|
- enter `CABAL_DIR` under "Variable name" and based on the installation destination from step 1. enter the device directory + `cabal` subdir (default `C:\cabal`)
|
||||||
|
- click "OK" at the bottom
|
||||||
|
- click "OK" at the bottom
|
||||||
|
- click "OK" at the bottom
|
||||||
|
3. Install tools
|
||||||
|
- open powershell
|
||||||
|
- run `ghcup install ghc --set recommended`
|
||||||
|
- run `ghcup install cabal latest`
|
||||||
|
- run `ghcup install stack latest`
|
||||||
|
- run `ghcup install hls latest`
|
||||||
|
- run `cabal update`
|
||||||
|
4. Update msys2
|
||||||
|
- run `ghcup run -m -- pacman --noconfirm -Syuu`
|
||||||
|
- run `ghcup run -m -- pacman --noconfirm -Syuu`
|
||||||
|
- run `ghcup run -m -- pacman --noconfirm -S --needed curl autoconf mingw-w64-x86_64-pkgconf`
|
||||||
|
- run `ghcup run -m -- pacman --noconfirm -S ca-certificates`
|
||||||
|
5. Update cabal config
|
||||||
|
- go to e.g. `C:\cabal` (based on device you picked in 1.)
|
||||||
|
- open file `config`
|
||||||
|
- uncomment `extra-include-dirs` (the `-- `) and add the value (depending on installation destination you chose in 2.), e.g. `C:\msys64\mingw64\include`... so the final line should be `extra-include-dirs: C:\msys64\mingw64\include`
|
||||||
|
- uncomment `extra-lib-dirs` and do the same, adding `C:\msys64\mingw64\lib`
|
||||||
|
- uncomment `extra-prog-path` and set it to `C:\ghcup\bin, C:\cabal\bin, C:\msys64\mingw64\bin, C:\msys64\usr\bin`, depending on your install destinations from 1. and 2.
|
||||||
|
6. Set up msys2 shell
|
||||||
|
- run `ghcup run -m -- sed -i -e 's/db_home:.*$/db_home: windows/' /etc/nsswitch.conf` to make the HOME in your msys2 shell match the one from windows
|
||||||
|
- make a desktop shortcut from `C:\msys64\msys2_shell.cmd`, which will allow you to start a proper msys2 shell
|
||||||
|
- run `ghcup run -m -- sed -i -e 's/#MSYS2_PATH_TYPE=.*/MSYS2_PATH_TYPE=inherit/' /c/msys64/msys2.ini`
|
||||||
|
- run `ghcup run -m -- sed -i -e 's/rem set MSYS2_PATH_TYPE=inherit/set MSYS2_PATH_TYPE=inherit/' /c/msys64/msys2_shell.cmd`
|
||||||
|
|
||||||
|
All set. You can run `cabal init` now in an empty directory to start a project.
|
||||||
|
|
||||||
## Vim integration
|
## Vim integration
|
||||||
|
|
||||||
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).
|
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).
|
||||||
|
|
||||||
|
## VSCode integration
|
||||||
|
The developers of the Haskell Language Server offer an [extension](https://github.com/haskell/vscode-haskell) tightly integrated with the [Haskell Language Server](https://github.com/haskell/haskell-language-server). To get started:
|
||||||
|
|
||||||
|
1. Install GHCup. During installation, opt in to install the Haskell Language Server (HLS).
|
||||||
|
2. Install the extension (from VSCode: Ctrl + P and then `ext install haskell.haskell`).
|
||||||
|
3. Make sure your project uses the GHC version installed from GHCup (otherwise HLS is likely to fail on launch):
|
||||||
|
- instructions for [stack](https://docs.haskellstack.org/en/stable/yaml_configuration/#system-ghc)
|
||||||
|
|
||||||
|
On Linux, some users have reported an issue when VSCode is not launched from a terminal ("cannot find ghc version"). A solution is to [let HLS know about your GHCup on $PATH](https://github.com/haskell/vscode-haskell#stackcabalghc-can-not-be-found).
|
||||||
|
|
||||||
## Get help
|
## Get help
|
||||||
|
|
||||||
* [Libera IRC chat on #haskell-ghcup or #haskell](https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup)
|
* [Libera IRC chat on #haskell-ghcup or #haskell](https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup)
|
||||||
* [GHCup issue tracker](https://gitlab.haskell.org/haskell/ghcup-hs/issues)
|
* [GHCup issue tracker](https://github.com/haskell/ghcup-hs/issues/new)
|
||||||
* [Matrix](https://app.element.io/#/room/#haskell-tooling:matrix.org)
|
* [Matrix](https://app.element.io/#/room/#haskell-tooling:matrix.org)
|
||||||
* [Discord](https://discord.gg/pKYf3zDQU7)
|
* [Discord](https://discord.gg/pKYf3zDQU7)
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 40 KiB |
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 40 KiB |
@@ -1,201 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="{{ config.theme.locale|default('en') }}">
|
|
||||||
<head>
|
|
||||||
{%- block site_meta %}
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
{% if page and page.is_homepage %}<meta name="description" content="{{ config['site_description'] }}">{% endif %}
|
|
||||||
{% if config.site_author %}<meta name="author" content="{{ config.site_author }}">{% endif %}
|
|
||||||
{% if page and page.canonical_url %}<link rel="canonical" href="{{ page.canonical_url }}">{% endif %}
|
|
||||||
{% if config.site_favicon %}<link rel="shortcut icon" href="{{ config.site_favicon|url }}">
|
|
||||||
{% else %}<link rel="shortcut icon" href="{{ 'img/favicon.ico'|url }}">{% endif %}
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- block htmltitle %}
|
|
||||||
<title>{% if page and page.title and not page.is_homepage %}{{ page.title }} - {% endif %}{{ config.site_name }}</title>
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- block styles %}
|
|
||||||
<link href="{{ 'css/bootstrap.min.css'|url }}" rel="stylesheet">
|
|
||||||
<link href="{{ 'css/font-awesome.min.css'|url }}" rel="stylesheet">
|
|
||||||
<link href="{{ 'css/base.css'|url }}" rel="stylesheet">
|
|
||||||
{%- if config.theme.highlightjs %}
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/{{ config.theme.hljs_style }}.min.css">
|
|
||||||
{%- endif %}
|
|
||||||
{%- for path in extra_css %}
|
|
||||||
<link href="{{ path }}" rel="stylesheet">
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- block libs %}
|
|
||||||
|
|
||||||
<script src="{{ 'js/jquery-1.10.2.min.js'|url }}" defer></script>
|
|
||||||
<script src="{{ 'js/bootstrap.min.js'|url }}" defer></script>
|
|
||||||
{%- if config.theme.highlightjs %}
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
|
|
||||||
{%- for lang in config.theme.hljs_languages %}
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/languages/{{lang}}.min.js"></script>
|
|
||||||
{%- endfor %}
|
|
||||||
<script>hljs.initHighlightingOnLoad();</script>
|
|
||||||
{%- endif %}
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- block analytics %}
|
|
||||||
{%- if config.theme.analytics.gtag %}
|
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id={{ config.theme.analytics.gtag }}"></script>
|
|
||||||
<script>
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
function gtag(){dataLayer.push(arguments);}
|
|
||||||
gtag('js', new Date());
|
|
||||||
|
|
||||||
gtag('config', '{{ config.theme.analytics.gtag }}');
|
|
||||||
</script>
|
|
||||||
{%- elif config.google_analytics %}
|
|
||||||
<script>
|
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
||||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
|
||||||
|
|
||||||
ga('create', '{{ config.google_analytics[0] }}', '{{ config.google_analytics[1] }}');
|
|
||||||
ga('send', 'pageview');
|
|
||||||
</script>
|
|
||||||
{%- endif %}
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- block extrahead %} {% endblock %}
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body{% if page and page.is_homepage %} class="homepage"{% endif %}>
|
|
||||||
<div class="navbar fixed-top navbar-expand-lg navbar-{% if config.theme.nav_style == "light" %}light{% else %}dark{% endif %} bg-{{ config.theme.nav_style }}">
|
|
||||||
<div class="container">
|
|
||||||
|
|
||||||
{%- block site_name %}
|
|
||||||
<a class="navbar-brand" href="{{ nav.homepage.url|url }}">{{ config.site_name }}</a>
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- if nav|length>1 or (page and (page.next_page or page.previous_page)) or config.repo_url %}
|
|
||||||
<!-- Expander button -->
|
|
||||||
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
{%- endif %}
|
|
||||||
|
|
||||||
<!-- Expanded navigation -->
|
|
||||||
<div id="navbar-collapse" class="navbar-collapse collapse">
|
|
||||||
{%- block site_nav %}
|
|
||||||
{%- if nav|length>1 %}
|
|
||||||
<!-- Main navigation -->
|
|
||||||
<ul class="nav navbar-nav">
|
|
||||||
{%- for nav_item in nav %}
|
|
||||||
{%- if nav_item.children %}
|
|
||||||
<li class="dropdown{% if nav_item.active %} active{% endif %}">
|
|
||||||
<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown">{{ nav_item.title }} <b class="caret"></b></a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
{%- for nav_item in nav_item.children %}
|
|
||||||
{% include "nav-sub.html" %}
|
|
||||||
{%- endfor %}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{%- else %}
|
|
||||||
<li class="navitem{% if nav_item.active %} active{% endif %}">
|
|
||||||
<a href="{{ nav_item.url|url }}" class="nav-link">{{ nav_item.title }}</a>
|
|
||||||
</li>
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor %}
|
|
||||||
</ul>
|
|
||||||
{%- endif %}
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
<ul class="nav navbar-nav ml-auto">
|
|
||||||
{%- block search_button %}
|
|
||||||
{%- if 'search' in config['plugins'] %}
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
|
|
||||||
<i class="fa fa-search"></i> {% trans %}Search{% endtrans %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{%- endif %}
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- block next_prev %}
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{%- block repo %}
|
|
||||||
{%- if page and page.edit_url %}
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="{{ page.edit_url }}" class="nav-link">
|
|
||||||
{%- if config.repo_name == 'GitHub' -%}
|
|
||||||
<i class="fa fa-github"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
|
||||||
{%- elif config.repo_name == 'Bitbucket' -%}
|
|
||||||
<i class="fa fa-bitbucket"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
|
||||||
{%- elif config.repo_name == 'GitLab' -%}
|
|
||||||
<i class="fa fa-gitlab"></i> {% trans repo_name=config.repo_name %}Edit on {{ repo_name }}{% endtrans %}
|
|
||||||
{%- else -%}
|
|
||||||
{% trans repo_name=config.repo_name%}Edit on {{ repo_name }}{% endtrans %}
|
|
||||||
{%- endif -%}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{%- elif config.repo_url %}
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="{{ config.repo_url }}" class="nav-link">
|
|
||||||
{%- if config.repo_name == 'GitHub' -%}
|
|
||||||
<i class="fa fa-github"></i> {{ config.repo_name }}
|
|
||||||
{%- elif config.repo_name == 'Bitbucket' -%}
|
|
||||||
<i class="fa fa-bitbucket"></i> {{ config.repo_name }}
|
|
||||||
{%- elif config.repo_name == 'GitLab' -%}
|
|
||||||
<i class="fa fa-gitlab"></i> {{ config.repo_name }}
|
|
||||||
{%- else -%}
|
|
||||||
{{ config.repo_name }}
|
|
||||||
{%- endif -%}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{%- endif %}
|
|
||||||
{%- endblock %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
{%- block content %}
|
|
||||||
<div class="col-md-3">{% include "toc.html" %}</div>
|
|
||||||
<div class="col-md-9" role="main">{% include "content.html" %}</div>
|
|
||||||
{%- endblock %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer class="col-md-12">
|
|
||||||
{%- block footer %}
|
|
||||||
<hr>
|
|
||||||
{%- if config.copyright %}
|
|
||||||
<p>{{ config.copyright }}</p>
|
|
||||||
{%- endif %}
|
|
||||||
<p>{% trans mkdocs_link='<a href="https://www.mkdocs.org/">MkDocs</a>' %}Documentation built with {{ mkdocs_link }}.{% endtrans %}</p>
|
|
||||||
{%- endblock %}
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
{%- block scripts %}
|
|
||||||
<script>
|
|
||||||
var base_url = {{ base_url | tojson }},
|
|
||||||
shortcuts = {{ config.theme.shortcuts | tojson }};
|
|
||||||
</script>
|
|
||||||
<script src="{{ 'js/base.js'|url }}" defer></script>
|
|
||||||
{%- for path in extra_javascript %}
|
|
||||||
<script src="{{ path }}" defer></script>
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endblock %}
|
|
||||||
|
|
||||||
{% if 'search' in config['plugins'] %}{%- include "search-modal.html" %}{% endif %}
|
|
||||||
{%- include "keyboard-modal.html" %}
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
{% if page and page.is_homepage %}
|
|
||||||
<!--
|
|
||||||
MkDocs version : {{ mkdocs_version }}
|
|
||||||
Build Date UTC : {{ build_date_utc }}
|
|
||||||
-->
|
|
||||||
{% endif %}
|
|
||||||
BIN
docs/overrides/img/favicon.ico
Normal file
BIN
docs/overrides/img/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
4
docs/overrides/main.html
Normal file
4
docs/overrides/main.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
<!-- Get rid of the next/prev buttons -->
|
||||||
|
{% block next_prev %}
|
||||||
|
{% endblock %}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user