hie-bios-0.16.0: src/HIE/Bios/Cradle/ProgramVersions.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecordWildCards #-}
module HIE.Bios.Cradle.ProgramVersions
( ProgramVersions(..)
, makeVersions
, runCachedIO
) where
import HIE.Bios.Types
import qualified HIE.Bios.Process as Process
import Colog.Core (LogAction (..), WithSeverity (..))
import Data.Version
import Data.IORef
import Text.ParserCombinators.ReadP (readP_to_S)
data ProgramVersions =
ProgramVersions { cabalVersion :: CachedIO (Maybe Version)
, stackVersion :: CachedIO (Maybe Version)
, ghcVersion :: CachedIO (Maybe Version)
}
newtype CachedIO a = CachedIO (IORef (Either (IO a) a))
makeCachedIO :: IO a -> IO (CachedIO a)
makeCachedIO act = CachedIO <$> newIORef (Left act)
runCachedIO :: CachedIO a -> IO a
runCachedIO (CachedIO ref) =
readIORef ref >>= \case
Right x -> pure x
Left act -> do
x <- act
writeIORef ref (Right x)
pure x
makeVersions :: LogAction IO (WithSeverity Log) -> FilePath -> ([String] -> IO (CradleLoadResult String)) -> IO ProgramVersions
makeVersions l wdir ghc = do
cabalVersion <- makeCachedIO $ getCabalVersion l wdir
stackVersion <- makeCachedIO $ getStackVersion l wdir
ghcVersion <- makeCachedIO $ getGhcVersion ghc
pure ProgramVersions{..}
getCabalVersion :: LogAction IO (WithSeverity Log) -> FilePath -> IO (Maybe Version)
getCabalVersion l wdir = do
res <- Process.readProcessWithCwd l wdir "cabal" ["--numeric-version"] ""
case res of
CradleSuccess stdo ->
pure $ versionMaybe stdo
_ -> pure Nothing
getStackVersion :: LogAction IO (WithSeverity Log) -> FilePath -> IO (Maybe Version)
getStackVersion l wdir = do
res <- Process.readProcessWithCwd l wdir "stack" ["--numeric-version"] ""
case res of
CradleSuccess stdo ->
pure $ versionMaybe stdo
_ -> pure Nothing
getGhcVersion :: ([String] -> IO (CradleLoadResult String)) -> IO (Maybe Version)
getGhcVersion ghc = do
res <- ghc ["--numeric-version"]
case res of
CradleSuccess stdo ->
pure $ versionMaybe stdo
_ -> pure Nothing
versionMaybe :: String -> Maybe Version
versionMaybe xs = case reverse $ readP_to_S parseVersion xs of
[] -> Nothing
(x:_) -> Just (fst x)