1
1
{-# LANGUAGE BangPatterns #-}
2
+ {-# LANGUAGE DeriveTraversable #-}
2
3
{-# LANGUAGE OverloadedStrings #-}
3
4
{-# LANGUAGE ScopedTypeVariables #-}
4
5
{-# LANGUAGE TupleSections #-}
5
6
{-# LANGUAGE LambdaCase #-}
6
- {-# LANGUAGE RecursiveDo #-}
7
- {-# LANGUAGE RecordWildCards #-}
8
7
module HIE.Bios.Cradle (
9
8
findCradle
10
9
, loadCradle
@@ -28,11 +27,13 @@ module HIE.Bios.Cradle (
28
27
29
28
-- expose to tests
30
29
, makeVersions
30
+ , getGhcVersion
31
31
, isCabalMultipleCompSupported
32
- , ProgramVersions
32
+ , BuildToolVersions
33
33
) where
34
34
35
35
import Control.Applicative ((<|>) , optional )
36
+ import Control.Concurrent.Async (mapConcurrently )
36
37
import Control.DeepSeq
37
38
import Control.Exception (handleJust )
38
39
import qualified Data.Yaml as Yaml
@@ -82,7 +83,6 @@ import GHC.Fingerprint (fingerprintString)
82
83
import GHC.ResponseFile (escapeArgs )
83
84
84
85
import Data.Version
85
- import Data.IORef
86
86
import Text.ParserCombinators.ReadP (readP_to_S )
87
87
import Data.Tuple.Extra (fst3 , snd3 , thd3 )
88
88
@@ -157,35 +157,18 @@ data ResolvedCradles a
157
157
= ResolvedCradles
158
158
{ cradleRoot :: FilePath
159
159
, resolvedCradles :: [ResolvedCradle a ] -- ^ In order of decreasing specificity
160
- , cradleProgramVersions :: ProgramVersions
160
+ , cradleBuildToolVersions :: BuildToolVersions
161
161
}
162
162
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
189
172
190
173
getCabalVersion :: LogAction IO (WithSeverity Log ) -> FilePath -> IO (Maybe Version )
191
174
getCabalVersion l wdir = do
@@ -224,9 +207,11 @@ addActionDeps deps =
224
207
(\ err -> CradleFail (err { cradleErrorDependencies = cradleErrorDependencies err `union` deps }))
225
208
(\ (ComponentOptions os' dir ds) -> CradleSuccess (ComponentOptions os' dir (ds `union` deps)))
226
209
227
-
228
210
resolvedCradlesToCradle :: 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
230
215
let run_ghc_cmd args =
231
216
-- We're being lazy here and just returning the ghc path for the
232
217
-- first non-none cradle. This shouldn't matter in practice: all
@@ -237,10 +222,6 @@ resolvedCradlesToCradle logger buildCustomCradle root cs = mdo
237
222
runGhcCmd
238
223
act
239
224
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
244
225
err_msg fp
245
226
= [" Multi Cradle: No prefixes matched"
246
227
, " pwd: " ++ root
@@ -608,16 +589,13 @@ projectLocationOrDefault = \case
608
589
-- Works for new-build by invoking `v2-repl`.
609
590
cabalCradle :: LogAction IO (WithSeverity Log ) -> ResolvedCradles b -> FilePath -> Maybe String -> CradleProjectConfig -> IO (CradleAction a )
610
591
cabalCradle l cs wdir mc projectFile = do
611
- res <- runCradleResultT $ callCabalPathForCompilerPath l (cradleProgramVersions cs) wdir projectFile
592
+ res <- runCradleResultT $ callCabalPathForCompilerPath l (cradleBuildToolVersions cs) wdir projectFile
612
593
let
613
594
ghcPath = case res of
614
595
CradleSuccess path -> path
615
596
_ -> Nothing
616
597
617
- pure $ CradleAction
618
- { actionName = Types. Cabal
619
- , runCradle = \ fp -> runCradleResultT . cabalAction cs wdir ghcPath mc l projectFile fp
620
- , runGhcCmd = \ args -> runCradleResultT $ do
598
+ runGhcCmd args = runCradleResultT $ do
621
599
case ghcPath of
622
600
Just p -> readProcessWithCwd_ l wdir p args " "
623
601
Nothing -> do
@@ -628,6 +606,13 @@ cabalCradle l cs wdir mc projectFile = do
628
606
-- Need to pass -v0 otherwise we get "resolving dependencies..."
629
607
cabalProc <- cabalProcess l projectFile wdir Nothing " v2-exec" $ [" ghc" , " -v0" , " --" ] ++ args
630
608
readProcessWithCwd' l cabalProc " "
609
+
610
+ pure $ CradleAction
611
+ { actionName = Types. Cabal
612
+ , runCradle = \ fp ls -> do
613
+ v <- getGhcVersion runGhcCmd
614
+ runCradleResultT $ cabalAction cs wdir ghcPath v mc l projectFile fp ls
615
+ , runGhcCmd = runGhcCmd
631
616
}
632
617
633
618
@@ -868,9 +853,9 @@ cabalGhcDirs l cabalProject workDir = do
868
853
where
869
854
projectFileArgs = projectFileProcessArgs cabalProject
870
855
871
- callCabalPathForCompilerPath :: LogAction IO (WithSeverity Log ) -> ProgramVersions -> FilePath -> CradleProjectConfig -> CradleLoadResultT IO (Maybe FilePath )
856
+ callCabalPathForCompilerPath :: LogAction IO (WithSeverity Log ) -> BuildToolVersions -> FilePath -> CradleProjectConfig -> CradleLoadResultT IO (Maybe FilePath )
872
857
callCabalPathForCompilerPath l vs workDir projectFile = do
873
- isCabalPathSupported vs >>= \ case
858
+ case isCabalPathSupported vs of
874
859
False -> pure Nothing
875
860
True -> do
876
861
let
@@ -885,32 +870,29 @@ callCabalPathForCompilerPath l vs workDir projectFile = do
885
870
pure Nothing
886
871
Right a -> pure a
887
872
888
- isCabalPathSupported :: MonadIO m => ProgramVersions -> m Bool
889
- isCabalPathSupported vs = do
890
- v <- liftIO $ runCachedIO $ cabalVersion vs
891
- pure $ maybe False (>= makeVersion [3 ,14 ]) v
873
+ isCabalPathSupported :: BuildToolVersions -> Bool
874
+ isCabalPathSupported = maybe False (>= makeVersion [3 ,14 ]) . cabalVersion
892
875
893
- isCabalMultipleCompSupported :: MonadIO m => ProgramVersions -> m Bool
894
- isCabalMultipleCompSupported vs = do
895
- cabal_version <- liftIO $ runCachedIO $ cabalVersion vs
896
- ghc_version <- liftIO $ runCachedIO $ ghcVersion vs
876
+ isCabalMultipleCompSupported :: BuildToolVersions -> Maybe Version -> Bool
877
+ isCabalMultipleCompSupported vs ghcVersion = do
897
878
-- determine which load style is supported by this cabal cradle.
898
- case (cabal_version, ghc_version ) of
899
- (Just cabal, Just ghc) -> pure $ ghc >= makeVersion [9 , 4 ] && cabal >= makeVersion [3 , 11 ]
900
- _ -> pure False
879
+ case (cabalVersion vs, ghcVersion ) of
880
+ (Just cabal, Just ghc) -> ghc >= makeVersion [9 , 4 ] && cabal >= makeVersion [3 , 11 ]
881
+ _ -> False
901
882
902
883
cabalAction
903
884
:: ResolvedCradles a
904
885
-> FilePath
905
886
-> Maybe FilePath
887
+ -> Maybe Version
906
888
-> Maybe String
907
889
-> LogAction IO (WithSeverity Log )
908
890
-> CradleProjectConfig
909
891
-> FilePath
910
892
-> LoadStyle
911
893
-> CradleLoadResultT IO ComponentOptions
912
- cabalAction (ResolvedCradles root cs vs) workDir ghcPath mc l projectFile fp loadStyle = do
913
- multiCompSupport <- isCabalMultipleCompSupported vs
894
+ cabalAction (ResolvedCradles root cs vs) workDir ghcPath ghcVersion mc l projectFile fp loadStyle = do
895
+ let multiCompSupport = isCabalMultipleCompSupported vs ghcVersion
914
896
-- determine which load style is supported by this cabal cradle.
915
897
determinedLoadStyle <- case loadStyle of
916
898
LoadWithContext _ | not multiCompSupport -> do
0 commit comments