2021-10-15 20:24:23 +00:00
|
|
|
{-# LANGUAGE CPP #-}
|
|
|
|
{-# LANGUAGE DataKinds #-}
|
|
|
|
{-# LANGUAGE TypeApplications #-}
|
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
{-# LANGUAGE QuasiQuotes #-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
|
|
|
{-# LANGUAGE RankNTypes #-}
|
|
|
|
|
|
|
|
module GHCup.OptParse.Set where
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import GHCup.OptParse.Common
|
|
|
|
|
|
|
|
import GHCup
|
|
|
|
import GHCup.Errors
|
|
|
|
import GHCup.Types
|
2022-05-21 20:54:18 +00:00
|
|
|
import GHCup.Prelude.Logger
|
|
|
|
import GHCup.Prelude.String.QQ
|
2021-10-15 20:24:23 +00:00
|
|
|
|
|
|
|
#if !MIN_VERSION_base(4,13,0)
|
|
|
|
import Control.Monad.Fail ( MonadFail )
|
|
|
|
#endif
|
|
|
|
import Control.Monad.Reader
|
|
|
|
import Control.Monad.Trans.Resource
|
|
|
|
import Data.Either
|
|
|
|
import Data.Functor
|
|
|
|
import Data.Maybe
|
2023-10-13 08:31:17 +00:00
|
|
|
import Data.Versions
|
2021-10-15 20:24:23 +00:00
|
|
|
import GHC.Unicode
|
|
|
|
import Haskus.Utils.Variant.Excepts
|
|
|
|
import Options.Applicative hiding ( style )
|
|
|
|
import Options.Applicative.Help.Pretty ( text )
|
|
|
|
import Prelude hiding ( appendFile )
|
|
|
|
import System.Exit
|
|
|
|
|
|
|
|
import qualified Data.Text as T
|
|
|
|
import Data.Bifunctor (second)
|
|
|
|
import Control.Exception.Safe (MonadMask)
|
|
|
|
import GHCup.Types.Optics
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
----------------
|
|
|
|
--[ Commands ]--
|
|
|
|
----------------
|
|
|
|
|
|
|
|
|
|
|
|
data SetCommand = SetGHC SetOptions
|
|
|
|
| SetCabal SetOptions
|
|
|
|
| SetHLS SetOptions
|
|
|
|
| SetStack SetOptions
|
2023-07-22 03:45:29 +00:00
|
|
|
deriving (Eq, Show)
|
2021-10-15 20:24:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------------
|
|
|
|
--[ Options ]--
|
|
|
|
---------------
|
|
|
|
|
|
|
|
|
|
|
|
data SetOptions = SetOptions
|
|
|
|
{ sToolVer :: SetToolVersion
|
2023-07-22 03:45:29 +00:00
|
|
|
} deriving (Eq, Show)
|
2021-10-15 20:24:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------------
|
|
|
|
--[ Parsers ]--
|
|
|
|
---------------
|
|
|
|
|
2022-07-11 14:05:39 +00:00
|
|
|
|
2021-10-15 20:24:23 +00:00
|
|
|
setParser :: Parser (Either SetCommand SetOptions)
|
|
|
|
setParser =
|
|
|
|
(Left <$> subparser
|
|
|
|
( command
|
|
|
|
"ghc"
|
|
|
|
( SetGHC
|
|
|
|
<$> info
|
2022-07-11 14:05:39 +00:00
|
|
|
(setOpts GHC <**> helper)
|
2021-10-15 20:24:23 +00:00
|
|
|
( progDesc "Set GHC version"
|
|
|
|
<> footerDoc (Just $ text setGHCFooter)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
<> command
|
|
|
|
"cabal"
|
|
|
|
( SetCabal
|
|
|
|
<$> info
|
2022-07-11 14:05:39 +00:00
|
|
|
(setOpts Cabal <**> helper)
|
2021-10-15 20:24:23 +00:00
|
|
|
( progDesc "Set Cabal version"
|
|
|
|
<> footerDoc (Just $ text setCabalFooter)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
<> command
|
|
|
|
"hls"
|
|
|
|
( SetHLS
|
|
|
|
<$> info
|
2022-07-11 14:05:39 +00:00
|
|
|
(setOpts HLS <**> helper)
|
2021-10-15 20:24:23 +00:00
|
|
|
( progDesc "Set haskell-language-server version"
|
|
|
|
<> footerDoc (Just $ text setHLSFooter)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
<> command
|
|
|
|
"stack"
|
|
|
|
( SetStack
|
|
|
|
<$> info
|
2022-07-11 14:05:39 +00:00
|
|
|
(setOpts Stack <**> helper)
|
2021-10-15 20:24:23 +00:00
|
|
|
( progDesc "Set stack version"
|
|
|
|
<> footerDoc (Just $ text setStackFooter)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
2022-07-11 14:05:39 +00:00
|
|
|
<|> (Right <$> setOpts GHC)
|
2021-10-15 20:24:23 +00:00
|
|
|
where
|
|
|
|
setGHCFooter :: String
|
|
|
|
setGHCFooter = [s|Discussion:
|
|
|
|
Sets the the current GHC version by creating non-versioned
|
|
|
|
symlinks for all ghc binaries of the specified version in
|
|
|
|
"~/.ghcup/bin/<binary>".|]
|
|
|
|
|
|
|
|
setCabalFooter :: String
|
|
|
|
setCabalFooter = [s|Discussion:
|
|
|
|
Sets the the current Cabal version.|]
|
|
|
|
|
|
|
|
setStackFooter :: String
|
|
|
|
setStackFooter = [s|Discussion:
|
|
|
|
Sets the the current Stack version.|]
|
|
|
|
|
|
|
|
setHLSFooter :: String
|
|
|
|
setHLSFooter = [s|Discussion:
|
|
|
|
Sets the the current haskell-language-server version.|]
|
|
|
|
|
|
|
|
|
2022-07-11 14:05:39 +00:00
|
|
|
setOpts :: Tool -> Parser SetOptions
|
2021-10-15 20:24:23 +00:00
|
|
|
setOpts tool = SetOptions <$>
|
|
|
|
(fromMaybe SetRecommended <$>
|
2023-05-01 09:46:27 +00:00
|
|
|
optional (setVersionArgument [ListInstalled True] tool))
|
2021-10-15 20:24:23 +00:00
|
|
|
|
2023-05-01 09:46:27 +00:00
|
|
|
setVersionArgument :: [ListCriteria] -> Tool -> Parser SetToolVersion
|
2021-10-15 20:24:23 +00:00
|
|
|
setVersionArgument criteria tool =
|
|
|
|
argument (eitherReader setEither)
|
|
|
|
(metavar "VERSION|TAG|next"
|
2022-07-11 14:05:39 +00:00
|
|
|
<> completer (tagCompleter tool ["next"])
|
|
|
|
<> (completer . versionCompleter criteria) tool)
|
2021-10-15 20:24:23 +00:00
|
|
|
where
|
|
|
|
setEither s' =
|
|
|
|
parseSet s'
|
|
|
|
<|> second SetToolTag (tagEither s')
|
2022-07-11 14:05:39 +00:00
|
|
|
<|> se s'
|
|
|
|
se s' = case tool of
|
|
|
|
GHC -> second SetGHCVersion (ghcVersionEither s')
|
|
|
|
_ -> second SetToolVersion (toolVersionEither s')
|
2021-10-15 20:24:23 +00:00
|
|
|
parseSet s' = case fmap toLower s' of
|
|
|
|
"next" -> Right SetNext
|
|
|
|
other -> Left $ "Unknown tag/version " <> other
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
--[ Footer ]--
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
|
|
setFooter :: String
|
|
|
|
setFooter = [s|Discussion:
|
|
|
|
Sets the currently active GHC or cabal version. When no command is given,
|
|
|
|
defaults to setting GHC with the specified version/tag (if no tag
|
|
|
|
is given, sets GHC to 'recommended' version).
|
|
|
|
It is recommended to always specify a subcommand (ghc/cabal/hls/stack).|]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------------------------
|
|
|
|
--[ Effect interpreters ]--
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
|
|
|
|
type SetGHCEffects = '[ FileDoesNotExistError
|
|
|
|
, NotInstalled
|
|
|
|
, TagNotFound
|
2023-05-01 09:46:27 +00:00
|
|
|
, DayNotFound
|
2021-10-15 20:24:23 +00:00
|
|
|
, NextVerNotFound
|
|
|
|
, NoToolVersionSet]
|
|
|
|
|
|
|
|
runSetGHC :: (ReaderT env m (VEither SetGHCEffects a) -> m (VEither SetGHCEffects a))
|
|
|
|
-> Excepts SetGHCEffects (ReaderT env m) a
|
|
|
|
-> m (VEither SetGHCEffects a)
|
|
|
|
runSetGHC runAppState =
|
|
|
|
runAppState
|
|
|
|
. runE
|
|
|
|
@SetGHCEffects
|
|
|
|
|
|
|
|
|
|
|
|
type SetCabalEffects = '[ NotInstalled
|
|
|
|
, TagNotFound
|
2023-05-01 09:46:27 +00:00
|
|
|
, DayNotFound
|
2021-10-15 20:24:23 +00:00
|
|
|
, NextVerNotFound
|
|
|
|
, NoToolVersionSet]
|
|
|
|
|
|
|
|
runSetCabal :: (ReaderT env m (VEither SetCabalEffects a) -> m (VEither SetCabalEffects a))
|
|
|
|
-> Excepts SetCabalEffects (ReaderT env m) a
|
|
|
|
-> m (VEither SetCabalEffects a)
|
|
|
|
runSetCabal runAppState =
|
|
|
|
runAppState
|
|
|
|
. runE
|
|
|
|
@SetCabalEffects
|
|
|
|
|
|
|
|
|
|
|
|
type SetHLSEffects = '[ NotInstalled
|
|
|
|
, TagNotFound
|
2023-05-01 09:46:27 +00:00
|
|
|
, DayNotFound
|
2021-10-15 20:24:23 +00:00
|
|
|
, NextVerNotFound
|
|
|
|
, NoToolVersionSet]
|
|
|
|
|
|
|
|
runSetHLS :: (ReaderT env m (VEither SetHLSEffects a) -> m (VEither SetHLSEffects a))
|
|
|
|
-> Excepts SetHLSEffects (ReaderT env m) a
|
|
|
|
-> m (VEither SetHLSEffects a)
|
|
|
|
runSetHLS runAppState =
|
|
|
|
runAppState
|
|
|
|
. runE
|
|
|
|
@SetHLSEffects
|
|
|
|
|
|
|
|
|
|
|
|
type SetStackEffects = '[ NotInstalled
|
|
|
|
, TagNotFound
|
2023-05-01 09:46:27 +00:00
|
|
|
, DayNotFound
|
2021-10-15 20:24:23 +00:00
|
|
|
, NextVerNotFound
|
|
|
|
, NoToolVersionSet]
|
|
|
|
|
|
|
|
runSetStack :: (ReaderT env m (VEither SetStackEffects a) -> m (VEither SetStackEffects a))
|
|
|
|
-> Excepts SetStackEffects (ReaderT env m) a
|
|
|
|
-> m (VEither SetStackEffects a)
|
|
|
|
runSetStack runAppState =
|
|
|
|
runAppState
|
|
|
|
. runE
|
|
|
|
@SetStackEffects
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-------------------
|
|
|
|
--[ Entrypoints ]--
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
|
|
set :: forall m env.
|
|
|
|
( Monad m
|
|
|
|
, MonadMask m
|
|
|
|
, MonadUnliftIO m
|
|
|
|
, MonadFail m
|
|
|
|
, HasDirs env
|
|
|
|
, HasLog env
|
|
|
|
)
|
|
|
|
=> Either SetCommand SetOptions
|
|
|
|
-> (forall eff . ReaderT AppState m (VEither eff GHCTargetVersion)
|
|
|
|
-> m (VEither eff GHCTargetVersion))
|
|
|
|
-> (forall eff. ReaderT env m (VEither eff GHCTargetVersion)
|
|
|
|
-> m (VEither eff GHCTargetVersion))
|
|
|
|
-> (ReaderT LeanAppState m () -> m ())
|
|
|
|
-> m ExitCode
|
2023-01-24 07:24:03 +00:00
|
|
|
set setCommand runAppState _ runLogger = case setCommand of
|
2021-10-15 20:24:23 +00:00
|
|
|
(Right sopts) -> do
|
|
|
|
runLogger (logWarn "This is an old-style command for setting GHC. Use 'ghcup set ghc' instead.")
|
|
|
|
setGHC' sopts
|
2022-07-11 14:05:39 +00:00
|
|
|
(Left (SetGHC sopts)) -> setGHC' sopts
|
2021-10-15 20:24:23 +00:00
|
|
|
(Left (SetCabal sopts)) -> setCabal' sopts
|
2022-07-11 14:05:39 +00:00
|
|
|
(Left (SetHLS sopts)) -> setHLS' sopts
|
2021-10-15 20:24:23 +00:00
|
|
|
(Left (SetStack sopts)) -> setStack' sopts
|
|
|
|
|
|
|
|
where
|
|
|
|
setGHC' :: SetOptions
|
|
|
|
-> m ExitCode
|
2023-01-24 07:24:03 +00:00
|
|
|
setGHC' SetOptions{ sToolVer } = runSetGHC runAppState (do
|
2021-10-15 20:24:23 +00:00
|
|
|
v <- liftE $ fst <$> fromVersion' sToolVer GHC
|
2022-02-09 17:57:59 +00:00
|
|
|
liftE $ setGHC v SetGHCOnly Nothing
|
2021-10-15 20:24:23 +00:00
|
|
|
)
|
|
|
|
>>= \case
|
|
|
|
VRight GHCTargetVersion{..} -> do
|
|
|
|
runLogger
|
|
|
|
$ logInfo $
|
|
|
|
"GHC " <> prettyVer _tvVersion <> " successfully set as default version" <> maybe "" (" for cross target " <>) _tvTarget
|
|
|
|
pure ExitSuccess
|
|
|
|
VLeft e -> do
|
2022-12-19 16:10:19 +00:00
|
|
|
runLogger $ logError $ T.pack $ prettyHFError e
|
2021-10-15 20:24:23 +00:00
|
|
|
pure $ ExitFailure 5
|
|
|
|
|
|
|
|
|
|
|
|
setCabal' :: SetOptions
|
|
|
|
-> m ExitCode
|
2023-01-24 07:24:03 +00:00
|
|
|
setCabal' SetOptions{ sToolVer } = runSetCabal runAppState (do
|
2021-10-15 20:24:23 +00:00
|
|
|
v <- liftE $ fst <$> fromVersion' sToolVer Cabal
|
|
|
|
liftE $ setCabal (_tvVersion v)
|
|
|
|
pure v
|
|
|
|
)
|
|
|
|
>>= \case
|
2022-07-11 14:05:39 +00:00
|
|
|
VRight v -> do
|
2021-10-15 20:24:23 +00:00
|
|
|
runLogger
|
|
|
|
$ logInfo $
|
2022-07-11 14:05:39 +00:00
|
|
|
"Cabal " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
2021-10-15 20:24:23 +00:00
|
|
|
pure ExitSuccess
|
|
|
|
VLeft e -> do
|
2022-12-19 16:10:19 +00:00
|
|
|
runLogger $ logError $ T.pack $ prettyHFError e
|
2021-10-15 20:24:23 +00:00
|
|
|
pure $ ExitFailure 14
|
|
|
|
|
|
|
|
setHLS' :: SetOptions
|
|
|
|
-> m ExitCode
|
2023-01-24 07:24:03 +00:00
|
|
|
setHLS' SetOptions{ sToolVer } = runSetHLS runAppState (do
|
2021-10-15 20:24:23 +00:00
|
|
|
v <- liftE $ fst <$> fromVersion' sToolVer HLS
|
2022-02-09 17:57:59 +00:00
|
|
|
liftE $ setHLS (_tvVersion v) SetHLSOnly Nothing
|
2021-10-15 20:24:23 +00:00
|
|
|
pure v
|
|
|
|
)
|
|
|
|
>>= \case
|
2022-07-11 14:05:39 +00:00
|
|
|
VRight v -> do
|
2021-10-15 20:24:23 +00:00
|
|
|
runLogger
|
|
|
|
$ logInfo $
|
2022-07-11 14:05:39 +00:00
|
|
|
"HLS " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
2021-10-15 20:24:23 +00:00
|
|
|
pure ExitSuccess
|
|
|
|
VLeft e -> do
|
2022-12-19 16:10:19 +00:00
|
|
|
runLogger $ logError $ T.pack $ prettyHFError e
|
2021-10-15 20:24:23 +00:00
|
|
|
pure $ ExitFailure 14
|
|
|
|
|
|
|
|
|
|
|
|
setStack' :: SetOptions
|
|
|
|
-> m ExitCode
|
2023-01-24 07:24:03 +00:00
|
|
|
setStack' SetOptions{ sToolVer } = runSetStack runAppState (do
|
2021-10-15 20:24:23 +00:00
|
|
|
v <- liftE $ fst <$> fromVersion' sToolVer Stack
|
|
|
|
liftE $ setStack (_tvVersion v)
|
|
|
|
pure v
|
|
|
|
)
|
|
|
|
>>= \case
|
2022-07-11 14:05:39 +00:00
|
|
|
VRight v -> do
|
2021-10-15 20:24:23 +00:00
|
|
|
runLogger
|
|
|
|
$ logInfo $
|
2022-07-11 14:05:39 +00:00
|
|
|
"Stack " <> prettyVer (_tvVersion v) <> " successfully set as default version"
|
2021-10-15 20:24:23 +00:00
|
|
|
pure ExitSuccess
|
|
|
|
VLeft e -> do
|
2022-12-19 16:10:19 +00:00
|
|
|
runLogger $ logError $ T.pack $ prettyHFError e
|
2021-10-15 20:24:23 +00:00
|
|
|
pure $ ExitFailure 14
|