Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| abc4278fc8 | |||
| 8c4cde3d14 |
@@ -18,14 +18,12 @@ apk add --no-cache \
|
|||||||
tar \
|
tar \
|
||||||
perl
|
perl
|
||||||
|
|
||||||
ln -sf libncurses.so /usr/lib/libtinfo.so
|
ln -s libncurses.so /usr/lib/libtinfo.so
|
||||||
ln -sf libncursesw.so.6 /usr/lib/libtinfow.so.6
|
ln -s libncursesw.so.6 /usr/lib/libtinfow.so.6
|
||||||
ln -sf libtinfow.so.6 /usr/lib/libtinfow.so
|
|
||||||
|
|
||||||
if [ "${BIT}" = "32" ] ; then
|
if [ "${BIT}" = "32" ] ; then
|
||||||
curl -sSfL https://downloads.haskell.org/~ghcup/0.1.5/i386-linux-ghcup-0.1.5 > ./ghcup-bin
|
curl -sSfL https://downloads.haskell.org/~ghcup/0.1.4/i386-linux-ghcup-0.1.4 > ./ghcup-bin
|
||||||
else
|
else
|
||||||
curl -sSfL https://downloads.haskell.org/~ghcup/0.1.5/x86_64-linux-ghcup-0.1.5 > ./ghcup-bin
|
curl -sSfL https://downloads.haskell.org/~ghcup/0.1.4/x86_64-linux-ghcup-0.1.4 > ./ghcup-bin
|
||||||
fi
|
fi
|
||||||
chmod +x ghcup-bin
|
chmod +x ghcup-bin
|
||||||
./ghcup-bin upgrade
|
./ghcup-bin upgrade
|
||||||
@@ -59,8 +57,7 @@ apk add --no-cache \
|
|||||||
openssl-dev \
|
openssl-dev \
|
||||||
openssl-libs-static \
|
openssl-libs-static \
|
||||||
xz \
|
xz \
|
||||||
xz-dev \
|
xz-dev
|
||||||
ncurses-static
|
|
||||||
|
|
||||||
ln -sf libncursesw.a /usr/lib/libtinfow.a
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,24 +16,16 @@ git describe
|
|||||||
ecabal update
|
ecabal update
|
||||||
|
|
||||||
if [ "${OS}" = "LINUX" ] ; then
|
if [ "${OS}" = "LINUX" ] ; then
|
||||||
if [ "${BIT}" = "32" ] ; then
|
ecabal build -w ghc-${GHC_VERSION} --ghc-options='-split-sections -optl-static'
|
||||||
ecabal build -w ghc-${GHC_VERSION} --ghc-options='-split-sections -optl-static'
|
|
||||||
else
|
|
||||||
ecabal build -w ghc-${GHC_VERSION} --ghc-options='-split-sections -optl-static' -ftui
|
|
||||||
fi
|
|
||||||
elif [ "${OS}" = "FREEBSD" ] ; then
|
elif [ "${OS}" = "FREEBSD" ] ; then
|
||||||
ecabal build -w ghc-${GHC_VERSION} --ghc-options='-split-sections' --constraint="zlib static"
|
ecabal build -w ghc-${GHC_VERSION} --ghc-options='-split-sections' --constraint="zlib static"
|
||||||
else
|
else
|
||||||
ecabal build -w ghc-${GHC_VERSION} --constraint="zlib static" --constraint="lzma static" -ftui
|
ecabal build -w ghc-${GHC_VERSION} --constraint="zlib static" --constraint="lzma static"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir out
|
mkdir out
|
||||||
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" .
|
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" .
|
||||||
ver=$(./ghcup --numeric-version)
|
ver=$(./ghcup --numeric-version)
|
||||||
if [ "${OS}" = "DARWIN" ] ; then
|
strip -s ./ghcup
|
||||||
strip ./ghcup
|
|
||||||
else
|
|
||||||
strip -s ./ghcup
|
|
||||||
fi
|
|
||||||
cp ghcup out/${ARTIFACT}-${ver}
|
cp ghcup out/${ARTIFACT}-${ver}
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ git describe --always
|
|||||||
ecabal update
|
ecabal update
|
||||||
|
|
||||||
if [ "${OS}" = "DARWIN" ] ; then
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
ecabal build -w ghc-${GHC_VERSION} -ftui
|
ecabal build -w ghc-${GHC_VERSION}
|
||||||
else
|
else
|
||||||
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader -ftui
|
ecabal build -w ghc-${GHC_VERSION} -finternal-downloader
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cp "$(ecabal new-exec --enable-tests --verbose=0 --offline sh -- -c 'command -v ghcup')" .
|
cp "$(ecabal new-exec --enable-tests --verbose=0 --offline sh -- -c 'command -v ghcup')" .
|
||||||
|
|||||||
16
3rdparty/libarchive/c/autoconf-linux/config.h
vendored
16
3rdparty/libarchive/c/autoconf-linux/config.h
vendored
@@ -260,7 +260,7 @@
|
|||||||
/* #undef HAVE_ACL_IS_TRIVIAL_NP */
|
/* #undef HAVE_ACL_IS_TRIVIAL_NP */
|
||||||
|
|
||||||
/* Define to 1 if you have the <acl/libacl.h> header file. */
|
/* Define to 1 if you have the <acl/libacl.h> header file. */
|
||||||
/* #undef HAVE_ACL_LIBACL_H */
|
#define HAVE_ACL_LIBACL_H 1
|
||||||
|
|
||||||
/* Define to 1 if the system has the type `acl_permset_t'. */
|
/* Define to 1 if the system has the type `acl_permset_t'. */
|
||||||
/* #undef HAVE_ACL_PERMSET_T */
|
/* #undef HAVE_ACL_PERMSET_T */
|
||||||
@@ -453,7 +453,6 @@
|
|||||||
/* #undef HAVE_EXPAT_H */
|
/* #undef HAVE_EXPAT_H */
|
||||||
|
|
||||||
/* Define to 1 if you have the <ext2fs/ext2_fs.h> header file. */
|
/* Define to 1 if you have the <ext2fs/ext2_fs.h> header file. */
|
||||||
/* #undef HAVE_EXT2FS_EXT2_FS_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `extattr_get_fd' function. */
|
/* Define to 1 if you have the `extattr_get_fd' function. */
|
||||||
/* #undef HAVE_EXTATTR_GET_FD */
|
/* #undef HAVE_EXTATTR_GET_FD */
|
||||||
@@ -606,7 +605,7 @@
|
|||||||
/* #undef HAVE_LCHFLAGS */
|
/* #undef HAVE_LCHFLAGS */
|
||||||
|
|
||||||
/* Define to 1 if you have the `lchmod' function. */
|
/* Define to 1 if you have the `lchmod' function. */
|
||||||
/* #undef HAVE_LCHMOD 1 */
|
/* #undef HAVE_LCHMOD */
|
||||||
|
|
||||||
/* Define to 1 if you have the `lchown' function. */
|
/* Define to 1 if you have the `lchown' function. */
|
||||||
#define HAVE_LCHOWN 1
|
#define HAVE_LCHOWN 1
|
||||||
@@ -1028,10 +1027,10 @@
|
|||||||
/* #undef HAVE_STRUCT_STAT_ST_UMTIME */
|
/* #undef HAVE_STRUCT_STAT_ST_UMTIME */
|
||||||
|
|
||||||
/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
|
/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
|
||||||
/* #undef HAVE_STRUCT_TM_TM_GMTOFF 1 */
|
#define HAVE_STRUCT_TM_TM_GMTOFF 1
|
||||||
|
|
||||||
/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */
|
/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */
|
||||||
/* #undef HAVE_STRUCT_TM___TM_GMTOFF 1 */
|
/* #undef HAVE_STRUCT_TM___TM_GMTOFF */
|
||||||
|
|
||||||
/* Define to 1 if the system has the type `struct vfsconf'. */
|
/* Define to 1 if the system has the type `struct vfsconf'. */
|
||||||
/* #undef HAVE_STRUCT_VFSCONF */
|
/* #undef HAVE_STRUCT_VFSCONF */
|
||||||
@@ -1043,10 +1042,9 @@
|
|||||||
#define HAVE_SYMLINK 1
|
#define HAVE_SYMLINK 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/acl.h> header file. */
|
/* Define to 1 if you have the <sys/acl.h> header file. */
|
||||||
/* #undef HAVE_SYS_ACL_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/cdefs.h> header file. */
|
/* Define to 1 if you have the <sys/cdefs.h> header file. */
|
||||||
/* #undef HAVE_SYS_CDEFS_H */
|
#define HAVE_SYS_CDEFS_H 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||||
*/
|
*/
|
||||||
@@ -1204,7 +1202,7 @@
|
|||||||
#define HAVE_WMEMMOVE 1
|
#define HAVE_WMEMMOVE 1
|
||||||
|
|
||||||
/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
|
/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
|
||||||
/* #undef HAVE_WORKING_EXT2_IOC_GETFLAGS */
|
#define HAVE_WORKING_EXT2_IOC_GETFLAGS 1
|
||||||
|
|
||||||
/* Define to 1 if you have a working FS_IOC_GETFLAGS */
|
/* Define to 1 if you have a working FS_IOC_GETFLAGS */
|
||||||
#define HAVE_WORKING_FS_IOC_GETFLAGS 1
|
#define HAVE_WORKING_FS_IOC_GETFLAGS 1
|
||||||
@@ -1291,7 +1289,7 @@
|
|||||||
#define STDC_HEADERS 1
|
#define STDC_HEADERS 1
|
||||||
|
|
||||||
/* Define to 1 if strerror_r returns char *. */
|
/* Define to 1 if strerror_r returns char *. */
|
||||||
/* #undef STRERROR_R_CHAR_P */
|
#define STRERROR_R_CHAR_P 1
|
||||||
|
|
||||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||||
#define TIME_WITH_SYS_TIME 1
|
#define TIME_WITH_SYS_TIME 1
|
||||||
|
|||||||
@@ -40,13 +40,7 @@ export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
|
|||||||
|
|
||||||
See `ghcup --help`.
|
See `ghcup --help`.
|
||||||
|
|
||||||
For the simple interactive TUI, run:
|
Common use cases are:
|
||||||
|
|
||||||
```sh
|
|
||||||
ghcup tui
|
|
||||||
```
|
|
||||||
|
|
||||||
For the full functionality via cli:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# list available ghc/cabal versions
|
# list available ghc/cabal versions
|
||||||
|
|||||||
@@ -1,320 +0,0 @@
|
|||||||
{-# LANGUAGE DataKinds #-}
|
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
|
||||||
{-# LANGUAGE TypeApplications #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
|
|
||||||
module BrickMain where
|
|
||||||
|
|
||||||
import GHCup
|
|
||||||
import GHCup.Download
|
|
||||||
import GHCup.Errors
|
|
||||||
import GHCup.Types
|
|
||||||
import GHCup.Utils
|
|
||||||
import GHCup.Utils.File
|
|
||||||
import GHCup.Utils.Logger
|
|
||||||
|
|
||||||
import Brick
|
|
||||||
import Brick.Widgets.Border
|
|
||||||
import Brick.Widgets.Border.Style
|
|
||||||
import Brick.Widgets.Center
|
|
||||||
import Brick.Widgets.List
|
|
||||||
import Codec.Archive
|
|
||||||
import Control.Exception.Safe
|
|
||||||
import Control.Monad.Logger
|
|
||||||
import Control.Monad.Reader
|
|
||||||
import Control.Monad.Trans.Resource
|
|
||||||
import Data.Bool
|
|
||||||
import Data.Functor
|
|
||||||
import Data.List
|
|
||||||
import Data.Maybe
|
|
||||||
import Data.Char
|
|
||||||
import Data.IORef
|
|
||||||
import Data.String.Interpolate
|
|
||||||
import Data.Vector ( Vector )
|
|
||||||
import Data.Versions hiding ( str )
|
|
||||||
import Haskus.Utils.Variant.Excepts
|
|
||||||
import Prelude hiding ( appendFile )
|
|
||||||
import System.Exit
|
|
||||||
import System.IO.Unsafe
|
|
||||||
import URI.ByteString
|
|
||||||
|
|
||||||
import qualified Data.Text as T
|
|
||||||
import qualified Graphics.Vty as Vty
|
|
||||||
import qualified Data.Vector as V
|
|
||||||
|
|
||||||
|
|
||||||
data AppState = AppState {
|
|
||||||
lr :: LR
|
|
||||||
, dls :: GHCupDownloads
|
|
||||||
}
|
|
||||||
|
|
||||||
type LR = GenericList String Vector ListResult
|
|
||||||
|
|
||||||
|
|
||||||
keyHandlers :: [(Char, String, AppState -> EventM n (Next AppState))]
|
|
||||||
keyHandlers =
|
|
||||||
[ ('q', "Quit" , halt)
|
|
||||||
, ('i', "Install" , withIOAction install')
|
|
||||||
, ('u', "Uninstall", withIOAction del')
|
|
||||||
, ('s', "Set" , withIOAction set')
|
|
||||||
, ('c', "ChangeLog", withIOAction changelog')
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
ui :: AppState -> Widget String
|
|
||||||
ui AppState {..} =
|
|
||||||
( padBottom Max
|
|
||||||
$ ( withBorderStyle unicode
|
|
||||||
$ borderWithLabel (str "GHCup")
|
|
||||||
$ (center $ renderList renderItem True lr)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<=> ( withAttr "help"
|
|
||||||
. txtWrap
|
|
||||||
. T.pack
|
|
||||||
. foldr1 (\x y -> x <> " " <> y)
|
|
||||||
. (++ ["↑↓:Navigation"])
|
|
||||||
$ (fmap (\(c, s, _) -> (c : ':' : s)) keyHandlers)
|
|
||||||
)
|
|
||||||
|
|
||||||
where
|
|
||||||
renderItem b ListResult {..} =
|
|
||||||
let marks = if
|
|
||||||
| lSet -> (withAttr "set" $ str "✔✔")
|
|
||||||
| lInstalled -> (withAttr "installed" $ str "✓ ")
|
|
||||||
| otherwise -> (withAttr "not-installed" $ str "✗ ")
|
|
||||||
ver = case lCross of
|
|
||||||
Nothing -> T.unpack . prettyVer $ lVer
|
|
||||||
Just c -> T.unpack (c <> "-" <> prettyVer lVer)
|
|
||||||
in ( marks
|
|
||||||
<+> ( padLeft (Pad 2)
|
|
||||||
$ minHSize 20
|
|
||||||
$ (withAttr
|
|
||||||
(bool "inactive" "active" b)
|
|
||||||
(str $ (fmap toLower . show $ lTool) <> " " <> ver)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<+> (padLeft (Pad 1) $ if null lTag
|
|
||||||
then emptyWidget
|
|
||||||
else
|
|
||||||
foldr1 (\x y -> x <+> str "," <+> y)
|
|
||||||
$ (fmap printTag $ sort lTag)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
printTag Recommended = withAttr "recommended" $ str "recommended"
|
|
||||||
printTag Latest = withAttr "latest" $ str "latest"
|
|
||||||
printTag (Base pvp'') = str ("base-" ++ T.unpack (prettyPVP pvp''))
|
|
||||||
printTag (UnknownTag t ) = str t
|
|
||||||
|
|
||||||
|
|
||||||
minHSize :: Int -> Widget n -> Widget n
|
|
||||||
minHSize s' = hLimit s' . vLimit 1 . (<+> fill ' ')
|
|
||||||
|
|
||||||
|
|
||||||
app :: App AppState e String
|
|
||||||
app = App { appDraw = \st -> [ui st]
|
|
||||||
, appHandleEvent = eventHandler
|
|
||||||
, appStartEvent = return
|
|
||||||
, appAttrMap = const theMap
|
|
||||||
, appChooseCursor = neverShowCursor
|
|
||||||
}
|
|
||||||
where
|
|
||||||
theMap = attrMap
|
|
||||||
Vty.defAttr
|
|
||||||
[ ("active" , bg Vty.blue)
|
|
||||||
, ("not-installed", fg Vty.red)
|
|
||||||
, ("set" , fg Vty.green)
|
|
||||||
, ("installed" , fg Vty.green)
|
|
||||||
, ("recommended" , fg Vty.green)
|
|
||||||
, ("latest" , fg Vty.yellow)
|
|
||||||
, ("help" , Vty.defAttr `Vty.withStyle` Vty.italic)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
eventHandler :: AppState -> BrickEvent n e -> EventM n (Next AppState)
|
|
||||||
eventHandler st (VtyEvent (Vty.EvResize _ _)) = continue st
|
|
||||||
eventHandler st (VtyEvent (Vty.EvKey (Vty.KChar 'q') _)) = halt st
|
|
||||||
eventHandler st (VtyEvent (Vty.EvKey Vty.KEsc _)) = halt st
|
|
||||||
eventHandler AppState {..} (VtyEvent (Vty.EvKey (Vty.KUp) _)) =
|
|
||||||
continue (AppState (listMoveUp lr) dls)
|
|
||||||
eventHandler AppState {..} (VtyEvent (Vty.EvKey (Vty.KDown) _)) =
|
|
||||||
continue (AppState (listMoveDown lr) dls)
|
|
||||||
eventHandler as (VtyEvent (Vty.EvKey (Vty.KChar c) _)) =
|
|
||||||
case find (\(c', _, _) -> c' == c) keyHandlers of
|
|
||||||
Nothing -> continue as
|
|
||||||
Just (_, _, handler) -> handler as
|
|
||||||
eventHandler st _ = continue st
|
|
||||||
|
|
||||||
|
|
||||||
-- | 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.
|
|
||||||
withIOAction :: (AppState -> (Int, ListResult) -> IO (Either String a))
|
|
||||||
-> AppState
|
|
||||||
-> EventM n (Next AppState)
|
|
||||||
withIOAction action as = case listSelectedElement (lr as) of
|
|
||||||
Nothing -> continue as
|
|
||||||
Just (ix, e) -> suspendAndResume $ do
|
|
||||||
r <- action as (ix, e)
|
|
||||||
case r of
|
|
||||||
Left err -> throwIO $ userError err
|
|
||||||
Right _ -> do
|
|
||||||
apps <- (fmap . fmap)
|
|
||||||
(\AppState {..} -> AppState { lr = listMoveTo ix lr, .. })
|
|
||||||
getAppState
|
|
||||||
case apps of
|
|
||||||
Right nas -> do
|
|
||||||
putStrLn "Press enter to continue"
|
|
||||||
_ <- getLine
|
|
||||||
pure nas
|
|
||||||
Left err -> throwIO $ userError err
|
|
||||||
|
|
||||||
|
|
||||||
install' :: AppState -> (Int, ListResult) -> IO (Either String ())
|
|
||||||
install' AppState {..} (_, ListResult {..}) = do
|
|
||||||
settings <- readIORef settings'
|
|
||||||
l <- readIORef logger'
|
|
||||||
let runLogger = myLoggerT l
|
|
||||||
|
|
||||||
let
|
|
||||||
run =
|
|
||||||
runLogger
|
|
||||||
. flip runReaderT settings
|
|
||||||
. runResourceT
|
|
||||||
. runE
|
|
||||||
@'[AlreadyInstalled, UnknownArchive, ArchiveResult, DistroNotFound, FileDoesNotExistError, CopyError, NoCompatibleArch, NoDownload, NotInstalled, NoCompatiblePlatform, BuildFailed, TagNotFound, DigestError, DownloadFailed, NoUpdate]
|
|
||||||
|
|
||||||
(run $ do
|
|
||||||
case lTool of
|
|
||||||
GHC -> liftE $ installGHCBin dls lVer Nothing
|
|
||||||
Cabal -> liftE $ installCabalBin dls lVer Nothing
|
|
||||||
GHCup -> liftE $ upgradeGHCup dls Nothing False $> ()
|
|
||||||
)
|
|
||||||
>>= \case
|
|
||||||
VRight _ -> pure $ Right ()
|
|
||||||
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
|
||||||
VLeft (V (BuildFailed _ e)) ->
|
|
||||||
pure $ Left [i|Build failed with #{e}|]
|
|
||||||
VLeft (V NoDownload) ->
|
|
||||||
pure $ Left [i|No available version for #{prettyVer lVer}|]
|
|
||||||
VLeft (V NoUpdate) -> pure $ Right ()
|
|
||||||
VLeft e -> pure $ Left [i|#{e}
|
|
||||||
Also check the logs in ~/.ghcup/logs|]
|
|
||||||
|
|
||||||
|
|
||||||
set' :: AppState -> (Int, ListResult) -> IO (Either String ())
|
|
||||||
set' _ (_, ListResult {..}) = do
|
|
||||||
settings <- readIORef settings'
|
|
||||||
l <- readIORef logger'
|
|
||||||
let runLogger = myLoggerT l
|
|
||||||
|
|
||||||
let run =
|
|
||||||
runLogger
|
|
||||||
. flip runReaderT settings
|
|
||||||
. runE @'[FileDoesNotExistError, NotInstalled, TagNotFound]
|
|
||||||
|
|
||||||
(run $ do
|
|
||||||
case lTool of
|
|
||||||
GHC -> liftE $ setGHC (GHCTargetVersion lCross lVer) SetGHCOnly $> ()
|
|
||||||
Cabal -> liftE $ setCabal lVer $> ()
|
|
||||||
GHCup -> pure ()
|
|
||||||
)
|
|
||||||
>>= \case
|
|
||||||
VRight _ -> pure $ Right ()
|
|
||||||
VLeft e -> pure $ Left [i|#{e}|]
|
|
||||||
|
|
||||||
|
|
||||||
del' :: AppState -> (Int, ListResult) -> IO (Either String ())
|
|
||||||
del' _ (_, ListResult {..}) = do
|
|
||||||
settings <- readIORef settings'
|
|
||||||
l <- readIORef logger'
|
|
||||||
let runLogger = myLoggerT l
|
|
||||||
|
|
||||||
let run = runLogger . flip runReaderT settings . runE @'[NotInstalled]
|
|
||||||
|
|
||||||
(run $ do
|
|
||||||
case lTool of
|
|
||||||
GHC -> liftE $ rmGHCVer (GHCTargetVersion lCross lVer) $> ()
|
|
||||||
Cabal -> liftE $ rmCabalVer lVer $> ()
|
|
||||||
GHCup -> pure ()
|
|
||||||
)
|
|
||||||
>>= \case
|
|
||||||
VRight _ -> pure $ Right ()
|
|
||||||
VLeft e -> pure $ Left [i|#{e}|]
|
|
||||||
|
|
||||||
|
|
||||||
changelog' :: AppState -> (Int, ListResult) -> IO (Either String ())
|
|
||||||
changelog' AppState {..} (_, ListResult {..}) = do
|
|
||||||
case getChangeLog dls lTool (Left lVer) of
|
|
||||||
Nothing -> pure $ Left
|
|
||||||
[i|Could not find ChangeLog for #{lTool}, version #{prettyVer lVer}|]
|
|
||||||
Just uri -> do
|
|
||||||
exec "xdg-open" True [serializeURIRef' uri] Nothing Nothing >>= \case
|
|
||||||
Right _ -> pure $ Right ()
|
|
||||||
Left e -> pure $ Left [i|#{e}|]
|
|
||||||
|
|
||||||
|
|
||||||
settings' :: IORef Settings
|
|
||||||
{-# NOINLINE settings' #-}
|
|
||||||
settings' = unsafePerformIO
|
|
||||||
(newIORef Settings { cache = True
|
|
||||||
, noVerify = False
|
|
||||||
, keepDirs = Never
|
|
||||||
, downloader = Curl
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
logger' :: IORef LoggerConfig
|
|
||||||
{-# NOINLINE logger' #-}
|
|
||||||
logger' = unsafePerformIO
|
|
||||||
(newIORef $ LoggerConfig { lcPrintDebug = False
|
|
||||||
, colorOutter = \_ -> pure ()
|
|
||||||
, rawOutter = \_ -> pure ()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
brickMain :: Settings -> LoggerConfig -> IO ()
|
|
||||||
brickMain s l = do
|
|
||||||
writeIORef settings' s
|
|
||||||
-- logger interpreter
|
|
||||||
writeIORef logger' l
|
|
||||||
let runLogger = myLoggerT l
|
|
||||||
|
|
||||||
eApps <- getAppState
|
|
||||||
case eApps of
|
|
||||||
Right as -> defaultMain app (selectLatest as) $> ()
|
|
||||||
Left e -> do
|
|
||||||
runLogger ($(logError) [i|Error building app state: #{show e}|])
|
|
||||||
exitWith $ ExitFailure 2
|
|
||||||
where
|
|
||||||
selectLatest :: AppState -> AppState
|
|
||||||
selectLatest AppState {..} =
|
|
||||||
(\ix -> AppState { lr = listMoveTo ix lr, .. })
|
|
||||||
. fromJust
|
|
||||||
. V.findIndex (\ListResult {..} -> lTool == GHC && Latest `elem` lTag)
|
|
||||||
$ (listElements lr)
|
|
||||||
|
|
||||||
|
|
||||||
getAppState :: IO (Either String AppState)
|
|
||||||
getAppState = do
|
|
||||||
settings <- readIORef settings'
|
|
||||||
l <- readIORef logger'
|
|
||||||
let runLogger = myLoggerT l
|
|
||||||
|
|
||||||
r <-
|
|
||||||
runLogger
|
|
||||||
. flip runReaderT settings
|
|
||||||
. runE
|
|
||||||
@'[JSONError, DownloadFailed, FileDoesNotExistError, NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
|
|
||||||
$ do
|
|
||||||
(GHCupInfo _ dls) <- liftE $ getDownloadsF GHCupURL
|
|
||||||
|
|
||||||
lV <- liftE $ listVersions dls Nothing Nothing
|
|
||||||
pure $ (AppState (list "Tool versions" (V.fromList lV) 1) dls)
|
|
||||||
|
|
||||||
case r of
|
|
||||||
VRight a -> pure $ Right a
|
|
||||||
VLeft e -> pure $ Left [i|#{e}|]
|
|
||||||
@@ -10,10 +10,6 @@
|
|||||||
|
|
||||||
module Main where
|
module Main where
|
||||||
|
|
||||||
#if defined(BRICK)
|
|
||||||
import BrickMain ( brickMain )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
@@ -99,9 +95,6 @@ data Command
|
|||||||
| Upgrade UpgradeOpts Bool
|
| Upgrade UpgradeOpts Bool
|
||||||
| ToolRequirements
|
| ToolRequirements
|
||||||
| ChangeLog ChangeLogOptions
|
| ChangeLog ChangeLogOptions
|
||||||
#if defined(BRICK)
|
|
||||||
| Interactive
|
|
||||||
#endif
|
|
||||||
|
|
||||||
data ToolVersion = ToolVersion GHCTargetVersion -- target is ignored for cabal
|
data ToolVersion = ToolVersion GHCTargetVersion -- target is ignored for cabal
|
||||||
| ToolTag Tag
|
| ToolTag Tag
|
||||||
@@ -230,20 +223,7 @@ opts =
|
|||||||
com :: Parser Command
|
com :: Parser Command
|
||||||
com =
|
com =
|
||||||
subparser
|
subparser
|
||||||
#if defined(BRICK)
|
|
||||||
( command
|
( command
|
||||||
"tui"
|
|
||||||
( (\_ -> Interactive)
|
|
||||||
<$> (info
|
|
||||||
helper
|
|
||||||
( progDesc "Start the interactive GHCup UI"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<> command
|
|
||||||
#else
|
|
||||||
( command
|
|
||||||
#endif
|
|
||||||
"install"
|
"install"
|
||||||
( Install
|
( Install
|
||||||
<$> (info
|
<$> (info
|
||||||
@@ -890,12 +870,11 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
|
|
||||||
-- logger interpreter
|
-- logger interpreter
|
||||||
logfile <- initGHCupFileLogging [rel|ghcup.log|]
|
logfile <- initGHCupFileLogging [rel|ghcup.log|]
|
||||||
let loggerConfig = LoggerConfig
|
let runLogger = myLoggerT LoggerConfig
|
||||||
{ lcPrintDebug = optVerbose
|
{ lcPrintDebug = optVerbose
|
||||||
, colorOutter = B.hPut stderr
|
, colorOutter = B.hPut stderr
|
||||||
, rawOutter = appendFile logfile
|
, rawOutter = appendFile logfile
|
||||||
}
|
}
|
||||||
let runLogger = myLoggerT loggerConfig
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------
|
-------------------------
|
||||||
@@ -931,6 +910,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
@'[ FileDoesNotExistError
|
@'[ FileDoesNotExistError
|
||||||
, NotInstalled
|
, NotInstalled
|
||||||
, TagNotFound
|
, TagNotFound
|
||||||
|
, TagNotFound
|
||||||
]
|
]
|
||||||
|
|
||||||
let
|
let
|
||||||
@@ -943,7 +923,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
|
|
||||||
let runListGHC = runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
|
let runListGHC = runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
|
||||||
|
|
||||||
let runRm =
|
let runRmGHC =
|
||||||
runLogger . flip runReaderT settings . runE @'[NotInstalled]
|
runLogger . flip runReaderT settings . runE @'[NotInstalled]
|
||||||
|
|
||||||
let runDebugInfo =
|
let runDebugInfo =
|
||||||
@@ -1127,7 +1107,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
pure $ ExitFailure 14
|
pure $ ExitFailure 14
|
||||||
|
|
||||||
let rmGHC' RmOptions{..} =
|
let rmGHC' RmOptions{..} =
|
||||||
(runRm $ do
|
(runRmGHC $ do
|
||||||
liftE $ rmGHCVer ghcVer
|
liftE $ rmGHCVer ghcVer
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -1137,7 +1117,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
pure $ ExitFailure 7
|
pure $ ExitFailure 7
|
||||||
|
|
||||||
let rmCabal' tv =
|
let rmCabal' tv =
|
||||||
(runRm $ do
|
(runSetCabal $ do
|
||||||
liftE $ rmCabalVer tv
|
liftE $ rmCabalVer tv
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
@@ -1149,9 +1129,6 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
|
|
||||||
|
|
||||||
res <- case optCommand of
|
res <- case optCommand of
|
||||||
#if defined(BRICK)
|
|
||||||
Interactive -> liftIO $ brickMain settings loggerConfig >> pure ExitSuccess
|
|
||||||
#endif
|
|
||||||
Install (Right iopts) -> do
|
Install (Right iopts) -> do
|
||||||
runLogger ($(logWarn) [i|This is an old-style command for installing GHC. Use 'ghcup install ghc' instead.|])
|
runLogger ($(logWarn) [i|This is an old-style command for installing GHC. Use 'ghcup install ghc' instead.|])
|
||||||
installGHC iopts
|
installGHC iopts
|
||||||
|
|||||||
19
ghcup.cabal
19
ghcup.cabal
@@ -21,11 +21,6 @@ source-repository head
|
|||||||
type: git
|
type: git
|
||||||
location: https://gitlab.haskell.org/haskell/ghcup-hs.git
|
location: https://gitlab.haskell.org/haskell/ghcup-hs.git
|
||||||
|
|
||||||
flag tui
|
|
||||||
description: Build the brick powered tui (ghcup tui)
|
|
||||||
default: False
|
|
||||||
manual: True
|
|
||||||
|
|
||||||
flag internal-downloader
|
flag internal-downloader
|
||||||
description: Compile the internal downloader, which links against OpenSSL
|
description: Compile the internal downloader, which links against OpenSSL
|
||||||
default: False
|
default: False
|
||||||
@@ -55,9 +50,6 @@ common base16-bytestring
|
|||||||
common binary
|
common binary
|
||||||
build-depends: binary >=0.8.6.0
|
build-depends: binary >=0.8.6.0
|
||||||
|
|
||||||
common brick
|
|
||||||
build-depends: brick >=0.54
|
|
||||||
|
|
||||||
common bytestring
|
common bytestring
|
||||||
build-depends: bytestring >=0.10
|
build-depends: bytestring >=0.10
|
||||||
|
|
||||||
@@ -166,6 +158,7 @@ common string-interpolate
|
|||||||
common table-layout
|
common table-layout
|
||||||
build-depends: table-layout >=0.8
|
build-depends: table-layout >=0.8
|
||||||
|
|
||||||
|
|
||||||
common template-haskell
|
common template-haskell
|
||||||
build-depends: template-haskell >=2.7
|
build-depends: template-haskell >=2.7
|
||||||
|
|
||||||
@@ -205,9 +198,6 @@ common vector
|
|||||||
common versions
|
common versions
|
||||||
build-depends: versions >=3.5
|
build-depends: versions >=3.5
|
||||||
|
|
||||||
common vty
|
|
||||||
build-depends: vty >=5.28.2
|
|
||||||
|
|
||||||
common word8
|
common word8
|
||||||
build-depends: word8 >=0.1.3
|
build-depends: word8 >=0.1.3
|
||||||
|
|
||||||
@@ -360,13 +350,6 @@ executable ghcup
|
|||||||
if flag(internal-downloader)
|
if flag(internal-downloader)
|
||||||
cpp-options: -DINTERNAL_DOWNLOADER
|
cpp-options: -DINTERNAL_DOWNLOADER
|
||||||
|
|
||||||
if flag(tui)
|
|
||||||
import:
|
|
||||||
brick
|
|
||||||
, vector
|
|
||||||
, vty
|
|
||||||
other-modules: BrickMain
|
|
||||||
cpp-options: -DBRICK
|
|
||||||
|
|
||||||
executable ghcup-gen
|
executable ghcup-gen
|
||||||
import:
|
import:
|
||||||
|
|||||||
21
lib/GHCup.hs
21
lib/GHCup.hs
@@ -927,13 +927,20 @@ upgradeGHCup dls mtarget force = do
|
|||||||
`unionFileModes` ownerExecuteMode
|
`unionFileModes` ownerExecuteMode
|
||||||
`unionFileModes` groupExecuteMode
|
`unionFileModes` groupExecuteMode
|
||||||
`unionFileModes` otherExecuteMode
|
`unionFileModes` otherExecuteMode
|
||||||
binDir <- liftIO $ ghcupBinDir
|
case mtarget of
|
||||||
let fullDest = fromMaybe (binDir </> fn) mtarget
|
Nothing -> do
|
||||||
liftIO $ hideError NoSuchThing $ deleteFile fullDest
|
dest <- liftIO $ ghcupBinDir
|
||||||
handleIO (throwE . CopyError . show) $ liftIO $ copyFile p
|
liftIO $ hideError NoSuchThing $ deleteFile (dest </> fn)
|
||||||
fullDest
|
handleIO (throwE . CopyError . show) $ liftIO $ copyFile p
|
||||||
Overwrite
|
(dest </> fn)
|
||||||
liftIO $ setFileMode (toFilePath fullDest) fileMode'
|
Overwrite
|
||||||
|
liftIO $ setFileMode (toFilePath (dest </> fn)) fileMode'
|
||||||
|
Just fullDest -> do
|
||||||
|
liftIO $ hideError NoSuchThing $ deleteFile fullDest
|
||||||
|
handleIO (throwE . CopyError . show) $ liftIO $ copyFile p
|
||||||
|
fullDest
|
||||||
|
Overwrite
|
||||||
|
liftIO $ setFileMode (toFilePath fullDest) fileMode'
|
||||||
pure latestVer
|
pure latestVer
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ body#idx p.other-help {
|
|||||||
|
|
||||||
.instructions div.command-button {
|
.instructions div.command-button {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instructions div.command-button button {
|
.instructions div.command-button button {
|
||||||
@@ -111,7 +112,7 @@ body#idx p.other-help {
|
|||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
margin-left: 1rem;
|
margin-left: 0.5rem;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
@@ -134,20 +135,21 @@ hr {
|
|||||||
#platform-instructions-linux > div > pre,
|
#platform-instructions-linux > div > pre,
|
||||||
#platform-instructions-mac > div > pre,
|
#platform-instructions-mac > div > pre,
|
||||||
#platform-instructions-freebsd > div > pre,
|
#platform-instructions-freebsd > div > pre,
|
||||||
#platform-instructions-win32 > pre,
|
#platform-instructions-win32 > div > pre,
|
||||||
#platform-instructions-win64 > pre,
|
#platform-instructions-win64 > div > pre,
|
||||||
#platform-instructions-default > div > div > pre,
|
#platform-instructions-default > div > div > pre,
|
||||||
#platform-instructions-unknown > div > div > pre {
|
#platform-instructions-unknown > div > div > pre {
|
||||||
background-color: #515151;
|
background-color: #515151;
|
||||||
color: white;
|
color: white;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: inset 0px 0px 20px 0px #333333;
|
box-shadow: inset 0px 0px 20px 0px #333333;
|
||||||
|
font-size: 0.6em;
|
||||||
|
width: 40rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#platform-instructions-win32 a.windows-download,
|
#platform-instructions-win32 a.windows-download,
|
||||||
|
|||||||
@@ -46,6 +46,9 @@
|
|||||||
<p>
|
<p>
|
||||||
To install Haskell, follow the instructions on
|
To install Haskell, follow the instructions on
|
||||||
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
||||||
|
<p>If you're a Windows Subsystem for Linux user run the following in your terminal, then follow the onscreen instructions to install Haskell.
|
||||||
|
</p>
|
||||||
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
</p>
|
</p>
|
||||||
<p class="other-help">You appear to be running Windows 32-bit. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
<p class="other-help">You appear to be running Windows 32-bit. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,6 +58,9 @@
|
|||||||
To install Haskell, follow the instructions on
|
To install Haskell, follow the instructions on
|
||||||
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
<a class="windows-download" href="https://www.haskell.org/platform/#windows">Haskell Platform</a>
|
||||||
</p>
|
</p>
|
||||||
|
<p>If you're a Windows Subsystem for Linux user run the following in your terminal, then follow the onscreen instructions to install Haskell.
|
||||||
|
</p>
|
||||||
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help">You appear to be running Windows 64-bit. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
<p class="other-help">You appear to be running Windows 64-bit. If not, <a class="default-platform-button" href="#">display all supported installers</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -77,7 +83,7 @@
|
|||||||
|
|
||||||
<!-- duplicate the default cross-platform instructions -->
|
<!-- duplicate the default cross-platform instructions -->
|
||||||
<div>
|
<div>
|
||||||
<p>If you are running Linux, macOS or FreeBSD,<br/>run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
<p>If you are running Linux, macOS, FreeBSD or Windows Subsystem for Linux, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -95,7 +101,7 @@
|
|||||||
|
|
||||||
<div id="platform-instructions-default" class="instructions">
|
<div id="platform-instructions-default" class="instructions">
|
||||||
<div>
|
<div>
|
||||||
<p>To install Haskell, if you are running Linux, macOS or FreeBSD,<br/>run the following
|
<p>To install Haskell, if you are running Linux, macOS, FreeBSD or Windows Subsystem for Linux, run the following
|
||||||
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
||||||
@@ -140,7 +146,7 @@
|
|||||||
|
|
||||||
<div id="platform-instructions-default" class="instructions">
|
<div id="platform-instructions-default" class="instructions">
|
||||||
<div>
|
<div>
|
||||||
<p>To install Haskell, if you are running Linux, macOS or FreeBSD,<br/>run the following
|
<p>To install Haskell, if you are running Linux, macOS, FreeBSD or Windows Subsystem for Linux, run the following
|
||||||
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre>
|
<pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre>
|
||||||
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
<p class="other-help">If you don't like curl | sh, see <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">other installation methods</a>.</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user