11{-# LANGUAGE BangPatterns #-}
2+ {-# LANGUAGE DeriveTraversable #-}
23{-# LANGUAGE OverloadedStrings #-}
34{-# LANGUAGE ScopedTypeVariables #-}
45{-# LANGUAGE TupleSections #-}
56{-# LANGUAGE LambdaCase #-}
6- {-# LANGUAGE RecursiveDo #-}
7- {-# LANGUAGE RecordWildCards #-}
87module HIE.Bios.Cradle (
98 findCradle
109 , loadCradle
@@ -28,11 +27,13 @@ module HIE.Bios.Cradle (
2827
2928 -- expose to tests
3029 , makeVersions
30+ , getGhcVersion
3131 , isCabalMultipleCompSupported
32- , ProgramVersions
32+ , BuildToolVersions
3333 ) where
3434
3535import Control.Applicative ((<|>) , optional )
36+ import Control.Concurrent.Async (mapConcurrently )
3637import Control.DeepSeq
3738import Control.Exception (handleJust )
3839import qualified Data.Yaml as Yaml
@@ -82,7 +83,6 @@ import GHC.Fingerprint (fingerprintString)
8283import GHC.ResponseFile (escapeArgs )
8384
8485import Data.Version
85- import Data.IORef
8686import Text.ParserCombinators.ReadP (readP_to_S )
8787import Data.Tuple.Extra (fst3 , snd3 , thd3 )
8888
@@ -157,35 +157,18 @@ data ResolvedCradles a
157157 = ResolvedCradles
158158 { cradleRoot :: FilePath
159159 , resolvedCradles :: [ResolvedCradle a ] -- ^ In order of decreasing specificity
160- , cradleProgramVersions :: ProgramVersions
160+ , cradleBuildToolVersions :: BuildToolVersions
161161 }
162162
163- data ProgramVersions =
164- ProgramVersions { cabalVersion :: CachedIO (Maybe Version )
165- , stackVersion :: CachedIO (Maybe Version )
166- , ghcVersion :: CachedIO (Maybe Version )
167- }
168-
169- newtype CachedIO a = CachedIO (IORef (Either (IO a ) a ))
170-
171- makeCachedIO :: IO a -> IO (CachedIO a )
172- makeCachedIO act = CachedIO <$> newIORef (Left act)
173-
174- runCachedIO :: CachedIO a -> IO a
175- runCachedIO (CachedIO ref) =
176- readIORef ref >>= \ case
177- Right x -> pure x
178- Left act -> do
179- x <- act
180- writeIORef ref (Right x)
181- pure x
182-
183- makeVersions :: LogAction IO (WithSeverity Log ) -> FilePath -> ([String ] -> IO (CradleLoadResult String )) -> IO ProgramVersions
184- makeVersions l wdir ghc = do
185- cabalVersion <- makeCachedIO $ getCabalVersion l wdir
186- stackVersion <- makeCachedIO $ getStackVersion l wdir
187- ghcVersion <- makeCachedIO $ getGhcVersion ghc
188- pure ProgramVersions {.. }
163+ type BuildToolVersions = BuildToolVersions' (Maybe Version )
164+ data BuildToolVersions' v =
165+ BuildToolVersions { cabalVersion :: v
166+ , stackVersion :: v
167+ }
168+ deriving (Functor , Foldable , Traversable )
169+
170+ makeVersions :: LogAction IO (WithSeverity Log ) -> FilePath -> IO BuildToolVersions
171+ makeVersions l wdir = mapConcurrently (\ v -> v l wdir) $ BuildToolVersions getCabalVersion getStackVersion
189172
190173getCabalVersion :: LogAction IO (WithSeverity Log ) -> FilePath -> IO (Maybe Version )
191174getCabalVersion l wdir = do
@@ -224,9 +207,11 @@ addActionDeps deps =
224207 (\ err -> CradleFail (err { cradleErrorDependencies = cradleErrorDependencies err `union` deps }))
225208 (\ (ComponentOptions os' dir ds) -> CradleSuccess (ComponentOptions os' dir (ds `union` deps)))
226209
227-
228210resolvedCradlesToCradle :: Show a => LogAction IO (WithSeverity Log ) -> (b -> CradleAction a ) -> FilePath -> [ResolvedCradle b ] -> IO (Cradle a )
229- resolvedCradlesToCradle logger buildCustomCradle root cs = mdo
211+ resolvedCradlesToCradle logger buildCustomCradle root cs = do
212+ versions <- makeVersions logger root
213+ cradleActions <- for cs $ \ c ->
214+ fmap (c,) $ resolveCradleAction logger buildCustomCradle (ResolvedCradles root cs versions) root c
230215 let run_ghc_cmd args =
231216 -- We're being lazy here and just returning the ghc path for the
232217 -- first non-none cradle. This shouldn't matter in practice: all
@@ -237,10 +222,6 @@ resolvedCradlesToCradle logger buildCustomCradle root cs = mdo
237222 runGhcCmd
238223 act
239224 args
240- versions <- makeVersions logger root run_ghc_cmd
241- cradleActions <- for cs $ \ c ->
242- fmap (c,) $ resolveCradleAction logger buildCustomCradle (ResolvedCradles root cs versions) root c
243- let
244225 err_msg fp
245226 = [" Multi Cradle: No prefixes matched"
246227 , " pwd: " ++ root
@@ -557,16 +538,13 @@ projectLocationOrDefault = \case
557538-- Works for new-build by invoking `v2-repl`.
558539cabalCradle :: LogAction IO (WithSeverity Log ) -> ResolvedCradles b -> FilePath -> Maybe String -> CradleProjectConfig -> IO (CradleAction a )
559540cabalCradle l cs wdir mc projectFile = do
560- res <- runCradleResultT $ callCabalPathForCompilerPath l (cradleProgramVersions cs) wdir projectFile
541+ res <- runCradleResultT $ callCabalPathForCompilerPath l (cradleBuildToolVersions cs) wdir projectFile
561542 let
562543 ghcPath = case res of
563544 CradleSuccess path -> path
564545 _ -> Nothing
565546
566- pure $ CradleAction
567- { actionName = Types. Cabal
568- , runCradle = \ fp -> runCradleResultT . cabalAction cs wdir ghcPath mc l projectFile fp
569- , runGhcCmd = \ args -> runCradleResultT $ do
547+ runGhcCmd args = runCradleResultT $ do
570548 case ghcPath of
571549 Just p -> readProcessWithCwd_ l wdir p args " "
572550 Nothing -> do
@@ -577,6 +555,13 @@ cabalCradle l cs wdir mc projectFile = do
577555 -- Need to pass -v0 otherwise we get "resolving dependencies..."
578556 cabalProc <- cabalProcess l projectFile wdir Nothing " v2-exec" $ [" ghc" , " -v0" , " --" ] ++ args
579557 readProcessWithCwd' l cabalProc " "
558+
559+ pure $ CradleAction
560+ { actionName = Types. Cabal
561+ , runCradle = \ fp ls -> do
562+ v <- getGhcVersion runGhcCmd
563+ runCradleResultT $ cabalAction cs wdir ghcPath v mc l projectFile fp ls
564+ , runGhcCmd = runGhcCmd
580565 }
581566
582567
@@ -823,9 +808,9 @@ cabalGhcDirs l cabalProject workDir = do
823808 where
824809 projectFileArgs = projectFileProcessArgs cabalProject
825810
826- callCabalPathForCompilerPath :: LogAction IO (WithSeverity Log ) -> ProgramVersions -> FilePath -> CradleProjectConfig -> CradleLoadResultT IO (Maybe FilePath )
811+ callCabalPathForCompilerPath :: LogAction IO (WithSeverity Log ) -> BuildToolVersions -> FilePath -> CradleProjectConfig -> CradleLoadResultT IO (Maybe FilePath )
827812callCabalPathForCompilerPath l vs workDir projectFile = do
828- isCabalPathSupported vs >>= \ case
813+ case isCabalPathSupported vs of
829814 False -> pure Nothing
830815 True -> do
831816 let
@@ -840,32 +825,29 @@ callCabalPathForCompilerPath l vs workDir projectFile = do
840825 pure Nothing
841826 Right a -> pure a
842827
843- isCabalPathSupported :: MonadIO m => ProgramVersions -> m Bool
844- isCabalPathSupported vs = do
845- v <- liftIO $ runCachedIO $ cabalVersion vs
846- pure $ maybe False (>= makeVersion [3 ,14 ]) v
828+ isCabalPathSupported :: BuildToolVersions -> Bool
829+ isCabalPathSupported = maybe False (>= makeVersion [3 ,14 ]) . cabalVersion
847830
848- isCabalMultipleCompSupported :: MonadIO m => ProgramVersions -> m Bool
849- isCabalMultipleCompSupported vs = do
850- cabal_version <- liftIO $ runCachedIO $ cabalVersion vs
851- ghc_version <- liftIO $ runCachedIO $ ghcVersion vs
831+ isCabalMultipleCompSupported :: BuildToolVersions -> Maybe Version -> Bool
832+ isCabalMultipleCompSupported vs ghcVersion = do
852833 -- determine which load style is supported by this cabal cradle.
853- case (cabal_version, ghc_version ) of
854- (Just cabal, Just ghc) -> pure $ ghc >= makeVersion [9 , 4 ] && cabal >= makeVersion [3 , 11 ]
855- _ -> pure False
834+ case (cabalVersion vs, ghcVersion ) of
835+ (Just cabal, Just ghc) -> ghc >= makeVersion [9 , 4 ] && cabal >= makeVersion [3 , 11 ]
836+ _ -> False
856837
857838cabalAction
858839 :: ResolvedCradles a
859840 -> FilePath
860841 -> Maybe FilePath
842+ -> Maybe Version
861843 -> Maybe String
862844 -> LogAction IO (WithSeverity Log )
863845 -> CradleProjectConfig
864846 -> FilePath
865847 -> LoadStyle
866848 -> CradleLoadResultT IO ComponentOptions
867- cabalAction (ResolvedCradles root cs vs) workDir ghcPath mc l projectFile fp loadStyle = do
868- multiCompSupport <- isCabalMultipleCompSupported vs
849+ cabalAction (ResolvedCradles root cs vs) workDir ghcPath ghcVersion mc l projectFile fp loadStyle = do
850+ let multiCompSupport = isCabalMultipleCompSupported vs ghcVersion
869851 -- determine which load style is supported by this cabal cradle.
870852 determinedLoadStyle <- case loadStyle of
871853 LoadWithContext _ | not multiCompSupport -> do
0 commit comments