Redo Settings as AppState
This commit is contained in:
		
							parent
							
								
									0d41d180d6
								
							
						
					
					
						commit
						e250d6013f
					
				@ -193,7 +193,7 @@ validateTarballs dls = do
 | 
			
		||||
 where
 | 
			
		||||
  downloadAll dli = do
 | 
			
		||||
    dirs <- liftIO getDirs
 | 
			
		||||
    let settings = Settings True False Never Curl False dirs
 | 
			
		||||
    let settings = AppState (Settings True False Never Curl False) dirs
 | 
			
		||||
    let runLogger = myLoggerT LoggerConfig { lcPrintDebug = True
 | 
			
		||||
                                           , colorOutter  = B.hPut stderr
 | 
			
		||||
                                           , rawOutter    = (\_ -> pure ())
 | 
			
		||||
 | 
			
		||||
@ -55,35 +55,35 @@ import qualified Data.Vector                   as V
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
data AppData = AppData
 | 
			
		||||
data BrickData = BrickData
 | 
			
		||||
  { lr    :: [ListResult]
 | 
			
		||||
  , dls   :: GHCupDownloads
 | 
			
		||||
  , pfreq :: PlatformRequest
 | 
			
		||||
  }
 | 
			
		||||
  deriving Show
 | 
			
		||||
 | 
			
		||||
data AppSettings = AppSettings
 | 
			
		||||
data BrickSettings = BrickSettings
 | 
			
		||||
  { showAll :: Bool
 | 
			
		||||
  }
 | 
			
		||||
  deriving Show
 | 
			
		||||
 | 
			
		||||
data AppInternalState = AppInternalState
 | 
			
		||||
data BrickInternalState = BrickInternalState
 | 
			
		||||
  { clr :: Vector ListResult
 | 
			
		||||
  , ix  :: Int
 | 
			
		||||
  }
 | 
			
		||||
  deriving Show
 | 
			
		||||
 | 
			
		||||
data AppState = AppState
 | 
			
		||||
  { appData     :: AppData
 | 
			
		||||
  , appSettings :: AppSettings
 | 
			
		||||
  , appState    :: AppInternalState
 | 
			
		||||
data BrickState = BrickState
 | 
			
		||||
  { appData     :: BrickData
 | 
			
		||||
  , appSettings :: BrickSettings
 | 
			
		||||
  , appState    :: BrickInternalState
 | 
			
		||||
  }
 | 
			
		||||
  deriving Show
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
keyHandlers :: [ ( Char
 | 
			
		||||
                 , AppSettings -> String
 | 
			
		||||
                 , AppState -> EventM n (Next AppState)
 | 
			
		||||
                 , BrickSettings -> String
 | 
			
		||||
                 , BrickState -> EventM n (Next BrickState)
 | 
			
		||||
                 )
 | 
			
		||||
               ]
 | 
			
		||||
keyHandlers =
 | 
			
		||||
@ -93,21 +93,21 @@ keyHandlers =
 | 
			
		||||
  , ('s', const "Set"      , withIOAction set')
 | 
			
		||||
  , ('c', const "ChangeLog", withIOAction changelog')
 | 
			
		||||
  , ( 'a'
 | 
			
		||||
    , (\AppSettings {..} ->
 | 
			
		||||
    , (\BrickSettings {..} ->
 | 
			
		||||
        if showAll then "Hide old versions" else "Show all versions"
 | 
			
		||||
      )
 | 
			
		||||
    , hideShowHandler
 | 
			
		||||
    )
 | 
			
		||||
  ]
 | 
			
		||||
 where
 | 
			
		||||
  hideShowHandler (AppState {..}) =
 | 
			
		||||
  hideShowHandler (BrickState {..}) =
 | 
			
		||||
    let newAppSettings   = appSettings { showAll = not . showAll $ appSettings }
 | 
			
		||||
        newInternalState = constructList appData newAppSettings (Just appState)
 | 
			
		||||
    in  continue (AppState appData newAppSettings newInternalState)
 | 
			
		||||
    in  continue (BrickState appData newAppSettings newInternalState)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ui :: AppState -> Widget String
 | 
			
		||||
ui AppState { appData = AppData {..}, appSettings = as@(AppSettings {..}), ..}
 | 
			
		||||
ui :: BrickState -> Widget String
 | 
			
		||||
ui BrickState { appSettings = as@(BrickSettings {}), ..}
 | 
			
		||||
  = ( padBottom Max
 | 
			
		||||
    $ ( withBorderStyle unicode
 | 
			
		||||
      $ borderWithLabel (str "GHCup")
 | 
			
		||||
@ -196,9 +196,9 @@ ui AppState { appData = AppData {..}, appSettings = as@(AppSettings {..}), ..}
 | 
			
		||||
  -- available height.
 | 
			
		||||
  drawListElements :: (Int -> Bool -> ListResult -> Widget String)
 | 
			
		||||
                   -> Bool
 | 
			
		||||
                   -> AppInternalState
 | 
			
		||||
                   -> BrickInternalState
 | 
			
		||||
                   -> Widget String
 | 
			
		||||
  drawListElements drawElem foc is@(AppInternalState clr _) =
 | 
			
		||||
  drawListElements drawElem foc is@(BrickInternalState clr _) =
 | 
			
		||||
    Widget Greedy Greedy $
 | 
			
		||||
      let
 | 
			
		||||
        es = clr
 | 
			
		||||
@ -228,7 +228,7 @@ minHSize :: Int -> Widget n -> Widget n
 | 
			
		||||
minHSize s' = hLimit s' . vLimit 1 . (<+> fill ' ')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
app :: App AppState e String
 | 
			
		||||
app :: App BrickState e String
 | 
			
		||||
app = App { appDraw         = \st -> [ui st]
 | 
			
		||||
          , appHandleEvent  = eventHandler
 | 
			
		||||
          , appStartEvent   = return
 | 
			
		||||
@ -261,14 +261,14 @@ dimAttributes = attrMap
 | 
			
		||||
  , ("no-bindist", Vty.defAttr `Vty.withStyle` Vty.dim)
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
eventHandler :: AppState -> BrickEvent n e -> EventM n (Next AppState)
 | 
			
		||||
eventHandler :: BrickState -> BrickEvent n e -> EventM n (Next BrickState)
 | 
			
		||||
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 { appState = (moveCursor appState Up), .. })
 | 
			
		||||
eventHandler AppState {..} (VtyEvent (Vty.EvKey (Vty.KDown) _)) =
 | 
			
		||||
  continue (AppState { appState = (moveCursor appState Down), .. })
 | 
			
		||||
eventHandler BrickState {..} (VtyEvent (Vty.EvKey (Vty.KUp) _)) =
 | 
			
		||||
  continue (BrickState { appState = (moveCursor appState Up), .. })
 | 
			
		||||
eventHandler BrickState {..} (VtyEvent (Vty.EvKey (Vty.KDown) _)) =
 | 
			
		||||
  continue (BrickState { appState = (moveCursor appState Down), .. })
 | 
			
		||||
eventHandler as (VtyEvent (Vty.EvKey (Vty.KChar c) _)) =
 | 
			
		||||
  case find (\(c', _, _) -> c' == c) keyHandlers of
 | 
			
		||||
    Nothing              -> continue as
 | 
			
		||||
@ -276,19 +276,19 @@ eventHandler as (VtyEvent (Vty.EvKey (Vty.KChar c) _)) =
 | 
			
		||||
eventHandler st _ = continue st
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
moveCursor :: AppInternalState -> Direction -> AppInternalState
 | 
			
		||||
moveCursor ais@(AppInternalState {..}) direction =
 | 
			
		||||
moveCursor :: BrickInternalState -> Direction -> BrickInternalState
 | 
			
		||||
moveCursor ais@(BrickInternalState {..}) direction =
 | 
			
		||||
  let newIx = if direction == Down then ix + 1 else ix - 1
 | 
			
		||||
  in  case clr !? newIx of
 | 
			
		||||
        Just _  -> AppInternalState { ix = newIx, .. }
 | 
			
		||||
        Just _  -> BrickInternalState { ix = newIx, .. }
 | 
			
		||||
        Nothing -> ais
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | 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 :: (BrickState -> (Int, ListResult) -> IO (Either String a))
 | 
			
		||||
             -> BrickState
 | 
			
		||||
             -> EventM n (Next BrickState)
 | 
			
		||||
withIOAction action as = case listSelectedElement' (appState as) of
 | 
			
		||||
  Nothing      -> continue as
 | 
			
		||||
  Just (ix, e) -> suspendAndResume $ do
 | 
			
		||||
@ -304,26 +304,26 @@ withIOAction action as = case listSelectedElement' (appState as) of
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Update app data and list internal state based on new evidence.
 | 
			
		||||
-- This synchronises @AppInternalState@ with @AppData@
 | 
			
		||||
-- and @AppSettings@.
 | 
			
		||||
updateList :: AppData -> AppState -> AppState
 | 
			
		||||
updateList appD (AppState {..}) =
 | 
			
		||||
-- This synchronises @BrickInternalState@ with @BrickData@
 | 
			
		||||
-- and @BrickSettings@.
 | 
			
		||||
updateList :: BrickData -> BrickState -> BrickState
 | 
			
		||||
updateList appD (BrickState {..}) =
 | 
			
		||||
  let newInternalState = constructList appD appSettings (Just appState)
 | 
			
		||||
  in  AppState { appState    = newInternalState
 | 
			
		||||
  in  BrickState { appState    = newInternalState
 | 
			
		||||
               , appData     = appD
 | 
			
		||||
               , appSettings = appSettings
 | 
			
		||||
               }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
constructList :: AppData
 | 
			
		||||
              -> AppSettings
 | 
			
		||||
              -> Maybe AppInternalState
 | 
			
		||||
              -> AppInternalState
 | 
			
		||||
constructList :: BrickData
 | 
			
		||||
              -> BrickSettings
 | 
			
		||||
              -> Maybe BrickInternalState
 | 
			
		||||
              -> BrickInternalState
 | 
			
		||||
constructList appD appSettings mapp =
 | 
			
		||||
  replaceLR (filterVisible (showAll appSettings)) (lr appD) mapp
 | 
			
		||||
 | 
			
		||||
listSelectedElement' :: AppInternalState -> Maybe (Int, ListResult)
 | 
			
		||||
listSelectedElement' (AppInternalState {..}) = fmap (ix, ) $ clr !? ix
 | 
			
		||||
listSelectedElement' :: BrickInternalState -> Maybe (Int, ListResult)
 | 
			
		||||
listSelectedElement' (BrickInternalState {..}) = fmap (ix, ) $ clr !? ix
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
selectLatest :: Vector ListResult -> Int
 | 
			
		||||
@ -338,8 +338,8 @@ selectLatest v =
 | 
			
		||||
-- When passed an existing @appState@, tries to keep the selected element.
 | 
			
		||||
replaceLR :: (ListResult -> Bool)
 | 
			
		||||
          -> [ListResult]
 | 
			
		||||
          -> Maybe AppInternalState
 | 
			
		||||
          -> AppInternalState
 | 
			
		||||
          -> Maybe BrickInternalState
 | 
			
		||||
          -> BrickInternalState
 | 
			
		||||
replaceLR filterF lr s =
 | 
			
		||||
  let oldElem = s >>= listSelectedElement'
 | 
			
		||||
      newVec  = V.fromList . filter filterF $ lr
 | 
			
		||||
@ -347,7 +347,7 @@ replaceLR filterF lr s =
 | 
			
		||||
        case oldElem >>= \(_, oldE) -> V.findIndex (toolEqual oldE) newVec of
 | 
			
		||||
          Just ix -> ix
 | 
			
		||||
          Nothing -> selectLatest newVec
 | 
			
		||||
  in  AppInternalState newVec newSelected
 | 
			
		||||
  in  BrickInternalState newVec newSelected
 | 
			
		||||
 where
 | 
			
		||||
  toolEqual e1 e2 =
 | 
			
		||||
    lTool e1 == lTool e2 && lVer e1 == lVer e2 && lCross e1 == lCross e2
 | 
			
		||||
@ -359,8 +359,8 @@ filterVisible showAll e | lInstalled e = True
 | 
			
		||||
                        | otherwise    = not (elem Old (lTag e))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
install' :: AppState -> (Int, ListResult) -> IO (Either String ())
 | 
			
		||||
install' AppState { appData = AppData {..} } (_, ListResult {..}) = do
 | 
			
		||||
install' :: BrickState -> (Int, ListResult) -> IO (Either String ())
 | 
			
		||||
install' BrickState { appData = BrickData {..} } (_, ListResult {..}) = do
 | 
			
		||||
  settings <- readIORef settings'
 | 
			
		||||
  l        <- readIORef logger'
 | 
			
		||||
  let runLogger = myLoggerT l
 | 
			
		||||
@ -406,7 +406,7 @@ install' AppState { appData = AppData {..} } (_, ListResult {..}) = do
 | 
			
		||||
Also check the logs in ~/.ghcup/logs|]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
set' :: AppState -> (Int, ListResult) -> IO (Either String ())
 | 
			
		||||
set' :: BrickState -> (Int, ListResult) -> IO (Either String ())
 | 
			
		||||
set' _ (_, ListResult {..}) = do
 | 
			
		||||
  settings <- readIORef settings'
 | 
			
		||||
  l        <- readIORef logger'
 | 
			
		||||
@ -429,7 +429,7 @@ set' _ (_, ListResult {..}) = do
 | 
			
		||||
          VLeft  e -> pure $ Left [i|#{e}|]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
del' :: AppState -> (Int, ListResult) -> IO (Either String ())
 | 
			
		||||
del' :: BrickState -> (Int, ListResult) -> IO (Either String ())
 | 
			
		||||
del' _ (_, ListResult {..}) = do
 | 
			
		||||
  settings <- readIORef settings'
 | 
			
		||||
  l        <- readIORef logger'
 | 
			
		||||
@ -449,8 +449,8 @@ del' _ (_, ListResult {..}) = do
 | 
			
		||||
          VLeft  e -> pure $ Left [i|#{e}|]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
changelog' :: AppState -> (Int, ListResult) -> IO (Either String ())
 | 
			
		||||
changelog' AppState { appData = AppData {..} } (_, ListResult {..}) = do
 | 
			
		||||
changelog' :: BrickState -> (Int, ListResult) -> IO (Either String ())
 | 
			
		||||
changelog' BrickState { appData = BrickData {..} } (_, ListResult {..}) = do
 | 
			
		||||
  case getChangeLog dls lTool (Left lVer) of
 | 
			
		||||
    Nothing -> pure $ Left
 | 
			
		||||
      [i|Could not find ChangeLog for #{lTool}, version #{prettyVer lVer}|]
 | 
			
		||||
@ -469,17 +469,19 @@ uri' :: IORef (Maybe URI)
 | 
			
		||||
uri' = unsafePerformIO (newIORef Nothing)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
settings' :: IORef Settings
 | 
			
		||||
settings' :: IORef AppState
 | 
			
		||||
{-# NOINLINE settings' #-}
 | 
			
		||||
settings' = unsafePerformIO $ do
 | 
			
		||||
  dirs <- getDirs
 | 
			
		||||
  newIORef Settings { cache      = True
 | 
			
		||||
  newIORef $ AppState (Settings { cache      = True
 | 
			
		||||
                                , noVerify   = False
 | 
			
		||||
                                , keepDirs   = Never
 | 
			
		||||
                                , downloader = Curl
 | 
			
		||||
                                , verbose    = False
 | 
			
		||||
                                , ..
 | 
			
		||||
                    }
 | 
			
		||||
                                })
 | 
			
		||||
                      dirs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
logger' :: IORef LoggerConfig
 | 
			
		||||
@ -492,7 +494,7 @@ logger' = unsafePerformIO
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
brickMain :: Settings
 | 
			
		||||
brickMain :: AppState
 | 
			
		||||
          -> Maybe URI
 | 
			
		||||
          -> LoggerConfig
 | 
			
		||||
          -> GHCupDownloads
 | 
			
		||||
@ -510,7 +512,7 @@ brickMain s muri l av pfreq' = do
 | 
			
		||||
    Right ad ->
 | 
			
		||||
      defaultMain
 | 
			
		||||
          app
 | 
			
		||||
          (AppState ad
 | 
			
		||||
          (BrickState ad
 | 
			
		||||
                    defaultAppSettings
 | 
			
		||||
                    (constructList ad defaultAppSettings Nothing)
 | 
			
		||||
          )
 | 
			
		||||
@ -520,8 +522,8 @@ brickMain s muri l av pfreq' = do
 | 
			
		||||
      exitWith $ ExitFailure 2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
defaultAppSettings :: AppSettings
 | 
			
		||||
defaultAppSettings = AppSettings { showAll = False }
 | 
			
		||||
defaultAppSettings :: BrickSettings
 | 
			
		||||
defaultAppSettings = BrickSettings { showAll = False }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
getDownloads' :: IO (Either String GHCupDownloads)
 | 
			
		||||
@ -546,7 +548,7 @@ getDownloads' = do
 | 
			
		||||
 | 
			
		||||
getAppData :: Maybe GHCupDownloads
 | 
			
		||||
           -> PlatformRequest
 | 
			
		||||
           -> IO (Either String AppData)
 | 
			
		||||
           -> IO (Either String BrickData)
 | 
			
		||||
getAppData mg pfreq' = do
 | 
			
		||||
  settings <- readIORef settings'
 | 
			
		||||
  l        <- readIORef logger'
 | 
			
		||||
@ -558,6 +560,6 @@ getAppData mg pfreq' = do
 | 
			
		||||
    case r of
 | 
			
		||||
      Right dls -> do
 | 
			
		||||
        lV <- listVersions dls Nothing Nothing pfreq'
 | 
			
		||||
        pure $ Right $ (AppData (reverse lV) dls pfreq')
 | 
			
		||||
        pure $ Right $ (BrickData (reverse lV) dls pfreq')
 | 
			
		||||
      Left e -> pure $ Left [i|#{e}|]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -856,7 +856,7 @@ bindistParser :: String -> Either String URI
 | 
			
		||||
bindistParser = first show . parseURI strictURIParserOptions . UTF8.fromString
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
toSettings :: Options -> IO Settings
 | 
			
		||||
toSettings :: Options -> IO AppState
 | 
			
		||||
toSettings Options {..} = do
 | 
			
		||||
  let cache      = optCache
 | 
			
		||||
      noVerify   = optNoVerify
 | 
			
		||||
@ -864,7 +864,7 @@ toSettings Options {..} = do
 | 
			
		||||
      downloader = optsDownloader
 | 
			
		||||
      verbose    = optVerbose
 | 
			
		||||
  dirs <- getDirs
 | 
			
		||||
  pure $ Settings { .. }
 | 
			
		||||
  pure $ AppState (Settings { .. }) dirs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
upgradeOptsP :: Parser UpgradeOpts
 | 
			
		||||
@ -940,13 +940,13 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
            (footerDoc (Just $ text main_footer))
 | 
			
		||||
      )
 | 
			
		||||
    >>= \opt@Options {..} -> do
 | 
			
		||||
          settings@Settings{dirs = Dirs{..}, ..} <- toSettings opt
 | 
			
		||||
          appstate@AppState{dirs = Dirs{..}, ..} <- toSettings opt
 | 
			
		||||
 | 
			
		||||
          -- create ~/.ghcup dir
 | 
			
		||||
          createDirRecursive' baseDir
 | 
			
		||||
 | 
			
		||||
          -- logger interpreter
 | 
			
		||||
          logfile <- flip runReaderT settings $ initGHCupFileLogging [rel|ghcup.log|]
 | 
			
		||||
          logfile <- flip runReaderT appstate $ initGHCupFileLogging [rel|ghcup.log|]
 | 
			
		||||
          let loggerConfig = LoggerConfig
 | 
			
		||||
                { lcPrintDebug = optVerbose
 | 
			
		||||
                , colorOutter  = B.hPut stderr
 | 
			
		||||
@ -959,9 +959,9 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
          -- Effect interpreters --
 | 
			
		||||
          -------------------------
 | 
			
		||||
 | 
			
		||||
          let runInstTool' settings' =
 | 
			
		||||
          let runInstTool' appstate' =
 | 
			
		||||
                runLogger
 | 
			
		||||
                  . flip runReaderT settings'
 | 
			
		||||
                  . flip runReaderT appstate'
 | 
			
		||||
                  . runResourceT
 | 
			
		||||
                  . runE
 | 
			
		||||
                    @'[ AlreadyInstalled
 | 
			
		||||
@ -980,12 +980,12 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
                      , TarDirDoesNotExist
 | 
			
		||||
                      ]
 | 
			
		||||
 | 
			
		||||
          let runInstTool = runInstTool' settings
 | 
			
		||||
          let runInstTool = runInstTool' appstate
 | 
			
		||||
 | 
			
		||||
          let
 | 
			
		||||
            runSetGHC =
 | 
			
		||||
              runLogger
 | 
			
		||||
                . flip runReaderT settings
 | 
			
		||||
                . flip runReaderT appstate
 | 
			
		||||
                . runE
 | 
			
		||||
                  @'[ FileDoesNotExistError
 | 
			
		||||
                    , NotInstalled
 | 
			
		||||
@ -995,7 +995,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
          let
 | 
			
		||||
            runSetCabal =
 | 
			
		||||
              runLogger
 | 
			
		||||
                . flip runReaderT settings
 | 
			
		||||
                . flip runReaderT appstate
 | 
			
		||||
                . runE
 | 
			
		||||
                  @'[ NotInstalled
 | 
			
		||||
                    , TagNotFound
 | 
			
		||||
@ -1004,26 +1004,26 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
          let
 | 
			
		||||
            runSetHLS =
 | 
			
		||||
              runLogger
 | 
			
		||||
                . flip runReaderT settings
 | 
			
		||||
                . flip runReaderT appstate
 | 
			
		||||
                . runE
 | 
			
		||||
                  @'[ NotInstalled
 | 
			
		||||
                    , TagNotFound
 | 
			
		||||
                    ]
 | 
			
		||||
 | 
			
		||||
          let runListGHC = runLogger . flip runReaderT settings
 | 
			
		||||
          let runListGHC = runLogger . flip runReaderT appstate
 | 
			
		||||
 | 
			
		||||
          let runRm =
 | 
			
		||||
                runLogger . flip runReaderT settings . runE @'[NotInstalled]
 | 
			
		||||
                runLogger . flip runReaderT appstate . runE @'[NotInstalled]
 | 
			
		||||
 | 
			
		||||
          let runDebugInfo =
 | 
			
		||||
                runLogger
 | 
			
		||||
                  . flip runReaderT settings
 | 
			
		||||
                  . flip runReaderT appstate
 | 
			
		||||
                  . runE
 | 
			
		||||
                    @'[NoCompatiblePlatform , NoCompatibleArch , DistroNotFound]
 | 
			
		||||
 | 
			
		||||
          let runCompileGHC =
 | 
			
		||||
                runLogger
 | 
			
		||||
                  . flip runReaderT settings
 | 
			
		||||
                  . flip runReaderT appstate
 | 
			
		||||
                  . runResourceT
 | 
			
		||||
                  . runE
 | 
			
		||||
                    @'[ AlreadyInstalled
 | 
			
		||||
@ -1044,7 +1044,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
 | 
			
		||||
          let runUpgrade =
 | 
			
		||||
                runLogger
 | 
			
		||||
                  . flip runReaderT settings
 | 
			
		||||
                  . flip runReaderT appstate
 | 
			
		||||
                  . runResourceT
 | 
			
		||||
                  . runE
 | 
			
		||||
                    @'[ DigestError
 | 
			
		||||
@ -1072,7 +1072,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
 | 
			
		||||
          (GHCupInfo treq dls) <-
 | 
			
		||||
            ( runLogger
 | 
			
		||||
              . flip runReaderT settings
 | 
			
		||||
              . flip runReaderT appstate
 | 
			
		||||
              . runE @'[JSONError , DownloadFailed, FileDoesNotExistError]
 | 
			
		||||
              $ liftE
 | 
			
		||||
              $ getDownloadsF (maybe GHCupURL OwnSource optUrlSource)
 | 
			
		||||
@ -1086,7 +1086,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
 | 
			
		||||
          case optCommand of
 | 
			
		||||
            Upgrade _ _ -> pure ()
 | 
			
		||||
            _ -> runLogger $ flip runReaderT settings $ checkForUpdates dls pfreq
 | 
			
		||||
            _ -> runLogger $ flip runReaderT appstate $ checkForUpdates dls pfreq
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1099,7 +1099,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
                     Nothing -> runInstTool $ do
 | 
			
		||||
                       v <- liftE $ fromVersion dls instVer GHC
 | 
			
		||||
                       liftE $ installGHCBin dls (_tvVersion v) (fromMaybe pfreq instPlatform)
 | 
			
		||||
                     Just uri -> runInstTool' settings{noVerify = True} $ do
 | 
			
		||||
                     Just uri -> runInstTool' appstate{ settings = settings {noVerify = True}} $ do
 | 
			
		||||
                       v <- liftE $ fromVersion dls instVer GHC
 | 
			
		||||
                       liftE $ installGHCBindist
 | 
			
		||||
                         (DownloadInfo uri (Just $ RegexDir "ghc-.*") "")
 | 
			
		||||
@ -1115,7 +1115,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
                              [i|GHC ver #{prettyVer v} already installed, you may want to run 'ghcup rm ghc #{prettyVer v}' first|]
 | 
			
		||||
                            pure ExitSuccess
 | 
			
		||||
                          VLeft (V (BuildFailed tmpdir e)) -> do
 | 
			
		||||
                            case keepDirs of
 | 
			
		||||
                            case keepDirs settings of
 | 
			
		||||
                              Never -> runLogger ($(logError) [i|Build failed with #{e}|])
 | 
			
		||||
                              _ -> runLogger ($(logError) [i|Build failed with #{e}
 | 
			
		||||
    Check the logs at #{logsDir} and the build directory #{tmpdir} for more clues.
 | 
			
		||||
@ -1140,7 +1140,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
                   Nothing -> runInstTool $ do
 | 
			
		||||
                     v <- liftE $ fromVersion dls instVer Cabal
 | 
			
		||||
                     liftE $ installCabalBin dls (_tvVersion v) (fromMaybe pfreq instPlatform)
 | 
			
		||||
                   Just uri -> runInstTool' settings{noVerify = True} $ do
 | 
			
		||||
                   Just uri -> runInstTool' appstate{ settings = settings { noVerify = True}} $ do
 | 
			
		||||
                     v <- liftE $ fromVersion dls instVer Cabal
 | 
			
		||||
                     liftE $ installCabalBindist
 | 
			
		||||
                         (DownloadInfo uri Nothing "")
 | 
			
		||||
@ -1173,7 +1173,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
                   Nothing -> runInstTool $ do
 | 
			
		||||
                     v <- liftE $ fromVersion dls instVer HLS
 | 
			
		||||
                     liftE $ installHLSBin dls (_tvVersion v) (fromMaybe pfreq instPlatform)
 | 
			
		||||
                   Just uri -> runInstTool' settings{noVerify = True} $ do
 | 
			
		||||
                   Just uri -> runInstTool' appstate{ settings = settings { noVerify = True}} $ do
 | 
			
		||||
                     v <- liftE $ fromVersion dls instVer HLS
 | 
			
		||||
                     liftE $ installHLSBindist
 | 
			
		||||
                         (DownloadInfo uri Nothing "")
 | 
			
		||||
@ -1272,7 +1272,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
 | 
			
		||||
          res <- case optCommand of
 | 
			
		||||
#if defined(BRICK)
 | 
			
		||||
            Interactive -> liftIO $ brickMain settings optUrlSource loggerConfig dls pfreq >> pure ExitSuccess
 | 
			
		||||
            Interactive -> liftIO $ brickMain appstate optUrlSource loggerConfig dls pfreq >> pure ExitSuccess
 | 
			
		||||
#endif
 | 
			
		||||
            Install (Right iopts) -> do
 | 
			
		||||
              runLogger ($(logWarn) [i|This is an old-style command for installing GHC. Use 'ghcup install ghc' instead.|])
 | 
			
		||||
@ -1336,7 +1336,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
 | 
			
		||||
                          [i|GHC ver #{prettyVer v} already installed, you may want to run 'ghcup rm ghc #{prettyVer v}' first|]
 | 
			
		||||
                        pure ExitSuccess
 | 
			
		||||
                      VLeft (V (BuildFailed tmpdir e)) -> do
 | 
			
		||||
                        case keepDirs of
 | 
			
		||||
                        case keepDirs settings of
 | 
			
		||||
                          Never -> runLogger ($(logError) [i|Build failed with #{e}
 | 
			
		||||
Check the logs at #{logsDir}|])
 | 
			
		||||
                          _ -> runLogger ($(logError) [i|Build failed with #{e}
 | 
			
		||||
@ -1602,7 +1602,14 @@ printListResult raw lr = do
 | 
			
		||||
      | otherwise                        -> 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
checkForUpdates :: (MonadReader Settings m, MonadCatch m, MonadLogger m, MonadThrow m, MonadIO m, MonadFail m, MonadLogger m)
 | 
			
		||||
checkForUpdates :: ( MonadReader AppState m
 | 
			
		||||
                   , MonadCatch m
 | 
			
		||||
                   , MonadLogger m
 | 
			
		||||
                   , MonadThrow m
 | 
			
		||||
                   , MonadIO m
 | 
			
		||||
                   , MonadFail m
 | 
			
		||||
                   , MonadLogger m
 | 
			
		||||
                   )
 | 
			
		||||
                => GHCupDownloads
 | 
			
		||||
                -> PlatformRequest
 | 
			
		||||
                -> m ()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										74
									
								
								lib/GHCup.hs
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								lib/GHCup.hs
									
									
									
									
									
								
							@ -99,7 +99,7 @@ import qualified Data.Text.Encoding            as E
 | 
			
		||||
installGHCBindist :: ( MonadFail m
 | 
			
		||||
                     , MonadMask m
 | 
			
		||||
                     , MonadCatch m
 | 
			
		||||
                     , MonadReader Settings m
 | 
			
		||||
                     , MonadReader AppState m
 | 
			
		||||
                     , MonadLogger m
 | 
			
		||||
                     , MonadResource m
 | 
			
		||||
                     , MonadIO m
 | 
			
		||||
@ -142,7 +142,7 @@ installGHCBindist dlinfo ver pfreq = do
 | 
			
		||||
-- build system and nothing else.
 | 
			
		||||
installPackedGHC :: ( MonadMask m
 | 
			
		||||
                    , MonadCatch m
 | 
			
		||||
                    , MonadReader Settings m
 | 
			
		||||
                    , MonadReader AppState m
 | 
			
		||||
                    , MonadThrow m
 | 
			
		||||
                    , MonadLogger m
 | 
			
		||||
                    , MonadIO m
 | 
			
		||||
@ -178,7 +178,7 @@ installPackedGHC dl msubdir inst ver pfreq@(PlatformRequest {..}) = do
 | 
			
		||||
 | 
			
		||||
-- | Install an unpacked GHC distribution. This only deals with the GHC
 | 
			
		||||
-- build system and nothing else.
 | 
			
		||||
installUnpackedGHC :: ( MonadReader Settings m
 | 
			
		||||
installUnpackedGHC :: ( MonadReader AppState m
 | 
			
		||||
                      , MonadThrow m
 | 
			
		||||
                      , MonadLogger m
 | 
			
		||||
                      , MonadIO m
 | 
			
		||||
@ -214,7 +214,7 @@ installUnpackedGHC path inst ver (PlatformRequest {..}) = do
 | 
			
		||||
installGHCBin :: ( MonadFail m
 | 
			
		||||
                 , MonadMask m
 | 
			
		||||
                 , MonadCatch m
 | 
			
		||||
                 , MonadReader Settings m
 | 
			
		||||
                 , MonadReader AppState m
 | 
			
		||||
                 , MonadLogger m
 | 
			
		||||
                 , MonadResource m
 | 
			
		||||
                 , MonadIO m
 | 
			
		||||
@ -246,7 +246,7 @@ installGHCBin bDls ver pfreq = do
 | 
			
		||||
-- argument instead of looking it up from 'GHCupDownloads'.
 | 
			
		||||
installCabalBindist :: ( MonadMask m
 | 
			
		||||
                       , MonadCatch m
 | 
			
		||||
                       , MonadReader Settings m
 | 
			
		||||
                       , MonadReader AppState m
 | 
			
		||||
                       , MonadLogger m
 | 
			
		||||
                       , MonadResource m
 | 
			
		||||
                       , MonadIO m
 | 
			
		||||
@ -273,7 +273,7 @@ installCabalBindist :: ( MonadMask m
 | 
			
		||||
installCabalBindist dlinfo ver (PlatformRequest {..}) = do
 | 
			
		||||
  lift $ $(logDebug) [i|Requested to install cabal version #{ver}|]
 | 
			
		||||
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
 | 
			
		||||
  whenM
 | 
			
		||||
      (lift (cabalInstalled ver) >>= \a -> liftIO $
 | 
			
		||||
@ -328,7 +328,7 @@ installCabalBindist dlinfo ver (PlatformRequest {..}) = do
 | 
			
		||||
-- the latest installed version.
 | 
			
		||||
installCabalBin :: ( MonadMask m
 | 
			
		||||
                   , MonadCatch m
 | 
			
		||||
                   , MonadReader Settings m
 | 
			
		||||
                   , MonadReader AppState m
 | 
			
		||||
                   , MonadLogger m
 | 
			
		||||
                   , MonadResource m
 | 
			
		||||
                   , MonadIO m
 | 
			
		||||
@ -361,7 +361,7 @@ installCabalBin bDls ver pfreq = do
 | 
			
		||||
-- argument instead of looking it up from 'GHCupDownloads'.
 | 
			
		||||
installHLSBindist :: ( MonadMask m
 | 
			
		||||
                     , MonadCatch m
 | 
			
		||||
                     , MonadReader Settings m
 | 
			
		||||
                     , MonadReader AppState m
 | 
			
		||||
                     , MonadLogger m
 | 
			
		||||
                     , MonadResource m
 | 
			
		||||
                     , MonadIO m
 | 
			
		||||
@ -388,7 +388,7 @@ installHLSBindist :: ( MonadMask m
 | 
			
		||||
installHLSBindist dlinfo ver (PlatformRequest {..}) = do
 | 
			
		||||
  lift $ $(logDebug) [i|Requested to install hls version #{ver}|]
 | 
			
		||||
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
 | 
			
		||||
  whenM (lift (hlsInstalled ver))
 | 
			
		||||
    $ (throwE $ AlreadyInstalled HLS ver)
 | 
			
		||||
@ -452,7 +452,7 @@ installHLSBindist dlinfo ver (PlatformRequest {..}) = do
 | 
			
		||||
-- into @~\/.ghcup\/bin/@, as well as @haskell-languager-server-wrapper@.
 | 
			
		||||
installHLSBin :: ( MonadMask m
 | 
			
		||||
                 , MonadCatch m
 | 
			
		||||
                 , MonadReader Settings m
 | 
			
		||||
                 , MonadReader AppState m
 | 
			
		||||
                 , MonadLogger m
 | 
			
		||||
                 , MonadResource m
 | 
			
		||||
                 , MonadIO m
 | 
			
		||||
@ -498,7 +498,7 @@ installHLSBin bDls ver pfreq = do
 | 
			
		||||
--
 | 
			
		||||
-- Additionally creates a @~\/.ghcup\/share -> ~\/.ghcup\/ghc\/\<ver\>\/share symlink@
 | 
			
		||||
-- for 'SetGHCOnly' constructor.
 | 
			
		||||
setGHC :: ( MonadReader Settings m
 | 
			
		||||
setGHC :: ( MonadReader AppState m
 | 
			
		||||
          , MonadLogger m
 | 
			
		||||
          , MonadThrow m
 | 
			
		||||
          , MonadFail m
 | 
			
		||||
@ -515,7 +515,7 @@ setGHC ver sghc = do
 | 
			
		||||
  whenM (lift $ fmap not $ ghcInstalled ver) (throwE (NotInstalled GHC (ver ^. tvVersion % to prettyVer)))
 | 
			
		||||
 | 
			
		||||
  -- symlink destination
 | 
			
		||||
  Settings { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
  liftIO $ createDirRecursive' binDir
 | 
			
		||||
 | 
			
		||||
  -- first delete the old symlinks (this fixes compatibility issues
 | 
			
		||||
@ -556,12 +556,12 @@ setGHC ver sghc = do
 | 
			
		||||
 | 
			
		||||
 where
 | 
			
		||||
 | 
			
		||||
  symlinkShareDir :: (MonadReader Settings m, MonadIO m, MonadLogger m)
 | 
			
		||||
  symlinkShareDir :: (MonadReader AppState m, MonadIO m, MonadLogger m)
 | 
			
		||||
                  => Path Abs
 | 
			
		||||
                  -> ByteString
 | 
			
		||||
                  -> m ()
 | 
			
		||||
  symlinkShareDir ghcdir verBS = do
 | 
			
		||||
    Settings { dirs = Dirs {..} } <- ask
 | 
			
		||||
    AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
    let destdir = baseDir
 | 
			
		||||
    case sghc of
 | 
			
		||||
      SetGHCOnly -> do
 | 
			
		||||
@ -579,7 +579,7 @@ setGHC ver sghc = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Set the @~\/.ghcup\/bin\/cabal@ symlink.
 | 
			
		||||
setCabal :: (MonadReader Settings m, MonadLogger m, MonadThrow m, MonadFail m, MonadIO m)
 | 
			
		||||
setCabal :: (MonadReader AppState m, MonadLogger m, MonadThrow m, MonadFail m, MonadIO m)
 | 
			
		||||
         => Version
 | 
			
		||||
         -> Excepts '[NotInstalled] m ()
 | 
			
		||||
setCabal ver = do
 | 
			
		||||
@ -587,7 +587,7 @@ setCabal ver = do
 | 
			
		||||
  targetFile <- parseRel ("cabal-" <> verBS)
 | 
			
		||||
 | 
			
		||||
  -- symlink destination
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  liftIO $ createDirRecursive' binDir
 | 
			
		||||
 | 
			
		||||
  whenM (liftIO $ fmap not $ doesFileExist (binDir </> targetFile))
 | 
			
		||||
@ -613,7 +613,7 @@ setCabal ver = do
 | 
			
		||||
 | 
			
		||||
-- | Set the haskell-language-server symlinks.
 | 
			
		||||
setHLS :: ( MonadCatch m
 | 
			
		||||
          , MonadReader Settings m
 | 
			
		||||
          , MonadReader AppState m
 | 
			
		||||
          , MonadLogger m
 | 
			
		||||
          , MonadThrow m
 | 
			
		||||
          , MonadFail m
 | 
			
		||||
@ -622,7 +622,7 @@ setHLS :: ( MonadCatch m
 | 
			
		||||
       => Version
 | 
			
		||||
       -> Excepts '[NotInstalled] m ()
 | 
			
		||||
setHLS ver = do
 | 
			
		||||
  Settings { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
  liftIO $ createDirRecursive' binDir
 | 
			
		||||
 | 
			
		||||
  -- Delete old symlinks, since these might have different ghc versions than the
 | 
			
		||||
@ -703,7 +703,7 @@ listVersions :: ( MonadCatch m
 | 
			
		||||
                , MonadThrow m
 | 
			
		||||
                , MonadLogger m
 | 
			
		||||
                , MonadIO m
 | 
			
		||||
                , MonadReader Settings m
 | 
			
		||||
                , MonadReader AppState m
 | 
			
		||||
                )
 | 
			
		||||
             => GHCupDownloads
 | 
			
		||||
             -> Maybe Tool
 | 
			
		||||
@ -736,7 +736,7 @@ listVersions av lt criteria pfreq = do
 | 
			
		||||
      pure (ghcvers <> cabalvers <> hlsvers <> ghcupvers)
 | 
			
		||||
 | 
			
		||||
 where
 | 
			
		||||
  strayGHCs :: (MonadCatch m, MonadReader Settings m, MonadThrow m, MonadLogger m, MonadIO m)
 | 
			
		||||
  strayGHCs :: (MonadCatch m, MonadReader AppState m, MonadThrow m, MonadLogger m, MonadIO m)
 | 
			
		||||
            => Map.Map Version [Tag]
 | 
			
		||||
            -> m [ListResult]
 | 
			
		||||
  strayGHCs avTools = do
 | 
			
		||||
@ -778,7 +778,7 @@ listVersions av lt criteria pfreq = do
 | 
			
		||||
          [i|Could not parse version of stray directory #{toFilePath e}|]
 | 
			
		||||
        pure Nothing
 | 
			
		||||
 | 
			
		||||
  strayCabals :: (MonadReader Settings m, MonadCatch m, MonadThrow m, MonadLogger m, MonadIO m)
 | 
			
		||||
  strayCabals :: (MonadReader AppState m, MonadCatch m, MonadThrow m, MonadLogger m, MonadIO m)
 | 
			
		||||
            => Map.Map Version [Tag]
 | 
			
		||||
            -> m [ListResult]
 | 
			
		||||
  strayCabals avTools = do
 | 
			
		||||
@ -806,7 +806,7 @@ listVersions av lt criteria pfreq = do
 | 
			
		||||
          [i|Could not parse version of stray directory #{toFilePath e}|]
 | 
			
		||||
        pure Nothing
 | 
			
		||||
 | 
			
		||||
  strayHLS :: (MonadReader Settings m, MonadCatch m, MonadThrow m, MonadLogger m, MonadIO m)
 | 
			
		||||
  strayHLS :: (MonadReader AppState m, MonadCatch m, MonadThrow m, MonadLogger m, MonadIO m)
 | 
			
		||||
           => Map.Map Version [Tag]
 | 
			
		||||
           -> m [ListResult]
 | 
			
		||||
  strayHLS avTools = do
 | 
			
		||||
@ -835,7 +835,7 @@ listVersions av lt criteria pfreq = do
 | 
			
		||||
        pure Nothing
 | 
			
		||||
 | 
			
		||||
  -- NOTE: this are not cross ones, because no bindists
 | 
			
		||||
  toListResult :: (MonadReader Settings m, MonadIO m, MonadCatch m) => Tool -> (Version, [Tag]) -> m ListResult
 | 
			
		||||
  toListResult :: (MonadReader AppState m, MonadIO m, MonadCatch m) => Tool -> (Version, [Tag]) -> m ListResult
 | 
			
		||||
  toListResult t (v, tags) = case t of
 | 
			
		||||
    GHC -> do
 | 
			
		||||
      let lNoBindist = isLeft $ getDownloadInfo GHC v pfreq av
 | 
			
		||||
@ -904,7 +904,7 @@ listVersions av lt criteria pfreq = do
 | 
			
		||||
-- This may leave GHCup without a "set" version.
 | 
			
		||||
-- Will try to fix the ghc-x.y symlink after removal (e.g. to an
 | 
			
		||||
-- older version).
 | 
			
		||||
rmGHCVer :: ( MonadReader Settings m
 | 
			
		||||
rmGHCVer :: ( MonadReader AppState m
 | 
			
		||||
            , MonadThrow m
 | 
			
		||||
            , MonadLogger m
 | 
			
		||||
            , MonadIO m
 | 
			
		||||
@ -942,7 +942,7 @@ rmGHCVer ver = do
 | 
			
		||||
  forM_ v' $ \(mj, mi) -> lift (getGHCForMajor mj mi (_tvTarget ver))
 | 
			
		||||
    >>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY)
 | 
			
		||||
 | 
			
		||||
  Settings { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
 | 
			
		||||
  liftIO
 | 
			
		||||
    $ hideError doesNotExistErrorType
 | 
			
		||||
@ -952,7 +952,7 @@ rmGHCVer ver = do
 | 
			
		||||
 | 
			
		||||
-- | Delete a cabal version. Will try to fix the @cabal@ symlink
 | 
			
		||||
-- after removal (e.g. setting it to an older version).
 | 
			
		||||
rmCabalVer :: (MonadReader Settings m, MonadThrow m, MonadLogger m, MonadIO m, MonadFail m, MonadCatch m)
 | 
			
		||||
rmCabalVer :: (MonadReader AppState m, MonadThrow m, MonadLogger m, MonadIO m, MonadFail m, MonadCatch m)
 | 
			
		||||
           => Version
 | 
			
		||||
           -> Excepts '[NotInstalled] m ()
 | 
			
		||||
rmCabalVer ver = do
 | 
			
		||||
@ -960,7 +960,7 @@ rmCabalVer ver = do
 | 
			
		||||
 | 
			
		||||
  cSet      <- lift $ cabalSet
 | 
			
		||||
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
 | 
			
		||||
  cabalFile <- lift $ parseRel ("cabal-" <> verToBS ver)
 | 
			
		||||
  liftIO $ hideError doesNotExistErrorType $ deleteFile (binDir </> cabalFile)
 | 
			
		||||
@ -975,7 +975,7 @@ rmCabalVer ver = do
 | 
			
		||||
 | 
			
		||||
-- | Delete a hls version. Will try to fix the hls symlinks
 | 
			
		||||
-- after removal (e.g. setting it to an older version).
 | 
			
		||||
rmHLSVer :: (MonadReader Settings m, MonadThrow m, MonadLogger m, MonadIO m, MonadFail m, MonadCatch m)
 | 
			
		||||
rmHLSVer :: (MonadReader AppState m, MonadThrow m, MonadLogger m, MonadIO m, MonadFail m, MonadCatch m)
 | 
			
		||||
         => Version
 | 
			
		||||
         -> Excepts '[NotInstalled] m ()
 | 
			
		||||
rmHLSVer ver = do
 | 
			
		||||
@ -983,7 +983,7 @@ rmHLSVer ver = do
 | 
			
		||||
 | 
			
		||||
  isHlsSet      <- lift $ hlsSet
 | 
			
		||||
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
 | 
			
		||||
  bins <- lift $ hlsAllBinaries ver
 | 
			
		||||
  forM_ bins $ \f -> liftIO $ deleteFile (binDir </> f)
 | 
			
		||||
@ -1008,13 +1008,13 @@ rmHLSVer ver = do
 | 
			
		||||
    ------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
getDebugInfo :: (MonadReader Settings m, MonadLogger m, MonadCatch m, MonadIO m)
 | 
			
		||||
getDebugInfo :: (MonadReader AppState m, MonadLogger m, MonadCatch m, MonadIO m)
 | 
			
		||||
             => Excepts
 | 
			
		||||
                  '[NoCompatiblePlatform , NoCompatibleArch , DistroNotFound]
 | 
			
		||||
                  m
 | 
			
		||||
                  DebugInfo
 | 
			
		||||
getDebugInfo = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  let diBaseDir  = baseDir
 | 
			
		||||
  let diBinDir   = binDir
 | 
			
		||||
  diGHCDir       <- lift ghcupGHCBaseDir
 | 
			
		||||
@ -1034,7 +1034,7 @@ getDebugInfo = do
 | 
			
		||||
-- | Compile a GHC from source. This behaves wrt symlinks and installation
 | 
			
		||||
-- the same as 'installGHCBin'.
 | 
			
		||||
compileGHC :: ( MonadMask m
 | 
			
		||||
              , MonadReader Settings m
 | 
			
		||||
              , MonadReader AppState m
 | 
			
		||||
              , MonadThrow m
 | 
			
		||||
              , MonadResource m
 | 
			
		||||
              , MonadLogger m
 | 
			
		||||
@ -1135,7 +1135,7 @@ BUILD_SPHINX_PDF = NO
 | 
			
		||||
HADDOCK_DOCS = NO
 | 
			
		||||
Stage1Only = YES|]
 | 
			
		||||
 | 
			
		||||
  compileBindist :: ( MonadReader Settings m
 | 
			
		||||
  compileBindist :: ( MonadReader AppState m
 | 
			
		||||
                    , MonadThrow m
 | 
			
		||||
                    , MonadCatch m
 | 
			
		||||
                    , MonadLogger m
 | 
			
		||||
@ -1153,7 +1153,7 @@ Stage1Only = YES|]
 | 
			
		||||
    lift $ $(logInfo) [i|configuring build|]
 | 
			
		||||
    liftE $ checkBuildConfig
 | 
			
		||||
 | 
			
		||||
    Settings { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
    AppState { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
 | 
			
		||||
    forM_ patchdir $ \dir -> liftE $ applyPatches dir workdir
 | 
			
		||||
 | 
			
		||||
@ -1270,7 +1270,7 @@ Stage1Only = YES|]
 | 
			
		||||
-- | Upgrade ghcup and place it in @~\/.ghcup\/bin\/ghcup@,
 | 
			
		||||
-- if no path is provided.
 | 
			
		||||
upgradeGHCup :: ( MonadMask m
 | 
			
		||||
                , MonadReader Settings m
 | 
			
		||||
                , MonadReader AppState m
 | 
			
		||||
                , MonadCatch m
 | 
			
		||||
                , MonadLogger m
 | 
			
		||||
                , MonadThrow m
 | 
			
		||||
@ -1292,7 +1292,7 @@ upgradeGHCup :: ( MonadMask m
 | 
			
		||||
                  m
 | 
			
		||||
                  Version
 | 
			
		||||
upgradeGHCup dls mtarget force pfreq = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  lift $ $(logInfo) [i|Upgrading GHCup...|]
 | 
			
		||||
  let latestVer = fromJust $ getLatest dls GHCup
 | 
			
		||||
  when (not force && (latestVer <= pvpToVersion ghcUpVer)) $ throwE NoUpdate
 | 
			
		||||
@ -1317,7 +1317,7 @@ upgradeGHCup dls mtarget force pfreq = do
 | 
			
		||||
 | 
			
		||||
-- | Creates @ghc-x.y.z@ and @ghc-x.y@ symlinks. This is used for
 | 
			
		||||
-- both installing from source and bindist.
 | 
			
		||||
postGHCInstall :: ( MonadReader Settings m
 | 
			
		||||
postGHCInstall :: ( MonadReader AppState m
 | 
			
		||||
                  , MonadLogger m
 | 
			
		||||
                  , MonadThrow m
 | 
			
		||||
                  , MonadFail m
 | 
			
		||||
 | 
			
		||||
@ -114,7 +114,7 @@ getDownloadsF :: ( FromJSONKey Tool
 | 
			
		||||
                 , MonadLogger m
 | 
			
		||||
                 , MonadThrow m
 | 
			
		||||
                 , MonadFail m
 | 
			
		||||
                 , MonadReader Settings m
 | 
			
		||||
                 , MonadReader AppState m
 | 
			
		||||
                 )
 | 
			
		||||
              => URLSource
 | 
			
		||||
              -> Excepts
 | 
			
		||||
@ -133,7 +133,7 @@ getDownloadsF urlSource = do
 | 
			
		||||
    (OwnSpec   _) -> liftE $ getDownloads urlSource
 | 
			
		||||
 where
 | 
			
		||||
  readFromCache = do
 | 
			
		||||
    Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
    AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
    lift $ $(logWarn)
 | 
			
		||||
      [i|Could not get download info, trying cached version (this may not be recent!)|]
 | 
			
		||||
    let path = view pathL' ghcupURL
 | 
			
		||||
@ -155,7 +155,7 @@ getDownloads :: ( FromJSONKey Tool
 | 
			
		||||
                , MonadLogger m
 | 
			
		||||
                , MonadThrow m
 | 
			
		||||
                , MonadFail m
 | 
			
		||||
                , MonadReader Settings m
 | 
			
		||||
                , MonadReader AppState m
 | 
			
		||||
                )
 | 
			
		||||
             => URLSource
 | 
			
		||||
             -> Excepts '[JSONError , DownloadFailed] m GHCupInfo
 | 
			
		||||
@ -185,7 +185,7 @@ getDownloads urlSource = do
 | 
			
		||||
             , MonadIO m1
 | 
			
		||||
             , MonadFail m1
 | 
			
		||||
             , MonadLogger m1
 | 
			
		||||
             , MonadReader Settings m1
 | 
			
		||||
             , MonadReader AppState m1
 | 
			
		||||
             )
 | 
			
		||||
          => URI
 | 
			
		||||
          -> Excepts
 | 
			
		||||
@ -200,7 +200,7 @@ getDownloads urlSource = do
 | 
			
		||||
               m1
 | 
			
		||||
               L.ByteString
 | 
			
		||||
  smartDl uri' = do
 | 
			
		||||
    Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
    AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
    let path = view pathL' uri'
 | 
			
		||||
    json_file <- (cacheDir </>) <$> urlBaseName path
 | 
			
		||||
    e         <- liftIO $ doesFileExist json_file
 | 
			
		||||
@ -311,7 +311,7 @@ getDownloadInfo t v (PlatformRequest a p mv) dls = maybe
 | 
			
		||||
--
 | 
			
		||||
-- The file must not exist.
 | 
			
		||||
download :: ( MonadMask m
 | 
			
		||||
            , MonadReader Settings m
 | 
			
		||||
            , MonadReader AppState m
 | 
			
		||||
            , MonadThrow m
 | 
			
		||||
            , MonadLogger m
 | 
			
		||||
            , MonadIO m
 | 
			
		||||
@ -383,7 +383,7 @@ downloadCached :: ( MonadMask m
 | 
			
		||||
                  , MonadThrow m
 | 
			
		||||
                  , MonadLogger m
 | 
			
		||||
                  , MonadIO m
 | 
			
		||||
                  , MonadReader Settings m
 | 
			
		||||
                  , MonadReader AppState m
 | 
			
		||||
                  )
 | 
			
		||||
               => DownloadInfo
 | 
			
		||||
               -> Maybe (Path Rel)  -- ^ optional filename
 | 
			
		||||
@ -392,7 +392,7 @@ downloadCached dli mfn = do
 | 
			
		||||
  cache <- lift getCache
 | 
			
		||||
  case cache of
 | 
			
		||||
    True -> do
 | 
			
		||||
      Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
      AppState {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
      fn       <- maybe (urlBaseName $ view (dlUri % pathL') dli) pure mfn
 | 
			
		||||
      let cachfile = cacheDir </> fn
 | 
			
		||||
      fileExists <- liftIO $ doesFileExist cachfile
 | 
			
		||||
@ -416,7 +416,7 @@ downloadCached dli mfn = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | This is used for downloading the JSON.
 | 
			
		||||
downloadBS :: (MonadReader Settings m, MonadCatch m, MonadIO m, MonadLogger m)
 | 
			
		||||
downloadBS :: (MonadReader AppState m, MonadCatch m, MonadIO m, MonadLogger m)
 | 
			
		||||
           => URI
 | 
			
		||||
           -> Excepts
 | 
			
		||||
                '[ FileDoesNotExistError
 | 
			
		||||
@ -473,12 +473,12 @@ downloadBS uri'
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
checkDigest :: (MonadIO m, MonadThrow m, MonadLogger m, MonadReader Settings m)
 | 
			
		||||
checkDigest :: (MonadIO m, MonadThrow m, MonadLogger m, MonadReader AppState m)
 | 
			
		||||
            => DownloadInfo
 | 
			
		||||
            -> Path Abs
 | 
			
		||||
            -> Excepts '[DigestError] m ()
 | 
			
		||||
checkDigest dli file = do
 | 
			
		||||
  verify <- lift ask <&> (not . noVerify)
 | 
			
		||||
  verify <- lift ask <&> (not . noVerify . settings)
 | 
			
		||||
  when verify $ do
 | 
			
		||||
    p' <- toFilePath <$> basename file
 | 
			
		||||
    lift $ $(logInfo) [i|verifying digest of: #{p'}|]
 | 
			
		||||
 | 
			
		||||
@ -193,16 +193,17 @@ data URLSource = GHCupURL
 | 
			
		||||
               deriving (GHC.Generic, Show)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
data AppState = AppState
 | 
			
		||||
  { settings :: Settings
 | 
			
		||||
  , dirs :: Dirs
 | 
			
		||||
  } deriving (Show)
 | 
			
		||||
 | 
			
		||||
data Settings = Settings
 | 
			
		||||
  { -- set by user
 | 
			
		||||
    cache      :: Bool
 | 
			
		||||
  { cache      :: Bool
 | 
			
		||||
  , noVerify   :: Bool
 | 
			
		||||
  , keepDirs   :: KeepDirs
 | 
			
		||||
  , downloader :: Downloader
 | 
			
		||||
  , verbose    :: Bool
 | 
			
		||||
 | 
			
		||||
    -- set on app start
 | 
			
		||||
  , dirs       :: Dirs
 | 
			
		||||
  }
 | 
			
		||||
  deriving Show
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -99,21 +99,21 @@ import qualified Text.Megaparsec               as MP
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | The symlink destination of a ghc tool.
 | 
			
		||||
ghcLinkDestination :: (MonadReader Settings m, MonadThrow m, MonadIO m)
 | 
			
		||||
ghcLinkDestination :: (MonadReader AppState m, MonadThrow m, MonadIO m)
 | 
			
		||||
                   => ByteString -- ^ the tool, such as 'ghc', 'haddock' etc.
 | 
			
		||||
                   -> GHCTargetVersion
 | 
			
		||||
                   -> m ByteString
 | 
			
		||||
ghcLinkDestination tool ver = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
  t <- parseRel tool
 | 
			
		||||
  ghcd <- ghcupGHCDir ver
 | 
			
		||||
  pure (relativeSymlink binDir (ghcd </> [rel|bin|] </> t))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Removes the minor GHC symlinks, e.g. ghc-8.6.5.
 | 
			
		||||
rmMinorSymlinks :: (MonadReader Settings m, MonadIO m, MonadLogger m) => GHCTargetVersion -> m ()
 | 
			
		||||
rmMinorSymlinks :: (MonadReader AppState m, MonadIO m, MonadLogger m) => GHCTargetVersion -> m ()
 | 
			
		||||
rmMinorSymlinks GHCTargetVersion {..} = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
 | 
			
		||||
  files  <- liftIO $ findFiles'
 | 
			
		||||
    binDir
 | 
			
		||||
@ -130,11 +130,11 @@ rmMinorSymlinks GHCTargetVersion {..} = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Removes the set ghc version for the given target, if any.
 | 
			
		||||
rmPlain :: (MonadReader Settings m, MonadLogger m, MonadThrow m, MonadFail m, MonadIO m)
 | 
			
		||||
rmPlain :: (MonadReader AppState m, MonadLogger m, MonadThrow m, MonadFail m, MonadIO m)
 | 
			
		||||
  => Maybe Text -- ^ target
 | 
			
		||||
        -> Excepts '[NotInstalled] m ()
 | 
			
		||||
rmPlain target = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- lift ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- lift ask
 | 
			
		||||
  mtv <- lift $ ghcSet target
 | 
			
		||||
  forM_ mtv $ \tv -> do
 | 
			
		||||
    files  <- liftE $ ghcToolFiles tv
 | 
			
		||||
@ -149,11 +149,11 @@ rmPlain target = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Remove the major GHC symlink, e.g. ghc-8.6.
 | 
			
		||||
rmMajorSymlinks :: (MonadReader Settings m, MonadThrow m, MonadLogger m, MonadIO m)
 | 
			
		||||
rmMajorSymlinks :: (MonadReader AppState m, MonadThrow m, MonadLogger m, MonadIO m)
 | 
			
		||||
                => GHCTargetVersion
 | 
			
		||||
                -> m ()
 | 
			
		||||
rmMajorSymlinks GHCTargetVersion {..} = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
  (mj, mi) <- getMajorMinorV _tvVersion
 | 
			
		||||
  let v' = intToText mj <> "." <> intToText mi
 | 
			
		||||
 | 
			
		||||
@ -179,26 +179,26 @@ rmMajorSymlinks GHCTargetVersion {..} = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Whethe the given GHC versin is installed.
 | 
			
		||||
ghcInstalled :: (MonadIO m, MonadReader Settings m, MonadThrow m) => GHCTargetVersion -> m Bool
 | 
			
		||||
ghcInstalled :: (MonadIO m, MonadReader AppState m, MonadThrow m) => GHCTargetVersion -> m Bool
 | 
			
		||||
ghcInstalled ver = do
 | 
			
		||||
  ghcdir <- ghcupGHCDir ver
 | 
			
		||||
  liftIO $ doesDirectoryExist ghcdir
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Whether the given GHC version is installed from source.
 | 
			
		||||
ghcSrcInstalled :: (MonadIO m, MonadReader Settings m, MonadThrow m) => GHCTargetVersion -> m Bool
 | 
			
		||||
ghcSrcInstalled :: (MonadIO m, MonadReader AppState m, MonadThrow m) => GHCTargetVersion -> m Bool
 | 
			
		||||
ghcSrcInstalled ver = do
 | 
			
		||||
  ghcdir <- ghcupGHCDir ver
 | 
			
		||||
  liftIO $ doesFileExist (ghcdir </> ghcUpSrcBuiltFile)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Whether the given GHC version is set as the current.
 | 
			
		||||
ghcSet :: (MonadReader Settings m, MonadThrow m, MonadIO m)
 | 
			
		||||
ghcSet :: (MonadReader AppState m, MonadThrow m, MonadIO m)
 | 
			
		||||
       => Maybe Text   -- ^ the target of the GHC version, if any
 | 
			
		||||
                       --  (e.g. armv7-unknown-linux-gnueabihf)
 | 
			
		||||
       -> m (Maybe GHCTargetVersion)
 | 
			
		||||
ghcSet mtarget = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- ask
 | 
			
		||||
  ghc    <- parseRel $ E.encodeUtf8 (maybe "ghc" (<> "-ghc") mtarget)
 | 
			
		||||
  let ghcBin = binDir </> ghc
 | 
			
		||||
 | 
			
		||||
@ -231,7 +231,7 @@ ghcLinkVersion bs = do
 | 
			
		||||
 | 
			
		||||
-- | Get all installed GHCs by reading ~/.ghcup/ghc/<dir>.
 | 
			
		||||
-- If a dir cannot be parsed, returns left.
 | 
			
		||||
getInstalledGHCs :: (MonadReader Settings m, MonadIO m) => m [Either (Path Rel) GHCTargetVersion]
 | 
			
		||||
getInstalledGHCs :: (MonadReader AppState m, MonadIO m) => m [Either (Path Rel) GHCTargetVersion]
 | 
			
		||||
getInstalledGHCs = do
 | 
			
		||||
  ghcdir <- ghcupGHCBaseDir
 | 
			
		||||
  fs     <- liftIO $ hideErrorDef [NoSuchThing] [] $ getDirsFiles' ghcdir
 | 
			
		||||
@ -241,10 +241,10 @@ getInstalledGHCs = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Get all installed cabals, by matching on @~\/.ghcup\/bin/cabal-*@.
 | 
			
		||||
getInstalledCabals :: (MonadReader Settings m, MonadIO m, MonadCatch m)
 | 
			
		||||
getInstalledCabals :: (MonadReader AppState m, MonadIO m, MonadCatch m)
 | 
			
		||||
                   => m [Either (Path Rel) Version]
 | 
			
		||||
getInstalledCabals = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- ask
 | 
			
		||||
  bins   <- liftIO $ handleIO (\_ -> pure []) $ findFiles
 | 
			
		||||
    binDir
 | 
			
		||||
    (makeRegexOpts compExtended execBlank ([s|^cabal-.*$|] :: ByteString))
 | 
			
		||||
@ -257,16 +257,16 @@ getInstalledCabals = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Whether the given cabal version is installed.
 | 
			
		||||
cabalInstalled :: (MonadIO m, MonadReader Settings m, MonadCatch m) => Version -> m Bool
 | 
			
		||||
cabalInstalled :: (MonadIO m, MonadReader AppState m, MonadCatch m) => Version -> m Bool
 | 
			
		||||
cabalInstalled ver = do
 | 
			
		||||
  vers <- fmap rights $ getInstalledCabals
 | 
			
		||||
  pure $ elem ver $ vers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- Return the currently set cabal version, if any.
 | 
			
		||||
cabalSet :: (MonadReader Settings m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
 | 
			
		||||
cabalSet :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
 | 
			
		||||
cabalSet = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- ask
 | 
			
		||||
  let cabalbin = binDir </> [rel|cabal|]
 | 
			
		||||
  b        <- handleIO (\_ -> pure False) $ fmap (== SymbolicLink) $ liftIO $ getFileType cabalbin
 | 
			
		||||
  if
 | 
			
		||||
@ -303,10 +303,10 @@ cabalSet = do
 | 
			
		||||
 | 
			
		||||
-- | Get all installed hls, by matching on
 | 
			
		||||
-- @~\/.ghcup\/bin/haskell-language-server-wrapper-<\hlsver\>@.
 | 
			
		||||
getInstalledHLSs :: (MonadReader Settings m, MonadIO m, MonadCatch m)
 | 
			
		||||
getInstalledHLSs :: (MonadReader AppState m, MonadIO m, MonadCatch m)
 | 
			
		||||
                 => m [Either (Path Rel) Version]
 | 
			
		||||
getInstalledHLSs = do
 | 
			
		||||
  Settings { dirs = Dirs {..} } <- ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
  bins                          <- liftIO $ handleIO (\_ -> pure []) $ findFiles
 | 
			
		||||
    binDir
 | 
			
		||||
    (makeRegexOpts compExtended
 | 
			
		||||
@ -326,7 +326,7 @@ getInstalledHLSs = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Whether the given HLS version is installed.
 | 
			
		||||
hlsInstalled :: (MonadIO m, MonadReader Settings m, MonadCatch m) => Version -> m Bool
 | 
			
		||||
hlsInstalled :: (MonadIO m, MonadReader AppState m, MonadCatch m) => Version -> m Bool
 | 
			
		||||
hlsInstalled ver = do
 | 
			
		||||
  vers <- fmap rights $ getInstalledHLSs
 | 
			
		||||
  pure $ elem ver $ vers
 | 
			
		||||
@ -334,9 +334,9 @@ hlsInstalled ver = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- Return the currently set hls version, if any.
 | 
			
		||||
hlsSet :: (MonadReader Settings m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
 | 
			
		||||
hlsSet :: (MonadReader AppState m, MonadIO m, MonadThrow m, MonadCatch m) => m (Maybe Version)
 | 
			
		||||
hlsSet = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- ask
 | 
			
		||||
  let hlsBin = binDir </> [rel|haskell-language-server-wrapper|]
 | 
			
		||||
 | 
			
		||||
  liftIO $ handleIO' NoSuchThing (\_ -> pure $ Nothing) $ do
 | 
			
		||||
@ -357,7 +357,7 @@ hlsSet = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Return the GHC versions the currently selected HLS supports.
 | 
			
		||||
hlsGHCVersions :: ( MonadReader Settings m
 | 
			
		||||
hlsGHCVersions :: ( MonadReader AppState m
 | 
			
		||||
                  , MonadIO m
 | 
			
		||||
                  , MonadThrow m
 | 
			
		||||
                  , MonadCatch m
 | 
			
		||||
@ -383,11 +383,11 @@ hlsGHCVersions = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Get all server binaries for an hls version, if any.
 | 
			
		||||
hlsServerBinaries :: (MonadReader Settings m, MonadIO m)
 | 
			
		||||
hlsServerBinaries :: (MonadReader AppState m, MonadIO m)
 | 
			
		||||
                  => Version
 | 
			
		||||
                  -> m [Path Rel]
 | 
			
		||||
hlsServerBinaries ver = do
 | 
			
		||||
  Settings { dirs = Dirs {..} } <- ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
  liftIO $ handleIO (\_ -> pure []) $ findFiles
 | 
			
		||||
    binDir
 | 
			
		||||
    (makeRegexOpts
 | 
			
		||||
@ -399,11 +399,11 @@ hlsServerBinaries ver = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Get the wrapper binary for an hls version, if any.
 | 
			
		||||
hlsWrapperBinary :: (MonadReader Settings m, MonadThrow m, MonadIO m)
 | 
			
		||||
hlsWrapperBinary :: (MonadReader AppState m, MonadThrow m, MonadIO m)
 | 
			
		||||
                 => Version
 | 
			
		||||
                 -> m (Maybe (Path Rel))
 | 
			
		||||
hlsWrapperBinary ver = do
 | 
			
		||||
  Settings { dirs = Dirs {..} } <- ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
  wrapper                       <- liftIO $ handleIO (\_ -> pure []) $ findFiles
 | 
			
		||||
    binDir
 | 
			
		||||
    (makeRegexOpts
 | 
			
		||||
@ -420,7 +420,7 @@ hlsWrapperBinary ver = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Get all binaries for an hls version, if any.
 | 
			
		||||
hlsAllBinaries :: (MonadReader Settings m, MonadIO m, MonadThrow m) => Version -> m [Path Rel]
 | 
			
		||||
hlsAllBinaries :: (MonadReader AppState m, MonadIO m, MonadThrow m) => Version -> m [Path Rel]
 | 
			
		||||
hlsAllBinaries ver = do
 | 
			
		||||
  hls     <- hlsServerBinaries ver
 | 
			
		||||
  wrapper <- hlsWrapperBinary ver
 | 
			
		||||
@ -428,9 +428,9 @@ hlsAllBinaries ver = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Get the active symlinks for hls.
 | 
			
		||||
hlsSymlinks :: (MonadReader Settings m, MonadIO m, MonadCatch m) => m [Path Rel]
 | 
			
		||||
hlsSymlinks :: (MonadReader AppState m, MonadIO m, MonadCatch m) => m [Path Rel]
 | 
			
		||||
hlsSymlinks = do
 | 
			
		||||
  Settings { dirs = Dirs {..} } <- ask
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
  oldSyms                       <- liftIO $ handleIO (\_ -> pure []) $ findFiles
 | 
			
		||||
    binDir
 | 
			
		||||
    (makeRegexOpts compExtended
 | 
			
		||||
@ -467,7 +467,7 @@ matchMajor v' major' minor' = case getMajorMinorV v' of
 | 
			
		||||
 | 
			
		||||
-- | Get the latest installed full GHC version that satisfies X.Y.
 | 
			
		||||
-- This reads `ghcupGHCBaseDir`.
 | 
			
		||||
getGHCForMajor :: (MonadReader Settings m, MonadIO m, MonadThrow m)
 | 
			
		||||
getGHCForMajor :: (MonadReader AppState m, MonadIO m, MonadThrow m)
 | 
			
		||||
               => Int        -- ^ major version component
 | 
			
		||||
               -> Int        -- ^ minor version component
 | 
			
		||||
               -> Maybe Text -- ^ the target triple
 | 
			
		||||
@ -603,16 +603,16 @@ getLatestBaseVersion av pvpVer =
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    -----------------------
 | 
			
		||||
    --[ Settings Getter ]--
 | 
			
		||||
    --[ AppState Getter ]--
 | 
			
		||||
    -----------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
getCache :: MonadReader Settings m => m Bool
 | 
			
		||||
getCache = ask <&> cache
 | 
			
		||||
getCache :: MonadReader AppState m => m Bool
 | 
			
		||||
getCache = ask <&> cache . settings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
getDownloader :: MonadReader Settings m => m Downloader
 | 
			
		||||
getDownloader = ask <&> downloader
 | 
			
		||||
getDownloader :: MonadReader AppState m => m Downloader
 | 
			
		||||
getDownloader = ask <&> downloader . settings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -633,7 +633,7 @@ urlBaseName = parseRel . snd . B.breakEnd (== _slash) . urlDecode False
 | 
			
		||||
-- Returns unversioned relative files, e.g.:
 | 
			
		||||
--
 | 
			
		||||
--   - @["hsc2hs","haddock","hpc","runhaskell","ghc","ghc-pkg","ghci","runghc","hp2ps"]@
 | 
			
		||||
ghcToolFiles :: (MonadReader Settings m, MonadThrow m, MonadFail m, MonadIO m)
 | 
			
		||||
ghcToolFiles :: (MonadReader AppState m, MonadThrow m, MonadFail m, MonadIO m)
 | 
			
		||||
             => GHCTargetVersion
 | 
			
		||||
             -> Excepts '[NotInstalled] m [Path Rel]
 | 
			
		||||
ghcToolFiles ver = do
 | 
			
		||||
@ -686,7 +686,7 @@ ghcUpSrcBuiltFile = [rel|.ghcup_src_built|]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Calls gmake if it exists in PATH, otherwise make.
 | 
			
		||||
make :: (MonadThrow m, MonadIO m, MonadReader Settings m)
 | 
			
		||||
make :: (MonadThrow m, MonadIO m, MonadReader AppState m)
 | 
			
		||||
     => [ByteString]
 | 
			
		||||
     -> Maybe (Path Abs)
 | 
			
		||||
     -> m (Either ProcessError ())
 | 
			
		||||
@ -739,13 +739,13 @@ getChangeLog dls tool (Right tag) =
 | 
			
		||||
--
 | 
			
		||||
--   1. the build directory, depending on the KeepDirs setting
 | 
			
		||||
--   2. the install destination, depending on whether the build failed
 | 
			
		||||
runBuildAction :: (Show (V e), MonadReader Settings m, MonadIO m, MonadMask m)
 | 
			
		||||
runBuildAction :: (Show (V e), MonadReader AppState m, MonadIO m, MonadMask m)
 | 
			
		||||
               => Path Abs          -- ^ build directory (cleaned up depending on Settings)
 | 
			
		||||
               -> Maybe (Path Abs)  -- ^ dir to *always* clean up on exception
 | 
			
		||||
               -> Excepts e m a
 | 
			
		||||
               -> Excepts '[BuildFailed] m a
 | 
			
		||||
runBuildAction bdir instdir action = do
 | 
			
		||||
  Settings {..} <- lift ask
 | 
			
		||||
  AppState { settings = Settings {..} } <- lift ask
 | 
			
		||||
  let exAction = do
 | 
			
		||||
        forM_ instdir $ \dir ->
 | 
			
		||||
          liftIO $ hideError doesNotExistErrorType $ deleteDirRecursive dir
 | 
			
		||||
 | 
			
		||||
@ -152,17 +152,17 @@ getDirs = do
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | ~/.ghcup/ghc by default.
 | 
			
		||||
ghcupGHCBaseDir :: (MonadReader Settings m) => m (Path Abs)
 | 
			
		||||
ghcupGHCBaseDir :: (MonadReader AppState m) => m (Path Abs)
 | 
			
		||||
ghcupGHCBaseDir = do
 | 
			
		||||
  Settings {..} <- ask
 | 
			
		||||
  pure (baseDir dirs </> [rel|ghc|])
 | 
			
		||||
  AppState { dirs = Dirs {..} } <- ask
 | 
			
		||||
  pure (baseDir </> [rel|ghc|])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- | Gets '~/.ghcup/ghc/<ghcupGHCDir>'.
 | 
			
		||||
-- The dir may be of the form
 | 
			
		||||
--   * armv7-unknown-linux-gnueabihf-8.8.3
 | 
			
		||||
--   * 8.8.4
 | 
			
		||||
ghcupGHCDir :: (MonadReader Settings m, MonadThrow m)
 | 
			
		||||
ghcupGHCDir :: (MonadReader AppState m, MonadThrow m)
 | 
			
		||||
            => GHCTargetVersion
 | 
			
		||||
            -> m (Path Abs)
 | 
			
		||||
ghcupGHCDir ver = do
 | 
			
		||||
 | 
			
		||||
@ -117,7 +117,7 @@ executeOut path args chdir = captureOutStreams $ do
 | 
			
		||||
  SPPB.executeFile (toFilePath path) True args Nothing
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
execLogged :: (MonadReader Settings m, MonadIO m, MonadThrow m)
 | 
			
		||||
execLogged :: (MonadReader AppState m, MonadIO m, MonadThrow m)
 | 
			
		||||
           => ByteString       -- ^ thing to execute
 | 
			
		||||
           -> Bool             -- ^ whether to search PATH for the thing
 | 
			
		||||
           -> [ByteString]     -- ^ args for the thing
 | 
			
		||||
@ -126,7 +126,7 @@ execLogged :: (MonadReader Settings m, MonadIO m, MonadThrow m)
 | 
			
		||||
           -> Maybe [(ByteString, ByteString)] -- ^ optional environment
 | 
			
		||||
           -> m (Either ProcessError ())
 | 
			
		||||
execLogged exe spath args lfile chdir env = do
 | 
			
		||||
  Settings {dirs = Dirs {..}, ..} <- ask
 | 
			
		||||
  AppState { settings = Settings {..}, dirs = Dirs {..} } <- ask
 | 
			
		||||
  logfile       <- (logsDir </>) <$> parseRel (toFilePath lfile <> ".log")
 | 
			
		||||
  liftIO $ bracket (createFile (toFilePath logfile) newFilePerms)
 | 
			
		||||
                   closeFd
 | 
			
		||||
 | 
			
		||||
@ -65,9 +65,9 @@ myLoggerT LoggerConfig {..} loggingt = runLoggingT loggingt mylogger
 | 
			
		||||
    rawOutter outr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
initGHCupFileLogging :: (MonadIO m, MonadReader Settings m) => Path Rel -> m (Path Abs)
 | 
			
		||||
initGHCupFileLogging :: (MonadIO m, MonadReader AppState m) => Path Rel -> m (Path Abs)
 | 
			
		||||
initGHCupFileLogging context = do
 | 
			
		||||
  Settings {dirs = Dirs {..}} <- ask
 | 
			
		||||
  AppState {dirs = Dirs {..}} <- ask
 | 
			
		||||
  let logfile = logsDir </> context
 | 
			
		||||
  liftIO $ do
 | 
			
		||||
    createDirRecursive' logsDir
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user